summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorg Ehrke <dev@georgswebsite.de>2012-04-26 18:08:49 +0200
committerGeorg Ehrke <dev@georgswebsite.de>2012-04-26 18:08:49 +0200
commit2b10371bdeb2c8a3d5cc2617ada5cf8195c264c9 (patch)
treef25b463c90992764887416c3082098fed6ecac65
parent40f95ffdf3edf9ab45c15bd5b9018d7f4d92baa9 (diff)
parent127796218314c6b1f19ba86f74caa913375aac8d (diff)
downloadnextcloud-server-2b10371bdeb2c8a3d5cc2617ada5cf8195c264c9.tar.gz
nextcloud-server-2b10371bdeb2c8a3d5cc2617ada5cf8195c264c9.zip
fix merge conflicts
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre.includes.php127
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Backend/Abstract.php95
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Backend/PDO.php166
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Calendar.php185
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/CalendarObject.php137
-rwxr-xr-x3rdparty/Sabre/CalDAV/CalendarQueryParser.php296
-rwxr-xr-x3rdparty/Sabre/CalDAV/CalendarQueryValidator.php347
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/CalendarRootNode.php34
-rw-r--r--3rdparty/Sabre/CalDAV/Exception/InvalidICalendarObject.php18
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/ICSExportPlugin.php61
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/ICalendar.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/ICalendarObject.php10
-rw-r--r--3rdparty/Sabre/CalDAV/ICalendarUtil.php157
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Plugin.php773
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/Collection.php14
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/ProxyRead.php90
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php90
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/User.php108
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php40
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php12
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php14
-rwxr-xr-x3rdparty/Sabre/CalDAV/Schedule/IMip.php104
-rwxr-xr-x3rdparty/Sabre/CalDAV/Schedule/IOutbox.php16
-rwxr-xr-x3rdparty/Sabre/CalDAV/Schedule/Outbox.php152
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Server.php21
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/UserCalendars.php132
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Version.php6
-rw-r--r--3rdparty/Sabre/CalDAV/XMLUtil.php208
-rwxr-xr-x3rdparty/Sabre/CalDAV/includes.php43
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/AddressBook.php125
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/AddressBookQueryParser.php70
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/AddressBookRoot.php38
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Backend/Abstract.php145
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Backend/PDO.php187
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Card.php136
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/IAddressBook.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/ICard.php12
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/IDirectory.php4
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Plugin.php252
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php30
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/UserAddressBooks.php119
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Version.php6
-rwxr-xr-x3rdparty/Sabre/CardDAV/includes.php32
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php14
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php32
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/Apache.php22
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/File.php33
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/PDO.php35
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/IBackend.php12
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Plugin.php60
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/GuessContentType.php26
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php31
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/Plugin.php488
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/favicon.icobin0 -> 4286 bytes
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.pngbin0 -> 7232 bytes
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/icons/calendar.pngbin0 -> 4388 bytes
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/icons/card.pngbin0 -> 5695 bytes
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/icons/collection.pngbin0 -> 3474 bytes
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/icons/file.pngbin0 -> 2837 bytes
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/icons/parent.pngbin0 -> 3474 bytes
-rwxr-xr-x3rdparty/Sabre/DAV/Browser/assets/icons/principal.pngbin0 -> 5480 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Client.php163
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Collection.php60
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Directory.php2
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception.php25
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/BadRequest.php10
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/Conflict.php4
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/ConflictingLock.php12
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/FileNotFound.php19
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/Forbidden.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/InsufficientStorage.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/InvalidResourceType.php14
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php12
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/Locked.php26
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php11
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/NotAuthenticated.php8
-rwxr-xr-x3rdparty/Sabre/DAV/Exception/NotFound.php28
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/NotImplemented.php8
-rwxr-xr-x3rdparty/Sabre/DAV/Exception/PaymentRequired.php28
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/PreconditionFailed.php36
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php10
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php10
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FS/Directory.php79
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FS/File.php40
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FS/Node.php37
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FSExt/Directory.php85
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FSExt/File.php33
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FSExt/Node.php118
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/File.php38
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/ICollection.php62
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IExtendedCollection.php8
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IFile.php48
-rw-r--r--3rdparty/Sabre/DAV/ILockable.php38
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/INode.php22
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IProperties.php16
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IQuota.php10
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/Abstract.php34
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/FS.php62
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/File.php64
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/PDO.php66
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/LockInfo.php38
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Plugin.php227
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Mount/Plugin.php33
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Node.php16
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/ObjectTree.php63
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/GetLastModified.php36
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/Href.php50
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/HrefList.php46
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/IHref.php10
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/LockDiscovery.php44
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/ResourceType.php56
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/Response.php65
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/ResponseList.php31
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/SupportedLock.php22
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/SupportedReportSet.php39
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Server.php506
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/ServerPlugin.php38
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/SimpleCollection.php47
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/SimpleDirectory.php4
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/SimpleFile.php57
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/StringUtil.php34
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php104
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Tree.php77
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Tree/Filesystem.php57
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/URLUtil.php62
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/UUIDUtil.php20
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Version.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/XMLUtil.php45
-rwxr-xr-x3rdparty/Sabre/DAV/includes.php97
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php101
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/AceConflict.php20
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php41
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NoAbstract.php18
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php18
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php18
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/IACL.php45
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/IPrincipal.php52
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/IPrincipalBackend.php140
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Plugin.php602
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Principal.php144
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php333
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/PrincipalCollection.php12
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/Acl.php105
-rwxr-xr-x3rdparty/Sabre/DAVACL/Property/AclRestrictions.php32
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php42
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/Principal.php56
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php44
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Version.php6
-rwxr-xr-x3rdparty/Sabre/DAVACL/includes.php38
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/AWSAuth.php79
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/AbstractAuth.php44
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/BasicAuth.php20
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/DigestAuth.php70
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Request.php113
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Response.php53
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Util.php33
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Version.php8
-rwxr-xr-x3rdparty/Sabre/HTTP/includes.php27
-rw-r--r--3rdparty/Sabre/LICENCE27
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Component.php209
-rwxr-xr-x3rdparty/Sabre/VObject/Component/VAlarm.php102
-rwxr-xr-x3rdparty/Sabre/VObject/Component/VCalendar.php133
-rwxr-xr-x3rdparty/Sabre/VObject/Component/VEvent.php70
-rwxr-xr-x3rdparty/Sabre/VObject/Component/VJournal.php46
-rwxr-xr-x3rdparty/Sabre/VObject/Component/VTodo.php68
-rwxr-xr-x3rdparty/Sabre/VObject/DateTimeParser.php177
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Element.php7
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Element/DateTime.php220
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Element/MultiDateTime.php163
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/ElementList.php68
-rwxr-xr-x3rdparty/Sabre/VObject/FreeBusyGenerator.php297
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Node.php62
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Parameter.php45
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/ParseException.php6
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Property.php177
-rwxr-xr-x3rdparty/Sabre/VObject/Property/DateTime.php260
-rwxr-xr-x3rdparty/Sabre/VObject/Property/MultiDateTime.php166
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Reader.php88
-rwxr-xr-x3rdparty/Sabre/VObject/RecurrenceIterator.php1009
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Version.php8
-rwxr-xr-x3rdparty/Sabre/VObject/WindowsTimezoneMap.php128
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/includes.php50
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/autoload.php8
-rw-r--r--apps/calendar/ajax/event/edit.form.php6
-rw-r--r--apps/calendar/ajax/event/move.php12
-rw-r--r--apps/calendar/ajax/event/resize.php4
-rwxr-xr-xapps/calendar/ajax/events.php1
-rw-r--r--apps/calendar/lib/object.php14
-rw-r--r--apps/calendar/lib/search.php2
-rw-r--r--apps/contacts/ajax/uploadimport.php39
-rw-r--r--apps/contacts/css/contacts.css2
-rw-r--r--apps/contacts/import.php5
-rw-r--r--apps/contacts/js/contacts.js58
-rw-r--r--apps/contacts/templates/part.contact.php2
-rw-r--r--apps/files/ajax/scan.php3
-rw-r--r--apps/files/css/files.css8
-rw-r--r--apps/files/index.php2
-rw-r--r--apps/files/js/fileactions.js15
-rw-r--r--apps/files/js/filelist.js1
-rw-r--r--apps/files/js/files.js286
-rw-r--r--apps/files/templates/index.php5
-rw-r--r--apps/files/templates/part.list.php4
-rw-r--r--apps/files_encryption/lib/cryptstream.php15
-rw-r--r--apps/files_encryption/lib/proxy.php17
-rw-r--r--apps/files_external/lib/swift.php17
-rw-r--r--apps/files_sharing/ajax/email.php15
-rw-r--r--apps/files_sharing/ajax/toggleresharing.php13
-rw-r--r--apps/files_sharing/appinfo/app.php9
-rw-r--r--apps/files_sharing/js/settings.js9
-rw-r--r--apps/files_sharing/js/share.js21
-rw-r--r--apps/files_sharing/lib_share.php28
-rw-r--r--apps/files_sharing/settings.php9
-rw-r--r--apps/files_sharing/templates/settings.php6
-rw-r--r--apps/files_versions/appinfo/app.php1
-rw-r--r--apps/files_versions/css/versions.css5
-rw-r--r--apps/files_versions/history.php39
-rw-r--r--apps/files_versions/js/versions.js65
-rw-r--r--apps/files_versions/templates/history.php4
-rw-r--r--apps/files_versions/versions.php2
-rw-r--r--apps/user_ldap/appinfo/database.xml95
-rw-r--r--apps/user_ldap/appinfo/version2
-rw-r--r--apps/user_ldap/group_ldap.php63
-rw-r--r--apps/user_ldap/js/settings.js3
-rw-r--r--apps/user_ldap/lib_ldap.php407
-rw-r--r--apps/user_ldap/settings.php9
-rw-r--r--apps/user_ldap/templates/settings.php31
-rw-r--r--core/img/actions/history.pngbin0 -> 370 bytes
-rw-r--r--core/img/actions/history.svg240
-rw-r--r--files/js/jquery.fileupload.js866
-rw-r--r--files/js/jquery.iframe-transport.js165
-rw-r--r--lib/base.php2
-rw-r--r--lib/connector/sabre/directory.php2
-rw-r--r--lib/connector/sabre/principal.php4
-rw-r--r--lib/filecache.php15
-rw-r--r--lib/filesystem.php48
-rw-r--r--lib/filesystemview.php19
-rwxr-xr-xlib/helper.php12
-rw-r--r--lib/vobject.php6
-rw-r--r--settings/templates/help.php1
241 files changed, 11916 insertions, 5403 deletions
diff --git a/3rdparty/Sabre.includes.php b/3rdparty/Sabre.includes.php
index d41b287b77d..c1334373663 100644..100755
--- a/3rdparty/Sabre.includes.php
+++ b/3rdparty/Sabre.includes.php
@@ -3,125 +3,24 @@
/**
* Library include file
*
+ * This file is deprecated, don't use it!
+ * Instead, use the specific includes files that are in the sub-packages.
+ *
+ * Sabre/DAV/includes.php
+ * Sabre/HTTP/includes.php
+ *
+ * etc..
+ *
* This file contains all includes to the rest of the SabreDAV library
- * Make sure the lib/ directory is in PHP's include_path
+ * Make sure the lib/ directory is in PHP's include_path.
*
* @package Sabre
- * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @deprecated Don't use this file, it will be remove in a future version
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-/* Utilities */
-include 'Sabre/HTTP/Util.php';
-include 'Sabre/HTTP/Response.php';
-include 'Sabre/HTTP/Request.php';
-include 'Sabre/HTTP/AbstractAuth.php';
-include 'Sabre/HTTP/BasicAuth.php';
-include 'Sabre/HTTP/DigestAuth.php';
-include 'Sabre/HTTP/AWSAuth.php';
-
-/* Version */
-include 'Sabre/DAV/Version.php';
-include 'Sabre/HTTP/Version.php';
-
-/* Exceptions */
-include 'Sabre/DAV/Exception.php';
-include 'Sabre/DAV/Exception/BadRequest.php';
-include 'Sabre/DAV/Exception/Conflict.php';
-include 'Sabre/DAV/Exception/FileNotFound.php';
-include 'Sabre/DAV/Exception/InsufficientStorage.php';
-include 'Sabre/DAV/Exception/Locked.php';
-include 'Sabre/DAV/Exception/LockTokenMatchesRequestUri.php';
-include 'Sabre/DAV/Exception/MethodNotAllowed.php';
-include 'Sabre/DAV/Exception/NotImplemented.php';
-include 'Sabre/DAV/Exception/Forbidden.php';
-include 'Sabre/DAV/Exception/PreconditionFailed.php';
-include 'Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php';
-include 'Sabre/DAV/Exception/UnsupportedMediaType.php';
-include 'Sabre/DAV/Exception/NotAuthenticated.php';
-
-include 'Sabre/DAV/Exception/ConflictingLock.php';
-include 'Sabre/DAV/Exception/ReportNotImplemented.php';
-include 'Sabre/DAV/Exception/InvalidResourceType.php';
-
-/* Properties */
-include 'Sabre/DAV/Property.php';
-include 'Sabre/DAV/Property/GetLastModified.php';
-include 'Sabre/DAV/Property/ResourceType.php';
-include 'Sabre/DAV/Property/SupportedLock.php';
-include 'Sabre/DAV/Property/LockDiscovery.php';
-include 'Sabre/DAV/Property/IHref.php';
-include 'Sabre/DAV/Property/Href.php';
-include 'Sabre/DAV/Property/HrefList.php';
-include 'Sabre/DAV/Property/SupportedReportSet.php';
-include 'Sabre/DAV/Property/Response.php';
-include 'Sabre/DAV/Property/ResponseList.php';
-
-/* Node interfaces */
-include 'Sabre/DAV/INode.php';
-include 'Sabre/DAV/IFile.php';
-include 'Sabre/DAV/ICollection.php';
-include 'Sabre/DAV/IProperties.php';
-include 'Sabre/DAV/ILockable.php';
-include 'Sabre/DAV/IQuota.php';
-include 'Sabre/DAV/IExtendedCollection.php';
-
-/* Node abstract implementations */
-include 'Sabre/DAV/Node.php';
-include 'Sabre/DAV/File.php';
-include 'Sabre/DAV/Collection.php';
-include 'Sabre/DAV/Directory.php';
-
-/* Utilities */
-include 'Sabre/DAV/SimpleCollection.php';
-include 'Sabre/DAV/SimpleDirectory.php';
-include 'Sabre/DAV/XMLUtil.php';
-include 'Sabre/DAV/URLUtil.php';
-
-/* Filesystem implementation */
-include 'Sabre/DAV/FS/Node.php';
-include 'Sabre/DAV/FS/File.php';
-include 'Sabre/DAV/FS/Directory.php';
-
-/* Advanced filesystem implementation */
-include 'Sabre/DAV/FSExt/Node.php';
-include 'Sabre/DAV/FSExt/File.php';
-include 'Sabre/DAV/FSExt/Directory.php';
-
-/* Trees */
-include 'Sabre/DAV/Tree.php';
-include 'Sabre/DAV/ObjectTree.php';
-include 'Sabre/DAV/Tree/Filesystem.php';
-
-/* Server */
-include 'Sabre/DAV/Server.php';
-include 'Sabre/DAV/ServerPlugin.php';
-
-/* Browser */
-include 'Sabre/DAV/Browser/Plugin.php';
-include 'Sabre/DAV/Browser/MapGetToPropFind.php';
-include 'Sabre/DAV/Browser/GuessContentType.php';
-
-/* Locks */
-include 'Sabre/DAV/Locks/LockInfo.php';
-include 'Sabre/DAV/Locks/Plugin.php';
-include 'Sabre/DAV/Locks/Backend/Abstract.php';
-include 'Sabre/DAV/Locks/Backend/FS.php';
-include 'Sabre/DAV/Locks/Backend/PDO.php';
-
-/* Temporary File Filter plugin */
-include 'Sabre/DAV/TemporaryFileFilterPlugin.php';
-
-/* Authentication plugin */
-include 'Sabre/DAV/Auth/Plugin.php';
-include 'Sabre/DAV/Auth/IBackend.php';
-include 'Sabre/DAV/Auth/Backend/AbstractDigest.php';
-include 'Sabre/DAV/Auth/Backend/AbstractBasic.php';
-include 'Sabre/DAV/Auth/Backend/File.php';
-include 'Sabre/DAV/Auth/Backend/PDO.php';
-
-/* DavMount plugin */
-include 'Sabre/DAV/Mount/Plugin.php';
+include 'Sabre/HTTP/includes.php';
+include 'Sabre/DAV/includes.php';
diff --git a/3rdparty/Sabre/CalDAV/Backend/Abstract.php b/3rdparty/Sabre/CalDAV/Backend/Abstract.php
index b694eef49e4..7aba1d69ffe 100644..100755
--- a/3rdparty/Sabre/CalDAV/Backend/Abstract.php
+++ b/3rdparty/Sabre/CalDAV/Backend/Abstract.php
@@ -2,10 +2,10 @@
/**
* Abstract Calendaring backend. Extend this class to create your own backends.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -17,16 +17,16 @@ abstract class Sabre_CalDAV_Backend_Abstract {
* Every project is an array with the following keys:
* * id, a unique id that will be used by other functions to modify the
* calendar. This can be the same as the uri or a database key.
- * * uri, which the basename of the uri with which the calendar is
+ * * uri, which the basename of the uri with which the calendar is
* accessed.
- * * principalUri. The owner of the calendar. Almost always the same as
+ * * principaluri. The owner of the calendar. Almost always the same as
* principalUri passed to this method.
*
* Furthermore it can contain webdav properties in clark notation. A very
- * common one is '{DAV:}displayname'.
+ * common one is '{DAV:}displayname'.
*
- * @param string $principalUri
- * @return array
+ * @param string $principalUri
+ * @return array
*/
abstract function getCalendarsForUser($principalUri);
@@ -39,9 +39,9 @@ abstract class Sabre_CalDAV_Backend_Abstract {
* @param string $principalUri
* @param string $calendarUri
* @param array $properties
- * @return void
+ * @return void
*/
- abstract function createCalendar($principalUri,$calendarUri,array $properties);
+ abstract function createCalendar($principalUri,$calendarUri,array $properties);
/**
* Updates properties for a calendar.
@@ -56,7 +56,7 @@ abstract class Sabre_CalDAV_Backend_Abstract {
* If the operation was successful, true can be returned.
* If the operation failed, false can be returned.
*
- * Deletion of a non-existant property is always succesful.
+ * Deletion of a non-existent property is always successful.
*
* Lastly, it is optional to return detailed information about any
* failures. In this case an array should be returned with the following
@@ -71,24 +71,24 @@ abstract class Sabre_CalDAV_Backend_Abstract {
* )
* )
*
- * In this example it was forbidden to update {DAV:}displayname.
+ * In this example it was forbidden to update {DAV:}displayname.
* (403 Forbidden), which in turn also caused {DAV:}owner to fail
* (424 Failed Dependency) because the request needs to be atomic.
*
* @param string $calendarId
* @param array $mutations
- * @return bool|array
+ * @return bool|array
*/
public function updateCalendar($calendarId, array $mutations) {
-
- return false;
+
+ return false;
}
/**
- * Delete a calendar and all it's objects
- *
- * @param string $calendarId
+ * Delete a calendar and all it's objects
+ *
+ * @param string $calendarId
* @return void
*/
abstract function deleteCalendar($calendarId);
@@ -98,22 +98,27 @@ abstract class Sabre_CalDAV_Backend_Abstract {
*
* Every item contains an array with the following keys:
* * id - unique identifier which will be used for subsequent updates
- * * calendardata - The iCalendar-compatible calnedar data
+ * * calendardata - The iCalendar-compatible calendar data
* * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
* * lastmodified - a timestamp of the last modification time
- * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
+ * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
* ' "abcdef"')
* * calendarid - The calendarid as it was passed to this function.
+ * * size - The size of the calendar objects, in bytes.
*
- * Note that the etag is optional, but it's highly encouraged to return for
+ * Note that the etag is optional, but it's highly encouraged to return for
* speed reasons.
*
- * The calendardata is also optional. If it's not returned
- * 'getCalendarObject' will be called later, which *is* expected to return
+ * The calendardata is also optional. If it's not returned
+ * 'getCalendarObject' will be called later, which *is* expected to return
* calendardata.
- *
- * @param string $calendarId
- * @return array
+ *
+ * If neither etag or size are specified, the calendardata will be
+ * used/fetched to determine these numbers. If both are specified the
+ * amount of times this is needed is reduced by a great degree.
+ *
+ * @param string $calendarId
+ * @return array
*/
abstract function getCalendarObjects($calendarId);
@@ -121,41 +126,41 @@ abstract class Sabre_CalDAV_Backend_Abstract {
* Returns information from a single calendar object, based on it's object
* uri.
*
- * The returned array must have the same keys as getCalendarObjects. The
- * 'calendardata' object is required here though, while it's not required
+ * The returned array must have the same keys as getCalendarObjects. The
+ * 'calendardata' object is required here though, while it's not required
* for getCalendarObjects.
- *
- * @param string $calendarId
- * @param string $objectUri
- * @return array
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return array
*/
abstract function getCalendarObject($calendarId,$objectUri);
/**
- * Creates a new calendar object.
- *
- * @param string $calendarId
- * @param string $objectUri
- * @param string $calendarData
+ * Creates a new calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
* @return void
*/
abstract function createCalendarObject($calendarId,$objectUri,$calendarData);
/**
- * Updates an existing calendarobject, based on it's uri.
- *
- * @param string $calendarId
- * @param string $objectUri
- * @param string $calendarData
+ * Updates an existing calendarobject, based on it's uri.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
* @return void
*/
abstract function updateCalendarObject($calendarId,$objectUri,$calendarData);
/**
- * Deletes an existing calendar object.
- *
- * @param string $calendarId
- * @param string $objectUri
+ * Deletes an existing calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
* @return void
*/
abstract function deleteCalendarObject($calendarId,$objectUri);
diff --git a/3rdparty/Sabre/CalDAV/Backend/PDO.php b/3rdparty/Sabre/CalDAV/Backend/PDO.php
index 7b1b33b912e..ddacf940c74 100644..100755
--- a/3rdparty/Sabre/CalDAV/Backend/PDO.php
+++ b/3rdparty/Sabre/CalDAV/Backend/PDO.php
@@ -3,35 +3,35 @@
/**
* PDO CalDAV backend
*
- * This backend is used to store calendar-data in a PDO database, such as
+ * This backend is used to store calendar-data in a PDO database, such as
* sqlite or MySQL
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
/**
- * pdo
- *
+ * pdo
+ *
* @var PDO
*/
protected $pdo;
/**
- * The table name that will be used for calendars
- *
- * @var string
+ * The table name that will be used for calendars
+ *
+ * @var string
*/
protected $calendarTableName;
/**
- * The table name that will be used for calendar objects
- *
- * @var string
+ * The table name that will be used for calendar objects
+ *
+ * @var string
*/
protected $calendarObjectTableName;
@@ -39,7 +39,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
* List of CalDAV properties, and how they map to database fieldnames
*
* Add your own properties by simply adding on to this array
- *
+ *
* @var array
*/
public $propertyMap = array(
@@ -51,9 +51,11 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
);
/**
- * Creates the backend
- *
- * @param PDO $pdo
+ * Creates the backend
+ *
+ * @param PDO $pdo
+ * @param string $calendarTableName
+ * @param string $calendarObjectTableName
*/
public function __construct(PDO $pdo, $calendarTableName = 'calendars', $calendarObjectTableName = 'calendarobjects') {
@@ -69,16 +71,16 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
* Every project is an array with the following keys:
* * id, a unique id that will be used by other functions to modify the
* calendar. This can be the same as the uri or a database key.
- * * uri, which the basename of the uri with which the calendar is
+ * * uri, which the basename of the uri with which the calendar is
* accessed.
- * * principalUri. The owner of the calendar. Almost always the same as
+ * * principaluri. The owner of the calendar. Almost always the same as
* principalUri passed to this method.
*
* Furthermore it can contain webdav properties in clark notation. A very
- * common one is '{DAV:}displayname'.
+ * common one is '{DAV:}displayname'.
*
- * @param string $principalUri
- * @return array
+ * @param string $principalUri
+ * @return array
*/
public function getCalendarsForUser($principalUri) {
@@ -89,15 +91,18 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
$fields[] = 'components';
$fields[] = 'principaluri';
- // Making fields a comma-delimited list
+ // Making fields a comma-delimited list
$fields = implode(', ', $fields);
- $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM `".$this->calendarTableName."` WHERE principaluri = ?");
+ $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM ".$this->calendarTableName." WHERE principaluri = ? ORDER BY calendarorder ASC");
$stmt->execute(array($principalUri));
$calendars = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
- $components = explode(',',$row['components']);
+ $components = array();
+ if ($row['components']) {
+ $components = explode(',',$row['components']);
+ }
$calendar = array(
'id' => $row['id'],
@@ -106,7 +111,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
'{' . Sabre_CalDAV_Plugin::NS_CALENDARSERVER . '}getctag' => $row['ctag']?$row['ctag']:'0',
'{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set' => new Sabre_CalDAV_Property_SupportedCalendarComponentSet($components),
);
-
+
foreach($this->propertyMap as $xmlName=>$dbName) {
$calendar[$xmlName] = $row[$dbName];
@@ -129,8 +134,9 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
* @param string $principalUri
* @param string $calendarUri
* @param array $properties
+ * @return string
*/
- public function createCalendar($principalUri,$calendarUri, array $properties) {
+ public function createCalendar($principalUri, $calendarUri, array $properties) {
$fieldNames = array(
'principaluri',
@@ -158,13 +164,12 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
foreach($this->propertyMap as $xmlName=>$dbName) {
if (isset($properties[$xmlName])) {
- $myValue = $properties[$xmlName];
$values[':' . $dbName] = $properties[$xmlName];
$fieldNames[] = $dbName;
}
}
- $stmt = $this->pdo->prepare("INSERT INTO `".$this->calendarTableName."` (".implode(', ', $fieldNames).") VALUES (".implode(', ',array_keys($values)).")");
+ $stmt = $this->pdo->prepare("INSERT INTO ".$this->calendarTableName." (".implode(', ', $fieldNames).") VALUES (".implode(', ',array_keys($values)).")");
$stmt->execute($values);
return $this->pdo->lastInsertId();
@@ -184,7 +189,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
* If the operation was successful, true can be returned.
* If the operation failed, false can be returned.
*
- * Deletion of a non-existant property is always succesful.
+ * Deletion of a non-existent property is always successful.
*
* Lastly, it is optional to return detailed information about any
* failures. In this case an array should be returned with the following
@@ -199,13 +204,13 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
* )
* )
*
- * In this example it was forbidden to update {DAV:}displayname.
+ * In this example it was forbidden to update {DAV:}displayname.
* (403 Forbidden), which in turn also caused {DAV:}owner to fail
* (424 Failed Dependency) because the request needs to be atomic.
*
* @param string $calendarId
- * @param array $mutations
- * @return bool|array
+ * @param array $mutations
+ * @return bool|array
*/
public function updateCalendar($calendarId, array $mutations) {
@@ -220,7 +225,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
foreach($mutations as $propertyName=>$propertyValue) {
- // We don't know about this property.
+ // We don't know about this property.
if (!isset($this->propertyMap[$propertyName])) {
$hasError = true;
$result[403][$propertyName] = null;
@@ -230,7 +235,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
$fieldName = $this->propertyMap[$propertyName];
$newValues[$fieldName] = $propertyValue;
-
+
}
// If there were any errors we need to fail the request
@@ -258,55 +263,60 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
}
$valuesSql[] = 'ctag = ctag + 1';
- $stmt = $this->pdo->prepare("UPDATE `" . $this->calendarTableName . "` SET " . implode(', ',$valuesSql) . " WHERE id = ?");
- $newValues['id'] = $calendarId;
+ $stmt = $this->pdo->prepare("UPDATE " . $this->calendarTableName . " SET " . implode(', ',$valuesSql) . " WHERE id = ?");
+ $newValues['id'] = $calendarId;
$stmt->execute(array_values($newValues));
- return true;
+ return true;
}
/**
- * Delete a calendar and all it's objects
- *
- * @param string $calendarId
+ * Delete a calendar and all it's objects
+ *
+ * @param string $calendarId
* @return void
*/
public function deleteCalendar($calendarId) {
- $stmt = $this->pdo->prepare('DELETE FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ?');
+ $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?');
$stmt->execute(array($calendarId));
- $stmt = $this->pdo->prepare('DELETE FROM `'.$this->calendarTableName.'` WHERE id = ?');
+ $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarTableName.' WHERE id = ?');
$stmt->execute(array($calendarId));
}
/**
- * Returns all calendar objects within a calendar.
+ * Returns all calendar objects within a calendar.
*
* Every item contains an array with the following keys:
* * id - unique identifier which will be used for subsequent updates
- * * calendardata - The iCalendar-compatible calnedar data
+ * * calendardata - The iCalendar-compatible calendar data
* * uri - a unique key which will be used to construct the uri. This can be any arbitrary string.
* * lastmodified - a timestamp of the last modification time
- * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
+ * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
* ' "abcdef"')
* * calendarid - The calendarid as it was passed to this function.
+ * * size - The size of the calendar objects, in bytes.
*
- * Note that the etag is optional, but it's highly encouraged to return for
+ * Note that the etag is optional, but it's highly encouraged to return for
* speed reasons.
*
- * The calendardata is also optional. If it's not returned
- * 'getCalendarObject' will be called later, which *is* expected to return
+ * The calendardata is also optional. If it's not returned
+ * 'getCalendarObject' will be called later, which *is* expected to return
* calendardata.
- *
- * @param string $calendarId
- * @return array
+ *
+ * If neither etag or size are specified, the calendardata will be
+ * used/fetched to determine these numbers. If both are specified the
+ * amount of times this is needed is reduced by a great degree.
+ *
+ * @param string $calendarId
+ * @return array
*/
public function getCalendarObjects($calendarId) {
- $stmt = $this->pdo->prepare('SELECT * FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ?');
+ $stmt = $this->pdo->prepare('SELECT * FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?');
$stmt->execute(array($calendarId));
return $stmt->fetchAll();
@@ -316,68 +326,68 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
* Returns information from a single calendar object, based on it's object
* uri.
*
- * The returned array must have the same keys as getCalendarObjects. The
- * 'calendardata' object is required here though, while it's not required
+ * The returned array must have the same keys as getCalendarObjects. The
+ * 'calendardata' object is required here though, while it's not required
* for getCalendarObjects.
- *
- * @param string $calendarId
- * @param string $objectUri
- * @return array
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return array
*/
public function getCalendarObject($calendarId,$objectUri) {
- $stmt = $this->pdo->prepare('SELECT * FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ? AND uri = ?');
+ $stmt = $this->pdo->prepare('SELECT * FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?');
$stmt->execute(array($calendarId, $objectUri));
return $stmt->fetch();
}
/**
- * Creates a new calendar object.
- *
- * @param string $calendarId
- * @param string $objectUri
- * @param string $calendarData
+ * Creates a new calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
* @return void
*/
public function createCalendarObject($calendarId,$objectUri,$calendarData) {
- $stmt = $this->pdo->prepare('INSERT INTO `'.$this->calendarObjectTableName.'` (calendarid, uri, calendardata, lastmodified) VALUES (?,?,?,?)');
+ $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarObjectTableName.' (calendarid, uri, calendardata, lastmodified) VALUES (?,?,?,?)');
$stmt->execute(array($calendarId,$objectUri,$calendarData,time()));
- $stmt = $this->pdo->prepare('UPDATE `'.$this->calendarTableName.'` SET ctag = ctag + 1 WHERE id = ?');
+ $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET ctag = ctag + 1 WHERE id = ?');
$stmt->execute(array($calendarId));
}
/**
- * Updates an existing calendarobject, based on it's uri.
- *
- * @param string $calendarId
- * @param string $objectUri
- * @param string $calendarData
+ * Updates an existing calendarobject, based on it's uri.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
* @return void
*/
public function updateCalendarObject($calendarId,$objectUri,$calendarData) {
- $stmt = $this->pdo->prepare('UPDATE `'.$this->calendarObjectTableName.'` SET calendardata = ?, lastmodified = ? WHERE calendarid = ? AND uri = ?');
+ $stmt = $this->pdo->prepare('UPDATE '.$this->calendarObjectTableName.' SET calendardata = ?, lastmodified = ? WHERE calendarid = ? AND uri = ?');
$stmt->execute(array($calendarData,time(),$calendarId,$objectUri));
- $stmt = $this->pdo->prepare('UPDATE `'.$this->calendarTableName.'` SET ctag = ctag + 1 WHERE id = ?');
+ $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET ctag = ctag + 1 WHERE id = ?');
$stmt->execute(array($calendarId));
}
/**
- * Deletes an existing calendar object.
- *
- * @param string $calendarId
- * @param string $objectUri
+ * Deletes an existing calendar object.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
* @return void
*/
public function deleteCalendarObject($calendarId,$objectUri) {
- $stmt = $this->pdo->prepare('DELETE FROM `'.$this->calendarObjectTableName.'` WHERE calendarid = ? AND uri = ?');
+ $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?');
$stmt->execute(array($calendarId,$objectUri));
- $stmt = $this->pdo->prepare('UPDATE `'. $this->calendarTableName .'` SET ctag = ctag + 1 WHERE id = ?');
+ $stmt = $this->pdo->prepare('UPDATE '. $this->calendarTableName .' SET ctag = ctag + 1 WHERE id = ?');
$stmt->execute(array($calendarId));
}
diff --git a/3rdparty/Sabre/CalDAV/Calendar.php b/3rdparty/Sabre/CalDAV/Calendar.php
index 0d2b3875771..623df2dd1b8 100644..100755
--- a/3rdparty/Sabre/CalDAV/Calendar.php
+++ b/3rdparty/Sabre/CalDAV/Calendar.php
@@ -5,42 +5,42 @@
*
* A calendar can contain multiple TODO and or Events. These are represented
* as Sabre_CalDAV_CalendarObject objects.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
/**
- * This is an array with calendar information
- *
- * @var array
+ * This is an array with calendar information
+ *
+ * @var array
*/
protected $calendarInfo;
/**
- * CalDAV backend
- *
- * @var Sabre_CalDAV_Backend_Abstract
+ * CalDAV backend
+ *
+ * @var Sabre_CalDAV_Backend_Abstract
*/
protected $caldavBackend;
/**
* Principal backend
- *
+ *
* @var Sabre_DAVACL_IPrincipalBackend
*/
protected $principalBackend;
/**
- * Constructor
- *
- * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
- * @param array $calendarInfo
- * @return void
+ * Constructor
+ *
+ * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+ * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+ * @param array $calendarInfo
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $calendarInfo) {
@@ -52,9 +52,9 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
}
/**
- * Returns the name of the calendar
- *
- * @return string
+ * Returns the name of the calendar
+ *
+ * @return string
*/
public function getName() {
@@ -63,10 +63,10 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
}
/**
- * Updates properties such as the display name and description
- *
- * @param array $mutations
- * @return array
+ * Updates properties such as the display name and description
+ *
+ * @param array $mutations
+ * @return array
*/
public function updateProperties($mutations) {
@@ -75,10 +75,10 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
}
/**
- * Returns the list of properties
- *
- * @param array $properties
- * @return array
+ * Returns the list of properties
+ *
+ * @param array $requestedProperties
+ * @return array
*/
public function getProperties($requestedProperties) {
@@ -86,16 +86,16 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
foreach($requestedProperties as $prop) switch($prop) {
- case '{urn:ietf:params:xml:ns:caldav}supported-calendar-data' :
- $response[$prop] = new Sabre_CalDAV_Property_SupportedCalendarData();
+ case '{urn:ietf:params:xml:ns:caldav}supported-calendar-data' :
+ $response[$prop] = new Sabre_CalDAV_Property_SupportedCalendarData();
break;
- case '{urn:ietf:params:xml:ns:caldav}supported-collation-set' :
- $response[$prop] = new Sabre_CalDAV_Property_SupportedCollationSet();
+ case '{urn:ietf:params:xml:ns:caldav}supported-collation-set' :
+ $response[$prop] = new Sabre_CalDAV_Property_SupportedCollationSet();
break;
case '{DAV:}owner' :
$response[$prop] = new Sabre_DAVACL_Property_Principal(Sabre_DAVACL_Property_Principal::HREF,$this->calendarInfo['principaluri']);
break;
- default :
+ default :
if (isset($this->calendarInfo[$prop])) $response[$prop] = $this->calendarInfo[$prop];
break;
@@ -108,22 +108,22 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
* Returns a calendar object
*
* The contained calendar objects are for example Events or Todo's.
- *
- * @param string $name
- * @return Sabre_DAV_ICalendarObject
+ *
+ * @param string $name
+ * @return Sabre_DAV_ICalendarObject
*/
public function getChild($name) {
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name);
- if (!$obj) throw new Sabre_DAV_Exception_FileNotFound('Calendar object not found');
+ if (!$obj) throw new Sabre_DAV_Exception_NotFound('Calendar object not found');
return new Sabre_CalDAV_CalendarObject($this->caldavBackend,$this->calendarInfo,$obj);
}
/**
- * Returns the full list of calendar objects
- *
- * @return array
+ * Returns the full list of calendar objects
+ *
+ * @return array
*/
public function getChildren() {
@@ -137,17 +137,17 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
}
/**
- * Checks if a child-node exists.
- *
- * @param string $name
- * @return bool
+ * Checks if a child-node exists.
+ *
+ * @param string $name
+ * @return bool
*/
public function childExists($name) {
$obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name);
- if (!$obj)
+ if (!$obj)
return false;
- else
+ else
return true;
}
@@ -156,8 +156,8 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
* Creates a new directory
*
* We actually block this, as subdirectories are not allowed in calendars.
- *
- * @param string $name
+ *
+ * @param string $name
* @return void
*/
public function createDirectory($name) {
@@ -170,32 +170,23 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
* Creates a new file
*
* The contents of the new file must be a valid ICalendar string.
- *
- * @param string $name
- * @param resource $calendarData
- * @return void
+ *
+ * @param string $name
+ * @param resource $calendarData
+ * @return string|null
*/
public function createFile($name,$calendarData = null) {
- $calendarData = stream_get_contents($calendarData);
- // Converting to UTF-8, if needed
- $calendarData = Sabre_DAV_StringUtil::ensureUTF8($calendarData);
-
- $supportedComponents = $this->calendarInfo['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set'];
- if ($supportedComponents) {
- $supportedComponents = $supportedComponents->getValue();
- } else {
- $supportedComponents = null;
+ if (is_resource($calendarData)) {
+ $calendarData = stream_get_contents($calendarData);
}
- Sabre_CalDAV_ICalendarUtil::validateICalendarObject($calendarData, $supportedComponents);
-
- $this->caldavBackend->createCalendarObject($this->calendarInfo['id'],$name,$calendarData);
+ return $this->caldavBackend->createCalendarObject($this->calendarInfo['id'],$name,$calendarData);
}
/**
- * Deletes the calendar.
- *
+ * Deletes the calendar.
+ *
* @return void
*/
public function delete() {
@@ -205,10 +196,10 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
}
/**
- * Renames the calendar. Note that most calendars use the
- * {DAV:}displayname to display a name to display a name.
- *
- * @param string $newName
+ * Renames the calendar. Note that most calendars use the
+ * {DAV:}displayname to display a name to display a name.
+ *
+ * @param string $newName
* @return void
*/
public function setName($newName) {
@@ -219,7 +210,7 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
/**
* Returns the last modification date as a unix timestamp.
- *
+ *
* @return void
*/
public function getLastModified() {
@@ -231,8 +222,8 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
public function getOwner() {
@@ -245,8 +236,8 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
public function getGroup() {
@@ -258,13 +249,13 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
@@ -294,6 +285,11 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
'protected' => true,
),
+ array(
+ 'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy',
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => true,
+ ),
);
@@ -302,9 +298,9 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
public function setACL(array $acl) {
@@ -313,6 +309,35 @@ class Sabre_CalDAV_Calendar implements Sabre_CalDAV_ICalendar, Sabre_DAV_IProper
}
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ $default = Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet();
+
+ // We need to inject 'read-free-busy' in the tree, aggregated under
+ // {DAV:}read.
+ foreach($default['aggregates'] as &$agg) {
+ if ($agg['privilege'] !== '{DAV:}read') continue;
+
+ $agg['aggregates'][] = array(
+ 'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}read-free-busy',
+ );
+
+ }
+ return $default;
+
+ }
}
diff --git a/3rdparty/Sabre/CalDAV/CalendarObject.php b/3rdparty/Sabre/CalDAV/CalendarObject.php
index 0c99f18deb7..72f0a578d16 100644..100755
--- a/3rdparty/Sabre/CalDAV/CalendarObject.php
+++ b/3rdparty/Sabre/CalDAV/CalendarObject.php
@@ -1,43 +1,43 @@
<?php
/**
- * The CalendarObject represents a single VEVENT or VTODO within a Calendar.
- *
+ * The CalendarObject represents a single VEVENT or VTODO within a Calendar.
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV_ICalendarObject, Sabre_DAVACL_IACL {
/**
- * Sabre_CalDAV_Backend_Abstract
- *
- * @var array
+ * Sabre_CalDAV_Backend_Abstract
+ *
+ * @var array
*/
protected $caldavBackend;
/**
- * Array with information about this CalendarObject
- *
- * @var array
+ * Array with information about this CalendarObject
+ *
+ * @var array
*/
protected $objectData;
/**
* Array with information about the containing calendar
- *
- * @var array
+ *
+ * @var array
*/
protected $calendarInfo;
/**
- * Constructor
- *
+ * Constructor
+ *
* @param Sabre_CalDAV_Backend_Abstract $caldavBackend
* @param array $calendarInfo
- * @param array $objectData
+ * @param array $objectData
*/
public function __construct(Sabre_CalDAV_Backend_Abstract $caldavBackend,array $calendarInfo,array $objectData) {
@@ -56,9 +56,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
}
/**
- * Returns the uri for this object
- *
- * @return string
+ * Returns the uri for this object
+ *
+ * @return string
*/
public function getName() {
@@ -67,9 +67,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
}
/**
- * Returns the ICalendar-formatted object
- *
- * @return string
+ * Returns the ICalendar-formatted object
+ *
+ * @return string
*/
public function get() {
@@ -83,35 +83,27 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
}
/**
- * Updates the ICalendar-formatted object
- *
- * @param string $calendarData
- * @return void
+ * Updates the ICalendar-formatted object
+ *
+ * @param string $calendarData
+ * @return void
*/
public function put($calendarData) {
- if (is_resource($calendarData))
+ if (is_resource($calendarData)) {
$calendarData = stream_get_contents($calendarData);
-
- // Converting to UTF-8, if needed
- $calendarData = Sabre_DAV_StringUtil::ensureUTF8($calendarData);
-
- $supportedComponents = $this->calendarInfo['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set'];
- if ($supportedComponents) {
- $supportedComponents = $supportedComponents->getValue();
- } else {
- $supportedComponents = null;
}
- Sabre_CalDAV_ICalendarUtil::validateICalendarObject($calendarData, $supportedComponents);
-
- $this->caldavBackend->updateCalendarObject($this->calendarInfo['id'],$this->objectData['uri'],$calendarData);
+ $etag = $this->caldavBackend->updateCalendarObject($this->calendarInfo['id'],$this->objectData['uri'],$calendarData);
$this->objectData['calendardata'] = $calendarData;
+ $this->objectData['etag'] = $etag;
+
+ return $etag;
}
/**
- * Deletes the calendar object
- *
+ * Deletes the calendar object
+ *
* @return void
*/
public function delete() {
@@ -121,9 +113,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
}
/**
- * Returns the mime content-type
- *
- * @return string
+ * Returns the mime content-type
+ *
+ * @return string
*/
public function getContentType() {
@@ -134,9 +126,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
/**
* Returns an ETag for this object.
*
- * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
- *
- * @return string
+ * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
+ *
+ * @return string
*/
public function getETag() {
@@ -150,8 +142,8 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
/**
* Returns the last modification date as a unix timestamp
- *
- * @return time
+ *
+ * @return time
*/
public function getLastModified() {
@@ -160,21 +152,25 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
}
/**
- * Returns the size of this object in bytes
- *
+ * Returns the size of this object in bytes
+ *
* @return int
*/
public function getSize() {
- return strlen($this->objectData['calendardata']);
+ if (array_key_exists('size',$this->objectData)) {
+ return $this->objectData['size'];
+ } else {
+ return strlen($this->get());
+ }
}
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
public function getOwner() {
@@ -187,8 +183,8 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
public function getGroup() {
@@ -200,13 +196,13 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
@@ -244,9 +240,9 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
public function setACL(array $acl) {
@@ -255,6 +251,23 @@ class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_CalDAV
}
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ return null;
+
+ }
}
diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryParser.php b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
new file mode 100755
index 00000000000..bd0d343382f
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
@@ -0,0 +1,296 @@
+<?php
+
+/**
+ * Parses the calendar-query report request body.
+ *
+ * Whoever designed this format, and the CalDAV equivalent even more so,
+ * has no feel for design.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_CalendarQueryParser {
+
+ /**
+ * List of requested properties the client wanted
+ *
+ * @var array
+ */
+ public $requestedProperties;
+
+ /**
+ * List of property/component filters.
+ *
+ * @var array
+ */
+ public $filters;
+
+ /**
+ * This property will contain null if CALDAV:expand was not specified,
+ * otherwise it will contain an array with 2 elements (start, end). Each
+ * contain a DateTime object.
+ *
+ * If expand is specified, recurring calendar objects are to be expanded
+ * into their individual components, and only the components that fall
+ * within the specified time-range are to be returned.
+ *
+ * For more details, see rfc4791, section 9.6.5.
+ *
+ * @var null|array
+ */
+ public $expand;
+
+ /**
+ * DOM Document
+ *
+ * @var DOMDocument
+ */
+ protected $dom;
+
+ /**
+ * DOM XPath object
+ *
+ * @var DOMXPath
+ */
+ protected $xpath;
+
+ /**
+ * Creates the parser
+ *
+ * @param DOMDocument $dom
+ */
+ public function __construct(DOMDocument $dom) {
+
+ $this->dom = $dom;
+
+ $this->xpath = new DOMXPath($dom);
+ $this->xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
+ $this->xpath->registerNameSpace('dav','urn:DAV');
+
+ }
+
+ /**
+ * Parses the request.
+ *
+ * @return void
+ */
+ public function parse() {
+
+ $filterNode = null;
+
+ $filter = $this->xpath->query('/cal:calendar-query/cal:filter');
+ if ($filter->length !== 1) {
+ throw new Sabre_DAV_Exception_BadRequest('Only one filter element is allowed');
+ }
+
+ $compFilters = $this->parseCompFilters($filter->item(0));
+ if (count($compFilters)!==1) {
+ throw new Sabre_DAV_Exception_BadRequest('There must be exactly 1 top-level comp-filter.');
+ }
+
+ $this->filters = $compFilters[0];
+ $this->requestedProperties = array_keys(Sabre_DAV_XMLUtil::parseProperties($this->dom->firstChild));
+
+ $expand = $this->xpath->query('/cal:calendar-query/dav:prop/cal:calendar-data/cal:expand');
+ if ($expand->length>0) {
+ $this->expand = $this->parseExpand($expand->item(0));
+ }
+
+
+ }
+
+ /**
+ * Parses all the 'comp-filter' elements from a node
+ *
+ * @param DOMElement $parentNode
+ * @return array
+ */
+ protected function parseCompFilters(DOMElement $parentNode) {
+
+ $compFilterNodes = $this->xpath->query('cal:comp-filter', $parentNode);
+ $result = array();
+
+ for($ii=0; $ii < $compFilterNodes->length; $ii++) {
+
+ $compFilterNode = $compFilterNodes->item($ii);
+
+ $compFilter = array();
+ $compFilter['name'] = $compFilterNode->getAttribute('name');
+ $compFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $compFilterNode)->length>0;
+ $compFilter['comp-filters'] = $this->parseCompFilters($compFilterNode);
+ $compFilter['prop-filters'] = $this->parsePropFilters($compFilterNode);
+ $compFilter['time-range'] = $this->parseTimeRange($compFilterNode);
+
+ if ($compFilter['time-range'] && !in_array($compFilter['name'],array(
+ 'VEVENT',
+ 'VTODO',
+ 'VJOURNAL',
+ 'VFREEBUSY',
+ 'VALARM',
+ ))) {
+ throw new Sabre_DAV_Exception_BadRequest('The time-range filter is not defined for the ' . $compFilter['name'] . ' component');
+ };
+
+ $result[] = $compFilter;
+
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * Parses all the prop-filter elements from a node
+ *
+ * @param DOMElement $parentNode
+ * @return array
+ */
+ protected function parsePropFilters(DOMElement $parentNode) {
+
+ $propFilterNodes = $this->xpath->query('cal:prop-filter', $parentNode);
+ $result = array();
+
+ for ($ii=0; $ii < $propFilterNodes->length; $ii++) {
+
+ $propFilterNode = $propFilterNodes->item($ii);
+ $propFilter = array();
+ $propFilter['name'] = $propFilterNode->getAttribute('name');
+ $propFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $propFilterNode)->length>0;
+ $propFilter['param-filters'] = $this->parseParamFilters($propFilterNode);
+ $propFilter['text-match'] = $this->parseTextMatch($propFilterNode);
+ $propFilter['time-range'] = $this->parseTimeRange($propFilterNode);
+
+ $result[] = $propFilter;
+
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * Parses the param-filter element
+ *
+ * @param DOMElement $parentNode
+ * @return array
+ */
+ protected function parseParamFilters(DOMElement $parentNode) {
+
+ $paramFilterNodes = $this->xpath->query('cal:param-filter', $parentNode);
+ $result = array();
+
+ for($ii=0;$ii<$paramFilterNodes->length;$ii++) {
+
+ $paramFilterNode = $paramFilterNodes->item($ii);
+ $paramFilter = array();
+ $paramFilter['name'] = $paramFilterNode->getAttribute('name');
+ $paramFilter['is-not-defined'] = $this->xpath->query('cal:is-not-defined', $paramFilterNode)->length>0;
+ $paramFilter['text-match'] = $this->parseTextMatch($paramFilterNode);
+
+ $result[] = $paramFilter;
+
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * Parses the text-match element
+ *
+ * @param DOMElement $parentNode
+ * @return array|null
+ */
+ protected function parseTextMatch(DOMElement $parentNode) {
+
+ $textMatchNodes = $this->xpath->query('cal:text-match', $parentNode);
+
+ if ($textMatchNodes->length === 0)
+ return null;
+
+ $textMatchNode = $textMatchNodes->item(0);
+ $negateCondition = $textMatchNode->getAttribute('negate-condition');
+ $negateCondition = $negateCondition==='yes';
+ $collation = $textMatchNode->getAttribute('collation');
+ if (!$collation) $collation = 'i;ascii-casemap';
+
+ return array(
+ 'negate-condition' => $negateCondition,
+ 'collation' => $collation,
+ 'value' => $textMatchNode->nodeValue
+ );
+
+ }
+
+ /**
+ * Parses the time-range element
+ *
+ * @param DOMElement $parentNode
+ * @return array|null
+ */
+ protected function parseTimeRange(DOMElement $parentNode) {
+
+ $timeRangeNodes = $this->xpath->query('cal:time-range', $parentNode);
+ if ($timeRangeNodes->length === 0) {
+ return null;
+ }
+
+ $timeRangeNode = $timeRangeNodes->item(0);
+
+ if ($start = $timeRangeNode->getAttribute('start')) {
+ $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+ } else {
+ $start = null;
+ }
+ if ($end = $timeRangeNode->getAttribute('end')) {
+ $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+ } else {
+ $end = null;
+ }
+
+ if (!is_null($start) && !is_null($end) && $end <= $start) {
+ throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the time-range filter');
+ }
+
+ return array(
+ 'start' => $start,
+ 'end' => $end,
+ );
+
+ }
+
+ /**
+ * Parses the CALDAV:expand element
+ *
+ * @param DOMElement $parentNode
+ * @return void
+ */
+ protected function parseExpand(DOMElement $parentNode) {
+
+ $start = $parentNode->getAttribute('start');
+ if(!$start) {
+ throw new Sabre_DAV_Exception_BadRequest('The "start" attribute is required for the CALDAV:expand element');
+ }
+ $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+
+ $end = $parentNode->getAttribute('end');
+ if(!$end) {
+ throw new Sabre_DAV_Exception_BadRequest('The "end" attribute is required for the CALDAV:expand element');
+ }
+ $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+
+ if ($end <= $start) {
+ throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
+ }
+
+ return array(
+ 'start' => $start,
+ 'end' => $end,
+ );
+
+ }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
new file mode 100755
index 00000000000..1bb6b5d53fa
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
@@ -0,0 +1,347 @@
+<?php
+
+/**
+ * CalendarQuery Validator
+ *
+ * This class is responsible for checking if an iCalendar object matches a set
+ * of filters. The main function to do this is 'validate'.
+ *
+ * This is used to determine which icalendar objects should be returned for a
+ * calendar-query REPORT request.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_CalendarQueryValidator {
+
+ /**
+ * Verify if a list of filters applies to the calendar data object
+ *
+ * The list of filters must be formatted as parsed by Sabre_CalDAV_CalendarQueryParser
+ *
+ * @param Sabre_VObject_Component $vObject
+ * @param array $filters
+ * @return bool
+ */
+ public function validate(Sabre_VObject_Component $vObject,array $filters) {
+
+ // The top level object is always a component filter.
+ // We'll parse it manually, as it's pretty simple.
+ if ($vObject->name !== $filters['name']) {
+ return false;
+ }
+
+ return
+ $this->validateCompFilters($vObject, $filters['comp-filters']) &&
+ $this->validatePropFilters($vObject, $filters['prop-filters']);
+
+
+ }
+
+ /**
+ * This method checks the validity of comp-filters.
+ *
+ * A list of comp-filters needs to be specified. Also the parent of the
+ * component we're checking should be specified, not the component to check
+ * itself.
+ *
+ * @param Sabre_VObject_Component $parent
+ * @param array $filters
+ * @return bool
+ */
+ protected function validateCompFilters(Sabre_VObject_Component $parent, array $filters) {
+
+ foreach($filters as $filter) {
+
+ $isDefined = isset($parent->$filter['name']);
+
+ if ($filter['is-not-defined']) {
+
+ if ($isDefined) {
+ return false;
+ } else {
+ continue;
+ }
+
+ }
+ if (!$isDefined) {
+ return false;
+ }
+
+ if ($filter['time-range']) {
+ foreach($parent->$filter['name'] as $subComponent) {
+ if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) {
+ continue 2;
+ }
+ }
+ return false;
+ }
+
+ if (!$filter['comp-filters'] && !$filter['prop-filters']) {
+ continue;
+ }
+
+ // If there are sub-filters, we need to find at least one component
+ // for which the subfilters hold true.
+ foreach($parent->$filter['name'] as $subComponent) {
+
+ if (
+ $this->validateCompFilters($subComponent, $filter['comp-filters']) &&
+ $this->validatePropFilters($subComponent, $filter['prop-filters'])) {
+ // We had a match, so this comp-filter succeeds
+ continue 2;
+ }
+
+ }
+
+ // If we got here it means there were sub-comp-filters or
+ // sub-prop-filters and there was no match. This means this filter
+ // needs to return false.
+ return false;
+
+ }
+
+ // If we got here it means we got through all comp-filters alive so the
+ // filters were all true.
+ return true;
+
+ }
+
+ /**
+ * This method checks the validity of prop-filters.
+ *
+ * A list of prop-filters needs to be specified. Also the parent of the
+ * property we're checking should be specified, not the property to check
+ * itself.
+ *
+ * @param Sabre_VObject_Component $parent
+ * @param array $filters
+ * @return bool
+ */
+ protected function validatePropFilters(Sabre_VObject_Component $parent, array $filters) {
+
+ foreach($filters as $filter) {
+
+ $isDefined = isset($parent->$filter['name']);
+
+ if ($filter['is-not-defined']) {
+
+ if ($isDefined) {
+ return false;
+ } else {
+ continue;
+ }
+
+ }
+ if (!$isDefined) {
+ return false;
+ }
+
+ if ($filter['time-range']) {
+ foreach($parent->$filter['name'] as $subComponent) {
+ if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) {
+ continue 2;
+ }
+ }
+ return false;
+ }
+
+ if (!$filter['param-filters'] && !$filter['text-match']) {
+ continue;
+ }
+
+ // If there are sub-filters, we need to find at least one property
+ // for which the subfilters hold true.
+ foreach($parent->$filter['name'] as $subComponent) {
+
+ if(
+ $this->validateParamFilters($subComponent, $filter['param-filters']) &&
+ (!$filter['text-match'] || $this->validateTextMatch($subComponent, $filter['text-match']))
+ ) {
+ // We had a match, so this prop-filter succeeds
+ continue 2;
+ }
+
+ }
+
+ // If we got here it means there were sub-param-filters or
+ // text-match filters and there was no match. This means the
+ // filter needs to return false.
+ return false;
+
+ }
+
+ // If we got here it means we got through all prop-filters alive so the
+ // filters were all true.
+ return true;
+
+ }
+
+ /**
+ * This method checks the validity of param-filters.
+ *
+ * A list of param-filters needs to be specified. Also the parent of the
+ * parameter we're checking should be specified, not the parameter to check
+ * itself.
+ *
+ * @param Sabre_VObject_Property $parent
+ * @param array $filters
+ * @return bool
+ */
+ protected function validateParamFilters(Sabre_VObject_Property $parent, array $filters) {
+
+ foreach($filters as $filter) {
+
+ $isDefined = isset($parent[$filter['name']]);
+
+ if ($filter['is-not-defined']) {
+
+ if ($isDefined) {
+ return false;
+ } else {
+ continue;
+ }
+
+ }
+ if (!$isDefined) {
+ return false;
+ }
+
+ if (!$filter['text-match']) {
+ continue;
+ }
+
+ // If there are sub-filters, we need to find at least one parameter
+ // for which the subfilters hold true.
+ foreach($parent[$filter['name']] as $subParam) {
+
+ if($this->validateTextMatch($subParam,$filter['text-match'])) {
+ // We had a match, so this param-filter succeeds
+ continue 2;
+ }
+
+ }
+
+ // If we got here it means there was a text-match filter and there
+ // were no matches. This means the filter needs to return false.
+ return false;
+
+ }
+
+ // If we got here it means we got through all param-filters alive so the
+ // filters were all true.
+ return true;
+
+ }
+
+ /**
+ * This method checks the validity of a text-match.
+ *
+ * A single text-match should be specified as well as the specific property
+ * or parameter we need to validate.
+ *
+ * @param Sabre_VObject_Node $parent
+ * @param array $textMatch
+ * @return bool
+ */
+ protected function validateTextMatch(Sabre_VObject_Node $parent, array $textMatch) {
+
+ $value = (string)$parent;
+
+ $isMatching = Sabre_DAV_StringUtil::textMatch($value, $textMatch['value'], $textMatch['collation']);
+
+ return ($textMatch['negate-condition'] xor $isMatching);
+
+ }
+
+ /**
+ * Validates if a component matches the given time range.
+ *
+ * This is all based on the rules specified in rfc4791, which are quite
+ * complex.
+ *
+ * @param Sabre_VObject_Node $component
+ * @param DateTime $start
+ * @param DateTime $end
+ * @return bool
+ */
+ protected function validateTimeRange(Sabre_VObject_Node $component, $start, $end) {
+
+ if (is_null($start)) {
+ $start = new DateTime('1900-01-01');
+ }
+ if (is_null($end)) {
+ $end = new DateTime('3000-01-01');
+ }
+
+ switch($component->name) {
+
+ case 'VEVENT' :
+ case 'VTODO' :
+ case 'VJOURNAL' :
+
+ return $component->isInTimeRange($start, $end);
+
+ case 'VALARM' :
+
+ // If the valarm is wrapped in a recurring event, we need to
+ // expand the recursions, and validate each.
+ //
+ // Our datamodel doesn't easily allow us to do this straight
+ // in the VALARM component code, so this is a hack, and an
+ // expensive one too.
+ if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
+ // Fire up the iterator!
+ $it = new Sabre_VObject_RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
+ while($it->valid()) {
+ $expandedEvent = $it->getEventObject();
+
+ // We need to check from these expanded alarms, which
+ // one is the first to trigger. Based on this, we can
+ // determine if we can 'give up' expanding events.
+ $firstAlarm = null;
+ foreach($expandedEvent->VALARM as $expandedAlarm) {
+ $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
+ if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
+ $firstAlarm = $effectiveTrigger;
+ }
+ if ($expandedAlarm->isInTimeRange($start, $end)) {
+ return true;
+ }
+
+ }
+ if ($firstAlarm > $end) {
+ return false;
+ }
+ $it->next();
+ }
+ return false;
+ } else {
+ return $component->isInTimeRange($start, $end);
+ }
+
+ case 'VFREEBUSY' :
+ throw new Sabre_DAV_Exception_NotImplemented('time-range filters are currently not supported on ' . $component->name . ' components');
+
+ case 'COMPLETED' :
+ case 'CREATED' :
+ case 'DTEND' :
+ case 'DTSTAMP' :
+ case 'DTSTART' :
+ case 'DUE' :
+ case 'LAST-MODIFIED' :
+ return ($start <= $component->getDateTime() && $end >= $component->getDateTime());
+
+
+
+ default :
+ throw new Sabre_DAV_Exception_BadRequest('You cannot create a time-range filter on a ' . $component->name . ' component');
+
+ }
+
+ }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/CalendarRootNode.php b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
index 69669a9d7fd..3907913cc78 100644..100755
--- a/3rdparty/Sabre/CalDAV/CalendarRootNode.php
+++ b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
@@ -1,38 +1,38 @@
<?php
/**
- * Users collection
+ * Users collection
*
* This object is responsible for generating a collection of users.
*
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollection {
/**
- * CalDAV backend
- *
- * @var Sabre_CalDAV_Backend_Abstract
+ * CalDAV backend
+ *
+ * @var Sabre_CalDAV_Backend_Abstract
*/
protected $caldavBackend;
/**
- * Constructor
+ * Constructor
*
* This constructor needs both an authentication and a caldav backend.
*
- * By default this class will show a list of calendar collections for
- * principals in the 'principals' collection. If your main principals are
- * actually located in a different path, use the $principalPrefix argument
+ * By default this class will show a list of calendar collections for
+ * principals in the 'principals' collection. If your main principals are
+ * actually located in a different path, use the $principalPrefix argument
* to override this.
*
*
- * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
- * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+ * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+ * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
* @param string $principalPrefix
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend,Sabre_CalDAV_Backend_Abstract $caldavBackend, $principalPrefix = 'principals') {
@@ -46,9 +46,9 @@ class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollec
* Returns the nodename
*
* We're overriding this, because the default will be the 'principalPrefix',
- * and we want it to be Sabre_CalDAV_Plugin::CALENDAR_ROOT
- *
- * @return void
+ * and we want it to be Sabre_CalDAV_Plugin::CALENDAR_ROOT
+ *
+ * @return string
*/
public function getName() {
@@ -62,9 +62,9 @@ class Sabre_CalDAV_CalendarRootNode extends Sabre_DAVACL_AbstractPrincipalCollec
* The passed array contains principal information, and is guaranteed to
* at least contain a uri item. Other properties may or may not be
* supplied by the authentication backend.
- *
- * @param array $principal
- * @return Sabre_DAV_INode
+ *
+ * @param array $principal
+ * @return Sabre_DAV_INode
*/
public function getChildForPrincipal(array $principal) {
diff --git a/3rdparty/Sabre/CalDAV/Exception/InvalidICalendarObject.php b/3rdparty/Sabre/CalDAV/Exception/InvalidICalendarObject.php
deleted file mode 100644
index 656b7286a66..00000000000
--- a/3rdparty/Sabre/CalDAV/Exception/InvalidICalendarObject.php
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-/**
- * InvalidICalendarObject
- *
- * This exception is thrown when an attempt is made to create or update
- * an invalid ICalendar object
- *
- * @package Sabre
- * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Sabre_CalDAV_Exception_InvalidICalendarObject extends Sabre_DAV_Exception_PreconditionFailed {
-
-
-}
diff --git a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
index 4e2c6eb93d2..ec42b406b2f 100644..100755
--- a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
+++ b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
@@ -4,28 +4,28 @@
* ICS Exporter
*
* This plugin adds the ability to export entire calendars as .ics files.
- * This is useful for clients that don't support CalDAV yet. They often do
+ * This is useful for clients that don't support CalDAV yet. They often do
* support ics files.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
/**
- * Reference to Server class
- *
- * @var Sabre_DAV_Server
+ * Reference to Server class
+ *
+ * @var Sabre_DAV_Server
*/
private $server;
/**
- * Initializes the plugin and registers event handlers
- *
- * @param Sabre_DAV_Server $server
+ * Initializes the plugin and registers event handlers
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -38,10 +38,10 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
/**
* 'beforeMethod' event handles. This event handles intercepts GET requests ending
* with ?export
- *
+ *
* @param string $method
* @param string $uri
- * @return void
+ * @return bool
*/
public function beforeMethod($method, $uri) {
@@ -55,9 +55,19 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
if (!($node instanceof Sabre_CalDAV_Calendar)) return;
+ // Checking ACL, if available.
+ if ($aclPlugin = $this->server->getPlugin('acl')) {
+ $aclPlugin->checkPrivileges($uri, '{DAV:}read');
+ }
+
$this->server->httpResponse->setHeader('Content-Type','text/calendar');
$this->server->httpResponse->sendStatus(200);
- $this->server->httpResponse->sendBody($this->generateICS($this->server->tree->getChildren($uri)));
+
+ $nodes = $this->server->getPropertiesForPath($uri, array(
+ '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data',
+ ),1);
+
+ $this->server->httpResponse->sendBody($this->generateICS($nodes));
// Returning false to break the event chain
return false;
@@ -65,16 +75,20 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Merges all calendar objects, and builds one big ics export
- *
- * @param array $nodes
- * @return void
+ * Merges all calendar objects, and builds one big ics export
+ *
+ * @param array $nodes
+ * @return string
*/
public function generateICS(array $nodes) {
$calendar = new Sabre_VObject_Component('vcalendar');
$calendar->version = '2.0';
- $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
+ if (Sabre_DAV_Server::$exposeVersion) {
+ $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
+ } else {
+ $calendar->prodid = '-//SabreDAV//SabreDAV//EN';
+ }
$calendar->calscale = 'GREGORIAN';
$collectedTimezones = array();
@@ -84,7 +98,11 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
foreach($nodes as $node) {
- $nodeData = $node->get();
+ if (!isset($node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'])) {
+ continue;
+ }
+ $nodeData = $node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'];
+
$nodeComp = Sabre_VObject_Reader::read($nodeData);
foreach($nodeComp->children() as $child) {
@@ -105,13 +123,10 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
$collectedTimezones[] = $child->TZID;
break;
-
}
-
}
-
}
foreach($timezones as $tz) $calendar->add($tz);
@@ -119,6 +134,6 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
return $calendar->serialize();
- }
+ }
}
diff --git a/3rdparty/Sabre/CalDAV/ICalendar.php b/3rdparty/Sabre/CalDAV/ICalendar.php
index 8193dff3a83..15d51ebcf79 100644..100755
--- a/3rdparty/Sabre/CalDAV/ICalendar.php
+++ b/3rdparty/Sabre/CalDAV/ICalendar.php
@@ -4,15 +4,15 @@
* Calendar interface
*
* Implement this interface to allow a node to be recognized as an calendar.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_CalDAV_ICalendar extends Sabre_DAV_ICollection {
-
+
}
diff --git a/3rdparty/Sabre/CalDAV/ICalendarObject.php b/3rdparty/Sabre/CalDAV/ICalendarObject.php
index 708300ad7bd..280f982a310 100644..100755
--- a/3rdparty/Sabre/CalDAV/ICalendarObject.php
+++ b/3rdparty/Sabre/CalDAV/ICalendarObject.php
@@ -1,20 +1,20 @@
<?php
/**
- * CalendarObject interface
+ * CalendarObject interface
/**
- * Extend the ICalendarObject interface to allow your custom nodes to be picked up as
+ * Extend the ICalendarObject interface to allow your custom nodes to be picked up as
* CalendarObjects.
*
* Calendar objects are resources such as Events, Todo's or Journals.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-interface Sabre_CalDAV_ICalendarObject extends Sabre_DAV_IFile {
+interface Sabre_CalDAV_ICalendarObject extends Sabre_DAV_IFile {
}
diff --git a/3rdparty/Sabre/CalDAV/ICalendarUtil.php b/3rdparty/Sabre/CalDAV/ICalendarUtil.php
deleted file mode 100644
index 699abfdd6f5..00000000000
--- a/3rdparty/Sabre/CalDAV/ICalendarUtil.php
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-
-/**
- * This class contains several utilities related to the ICalendar (rfc2445) format
- *
- * This class is now deprecated, and won't be further maintained. Please use
- * the Sabre_VObject package for your ics parsing needs.
- *
- * @package Sabre
- * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- * @deprecated Use Sabre_VObject instead.
- */
-class Sabre_CalDAV_ICalendarUtil {
-
- /**
- * Validates an ICalendar object
- *
- * This method makes sure this ICalendar object is properly formatted.
- * If we can't parse it, we'll throw exceptions.
- *
- * @param string $icalData
- * @param array $allowedComponents
- * @return bool
- */
- static function validateICalendarObject($icalData, array $allowedComponents = null) {
-
- $xcal = simplexml_load_string(self::toXCal($icalData));
- if (!$xcal) throw new Sabre_CalDAV_Exception_InvalidICalendarObject('Invalid calendarobject format');
-
- $xcal->registerXPathNameSpace('cal','urn:ietf:params:xml:ns:xcal');
-
- // Check if there's only 1 component
- $components = array('vevent','vtodo','vjournal','vfreebusy');
- $componentsFound = array();
-
- foreach($components as $component) {
- $test = $xcal->xpath('/cal:iCalendar/cal:vcalendar/cal:' . $component);
- if (is_array($test)) $componentsFound = array_merge($componentsFound, $test);
- }
- if (count($componentsFound)<1) {
- throw new Sabre_CalDAV_Exception_InvalidICalendarObject('One VEVENT, VTODO, VJOURNAL or VFREEBUSY must be specified. 0 found.');
- }
- $component = $componentsFound[0];
-
- if (is_null($allowedComponents)) return true;
-
- // Check if the component is allowed
- $name = $component->getName();
- if (!in_array(strtoupper($name),$allowedComponents)) {
- throw new Sabre_CalDAV_Exception_InvalidICalendarObject(strtoupper($name) . ' is not allowed in this calendar.');
- }
-
- if (count($xcal->xpath('/cal:iCalendar/cal:vcalendar/cal:method'))>0) {
- throw new Sabre_CalDAV_Exception_InvalidICalendarObject('The METHOD property is not allowed in calendar objects');
- }
-
- return true;
-
- }
-
- /**
- * Converts ICalendar data to XML.
- *
- * Properties are converted to lowercase xml elements. Parameters are;
- * converted to attributes. BEGIN:VEVENT is converted to <vevent> and
- * END:VEVENT </vevent> as well as other components.
- *
- * It's a very loose parser. If any line does not conform to the spec, it
- * will simply be ignored. It will try to detect if \r\n or \n line endings
- * are used.
- *
- * @todo Currently quoted attributes are not parsed correctly.
- * @see http://tools.ietf.org/html/draft-royer-calsch-xcal-03
- * @param string $icalData
- * @return string.
- */
- static function toXCAL($icalData) {
-
- // Detecting line endings
- $lb="\r\n";
- if (strpos($icalData,"\r\n")!==false) $lb = "\r\n";
- elseif (strpos($icalData,"\n")!==false) $lb = "\n";
-
- // Splitting up items per line
- $lines = explode($lb,$icalData);
-
- // Properties can be folded over 2 lines. In this case the second
- // line will be preceeded by a space or tab.
- $lines2 = array();
- foreach($lines as $line) {
-
- if (!$line) continue;
- if ($line[0]===" " || $line[0]==="\t") {
- $lines2[count($lines2)-1].=substr($line,1);
- continue;
- }
-
- $lines2[]=$line;
-
- }
-
- $xml = '<?xml version="1.0"?>' . "\n";
- $xml.= "<iCalendar xmlns=\"urn:ietf:params:xml:ns:xcal\">\n";
-
- $spaces = 2;
- foreach($lines2 as $line) {
-
- $matches = array();
- // This matches PROPERTYNAME;ATTRIBUTES:VALUE
- if (!preg_match('/^([^:^;]*)(?:;([^:]*))?:(.*)$/',$line,$matches))
- continue;
-
- $propertyName = strtolower($matches[1]);
- $attributes = $matches[2];
- $value = $matches[3];
-
- // If the line was in the format BEGIN:COMPONENT or END:COMPONENT, we need to special case it.
- if ($propertyName === 'begin') {
- $xml.=str_repeat(" ",$spaces);
- $xml.='<' . strtolower($value) . ">\n";
- $spaces+=2;
- continue;
- } elseif ($propertyName === 'end') {
- $spaces-=2;
- $xml.=str_repeat(" ",$spaces);
- $xml.='</' . strtolower($value) . ">\n";
- continue;
- }
-
- $xml.=str_repeat(" ",$spaces);
- $xml.='<' . $propertyName;
- if ($attributes) {
- // There can be multiple attributes
- $attributes = explode(';',$attributes);
- foreach($attributes as $att) {
-
- list($attName,$attValue) = explode('=',$att,2);
- $attName = strtolower($attName);
- if ($attName === 'language') $attName='xml:lang';
- $xml.=' ' . $attName . '="' . htmlspecialchars($attValue) . '"';
-
- }
- }
-
- $xml.='>'. htmlspecialchars(trim($value)) . '</' . $propertyName . ">\n";
-
- }
- $xml.="</iCalendar>";
- return $xml;
-
- }
-
-}
-
diff --git a/3rdparty/Sabre/CalDAV/Plugin.php b/3rdparty/Sabre/CalDAV/Plugin.php
index 02747c8395e..d7d1d970518 100644..100755
--- a/3rdparty/Sabre/CalDAV/Plugin.php
+++ b/3rdparty/Sabre/CalDAV/Plugin.php
@@ -8,8 +8,8 @@
*
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
@@ -18,7 +18,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
* This is the official CalDAV namespace
*/
const NS_CALDAV = 'urn:ietf:params:xml:ns:caldav';
-
+
/**
* This is the namespace for the proprietary calendarserver extensions
*/
@@ -41,21 +41,48 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
const CALENDAR_ROOT = 'calendars';
/**
- * Reference to server object
- *
- * @var Sabre_DAV_Server
+ * Reference to server object
+ *
+ * @var Sabre_DAV_Server
*/
private $server;
/**
+ * The email handler for invites and other scheduling messages.
+ *
+ * @var Sabre_CalDAV_Schedule_IMip
+ */
+ protected $imipHandler;
+
+ /**
+ * Sets the iMIP handler.
+ *
+ * iMIP = The email transport of iCalendar scheduling messages. Setting
+ * this is optional, but if you want the server to allow invites to be sent
+ * out, you must set a handler.
+ *
+ * Specifically iCal will plain assume that the server supports this. If
+ * the server doesn't, iCal will display errors when inviting people to
+ * events.
+ *
+ * @param Sabre_CalDAV_Schedule_IMip $imipHandler
+ * @return void
+ */
+ public function setIMipHandler(Sabre_CalDAV_Schedule_IMip $imipHandler) {
+
+ $this->imipHandler = $imipHandler;
+
+ }
+
+ /**
* Use this method to tell the server this plugin defines additional
* HTTP methods.
*
- * This method is passed a uri. It should only return HTTP methods that are
+ * This method is passed a uri. It should only return HTTP methods that are
* available for the specified uri.
*
* @param string $uri
- * @return array
+ * @return array
*/
public function getHTTPMethods($uri) {
@@ -68,7 +95,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if ($node instanceof Sabre_DAV_IExtendedCollection) {
try {
$node->getChild($name);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
return array('MKCALENDAR');
}
}
@@ -77,9 +104,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Returns a list of features for the DAV: HTTP header.
- *
- * @return array
+ * Returns a list of features for the DAV: HTTP header.
+ *
+ * @return array
*/
public function getFeatures() {
@@ -89,11 +116,11 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Returns a plugin name.
- *
+ *
* Using this name other plugins will be able to access other plugins
- * using Sabre_DAV_Server::getPlugin
- *
- * @return string
+ * using Sabre_DAV_Server::getPlugin
+ *
+ * @return string
*/
public function getPluginName() {
@@ -105,38 +132,46 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
* Returns a list of reports this plugin supports.
*
* This will be used in the {DAV:}supported-report-set property.
- * Note that you still need to subscribe to the 'report' event to actually
- * implement them
- *
+ * Note that you still need to subscribe to the 'report' event to actually
+ * implement them
+ *
* @param string $uri
- * @return array
+ * @return array
*/
public function getSupportedReportSet($uri) {
$node = $this->server->tree->getNodeForPath($uri);
+
+ $reports = array();
if ($node instanceof Sabre_CalDAV_ICalendar || $node instanceof Sabre_CalDAV_ICalendarObject) {
- return array(
- '{' . self::NS_CALDAV . '}calendar-multiget',
- '{' . self::NS_CALDAV . '}calendar-query',
- );
+ $reports[] = '{' . self::NS_CALDAV . '}calendar-multiget';
+ $reports[] = '{' . self::NS_CALDAV . '}calendar-query';
}
- return array();
+ if ($node instanceof Sabre_CalDAV_ICalendar) {
+ $reports[] = '{' . self::NS_CALDAV . '}free-busy-query';
+ }
+ return $reports;
}
/**
- * Initializes the plugin
- *
- * @param Sabre_DAV_Server $server
+ * Initializes the plugin
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
$this->server = $server;
+
$server->subscribeEvent('unknownMethod',array($this,'unknownMethod'));
//$server->subscribeEvent('unknownMethod',array($this,'unknownMethod2'),1000);
$server->subscribeEvent('report',array($this,'report'));
$server->subscribeEvent('beforeGetProperties',array($this,'beforeGetProperties'));
+ $server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel'));
+ $server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
+ $server->subscribeEvent('beforeWriteContent', array($this, 'beforeWriteContent'));
+ $server->subscribeEvent('beforeCreateFile', array($this, 'beforeCreateFile'));
$server->xmlNamespaces[self::NS_CALDAV] = 'cal';
$server->xmlNamespaces[self::NS_CALENDARSERVER] = 'cs';
@@ -144,6 +179,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
$server->propertyMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre_CalDAV_Property_SupportedCalendarComponentSet';
$server->resourceTypeMapping['Sabre_CalDAV_ICalendar'] = '{urn:ietf:params:xml:ns:caldav}calendar';
+ $server->resourceTypeMapping['Sabre_CalDAV_Schedule_IOutbox'] = '{urn:ietf:params:xml:ns:caldav}schedule-outbox';
$server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyRead'] = '{http://calendarserver.org/ns/}calendar-proxy-read';
$server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyWrite'] = '{http://calendarserver.org/ns/}calendar-proxy-write';
@@ -161,7 +197,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
'{' . self::NS_CALDAV . '}calendar-data',
// scheduling extension
+ '{' . self::NS_CALDAV . '}schedule-inbox-URL',
+ '{' . self::NS_CALDAV . '}schedule-outbox-URL',
'{' . self::NS_CALDAV . '}calendar-user-address-set',
+ '{' . self::NS_CALDAV . '}calendar-user-type',
// CalendarServer extensions
'{' . self::NS_CALENDARSERVER . '}getctag',
@@ -173,36 +212,55 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
/**
* This function handles support for the MKCALENDAR method
- *
- * @param string $method
- * @return bool
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
*/
public function unknownMethod($method, $uri) {
- if ($method!=='MKCALENDAR') return;
+ switch ($method) {
+ case 'MKCALENDAR' :
+ $this->httpMkCalendar($uri);
+ // false is returned to stop the propagation of the
+ // unknownMethod event.
+ return false;
+ case 'POST' :
+ // Checking if we're talking to an outbox
+ try {
+ $node = $this->server->tree->getNodeForPath($uri);
+ } catch (Sabre_DAV_Exception_NotFound $e) {
+ return;
+ }
+ if (!$node instanceof Sabre_CalDAV_Schedule_IOutbox)
+ return;
- $this->httpMkCalendar($uri);
- // false is returned to stop the unknownMethod event
- return false;
+ $this->outboxRequest($node);
+ return false;
+
+ }
}
/**
- * This functions handles REPORT requests specific to CalDAV
- *
- * @param string $reportName
- * @param DOMNode $dom
- * @return bool
+ * This functions handles REPORT requests specific to CalDAV
+ *
+ * @param string $reportName
+ * @param DOMNode $dom
+ * @return bool
*/
public function report($reportName,$dom) {
- switch($reportName) {
+ switch($reportName) {
case '{'.self::NS_CALDAV.'}calendar-multiget' :
$this->calendarMultiGetReport($dom);
return false;
case '{'.self::NS_CALDAV.'}calendar-query' :
$this->calendarQueryReport($dom);
return false;
+ case '{'.self::NS_CALDAV.'}free-busy-query' :
+ $this->freeBusyQueryReport($dom);
+ return false;
}
@@ -212,9 +270,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
/**
* This function handles the MKCALENDAR HTTP method, which creates
* a new calendar.
- *
+ *
* @param string $uri
- * @return void
+ * @return void
*/
public function httpMkCalendar($uri) {
@@ -238,7 +296,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
foreach(Sabre_DAV_XMLUtil::parseProperties($child,$this->server->propertyMap) as $k=>$prop) {
$properties[$k] = $prop;
}
-
+
}
}
@@ -254,9 +312,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
* beforeGetProperties
*
* This method handler is invoked before any after properties for a
- * resource are fetched. This allows us to add in any CalDAV specific
- * properties.
- *
+ * resource are fetched. This allows us to add in any CalDAV specific
+ * properties.
+ *
* @param string $path
* @param Sabre_DAV_INode $node
* @param array $requestedProperties
@@ -270,12 +328,21 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
// calendar-home-set property
$calHome = '{' . self::NS_CALDAV . '}calendar-home-set';
if (in_array($calHome,$requestedProperties)) {
- $principalId = $node->getName();
+ $principalId = $node->getName();
$calendarHomePath = self::CALENDAR_ROOT . '/' . $principalId . '/';
unset($requestedProperties[$calHome]);
$returnedProperties[200][$calHome] = new Sabre_DAV_Property_Href($calendarHomePath);
}
+ // schedule-outbox-URL property
+ $scheduleProp = '{' . self::NS_CALDAV . '}schedule-outbox-URL';
+ if (in_array($scheduleProp,$requestedProperties)) {
+ $principalId = $node->getName();
+ $outboxPath = self::CALENDAR_ROOT . '/' . $principalId . '/outbox';
+ unset($requestedProperties[$scheduleProp]);
+ $returnedProperties[200][$scheduleProp] = new Sabre_DAV_Property_Href($outboxPath);
+ }
+
// calendar-user-address-set property
$calProp = '{' . self::NS_CALDAV . '}calendar-user-address-set';
if (in_array($calProp,$requestedProperties)) {
@@ -287,7 +354,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
- // These two properties are shortcuts for ical to easily find
+ // These two properties are shortcuts for ical to easily find
// other principals this principal has access to.
$propRead = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for';
$propWrite = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for';
@@ -301,8 +368,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
$groupNode = $this->server->tree->getNodeForPath($group);
- // If the node is either ap proxy-read or proxy-write
- // group, we grab the parent principal and add it to the
+ // If the node is either ap proxy-read or proxy-write
+ // group, we grab the parent principal and add it to the
// list.
if ($groupNode instanceof Sabre_CalDAV_Principal_ProxyRead) {
list($readList[]) = Sabre_DAV_URLUtil::splitPath($group);
@@ -327,8 +394,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if ($node instanceof Sabre_CalDAV_ICalendarObject) {
- // The calendar-data property is not supposed to be a 'real'
- // property, but in large chunks of the spec it does act as such.
+ // The calendar-data property is not supposed to be a 'real'
+ // property, but in large chunks of the spec it does act as such.
// Therefore we simply expose it as a property.
$calDataProp = '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data';
if (in_array($calDataProp, $requestedProperties)) {
@@ -350,18 +417,52 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
*
* This report is used by the client to fetch the content of a series
* of urls. Effectively avoiding a lot of redundant requests.
- *
- * @param DOMNode $dom
+ *
+ * @param DOMNode $dom
* @return void
*/
public function calendarMultiGetReport($dom) {
$properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
-
$hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href');
+
+ $xpath = new DOMXPath($dom);
+ $xpath->registerNameSpace('cal',Sabre_CalDAV_Plugin::NS_CALDAV);
+ $xpath->registerNameSpace('dav','urn:DAV');
+
+ $expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand');
+ if ($expand->length>0) {
+ $expandElem = $expand->item(0);
+ $start = $expandElem->getAttribute('start');
+ $end = $expandElem->getAttribute('end');
+ if(!$start || !$end) {
+ throw new Sabre_DAV_Exception_BadRequest('The "start" and "end" attributes are required for the CALDAV:expand element');
+ }
+ $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+ $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
+
+ if ($end <= $start) {
+ throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
+ }
+
+ $expand = true;
+
+ } else {
+
+ $expand = false;
+
+ }
+
foreach($hrefElems as $elem) {
$uri = $this->server->calculateUri($elem->nodeValue);
list($objProps) = $this->server->getPropertiesForPath($uri,$properties);
+
+ if ($expand && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) {
+ $vObject = Sabre_VObject_Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
+ $vObject->expand($start, $end);
+ $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
+ }
+
$propertyList[]=$objProps;
}
@@ -377,48 +478,57 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
*
* This report is used by clients to request calendar objects based on
* complex conditions.
- *
- * @param DOMNode $dom
+ *
+ * @param DOMNode $dom
* @return void
*/
public function calendarQueryReport($dom) {
- $requestedProperties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild));
-
- $filterNode = $dom->getElementsByTagNameNS('urn:ietf:params:xml:ns:caldav','filter');
- if ($filterNode->length!==1) {
- throw new Sabre_DAV_Exception_BadRequest('The calendar-query report must have a filter element');
- }
- $filters = Sabre_CalDAV_XMLUtil::parseCalendarQueryFilters($filterNode->item(0));
+ $parser = new Sabre_CalDAV_CalendarQueryParser($dom);
+ $parser->parse();
$requestedCalendarData = true;
+ $requestedProperties = $parser->requestedProperties;
if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) {
+
// We always retrieve calendar-data, as we need it for filtering.
$requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data';
- // If calendar-data wasn't explicitly requested, we need to remove
+ // If calendar-data wasn't explicitly requested, we need to remove
// it after processing.
$requestedCalendarData = false;
}
// These are the list of nodes that potentially match the requirement
- $candidateNodes = $this->server->getPropertiesForPath($this->server->getRequestUri(),$requestedProperties,$this->server->getHTTPDepth(0));
+ $candidateNodes = $this->server->getPropertiesForPath(
+ $this->server->getRequestUri(),
+ $requestedProperties,
+ $this->server->getHTTPDepth(0)
+ );
$verifiedNodes = array();
+ $validator = new Sabre_CalDAV_CalendarQueryValidator();
+
foreach($candidateNodes as $node) {
// If the node didn't have a calendar-data property, it must not be a calendar object
- if (!isset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'])) continue;
+ if (!isset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']))
+ continue;
+
+ $vObject = Sabre_VObject_Reader::read($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
+ if ($validator->validate($vObject,$parser->filters)) {
- if ($this->validateFilters($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'],$filters)) {
-
if (!$requestedCalendarData) {
unset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
}
+ if ($parser->expand) {
+ $vObject->expand($parser->expand['start'], $parser->expand['end']);
+ $node[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
+ }
$verifiedNodes[] = $node;
- }
+ }
}
@@ -428,360 +538,291 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
-
/**
- * Verify if a list of filters applies to the calendar data object
+ * This method is responsible for parsing the request and generating the
+ * response for the CALDAV:free-busy-query REPORT.
*
- * The calendarData object must be a valid iCalendar blob. The list of
- * filters must be formatted as parsed by Sabre_CalDAV_Plugin::parseCalendarQueryFilters
- *
- * @param string $calendarData
- * @param array $filters
- * @return bool
+ * @param DOMNode $dom
+ * @return void
*/
- public function validateFilters($calendarData,$filters) {
-
- // We are converting the calendar object to an XML structure
- // This makes it far easier to parse
- $xCalendarData = Sabre_CalDAV_ICalendarUtil::toXCal($calendarData);
- $xml = simplexml_load_string($xCalendarData);
- $xml->registerXPathNamespace('c','urn:ietf:params:xml:ns:xcal');
-
- foreach($filters as $xpath=>$filter) {
-
- // if-not-defined comes first
- if (isset($filter['is-not-defined'])) {
- if (!$xml->xpath($xpath))
- continue;
- else
- return false;
-
- }
-
- $elem = $xml->xpath($xpath);
-
- if (!$elem) return false;
- $elem = $elem[0];
-
- if (isset($filter['time-range'])) {
-
- switch($elem->getName()) {
- case 'vevent' :
- $result = $this->validateTimeRangeFilterForEvent($xml,$xpath,$filter);
- if ($result===false) return false;
- break;
- case 'vtodo' :
- $result = $this->validateTimeRangeFilterForTodo($xml,$xpath,$filter);
- if ($result===false) return false;
- break;
- case 'vjournal' :
- case 'vfreebusy' :
- case 'valarm' :
- // TODO: not implemented
- break;
-
- /*
-
- case 'vjournal' :
- $result = $this->validateTimeRangeFilterForJournal($xml,$xpath,$filter);
- if ($result===false) return false;
- break;
- case 'vfreebusy' :
- $result = $this->validateTimeRangeFilterForFreeBusy($xml,$xpath,$filter);
- if ($result===false) return false;
- break;
- case 'valarm' :
- $result = $this->validateTimeRangeFilterForAlarm($xml,$xpath,$filter);
- if ($result===false) return false;
- break;
-
- */
-
- }
+ protected function freeBusyQueryReport(DOMNode $dom) {
- }
+ $start = null;
+ $end = null;
- if (isset($filter['text-match'])) {
- $currentString = (string)$elem;
+ foreach($dom->firstChild->childNodes as $childNode) {
- $isMatching = Sabre_DAV_StringUtil::textMatch($currentString, $filter['text-match']['value'], $filter['text-match']['collation']);
- if ($filter['text-match']['negate-condition'] && $isMatching) return false;
- if (!$filter['text-match']['negate-condition'] && !$isMatching) return false;
-
+ $clark = Sabre_DAV_XMLUtil::toClarkNotation($childNode);
+ if ($clark == '{' . self::NS_CALDAV . '}time-range') {
+ $start = $childNode->getAttribute('start');
+ $end = $childNode->getAttribute('end');
+ break;
}
}
- return true;
-
- }
-
- /**
- * Checks whether a time-range filter matches an event.
- *
- * @param SimpleXMLElement $xml Event as xml object
- * @param string $currentXPath XPath to check
- * @param array $currentFilter Filter information
- * @return void
- */
- private function validateTimeRangeFilterForEvent(SimpleXMLElement $xml,$currentXPath,array $currentFilter) {
-
- // Grabbing the DTSTART property
- $xdtstart = $xml->xpath($currentXPath.'/c:dtstart');
- if (!count($xdtstart)) {
- throw new Sabre_DAV_Exception_BadRequest('DTSTART property missing from calendar object');
+ if ($start) {
+ $start = Sabre_VObject_DateTimeParser::parseDateTime($start);
+ }
+ if ($end) {
+ $end = Sabre_VObject_DateTimeParser::parseDateTime($end);
}
- // The dtstart can be both a date, or datetime property
- if ((string)$xdtstart[0]['value']==='DATE' || strlen((string)$xdtstart[0])===8) {
- $isDateTime = false;
- } else {
- $isDateTime = true;
+ if (!$start && !$end) {
+ throw new Sabre_DAV_Exception_BadRequest('The freebusy report must have a time-range filter');
}
+ $acl = $this->server->getPlugin('acl');
- // Determining the timezone
- if ($tzid = (string)$xdtstart[0]['tzid']) {
- $tz = new DateTimeZone($tzid);
- } else {
- $tz = null;
+ if (!$acl) {
+ throw new Sabre_DAV_Exception('The ACL plugin must be loaded for free-busy queries to work');
}
- if ($isDateTime) {
- $dtstart = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdtstart[0],$tz);
- } else {
- $dtstart = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdtstart[0]);
+ $uri = $this->server->getRequestUri();
+ $acl->checkPrivileges($uri,'{' . self::NS_CALDAV . '}read-free-busy');
+
+ $calendar = $this->server->tree->getNodeForPath($uri);
+ if (!$calendar instanceof Sabre_CalDAV_ICalendar) {
+ throw new Sabre_DAV_Exception_NotImplemented('The free-busy-query REPORT is only implemented on calendars');
}
+ $objects = array_map(function($child) {
+ $obj = $child->get();
+ if (is_resource($obj)) {
+ $obj = stream_get_contents($obj);
+ }
+ return $obj;
+ }, $calendar->getChildren());
- // Grabbing the DTEND property
- $xdtend = $xml->xpath($currentXPath.'/c:dtend');
- $dtend = null;
+ $generator = new Sabre_VObject_FreeBusyGenerator();
+ $generator->setObjects($objects);
+ $generator->setTimeRange($start, $end);
+ $result = $generator->getResult();
+ $result = $result->serialize();
- if (count($xdtend)) {
- // Determining the timezone
- if ($tzid = (string)$xdtend[0]['tzid']) {
- $tz = new DateTimeZone($tzid);
- } else {
- $tz = null;
- }
+ $this->server->httpResponse->sendStatus(200);
+ $this->server->httpResponse->setHeader('Content-Type', 'text/calendar');
+ $this->server->httpResponse->setHeader('Content-Length', strlen($result));
+ $this->server->httpResponse->sendBody($result);
- // Since the VALUE prameter of both DTSTART and DTEND must be the same
- // we can assume we don't need to check the VALUE paramter of DTEND.
- if ($isDateTime) {
- $dtend = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdtend[0],$tz);
- } else {
- $dtend = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdtend[0],$tz);
- }
+ }
- }
-
- if (is_null($dtend)) {
- // The DTEND property was not found. We will first see if the event has a duration
- // property
-
- $xduration = $xml->xpath($currentXPath.'/c:duration');
- if (count($xduration)) {
- $duration = Sabre_CalDAV_XMLUtil::parseICalendarDuration((string)$xduration[0]);
-
- // Making sure that the duration is bigger than 0 seconds.
- $tempDT = clone $dtstart;
- $tempDT->modify($duration);
- if ($tempDT > $dtstart) {
-
- // use DTEND = DTSTART + DURATION
- $dtend = $tempDT;
- } else {
- // use DTEND = DTSTART
- $dtend = $dtstart;
- }
+ /**
+ * This method is triggered before a file gets updated with new content.
+ *
+ * This plugin uses this method to ensure that CalDAV objects receive
+ * valid calendar data.
+ *
+ * @param string $path
+ * @param Sabre_DAV_IFile $node
+ * @param resource $data
+ * @return void
+ */
+ public function beforeWriteContent($path, Sabre_DAV_IFile $node, &$data) {
- }
- }
+ if (!$node instanceof Sabre_CalDAV_ICalendarObject)
+ return;
+
+ $this->validateICalendar($data);
- if (is_null($dtend)) {
- if ($isDateTime) {
- // DTEND = DTSTART
- $dtend = $dtstart;
- } else {
- // DTEND = DTSTART + 1 DAY
- $dtend = clone $dtstart;
- $dtend->modify('+1 day');
- }
- }
- // TODO: we need to properly parse RRULE's, but it's very difficult.
- // For now, we're always returning events if they have an RRULE at all.
- $rrule = $xml->xpath($currentXPath.'/c:rrule');
- $hasRrule = (count($rrule))>0;
-
- if (!is_null($currentFilter['time-range']['start']) && $currentFilter['time-range']['start'] >= $dtend) return false;
- if (!is_null($currentFilter['time-range']['end']) && $currentFilter['time-range']['end'] <= $dtstart && !$hasRrule) return false;
- return true;
-
}
- private function validateTimeRangeFilterForTodo(SimpleXMLElement $xml,$currentXPath,array $filter) {
+ /**
+ * This method is triggered before a new file is created.
+ *
+ * This plugin uses this method to ensure that newly created calendar
+ * objects contain valid calendar data.
+ *
+ * @param string $path
+ * @param resource $data
+ * @param Sabre_DAV_ICollection $parentNode
+ * @return void
+ */
+ public function beforeCreateFile($path, &$data, Sabre_DAV_ICollection $parentNode) {
- // Gathering all relevant elements
+ if (!$parentNode instanceof Sabre_CalDAV_Calendar)
+ return;
- $dtStart = null;
- $duration = null;
- $due = null;
- $completed = null;
- $created = null;
+ $this->validateICalendar($data);
- $xdt = $xml->xpath($currentXPath.'/c:dtstart');
- if (count($xdt)) {
- // The dtstart can be both a date, or datetime property
- if ((string)$xdt[0]['value']==='DATE') {
- $isDateTime = false;
- } else {
- $isDateTime = true;
- }
+ }
- // Determining the timezone
- if ($tzid = (string)$xdt[0]['tzid']) {
- $tz = new DateTimeZone($tzid);
- } else {
- $tz = null;
- }
- if ($isDateTime) {
- $dtStart = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0],$tz);
- } else {
- $dtStart = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdt[0]);
- }
+ /**
+ * Checks if the submitted iCalendar data is in fact, valid.
+ *
+ * An exception is thrown if it's not.
+ *
+ * @param resource|string $data
+ * @return void
+ */
+ protected function validateICalendar(&$data) {
+
+ // If it's a stream, we convert it to a string first.
+ if (is_resource($data)) {
+ $data = stream_get_contents($data);
}
- // Only need to grab duration if dtStart is set
- if (!is_null($dtStart)) {
+ // Converting the data to unicode, if needed.
+ $data = Sabre_DAV_StringUtil::ensureUTF8($data);
- $xduration = $xml->xpath($currentXPath.'/c:duration');
- if (count($xduration)) {
- $duration = Sabre_CalDAV_XMLUtil::parseICalendarDuration((string)$xduration[0]);
- }
+ try {
+
+ $vobj = Sabre_VObject_Reader::read($data);
+
+ } catch (Sabre_VObject_ParseException $e) {
+
+ throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid iCalendar 2.0 data. Parse error: ' . $e->getMessage());
}
- if (!is_null($dtStart) && !is_null($duration)) {
+ }
- // Comparision from RFC 4791:
- // (start <= DTSTART+DURATION) AND ((end > DTSTART) OR (end >= DTSTART+DURATION))
+ /**
+ * This method handles POST requests to the schedule-outbox
+ *
+ * @param Sabre_CalDAV_Schedule_IOutbox $outboxNode
+ * @return void
+ */
+ public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode) {
- $end = clone $dtStart;
- $end->modify($duration);
+ $originator = $this->server->httpRequest->getHeader('Originator');
+ $recipients = $this->server->httpRequest->getHeader('Recipient');
- if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $end) &&
- (is_null($filter['time-range']['end']) || $filter['time-range']['end'] > $dtStart || $filter['time-range']['end'] >= $end) ) {
- return true;
- } else {
- return false;
- }
+ if (!$originator) {
+ throw new Sabre_DAV_Exception_BadRequest('The Originator: header must be specified when making POST requests');
+ }
+ if (!$recipients) {
+ throw new Sabre_DAV_Exception_BadRequest('The Recipient: header must be specified when making POST requests');
+ }
+ if (!preg_match('/^mailto:(.*)@(.*)$/', $originator)) {
+ throw new Sabre_DAV_Exception_BadRequest('Originator must start with mailto: and must be valid email address');
}
+ $originator = substr($originator,7);
- // Need to grab the DUE property
- $xdt = $xml->xpath($currentXPath.'/c:due');
- if (count($xdt)) {
- // The due property can be both a date, or datetime property
- if ((string)$xdt[0]['value']==='DATE') {
- $isDateTime = false;
- } else {
- $isDateTime = true;
- }
- // Determining the timezone
- if ($tzid = (string)$xdt[0]['tzid']) {
- $tz = new DateTimeZone($tzid);
- } else {
- $tz = null;
- }
- if ($isDateTime) {
- $due = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0],$tz);
- } else {
- $due = Sabre_CalDAV_XMLUtil::parseICalendarDate((string)$xdt[0]);
+ $recipients = explode(',',$recipients);
+ foreach($recipients as $k=>$recipient) {
+
+ $recipient = trim($recipient);
+ if (!preg_match('/^mailto:(.*)@(.*)$/', $recipient)) {
+ throw new Sabre_DAV_Exception_BadRequest('Recipients must start with mailto: and must be valid email address');
}
+ $recipient = substr($recipient, 7);
+ $recipients[$k] = $recipient;
}
- if (!is_null($dtStart) && !is_null($due)) {
-
- // Comparision from RFC 4791:
- // ((start < DUE) OR (start <= DTSTART)) AND ((end > DTSTART) OR (end >= DUE))
-
- if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] < $due || $filter['time-range']['start'] < $dtstart) &&
- (is_null($filter['time-range']['end']) || $filter['time-range']['end'] >= $due) ) {
- return true;
- } else {
- return false;
- }
+ // We need to make sure that 'originator' matches one of the email
+ // addresses of the selected principal.
+ $principal = $outboxNode->getOwner();
+ $props = $this->server->getProperties($principal,array(
+ '{' . self::NS_CALDAV . '}calendar-user-address-set',
+ ));
+ $addresses = array();
+ if (isset($props['{' . self::NS_CALDAV . '}calendar-user-address-set'])) {
+ $addresses = $props['{' . self::NS_CALDAV . '}calendar-user-address-set']->getHrefs();
}
- if (!is_null($dtStart)) {
-
- // Comparision from RFC 4791
- // (start <= DTSTART) AND (end > DTSTART)
- if ( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $dtStart) &&
- (is_null($filter['time-range']['end']) || $filter['time-range']['end'] > $dtStart) ) {
- return true;
- } else {
- return false;
- }
+ if (!in_array('mailto:' . $originator, $addresses)) {
+ throw new Sabre_DAV_Exception_Forbidden('The addresses specified in the Originator header did not match any addresses in the owners calendar-user-address-set header');
+ }
+ try {
+ $vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true));
+ } catch (Sabre_VObject_ParseException $e) {
+ throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
}
- if (!is_null($due)) {
-
- // Comparison from RFC 4791
- // (start < DUE) AND (end >= DUE)
- if ( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] < $due) &&
- (is_null($filter['time-range']['end']) || $filter['time-range']['end'] >= $due) ) {
- return true;
- } else {
- return false;
+ // Checking for the object type
+ $componentType = null;
+ foreach($vObject->getComponents() as $component) {
+ if ($component->name !== 'VTIMEZONE') {
+ $componentType = $component->name;
+ break;
}
-
- }
- // Need to grab the COMPLETED property
- $xdt = $xml->xpath($currentXPath.'/c:completed');
- if (count($xdt)) {
- $completed = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0]);
}
- // Need to grab the CREATED property
- $xdt = $xml->xpath($currentXPath.'/c:created');
- if (count($xdt)) {
- $created = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdt[0]);
+ if (is_null($componentType)) {
+ throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component');
}
- if (!is_null($completed) && !is_null($created)) {
- // Comparison from RFC 4791
- // ((start <= CREATED) OR (start <= COMPLETED)) AND ((end >= CREATED) OR (end >= COMPLETED))
- if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $created || $filter['time-range']['start'] <= $completed) &&
- (is_null($filter['time-range']['end']) || $filter['time-range']['end'] >= $created || $filter['time-range']['end'] >= $completed)) {
- return true;
- } else {
- return false;
- }
+ // Validating the METHOD
+ $method = strtoupper((string)$vObject->METHOD);
+ if (!$method) {
+ throw new Sabre_DAV_Exception_BadRequest('A METHOD property must be specified in iTIP messages');
}
- if (!is_null($completed)) {
- // Comparison from RFC 4791
- // (start <= COMPLETED) AND (end >= COMPLETED)
- if( (is_null($filter['time-range']['start']) || $filter['time-range']['start'] <= $completed) &&
- (is_null($filter['time-range']['end']) || $filter['time-range']['end'] >= $completed)) {
- return true;
- } else {
- return false;
- }
+ if (in_array($method, array('REQUEST','REPLY','ADD','CANCEL')) && $componentType==='VEVENT') {
+ $this->iMIPMessage($originator, $recipients, $vObject);
+ $this->server->httpResponse->sendStatus(200);
+ $this->server->httpResponse->sendBody('Messages sent');
+ } else {
+ throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented');
}
- if (!is_null($created)) {
- // Comparison from RFC 4791
- // (end > CREATED)
- if( (is_null($filter['time-range']['end']) || $filter['time-range']['end'] > $created) ) {
- return true;
- } else {
- return false;
- }
+ }
+
+ /**
+ * Sends an iMIP message by email.
+ *
+ * @param string $originator
+ * @param array $recipients
+ * @param Sabre_VObject_Component $vObject
+ * @return void
+ */
+ protected function iMIPMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
+
+ if (!$this->imipHandler) {
+ throw new Sabre_DAV_Exception_NotImplemented('No iMIP handler is setup on this server.');
}
+ $this->imipHandler->sendMessage($originator, $recipients, $vObject);
+
+ }
+
+ /**
+ * This method is used to generate HTML output for the
+ * Sabre_DAV_Browser_Plugin. This allows us to generate an interface users
+ * can use to create new calendars.
+ *
+ * @param Sabre_DAV_INode $node
+ * @param string $output
+ * @return bool
+ */
+ public function htmlActionsPanel(Sabre_DAV_INode $node, &$output) {
+
+ if (!$node instanceof Sabre_CalDAV_UserCalendars)
+ return;
+
+ $output.= '<tr><td colspan="2"><form method="post" action="">
+ <h3>Create new calendar</h3>
+ <input type="hidden" name="sabreAction" value="mkcalendar" />
+ <label>Name (uri):</label> <input type="text" name="name" /><br />
+ <label>Display name:</label> <input type="text" name="{DAV:}displayname" /><br />
+ <input type="submit" value="create" />
+ </form>
+ </td></tr>';
+
+ return false;
- // Everything else is TRUE
- return true;
+ }
+
+ /**
+ * This method allows us to intercept the 'mkcalendar' sabreAction. This
+ * action enables the user to create new calendars from the browser plugin.
+ *
+ * @param string $uri
+ * @param string $action
+ * @param array $postVars
+ * @return bool
+ */
+ public function browserPostAction($uri, $action, array $postVars) {
+
+ if ($action!=='mkcalendar')
+ return;
+
+ $resourceType = array('{DAV:}collection','{urn:ietf:params:xml:ns:caldav}calendar');
+ $properties = array();
+ if (isset($postVars['{DAV:}displayname'])) {
+ $properties['{DAV:}displayname'] = $postVars['{DAV:}displayname'];
+ }
+ $this->server->createCollection($uri . '/' . $postVars['name'],$resourceType,$properties);
+ return false;
}
diff --git a/3rdparty/Sabre/CalDAV/Principal/Collection.php b/3rdparty/Sabre/CalDAV/Principal/Collection.php
index 13435b2448e..abbefa5567a 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/Collection.php
+++ b/3rdparty/Sabre/CalDAV/Principal/Collection.php
@@ -4,23 +4,23 @@
* Principal collection
*
* This is an alternative collection to the standard ACL principal collection.
- * This collection adds support for the calendar-proxy-read and
- * calendar-proxy-write sub-principals, as defined by the caldav-proxy
+ * This collection adds support for the calendar-proxy-read and
+ * calendar-proxy-write sub-principals, as defined by the caldav-proxy
* specification.
*
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Principal_Collection extends Sabre_DAVACL_AbstractPrincipalCollection {
/**
- * Returns a child object based on principal information
- *
- * @param array $principalInfo
- * @return Sabre_CalDAV_Principal_User
+ * Returns a child object based on principal information
+ *
+ * @param array $principalInfo
+ * @return Sabre_CalDAV_Principal_User
*/
public function getChildForPrincipal(array $principalInfo) {
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
index f531d85d1ff..4b3f035634a 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
+++ b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
@@ -4,38 +4,38 @@
* ProxyRead principal
*
* This class represents a principal group, hosted under the main principal.
- * This is needed to implement 'Calendar delegation' support. This class is
+ * This is needed to implement 'Calendar delegation' support. This class is
* instantiated by Sabre_CalDAV_Principal_User.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
/**
- * Principal information from the parent principal.
- *
- * @var array
+ * Principal information from the parent principal.
+ *
+ * @var array
*/
protected $principalInfo;
/**
- * Principal backend
- *
- * @var Sabre_DAVACL_IPrincipalBackend
+ * Principal backend
+ *
+ * @var Sabre_DAVACL_IPrincipalBackend
*/
protected $principalBackend;
/**
* Creates the object.
*
- * Note that you MUST supply the parent principal information.
- *
- * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
- * @param array $principalInfo
+ * Note that you MUST supply the parent principal information.
+ *
+ * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+ * @param array $principalInfo
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, array $principalInfo) {
@@ -46,8 +46,8 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
/**
* Returns this principals name.
- *
- * @return string
+ *
+ * @return string
*/
public function getName() {
@@ -56,13 +56,13 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
}
/**
- * Returns the last modification time
+ * Returns the last modification time
*
- * @return null
+ * @return null
*/
public function getLastModified() {
- return null;
+ return null;
}
@@ -70,7 +70,7 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
* Deletes the current node
*
* @throws Sabre_DAV_Exception_Forbidden
- * @return void
+ * @return void
*/
public function delete() {
@@ -80,7 +80,7 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
/**
* Renames the node
- *
+ *
* @throws Sabre_DAV_Exception_Forbidden
* @param string $name The new name
* @return void
@@ -93,11 +93,11 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
/**
- * Returns a list of altenative urls for a principal
- *
+ * Returns a list of alternative urls for a principal
+ *
* This can for example be an email address, or ldap url.
- *
- * @return array
+ *
+ * @return array
*/
public function getAlternateUriSet() {
@@ -106,41 +106,41 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
}
/**
- * Returns the full principal url
- *
- * @return string
+ * Returns the full principal url
+ *
+ * @return string
*/
public function getPrincipalUrl() {
- return $this->principalInfo['uri'] . '/' . $this->getName();
+ return $this->principalInfo['uri'] . '/' . $this->getName();
}
/**
* Returns the list of group members
- *
+ *
* If this principal is a group, this function should return
- * all member principal uri's for the group.
- *
+ * all member principal uri's for the group.
+ *
* @return array
*/
public function getGroupMemberSet() {
- return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
+ return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
}
/**
* Returns the list of groups this principal is member of
- *
+ *
* If this principal is a member of a (list of) groups, this function
- * should return a list of principal uri's for it's members.
- *
- * @return array
+ * should return a list of principal uri's for it's members.
+ *
+ * @return array
*/
public function getGroupMembership() {
- return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
+ return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
}
@@ -149,11 +149,11 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
*
* If this principal is a group, this method sets all the group members.
* The list of members is always overwritten, never appended to.
- *
- * This method should throw an exception if the members could not be set.
- *
- * @param array $principals
- * @return void
+ *
+ * This method should throw an exception if the members could not be set.
+ *
+ * @param array $principals
+ * @return void
*/
public function setGroupMemberSet(array $principals) {
@@ -165,9 +165,9 @@ class Sabre_CalDAV_Principal_ProxyRead implements Sabre_DAVACL_IPrincipal {
* Returns the displayname
*
* This should be a human readable name for the principal.
- * If none is available, return the nodename.
- *
- * @return string
+ * If none is available, return the nodename.
+ *
+ * @return string
*/
public function getDisplayName() {
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
index 4d8face2060..dd0c2e86edd 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
+++ b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
@@ -4,38 +4,38 @@
* ProxyWrite principal
*
* This class represents a principal group, hosted under the main principal.
- * This is needed to implement 'Calendar delegation' support. This class is
+ * This is needed to implement 'Calendar delegation' support. This class is
* instantiated by Sabre_CalDAV_Principal_User.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
/**
- * Parent principal information
- *
- * @var array
+ * Parent principal information
+ *
+ * @var array
*/
protected $principalInfo;
/**
- * Principal Backend
- *
- * @var Sabre_DAVACL_IPrincipalBackend
+ * Principal Backend
+ *
+ * @var Sabre_DAVACL_IPrincipalBackend
*/
protected $principalBackend;
/**
* Creates the object
*
- * Note that you MUST supply the parent principal information.
- *
- * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
- * @param array $principalInfo
+ * Note that you MUST supply the parent principal information.
+ *
+ * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+ * @param array $principalInfo
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, array $principalInfo) {
@@ -46,8 +46,8 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
/**
* Returns this principals name.
- *
- * @return string
+ *
+ * @return string
*/
public function getName() {
@@ -56,13 +56,13 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
}
/**
- * Returns the last modification time
+ * Returns the last modification time
*
- * @return null
+ * @return null
*/
public function getLastModified() {
- return null;
+ return null;
}
@@ -70,7 +70,7 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
* Deletes the current node
*
* @throws Sabre_DAV_Exception_Forbidden
- * @return void
+ * @return void
*/
public function delete() {
@@ -80,7 +80,7 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
/**
* Renames the node
- *
+ *
* @throws Sabre_DAV_Exception_Forbidden
* @param string $name The new name
* @return void
@@ -93,11 +93,11 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
/**
- * Returns a list of altenative urls for a principal
- *
+ * Returns a list of alternative urls for a principal
+ *
* This can for example be an email address, or ldap url.
- *
- * @return array
+ *
+ * @return array
*/
public function getAlternateUriSet() {
@@ -106,41 +106,41 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
}
/**
- * Returns the full principal url
- *
- * @return string
+ * Returns the full principal url
+ *
+ * @return string
*/
public function getPrincipalUrl() {
- return $this->principalInfo['uri'] . '/' . $this->getName();
+ return $this->principalInfo['uri'] . '/' . $this->getName();
}
/**
* Returns the list of group members
- *
+ *
* If this principal is a group, this function should return
- * all member principal uri's for the group.
- *
+ * all member principal uri's for the group.
+ *
* @return array
*/
public function getGroupMemberSet() {
- return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
+ return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl());
}
/**
* Returns the list of groups this principal is member of
- *
+ *
* If this principal is a member of a (list of) groups, this function
- * should return a list of principal uri's for it's members.
- *
- * @return array
+ * should return a list of principal uri's for it's members.
+ *
+ * @return array
*/
public function getGroupMembership() {
- return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
+ return $this->principalBackend->getGroupMembership($this->getPrincipalUrl());
}
@@ -149,11 +149,11 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
*
* If this principal is a group, this method sets all the group members.
* The list of members is always overwritten, never appended to.
- *
- * This method should throw an exception if the members could not be set.
- *
- * @param array $principals
- * @return void
+ *
+ * This method should throw an exception if the members could not be set.
+ *
+ * @param array $principals
+ * @return void
*/
public function setGroupMemberSet(array $principals) {
@@ -165,9 +165,9 @@ class Sabre_CalDAV_Principal_ProxyWrite implements Sabre_DAVACL_IPrincipal {
* Returns the displayname
*
* This should be a human readable name for the principal.
- * If none is available, return the nodename.
- *
- * @return string
+ * If none is available, return the nodename.
+ *
+ * @return string
*/
public function getDisplayName() {
diff --git a/3rdparty/Sabre/CalDAV/Principal/User.php b/3rdparty/Sabre/CalDAV/Principal/User.php
index 034629b89b3..8453b877a73 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/User.php
+++ b/3rdparty/Sabre/CalDAV/Principal/User.php
@@ -1,25 +1,25 @@
<?php
/**
- * CalDAV principal
+ * CalDAV principal
*
- * This is a standard user-principal for CalDAV. This principal is also a
- * collection and returns the caldav-proxy-read and caldav-proxy-write child
+ * This is a standard user-principal for CalDAV. This principal is also a
+ * collection and returns the caldav-proxy-read and caldav-proxy-write child
* principals.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Principal_User extends Sabre_DAVACL_Principal implements Sabre_DAV_ICollection {
/**
- * Creates a new file in the directory
- *
- * @param string $name Name of the file
- * @param resource $data Initial payload, passed as a readable stream resource.
+ * Creates a new file in the directory
+ *
+ * @param string $name Name of the file
+ * @param resource $data Initial payload, passed as a readable stream resource.
* @throws Sabre_DAV_Exception_Forbidden
* @return void
*/
@@ -30,9 +30,9 @@ class Sabre_CalDAV_Principal_User extends Sabre_DAVACL_Principal implements Sabr
}
/**
- * Creates a new subdirectory
- *
- * @param string $name
+ * Creates a new subdirectory
+ *
+ * @param string $name
* @throws Sabre_DAV_Exception_Forbidden
* @return void
*/
@@ -43,45 +43,60 @@ class Sabre_CalDAV_Principal_User extends Sabre_DAVACL_Principal implements Sabr
}
/**
- * Returns a specific child node, referenced by its name
- *
- * @param string $name
- * @return Sabre_DAV_INode
+ * Returns a specific child node, referenced by its name
+ *
+ * @param string $name
+ * @return Sabre_DAV_INode
*/
public function getChild($name) {
+ $principal = $this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/' . $name);
+ if (!$principal) {
+ throw new Sabre_DAV_Exception_NotFound('Node with name ' . $name . ' was not found');
+ }
if ($name === 'calendar-proxy-read')
return new Sabre_CalDAV_Principal_ProxyRead($this->principalBackend, $this->principalProperties);
if ($name === 'calendar-proxy-write')
return new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties);
- throw new Sabre_DAV_Exception_FileNotFound('Node with name ' . $name . ' was not found');
+ throw new Sabre_DAV_Exception_NotFound('Node with name ' . $name . ' was not found');
}
/**
- * Returns an array with all the child nodes
- *
- * @return Sabre_DAV_INode[]
+ * Returns an array with all the child nodes
+ *
+ * @return Sabre_DAV_INode[]
*/
public function getChildren() {
- return array(
- new Sabre_CalDAV_Principal_ProxyRead($this->principalBackend, $this->principalProperties),
- new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties),
- );
+ $r = array();
+ if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/calendar-proxy-read')) {
+ $r[] = new Sabre_CalDAV_Principal_ProxyRead($this->principalBackend, $this->principalProperties);
+ }
+ if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/calendar-proxy-write')) {
+ $r[] = new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties);
+ }
+
+ return $r;
}
/**
- * Checks if a child-node with the specified name exists
- *
- * @return bool
+ * Returns whether or not the child node exists
+ *
+ * @param string $name
+ * @return bool
*/
public function childExists($name) {
- return $name === 'calendar-proxy-read' || $name === 'calendar-proxy-write';
+ try {
+ $this->getChild($name);
+ return true;
+ } catch (Sabre_DAV_Exception_NotFound $e) {
+ return false;
+ }
}
@@ -89,33 +104,28 @@ class Sabre_CalDAV_Principal_User extends Sabre_DAVACL_Principal implements Sabr
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
- return array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => $this->principalProperties['uri'],
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => $this->principalProperties['uri'] . '/calendar-proxy-read',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => $this->principalProperties['uri'] . '/calendar-proxy-write',
- 'protected' => true,
- ),
+ $acl = parent::getACL();
+ $acl[] = array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->principalProperties['uri'] . '/calendar-proxy-read',
+ 'protected' => true,
+ );
+ $acl[] = array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->principalProperties['uri'] . '/calendar-proxy-write',
+ 'protected' => true,
);
+ return $acl;
}
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
index 1bbaca6b8a7..2ea078d7dac 100644..100755
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
@@ -3,40 +3,40 @@
/**
* Supported component set property
*
- * This property is a representation of the supported-calendar_component-set
+ * This property is a representation of the supported-calendar_component-set
* property in the CalDAV namespace. It simply requires an array of components,
* such as VEVENT, VTODO
*
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Property_SupportedCalendarComponentSet extends Sabre_DAV_Property {
/**
- * List of supported components, such as "VEVENT, VTODO"
- *
- * @var array
+ * List of supported components, such as "VEVENT, VTODO"
+ *
+ * @var array
*/
private $components;
/**
- * Creates the property
- *
- * @param array $components
+ * Creates the property
+ *
+ * @param array $components
*/
public function __construct(array $components) {
- $this->components = $components;
+ $this->components = $components;
}
/**
- * Returns the list of supported components
- *
- * @return array
+ * Returns the list of supported components
+ *
+ * @return array
*/
public function getValue() {
@@ -45,10 +45,10 @@ class Sabre_CalDAV_Property_SupportedCalendarComponentSet extends Sabre_DAV_Prop
}
/**
- * Serializes the property in a DOMDocument
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property in a DOMDocument
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -58,7 +58,7 @@ class Sabre_CalDAV_Property_SupportedCalendarComponentSet extends Sabre_DAV_Prop
$xcomp = $doc->createElement('cal:comp');
$xcomp->setAttribute('name',$component);
- $node->appendChild($xcomp);
+ $node->appendChild($xcomp);
}
@@ -66,9 +66,9 @@ class Sabre_CalDAV_Property_SupportedCalendarComponentSet extends Sabre_DAV_Prop
/**
* Unserializes the DOMElement back into a Property class.
- *
- * @param DOMElement $node
- * @return void
+ *
+ * @param DOMElement $node
+ * @return Sabre_CalDAV_Property_SupportedCalendarComponentSet
*/
static function unserialize(DOMElement $node) {
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
index 5010ee6d525..1d848dd5cf6 100644..100755
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
@@ -9,17 +9,17 @@
*
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Property_SupportedCalendarData extends Sabre_DAV_Property {
/**
- * Serializes the property in a DOMDocument
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property in a DOMDocument
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -32,7 +32,7 @@ class Sabre_CalDAV_Property_SupportedCalendarData extends Sabre_DAV_Property {
$caldata->setAttribute('content-type','text/calendar');
$caldata->setAttribute('version','2.0');
- $node->appendChild($caldata);
+ $node->appendChild($caldata);
}
}
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
index e585e9db3d8..24e84d4c17d 100644..100755
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
@@ -4,27 +4,27 @@
* supported-collation-set property
*
* This property is a representation of the supported-collation-set property
- * in the CalDAV namespace.
+ * in the CalDAV namespace.
*
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Property_SupportedCollationSet extends Sabre_DAV_Property {
/**
- * Serializes the property in a DOM document
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property in a DOM document
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
$doc = $node->ownerDocument;
-
+
$prefix = $node->lookupPrefix('urn:ietf:params:xml:ns:caldav');
if (!$prefix) $prefix = 'cal';
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IMip.php b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
new file mode 100755
index 00000000000..37e75fcc4a7
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * iMIP handler.
+ *
+ * This class is responsible for sending out iMIP messages. iMIP is the
+ * email-based transport for iTIP. iTIP deals with scheduling operations for
+ * iCalendar objects.
+ *
+ * If you want to customize the email that gets sent out, you can do so by
+ * extending this class and overriding the sendMessage method.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Schedule_IMip {
+
+ /**
+ * Email address used in From: header.
+ *
+ * @var string
+ */
+ protected $senderEmail;
+
+ /**
+ * Creates the email handler.
+ *
+ * @param string $senderEmail. The 'senderEmail' is the email that shows up
+ * in the 'From:' address. This should
+ * generally be some kind of no-reply email
+ * address you own.
+ */
+ public function __construct($senderEmail) {
+
+ $this->senderEmail = $senderEmail;
+
+ }
+
+ /**
+ * Sends one or more iTip messages through email.
+ *
+ * @param string $originator
+ * @param array $recipients
+ * @param Sabre_VObject_Component $vObject
+ * @return void
+ */
+ public function sendMessage($originator, array $recipients, Sabre_VObject_Component $vObject) {
+
+ foreach($recipients as $recipient) {
+
+ $to = $recipient;
+ $replyTo = $originator;
+ $subject = 'SabreDAV iTIP message';
+
+ switch(strtoupper($vObject->METHOD)) {
+ case 'REPLY' :
+ $subject = 'Response for: ' . $vObject->VEVENT->SUMMARY;
+ break;
+ case 'REQUEST' :
+ $subject = 'Invitation for: ' .$vObject->VEVENT->SUMMARY;
+ break;
+ case 'CANCEL' :
+ $subject = 'Cancelled event: ' . $vObject->VEVENT->SUMMARY;
+ break;
+ }
+
+ $headers = array();
+ $headers[] = 'Reply-To: ' . $replyTo;
+ $headers[] = 'From: ' . $this->senderEmail;
+ $headers[] = 'Content-Type: text/calendar; method=' . (string)$vObject->method . '; charset=utf-8';
+ if (Sabre_DAV_Server::$exposeVersion) {
+ $headers[] = 'X-Sabre-Version: ' . Sabre_DAV_Version::VERSION . '-' . Sabre_DAV_Version::STABILITY;
+ }
+
+ $vcalBody = $vObject->serialize();
+
+ $this->mail($to, $subject, $vcalBody, $headers);
+
+ }
+
+ }
+
+ /**
+ * This function is reponsible for sending the actual email.
+ *
+ * @param string $to Recipient email address
+ * @param string $subject Subject of the email
+ * @param string $body iCalendar body
+ * @param array $headers List of headers
+ * @return void
+ */
+ protected function mail($to, $subject, $body, array $headers) {
+
+ mail($to, $subject, $body, implode("\r\n", $headers));
+
+ }
+
+
+}
+
+?>
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
new file mode 100755
index 00000000000..46d77514bc0
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * Implement this interface to have a node be recognized as a CalDAV scheduling
+ * outbox.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+interface Sabre_CalDAV_Schedule_IOutbox extends Sabre_DAV_ICollection, Sabre_DAVACL_IACL {
+
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Schedule/Outbox.php b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
new file mode 100755
index 00000000000..014c37230d1
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
@@ -0,0 +1,152 @@
+<?php
+
+/**
+ * The CalDAV scheduling outbox
+ *
+ * The outbox is mainly used as an endpoint in the tree for a client to do
+ * free-busy requests. This functionality is completely handled by the
+ * Scheduling plugin, so this object is actually mostly static.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CalDAV_Schedule_Outbox extends Sabre_DAV_Directory implements Sabre_CalDAV_Schedule_IOutbox {
+
+ /**
+ * The principal Uri
+ *
+ * @var string
+ */
+ protected $principalUri;
+
+ /**
+ * Constructor
+ *
+ * @param string $principalUri
+ */
+ public function __construct($principalUri) {
+
+ $this->principalUri = $principalUri;
+
+ }
+
+ /**
+ * Returns the name of the node.
+ *
+ * This is used to generate the url.
+ *
+ * @return string
+ */
+ public function getName() {
+
+ return 'outbox';
+
+ }
+
+ /**
+ * Returns an array with all the child nodes
+ *
+ * @return Sabre_DAV_INode[]
+ */
+ public function getChildren() {
+
+ return array();
+
+ }
+
+ /**
+ * Returns the owner principal
+ *
+ * This must be a url to a principal, or null if there's no owner
+ *
+ * @return string|null
+ */
+ public function getOwner() {
+
+ return $this->principalUri;
+
+ }
+
+ /**
+ * Returns a group principal
+ *
+ * This must be a url to a principal, or null if there's no owner
+ *
+ * @return string|null
+ */
+ public function getGroup() {
+
+ return null;
+
+ }
+
+ /**
+ * Returns a list of ACE's for this node.
+ *
+ * Each ACE has the following properties:
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * currently the only supported privileges
+ * * 'principal', a url to the principal who owns the node
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
+ */
+ public function getACL() {
+
+ return array(
+ array(
+ 'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy',
+ 'principal' => $this->getOwner(),
+ 'protected' => true,
+ ),
+ array(
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->getOwner(),
+ 'protected' => true,
+ ),
+ );
+
+ }
+
+ /**
+ * Updates the ACL
+ *
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
+ * @return void
+ */
+ public function setACL(array $acl) {
+
+ throw new Sabre_DAV_Exception_MethodNotAllowed('You\'re not allowed to update the ACL');
+
+ }
+
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ $default = Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet();
+ $default['aggregates'][] = array(
+ 'privilege' => '{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}schedule-query-freebusy',
+ );
+
+ return $default;
+
+ }
+
+}
diff --git a/3rdparty/Sabre/CalDAV/Server.php b/3rdparty/Sabre/CalDAV/Server.php
index 969d69c6279..325e3d80a7f 100644..100755
--- a/3rdparty/Sabre/CalDAV/Server.php
+++ b/3rdparty/Sabre/CalDAV/Server.php
@@ -3,17 +3,20 @@
/**
* CalDAV server
*
+ * Deprecated! Warning: This class is now officially deprecated
+ *
* This script is a convenience script. It quickly sets up a WebDAV server
* with caldav and ACL support, and it creates the root 'principals' and
* 'calendars' collections.
*
- * Note that if you plan to do anything moderately complex, you are advised to
- * not subclass this server, but use Sabre_DAV_Server directly instead. This
+ * Note that if you plan to do anything moderately complex, you are advised to
+ * not subclass this server, but use Sabre_DAV_Server directly instead. This
* class is nothing more than an 'easy setup'.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @deprecated Don't use this class anymore, it will be removed in version 1.7.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -22,17 +25,17 @@ class Sabre_CalDAV_Server extends Sabre_DAV_Server {
/**
* The authentication realm
*
- * Note that if this changes, the hashes in the auth backend must also
- * be recalculated.
- *
+ * Note that if this changes, the hashes in the auth backend must also
+ * be recalculated.
+ *
* @var string
*/
public $authRealm = 'SabreDAV';
/**
* Sets up the object. A PDO object must be passed to setup all the backends.
- *
- * @param PDO $pdo
+ *
+ * @param PDO $pdo
*/
public function __construct(PDO $pdo) {
diff --git a/3rdparty/Sabre/CalDAV/UserCalendars.php b/3rdparty/Sabre/CalDAV/UserCalendars.php
index f52d65e9a73..b8d3f0573fa 100644..100755
--- a/3rdparty/Sabre/CalDAV/UserCalendars.php
+++ b/3rdparty/Sabre/CalDAV/UserCalendars.php
@@ -1,68 +1,68 @@
<?php
/**
- * The UserCalenders class contains all calendars associated to one user
- *
+ * The UserCalenders class contains all calendars associated to one user
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre_DAVACL_IACL {
/**
- * Principal backend
- *
+ * Principal backend
+ *
* @var Sabre_DAVACL_IPrincipalBackend
*/
protected $principalBackend;
/**
* CalDAV backend
- *
+ *
* @var Sabre_CalDAV_Backend_Abstract
*/
protected $caldavBackend;
/**
- * Principal information
- *
- * @var array
+ * Principal information
+ *
+ * @var array
*/
protected $principalInfo;
-
+
/**
- * Constructor
- *
+ * Constructor
+ *
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend
- * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
- * @param mixed $userUri
+ * @param Sabre_CalDAV_Backend_Abstract $caldavBackend
+ * @param mixed $userUri
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $userUri) {
$this->principalBackend = $principalBackend;
$this->caldavBackend = $caldavBackend;
$this->principalInfo = $principalBackend->getPrincipalByPath($userUri);
-
+
}
/**
- * Returns the name of this object
- *
+ * Returns the name of this object
+ *
* @return string
*/
public function getName() {
-
+
list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalInfo['uri']);
- return $name;
+ return $name;
}
/**
- * Updates the name of this object
- *
- * @param string $name
+ * Updates the name of this object
+ *
+ * @param string $name
* @return void
*/
public function setName($name) {
@@ -72,8 +72,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
}
/**
- * Deletes this object
- *
+ * Deletes this object
+ *
* @return void
*/
public function delete() {
@@ -83,13 +83,13 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
}
/**
- * Returns the last modification date
- *
- * @return int
+ * Returns the last modification date
+ *
+ * @return int
*/
public function getLastModified() {
- return null;
+ return null;
}
@@ -97,9 +97,9 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
* Creates a new file under this object.
*
* This is currently not allowed
- *
- * @param string $filename
- * @param resource $data
+ *
+ * @param string $filename
+ * @param resource $data
* @return void
*/
public function createFile($filename, $data=null) {
@@ -112,8 +112,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
* Creates a new directory under this object.
*
* This is currently not allowed.
- *
- * @param string $filename
+ *
+ * @param string $filename
* @return void
*/
public function createDirectory($filename) {
@@ -123,11 +123,11 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
}
/**
- * Returns a single calendar, by name
- *
+ * Returns a single calendar, by name
+ *
* @param string $name
* @todo needs optimizing
- * @return Sabre_CalDAV_Calendar
+ * @return Sabre_CalDAV_Calendar
*/
public function getChild($name) {
@@ -136,22 +136,22 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
return $child;
}
- throw new Sabre_DAV_Exception_FileNotFound('Calendar with name \'' . $name . '\' could not be found');
+ throw new Sabre_DAV_Exception_NotFound('Calendar with name \'' . $name . '\' could not be found');
}
/**
* Checks if a calendar exists.
- *
+ *
* @param string $name
* @todo needs optimizing
- * @return bool
+ * @return bool
*/
public function childExists($name) {
foreach($this->getChildren() as $child) {
if ($name==$child->getName())
- return true;
+ return true;
}
return false;
@@ -160,8 +160,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
/**
* Returns a list of calendars
- *
- * @return array
+ *
+ * @return array
*/
public function getChildren() {
@@ -170,15 +170,17 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
foreach($calendars as $calendar) {
$objs[] = new Sabre_CalDAV_Calendar($this->principalBackend, $this->caldavBackend, $calendar);
}
+ $objs[] = new Sabre_CalDAV_Schedule_Outbox($this->principalInfo['uri']);
return $objs;
}
/**
* Creates a new calendar
- *
- * @param string $name
- * @param string $properties
+ *
+ * @param string $name
+ * @param array $resourceType
+ * @param array $properties
* @return void
*/
public function createExtendedCollection($name, array $resourceType, array $properties) {
@@ -193,8 +195,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
public function getOwner() {
@@ -207,8 +209,8 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
public function getGroup() {
@@ -220,13 +222,13 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
@@ -264,9 +266,9 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
public function setACL(array $acl) {
@@ -275,6 +277,22 @@ class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre
}
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ return null;
+ }
}
diff --git a/3rdparty/Sabre/CalDAV/Version.php b/3rdparty/Sabre/CalDAV/Version.php
index df8fe1f6bd6..939e903c89f 100644..100755
--- a/3rdparty/Sabre/CalDAV/Version.php
+++ b/3rdparty/Sabre/CalDAV/Version.php
@@ -2,10 +2,10 @@
/**
* This class contains the Sabre_CalDAV version constants.
- *
+ *
* @package Sabre
* @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -14,7 +14,7 @@ class Sabre_CalDAV_Version {
/**
* Full version number
*/
- const VERSION = '1.5.3';
+ const VERSION = '1.6.2';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CalDAV/XMLUtil.php b/3rdparty/Sabre/CalDAV/XMLUtil.php
deleted file mode 100644
index bf349a36aae..00000000000
--- a/3rdparty/Sabre/CalDAV/XMLUtil.php
+++ /dev/null
@@ -1,208 +0,0 @@
-<?php
-
-/**
- * XML utilities for CalDAV
- *
- * This class contains a few static methods used for parsing certain CalDAV
- * requests.
- *
- * @package Sabre
- * @subpackage CalDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-class Sabre_CalDAV_XMLUtil {
-
- /**
- * This function parses the calendar-query report request body
- *
- * The body is quite complicated, so we're turning it into a PHP
- * array.
- *
- * The resulting associative array has xpath expressions as keys.
- * By default the xpath expressions should simply be checked for existance
- * The xpath expressions can point to elements or attributes.
- *
- * The array values can contain a number of items, which alters the query
- * filter.
- *
- * * time-range. Must also check if the todo or event falls within the
- * specified timerange. How this is interpreted depends on
- * the type of object (VTODO, VEVENT, VJOURNAL, etc)
- * * is-not-defined
- * Instead of checking if the attribute or element exist,
- * we must check if it doesn't.
- * * text-match
- * Checks if the value of the attribute or element matches
- * the specified value. This is actually another array with
- * the 'collation', 'value' and 'negate-condition' items.
- *
- * Refer to the CalDAV spec for more information.
- *
- * @param DOMNode $domNode
- * @param string $basePath used for recursive calls.
- * @param array $filters used for recursive calls.
- * @return array
- */
- static public function parseCalendarQueryFilters($domNode,$basePath = '/c:iCalendar', &$filters = array()) {
-
- foreach($domNode->childNodes as $child) {
-
- switch(Sabre_DAV_XMLUtil::toClarkNotation($child)) {
-
- case '{urn:ietf:params:xml:ns:caldav}comp-filter' :
- case '{urn:ietf:params:xml:ns:caldav}prop-filter' :
-
- $filterName = $basePath . '/' . 'c:' . strtolower($child->getAttribute('name'));
- $filters[$filterName] = array();
-
- self::parseCalendarQueryFilters($child, $filterName,$filters);
- break;
-
- case '{urn:ietf:params:xml:ns:caldav}time-range' :
-
- if ($start = $child->getAttribute('start')) {
- $start = self::parseICalendarDateTime($start);
- } else {
- $start = null;
- }
- if ($end = $child->getAttribute('end')) {
- $end = self::parseICalendarDateTime($end);
- } else {
- $end = null;
- }
-
- if (!is_null($start) && !is_null($end) && $end <= $start) {
- throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the time-range filter');
- }
-
- $filters[$basePath]['time-range'] = array(
- 'start' => $start,
- 'end' => $end
- );
- break;
-
- case '{urn:ietf:params:xml:ns:caldav}is-not-defined' :
- $filters[$basePath]['is-not-defined'] = true;
- break;
-
- case '{urn:ietf:params:xml:ns:caldav}param-filter' :
-
- $filterName = $basePath . '/@' . strtolower($child->getAttribute('name'));
- $filters[$filterName] = array();
- self::parseCalendarQueryFilters($child, $filterName, $filters);
- break;
-
- case '{urn:ietf:params:xml:ns:caldav}text-match' :
-
- $collation = $child->getAttribute('collation');
- if (!$collation) $collation = 'i;ascii-casemap';
-
- $filters[$basePath]['text-match'] = array(
- 'collation' => ($collation == 'default'?'i;ascii-casemap':$collation),
- 'negate-condition' => $child->getAttribute('negate-condition')==='yes',
- 'value' => $child->nodeValue,
- );
- break;
-
- }
-
- }
-
- return $filters;
-
- }
-
- /**
- * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
- *
- * Specifying a reference timezone is optional. It will only be used
- * if the non-UTC format is used. The argument is used as a reference, the
- * returned DateTime object will still be in the UTC timezone.
- *
- * @param string $dt
- * @param DateTimeZone $tz
- * @return DateTime
- */
- static public function parseICalendarDateTime($dt,DateTimeZone $tz = null) {
-
- // Format is YYYYMMDD + "T" + hhmmss
- $result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
-
- if (!$result) {
- throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar datetime value is incorrect: ' . $dt);
- }
-
- if ($matches[7]==='Z' || is_null($tz)) {
- $tz = new DateTimeZone('UTC');
- }
- $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
-
- // Still resetting the timezone, to normalize everything to UTC
- $date->setTimeZone(new DateTimeZone('UTC'));
- return $date;
-
- }
-
- /**
- * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
- *
- * @param string $date
- * @param DateTimeZone $tz
- * @return DateTime
- */
- static public function parseICalendarDate($date) {
-
- // Format is YYYYMMDD
- $result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
-
- if (!$result) {
- throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar date value is incorrect: ' . $date);
- }
-
- $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new DateTimeZone('UTC'));
- return $date;
-
- }
-
- /**
- * Parses an iCalendar (RFC5545) formatted duration and returns a string suitable
- * for strtotime or DateTime::modify.
- *
- * NOTE: When we require PHP 5.3 this can be replaced by the DateTimeInterval object, which
- * supports ISO 8601 Intervals, which is a superset of ICalendar durations.
- *
- * For now though, we're just gonna live with this messy system
- *
- * @param string $duration
- * @return string
- */
- static public function parseICalendarDuration($duration) {
-
- $result = preg_match('/^(?P<plusminus>\+|-)?P((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$/', $duration, $matches);
- if (!$result) {
- throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar duration value is incorrect: ' . $duration);
- }
-
- $parts = array(
- 'week',
- 'day',
- 'hour',
- 'minute',
- 'second',
- );
-
- $newDur = '';
- foreach($parts as $part) {
- if (isset($matches[$part]) && $matches[$part]) {
- $newDur.=' '.$matches[$part] . ' ' . $part . 's';
- }
- }
-
- $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
- return $newDur;
-
- }
-
-}
diff --git a/3rdparty/Sabre/CalDAV/includes.php b/3rdparty/Sabre/CalDAV/includes.php
new file mode 100755
index 00000000000..1ecb870a0e1
--- /dev/null
+++ b/3rdparty/Sabre/CalDAV/includes.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * Sabre_CalDAV includes file
+ *
+ * Including this file will automatically include all files from the
+ * Sabre_CalDAV package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @subpackage CalDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+
+// Begin includes
+include __DIR__ . '/Backend/Abstract.php';
+include __DIR__ . '/Backend/PDO.php';
+include __DIR__ . '/CalendarQueryParser.php';
+include __DIR__ . '/CalendarQueryValidator.php';
+include __DIR__ . '/CalendarRootNode.php';
+include __DIR__ . '/ICalendar.php';
+include __DIR__ . '/ICalendarObject.php';
+include __DIR__ . '/ICSExportPlugin.php';
+include __DIR__ . '/Plugin.php';
+include __DIR__ . '/Principal/Collection.php';
+include __DIR__ . '/Principal/ProxyRead.php';
+include __DIR__ . '/Principal/ProxyWrite.php';
+include __DIR__ . '/Principal/User.php';
+include __DIR__ . '/Property/SupportedCalendarComponentSet.php';
+include __DIR__ . '/Property/SupportedCalendarData.php';
+include __DIR__ . '/Property/SupportedCollationSet.php';
+include __DIR__ . '/Schedule/IMip.php';
+include __DIR__ . '/Schedule/IOutbox.php';
+include __DIR__ . '/Schedule/Outbox.php';
+include __DIR__ . '/Server.php';
+include __DIR__ . '/UserCalendars.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/Calendar.php';
+include __DIR__ . '/CalendarObject.php';
+// End includes
diff --git a/3rdparty/Sabre/CardDAV/AddressBook.php b/3rdparty/Sabre/CardDAV/AddressBook.php
index 471ca7b338a..3b381e1eea3 100644..100755
--- a/3rdparty/Sabre/CardDAV/AddressBook.php
+++ b/3rdparty/Sabre/CardDAV/AddressBook.php
@@ -7,34 +7,33 @@
*
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_CardDAV_IAddressBook, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
/**
- * This is an array with addressbook information
- *
- * @var array
+ * This is an array with addressbook information
+ *
+ * @var array
*/
private $addressBookInfo;
/**
- * CardDAV backend
- *
- * @var Sabre_CardDAV_Backend_Abstract
+ * CardDAV backend
+ *
+ * @var Sabre_CardDAV_Backend_Abstract
*/
private $carddavBackend;
/**
- * Constructor
- *
- * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
- * @param array $addressBookInfo
- * @return void
+ * Constructor
+ *
+ * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
+ * @param array $addressBookInfo
*/
- public function __construct(Sabre_CardDAV_Backend_Abstract $carddavBackend,array $addressBookInfo) {
+ public function __construct(Sabre_CardDAV_Backend_Abstract $carddavBackend, array $addressBookInfo) {
$this->carddavBackend = $carddavBackend;
$this->addressBookInfo = $addressBookInfo;
@@ -42,9 +41,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
}
/**
- * Returns the name of the addressbook
- *
- * @return string
+ * Returns the name of the addressbook
+ *
+ * @return string
*/
public function getName() {
@@ -55,21 +54,21 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
/**
* Returns a card
*
- * @param string $name
+ * @param string $name
* @return Sabre_DAV_Card
*/
public function getChild($name) {
$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'],$name);
- if (!$obj) throw new Sabre_DAV_Exception_FileNotFound('Card not found');
+ if (!$obj) throw new Sabre_DAV_Exception_NotFound('Card not found');
return new Sabre_CardDAV_Card($this->carddavBackend,$this->addressBookInfo,$obj);
}
/**
* Returns the full list of cards
- *
- * @return array
+ *
+ * @return array
*/
public function getChildren() {
@@ -85,9 +84,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
/**
* Creates a new directory
*
- * We actually block this, as subdirectories are not allowed in addressbooks.
- *
- * @param string $name
+ * We actually block this, as subdirectories are not allowed in addressbooks.
+ *
+ * @param string $name
* @return void
*/
public function createDirectory($name) {
@@ -99,11 +98,13 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
/**
* Creates a new file
*
- * The contents of the new file must be a valid VCARD
- *
- * @param string $name
- * @param resource $vcardData
- * @return void
+ * The contents of the new file must be a valid VCARD.
+ *
+ * This method may return an ETag.
+ *
+ * @param string $name
+ * @param resource $vcardData
+ * @return void|null
*/
public function createFile($name,$vcardData = null) {
@@ -111,13 +112,13 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
// Converting to UTF-8, if needed
$vcardData = Sabre_DAV_StringUtil::ensureUTF8($vcardData);
- $this->carddavBackend->createCard($this->addressBookInfo['id'],$name,$vcardData);
+ return $this->carddavBackend->createCard($this->addressBookInfo['id'],$name,$vcardData);
}
/**
- * Deletes the entire addressbook.
- *
+ * Deletes the entire addressbook.
+ *
* @return void
*/
public function delete() {
@@ -128,8 +129,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
/**
* Renames the addressbook
- *
- * @param string $newName
+ *
+ * @param string $newName
* @return void
*/
public function setName($newName) {
@@ -140,7 +141,7 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
/**
* Returns the last modification date as a unix timestamp.
- *
+ *
* @return void
*/
public function getLastModified() {
@@ -162,7 +163,7 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
* If the operation was successful, true can be returned.
* If the operation failed, false can be returned.
*
- * Deletion of a non-existant property is always succesful.
+ * Deletion of a non-existent property is always successful.
*
* Lastly, it is optional to return detailed information about any
* failures. In this case an array should be returned with the following
@@ -177,16 +178,16 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
* )
* )
*
- * In this example it was forbidden to update {DAV:}displayname.
+ * In this example it was forbidden to update {DAV:}displayname.
* (403 Forbidden), which in turn also caused {DAV:}owner to fail
* (424 Failed Dependency) because the request needs to be atomic.
*
- * @param array $mutations
- * @return bool|array
+ * @param array $mutations
+ * @return bool|array
*/
public function updateProperties($mutations) {
- return $this->carddavBackend->updateAddressBook($this->addressBookInfo['id'], $mutations);
+ return $this->carddavBackend->updateAddressBook($this->addressBookInfo['id'], $mutations);
}
@@ -198,8 +199,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
*
* If the array is empty, it means 'all properties' were requested.
*
- * @param array $properties
- * @return void
+ * @param array $properties
+ * @return array
*/
public function getProperties($properties) {
@@ -221,8 +222,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
public function getOwner() {
@@ -235,8 +236,8 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
public function getGroup() {
@@ -248,13 +249,13 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
@@ -277,9 +278,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
public function setACL(array $acl) {
@@ -288,6 +289,22 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
}
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ return null;
+ }
}
diff --git a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
index 08adc3b8157..85a4963127b 100644..100755
--- a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
+++ b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
@@ -3,12 +3,12 @@
/**
* Parses the addressbook-query report request body.
*
- * Whoever designed this format, and the CalDAV equavalent even more so,
+ * Whoever designed this format, and the CalDAV equivalent even more so,
* has no feel for design.
- *
+ *
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -19,8 +19,8 @@ class Sabre_CardDAV_AddressBookQueryParser {
/**
* List of requested properties the client wanted
- *
- * @var array
+ *
+ * @var array
*/
public $requestedProperties;
@@ -28,44 +28,43 @@ class Sabre_CardDAV_AddressBookQueryParser {
* The number of results the client wants
*
* null means it wasn't specified, which in most cases means 'all results'.
- *
- * @var int|null
+ *
+ * @var int|null
*/
public $limit;
/**
* List of property filters.
*
- * @var array
+ * @var array
*/
public $filters;
/**
* Either TEST_ANYOF or TEST_ALLOF
- *
- * @var string
+ *
+ * @var string
*/
public $test;
/**
* DOM Document
- *
- * @var DOMDocument
+ *
+ * @var DOMDocument
*/
protected $dom;
/**
- * DOM XPath object
- *
- * @var DOMXPath
+ * DOM XPath object
+ *
+ * @var DOMXPath
*/
protected $xpath;
/**
* Creates the parser
- *
- * @param DOMNode $dom
- * @return void
+ *
+ * @param DOMDocument $dom
*/
public function __construct(DOMDocument $dom) {
@@ -77,15 +76,14 @@ class Sabre_CardDAV_AddressBookQueryParser {
}
/**
- * Parses the request.
- *
- * @param DOMNode $dom
+ * Parses the request.
+ *
* @return void
*/
public function parse() {
$filterNode = null;
-
+
$limit = $this->xpath->evaluate('number(/card:addressbook-query/card:limit/card:nresults)');
if (is_nan($limit)) $limit = null;
@@ -120,9 +118,9 @@ class Sabre_CardDAV_AddressBookQueryParser {
/**
* Parses the prop-filter xml element
- *
- * @param DOMElement $propFilterNode
- * @return array
+ *
+ * @param DOMElement $propFilterNode
+ * @return array
*/
protected function parsePropFilterNode(DOMElement $propFilterNode) {
@@ -157,13 +155,13 @@ class Sabre_CardDAV_AddressBookQueryParser {
}
/**
- * Parses the param-filter element
- *
- * @param DOMElement $paramFilterNode
- * @return array
+ * Parses the param-filter element
+ *
+ * @param DOMElement $paramFilterNode
+ * @return array
*/
public function parseParamFilterNode(DOMElement $paramFilterNode) {
-
+
$paramFilter = array();
$paramFilter['name'] = $paramFilterNode->getAttribute('name');
$paramFilter['is-not-defined'] = $this->xpath->query('card:is-not-defined', $paramFilterNode)->length>0;
@@ -174,15 +172,15 @@ class Sabre_CardDAV_AddressBookQueryParser {
$paramFilter['text-match'] = $this->parseTextMatchNode($textMatch->item(0));
}
- return $paramFilter;
+ return $paramFilter;
}
/**
* Text match
- *
- * @param DOMElement $textMatchNode
- * @return void
+ *
+ * @param DOMElement $textMatchNode
+ * @return array
*/
public function parseTextMatchNode(DOMElement $textMatchNode) {
@@ -204,8 +202,8 @@ class Sabre_CardDAV_AddressBookQueryParser {
'match-type' => $matchType,
'value' => $textMatchNode->nodeValue
);
-
- }
+
+ }
}
diff --git a/3rdparty/Sabre/CardDAV/AddressBookRoot.php b/3rdparty/Sabre/CardDAV/AddressBookRoot.php
index 1a80efba35e..9d37b15f08e 100644..100755
--- a/3rdparty/Sabre/CardDAV/AddressBookRoot.php
+++ b/3rdparty/Sabre/CardDAV/AddressBookRoot.php
@@ -1,45 +1,45 @@
<?php
/**
- * AddressBook rootnode
+ * AddressBook rootnode
*
* This object lists a collection of users, which can contain addressbooks.
*
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CardDAV_AddressBookRoot extends Sabre_DAVACL_AbstractPrincipalCollection {
/**
- * Principal Backend
- *
+ * Principal Backend
+ *
* @var Sabre_DAVACL_IPrincipalBackend
*/
protected $principalBackend;
/**
- * CardDAV backend
- *
- * @var Sabre_CardDAV_Backend_Abstract
+ * CardDAV backend
+ *
+ * @var Sabre_CardDAV_Backend_Abstract
*/
protected $carddavBackend;
/**
- * Constructor
+ * Constructor
*
* This constructor needs both a principal and a carddav backend.
*
- * By default this class will show a list of addressbook collections for
- * principals in the 'principals' collection. If your main principals are
- * actually located in a different path, use the $principalPrefix argument
+ * By default this class will show a list of addressbook collections for
+ * principals in the 'principals' collection. If your main principals are
+ * actually located in a different path, use the $principalPrefix argument
* to override this.
*
- * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+ * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
* @param Sabre_CardDAV_Backend_Abstract $carddavBackend
- * @param string $principalPrefix
+ * @param string $principalPrefix
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend,Sabre_CardDAV_Backend_Abstract $carddavBackend, $principalPrefix = 'principals') {
@@ -49,9 +49,9 @@ class Sabre_CardDAV_AddressBookRoot extends Sabre_DAVACL_AbstractPrincipalCollec
}
/**
- * Returns the name of the node
- *
- * @return string
+ * Returns the name of the node
+ *
+ * @return string
*/
public function getName() {
@@ -65,9 +65,9 @@ class Sabre_CardDAV_AddressBookRoot extends Sabre_DAVACL_AbstractPrincipalCollec
* The passed array contains principal information, and is guaranteed to
* at least contain a uri item. Other properties may or may not be
* supplied by the authentication backend.
- *
- * @param array $principal
- * @return Sabre_DAV_INode
+ *
+ * @param array $principal
+ * @return Sabre_DAV_INode
*/
public function getChildForPrincipal(array $principal) {
diff --git a/3rdparty/Sabre/CardDAV/Backend/Abstract.php b/3rdparty/Sabre/CardDAV/Backend/Abstract.php
index 1f0253ddab8..e4806b7161f 100644..100755
--- a/3rdparty/Sabre/CardDAV/Backend/Abstract.php
+++ b/3rdparty/Sabre/CardDAV/Backend/Abstract.php
@@ -5,14 +5,14 @@
*
* This class serves as a base-class for addressbook backends
*
- * Note that there are references to 'addressBookId' scattered throughout the
- * class. The value of the addressBookId is completely up to you, it can be any
+ * Note that there are references to 'addressBookId' scattered throughout the
+ * class. The value of the addressBookId is completely up to you, it can be any
* arbitrary value you can use as an unique identifier.
- *
+ *
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_CardDAV_Backend_Abstract {
@@ -25,97 +25,142 @@ abstract class Sabre_CardDAV_Backend_Abstract {
* uri - the 'basename' part of the url
* principaluri - Same as the passed parameter
*
- * Any additional clark-notation property may be passed besides this. Some
+ * Any additional clark-notation property may be passed besides this. Some
* common ones are :
* {DAV:}displayname
* {urn:ietf:params:xml:ns:carddav}addressbook-description
* {http://calendarserver.org/ns/}getctag
- *
- * @param string $principalUri
- * @return array
+ *
+ * @param string $principalUri
+ * @return array
*/
- public abstract function getAddressBooksForUser($principalUri);
+ public abstract function getAddressBooksForUser($principalUri);
/**
* Updates an addressbook's properties
*
- * See Sabre_DAV_IProperties for a description of the mutations array, as
- * well as the return value.
+ * See Sabre_DAV_IProperties for a description of the mutations array, as
+ * well as the return value.
*
* @param mixed $addressBookId
* @param array $mutations
* @see Sabre_DAV_IProperties::updateProperties
* @return bool|array
*/
- public abstract function updateAddressBook($addressBookId, array $mutations);
+ public abstract function updateAddressBook($addressBookId, array $mutations);
/**
- * Creates a new address book
+ * Creates a new address book
*
- * @param string $principalUri
- * @param string $url Just the 'basename' of the url.
- * @param array $properties
+ * @param string $principalUri
+ * @param string $url Just the 'basename' of the url.
+ * @param array $properties
* @return void
*/
- abstract public function createAddressBook($principalUri, $url, array $properties);
+ abstract public function createAddressBook($principalUri, $url, array $properties);
/**
* Deletes an entire addressbook and all its contents
*
- * @param mixed $addressBookId
+ * @param mixed $addressBookId
* @return void
*/
- abstract public function deleteAddressBook($addressBookId);
+ abstract public function deleteAddressBook($addressBookId);
/**
- * Returns all cards for a specific addressbook id.
+ * Returns all cards for a specific addressbook id.
*
* This method should return the following properties for each card:
* * carddata - raw vcard data
* * uri - Some unique url
* * lastmodified - A unix timestamp
-
- * @param mixed $addressbookId
- * @return array
+ *
+ * It's recommended to also return the following properties:
+ * * etag - A unique etag. This must change every time the card changes.
+ * * size - The size of the card in bytes.
+ *
+ * If these last two properties are provided, less time will be spent
+ * calculating them. If they are specified, you can also ommit carddata.
+ * This may speed up certain requests, especially with large cards.
+ *
+ * @param mixed $addressbookId
+ * @return array
*/
- public abstract function getCards($addressbookId);
+ public abstract function getCards($addressbookId);
/**
- * Returns a specfic card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @return void
+ * Returns a specfic card.
+ *
+ * The same set of properties must be returned as with getCards. The only
+ * exception is that 'carddata' is absolutely required.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @return array
*/
- public abstract function getCard($addressBookId, $cardUri);
+ public abstract function getCard($addressBookId, $cardUri);
/**
- * Creates a new card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @param string $cardData
- * @return bool
+ * Creates a new card.
+ *
+ * The addressbook id will be passed as the first argument. This is the
+ * same id as it is returned from the getAddressbooksForUser method.
+ *
+ * The cardUri is a base uri, and doesn't include the full path. The
+ * cardData argument is the vcard body, and is passed as a string.
+ *
+ * It is possible to return an ETag from this method. This ETag is for the
+ * newly created resource, and must be enclosed with double quotes (that
+ * is, the string itself must contain the double quotes).
+ *
+ * You should only return the ETag if you store the carddata as-is. If a
+ * subsequent GET request on the same card does not have the same body,
+ * byte-by-byte and you did return an ETag here, clients tend to get
+ * confused.
+ *
+ * If you don't return an ETag, you can just return null.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @param string $cardData
+ * @return string|null
*/
- abstract public function createCard($addressBookId, $cardUri, $cardData);
+ abstract public function createCard($addressBookId, $cardUri, $cardData);
/**
- * Updates a card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @param string $cardData
- * @return bool
+ * Updates a card.
+ *
+ * The addressbook id will be passed as the first argument. This is the
+ * same id as it is returned from the getAddressbooksForUser method.
+ *
+ * The cardUri is a base uri, and doesn't include the full path. The
+ * cardData argument is the vcard body, and is passed as a string.
+ *
+ * It is possible to return an ETag from this method. This ETag should
+ * match that of the updated resource, and must be enclosed with double
+ * quotes (that is: the string itself must contain the actual quotes).
+ *
+ * You should only return the ETag if you store the carddata as-is. If a
+ * subsequent GET request on the same card does not have the same body,
+ * byte-by-byte and you did return an ETag here, clients tend to get
+ * confused.
+ *
+ * If you don't return an ETag, you can just return null.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @param string $cardData
+ * @return string|null
*/
- abstract public function updateCard($addressBookId, $cardUri, $cardData);
+ abstract public function updateCard($addressBookId, $cardUri, $cardData);
/**
* Deletes a card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @return bool
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @return bool
*/
- abstract public function deleteCard($addressBookId, $cardUri);
+ abstract public function deleteCard($addressBookId, $cardUri);
}
diff --git a/3rdparty/Sabre/CardDAV/Backend/PDO.php b/3rdparty/Sabre/CardDAV/Backend/PDO.php
index f4e44610ccf..413a77f3bcc 100644..100755
--- a/3rdparty/Sabre/CardDAV/Backend/PDO.php
+++ b/3rdparty/Sabre/CardDAV/Backend/PDO.php
@@ -4,19 +4,19 @@
* PDO CardDAV backend
*
* This CardDAV backend uses PDO to store addressbooks
- *
+ *
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
/**
- * PDO connection
- *
- * @var PDO
+ * PDO connection
+ *
+ * @var PDO
*/
protected $pdo;
@@ -31,28 +31,30 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
protected $cardsTableName;
/**
- * Sets up the object
- *
- * @param PDO $pdo
+ * Sets up the object
+ *
+ * @param PDO $pdo
+ * @param string $addressBooksTableName
+ * @param string $cardsTableName
*/
public function __construct(PDO $pdo, $addressBooksTableName = 'addressbooks', $cardsTableName = 'cards') {
$this->pdo = $pdo;
$this->addressBooksTableName = $addressBooksTableName;
- $this->cardsTableName = $cardsTableName;
+ $this->cardsTableName = $cardsTableName;
}
/**
- * Returns the list of addressbooks for a specific user.
- *
- * @param string $principalUri
- * @return array
+ * Returns the list of addressbooks for a specific user.
+ *
+ * @param string $principalUri
+ * @return array
*/
public function getAddressBooksForUser($principalUri) {
- $stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, ctag FROM `'.$this->addressBooksTableName.'` WHERE principaluri = ?');
- $result = $stmt->execute(array($principalUri));
+ $stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, ctag FROM '.$this->addressBooksTableName.' WHERE principaluri = ?');
+ $stmt->execute(array($principalUri));
$addressBooks = array();
@@ -65,7 +67,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
'{DAV:}displayname' => $row['displayname'],
'{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'],
'{http://calendarserver.org/ns/}getctag' => $row['ctag'],
- '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' =>
+ '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' =>
new Sabre_CardDAV_Property_SupportedAddressData(),
);
@@ -79,8 +81,8 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
/**
* Updates an addressbook's properties
*
- * See Sabre_DAV_IProperties for a description of the mutations array, as
- * well as the return value.
+ * See Sabre_DAV_IProperties for a description of the mutations array, as
+ * well as the return value.
*
* @param mixed $addressBookId
* @param array $mutations
@@ -88,7 +90,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
* @return bool|array
*/
public function updateAddressBook($addressBookId, array $mutations) {
-
+
$updates = array();
foreach($mutations as $property=>$newValue) {
@@ -101,7 +103,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
$updates['description'] = $newValue;
break;
default :
- // If any unsupported values were being updated, we must
+ // If any unsupported values were being updated, we must
// let the entire request fail.
return false;
}
@@ -113,7 +115,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
return false;
}
- $query = 'UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 ';
+ $query = 'UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 ';
foreach($updates as $key=>$value) {
$query.=', `' . $key . '` = :' . $key . ' ';
}
@@ -129,11 +131,11 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
}
/**
- * Creates a new address book
+ * Creates a new address book
*
- * @param string $principalUri
- * @param string $url Just the 'basename' of the url.
- * @param array $properties
+ * @param string $principalUri
+ * @param string $url Just the 'basename' of the url.
+ * @param array $properties
* @return void
*/
public function createAddressBook($principalUri, $url, array $properties) {
@@ -160,7 +162,7 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
}
- $query = 'INSERT INTO `' . $this->addressBooksTableName . '` (uri, displayname, description, principaluri, ctag) VALUES (:uri, :displayname, :description, :principaluri, 1)';
+ $query = 'INSERT INTO ' . $this->addressBooksTableName . ' (uri, displayname, description, principaluri, ctag) VALUES (:uri, :displayname, :description, :principaluri, 1)';
$stmt = $this->pdo->prepare($query);
$stmt->execute($values);
@@ -169,44 +171,61 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
/**
* Deletes an entire addressbook and all its contents
*
- * @param int $addressBookId
+ * @param int $addressBookId
* @return void
*/
public function deleteAddressBook($addressBookId) {
- $stmt = $this->pdo->prepare('DELETE FROM `' . $this->cardsTableName . '` WHERE addressbookid = ?');
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?');
$stmt->execute(array($addressBookId));
- $stmt = $this->pdo->prepare('DELETE FROM `' . $this->addressBooksTableName . '` WHERE id = ?');
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->addressBooksTableName . ' WHERE id = ?');
$stmt->execute(array($addressBookId));
}
/**
- * Returns all cards for a specific addressbook id.
- *
- * @param mixed $addressbookId
- * @return array
+ * Returns all cards for a specific addressbook id.
+ *
+ * This method should return the following properties for each card:
+ * * carddata - raw vcard data
+ * * uri - Some unique url
+ * * lastmodified - A unix timestamp
+ *
+ * It's recommended to also return the following properties:
+ * * etag - A unique etag. This must change every time the card changes.
+ * * size - The size of the card in bytes.
+ *
+ * If these last two properties are provided, less time will be spent
+ * calculating them. If they are specified, you can also ommit carddata.
+ * This may speed up certain requests, especially with large cards.
+ *
+ * @param mixed $addressbookId
+ * @return array
*/
public function getCards($addressbookId) {
- $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM `' . $this->cardsTableName . '` WHERE addressbookid = ?');
+ $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?');
$stmt->execute(array($addressbookId));
return $stmt->fetchAll(PDO::FETCH_ASSOC);
-
+
}
+
/**
- * Returns a specfic card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @return array
+ * Returns a specfic card.
+ *
+ * The same set of properties must be returned as with getCards. The only
+ * exception is that 'carddata' is absolutely required.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @return array
*/
public function getCard($addressBookId, $cardUri) {
- $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM `' . $this->cardsTableName . '` WHERE addressbookid = ? AND uri = ? LIMIT 1');
+ $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ? LIMIT 1');
$stmt->execute(array($addressBookId, $cardUri));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
@@ -216,59 +235,93 @@ class Sabre_CardDAV_Backend_PDO extends Sabre_CardDAV_Backend_Abstract {
}
/**
- * Creates a new card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @param string $cardData
- * @return bool
+ * Creates a new card.
+ *
+ * The addressbook id will be passed as the first argument. This is the
+ * same id as it is returned from the getAddressbooksForUser method.
+ *
+ * The cardUri is a base uri, and doesn't include the full path. The
+ * cardData argument is the vcard body, and is passed as a string.
+ *
+ * It is possible to return an ETag from this method. This ETag is for the
+ * newly created resource, and must be enclosed with double quotes (that
+ * is, the string itself must contain the double quotes).
+ *
+ * You should only return the ETag if you store the carddata as-is. If a
+ * subsequent GET request on the same card does not have the same body,
+ * byte-by-byte and you did return an ETag here, clients tend to get
+ * confused.
+ *
+ * If you don't return an ETag, you can just return null.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @param string $cardData
+ * @return string|null
*/
public function createCard($addressBookId, $cardUri, $cardData) {
- $stmt = $this->pdo->prepare('INSERT INTO `' . $this->cardsTableName . '` (carddata, uri, lastmodified, addressbookid) VALUES (?, ?, ?, ?)');
+ $stmt = $this->pdo->prepare('INSERT INTO ' . $this->cardsTableName . ' (carddata, uri, lastmodified, addressbookid) VALUES (?, ?, ?, ?)');
$result = $stmt->execute(array($cardData, $cardUri, time(), $addressBookId));
- $stmt2 = $this->pdo->prepare('UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 WHERE id = ?');
+ $stmt2 = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 WHERE id = ?');
$stmt2->execute(array($addressBookId));
- return $result;
+ return '"' . md5($cardData) . '"';
}
/**
- * Updates a card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @param string $cardData
- * @return bool
+ * Updates a card.
+ *
+ * The addressbook id will be passed as the first argument. This is the
+ * same id as it is returned from the getAddressbooksForUser method.
+ *
+ * The cardUri is a base uri, and doesn't include the full path. The
+ * cardData argument is the vcard body, and is passed as a string.
+ *
+ * It is possible to return an ETag from this method. This ETag should
+ * match that of the updated resource, and must be enclosed with double
+ * quotes (that is: the string itself must contain the actual quotes).
+ *
+ * You should only return the ETag if you store the carddata as-is. If a
+ * subsequent GET request on the same card does not have the same body,
+ * byte-by-byte and you did return an ETag here, clients tend to get
+ * confused.
+ *
+ * If you don't return an ETag, you can just return null.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @param string $cardData
+ * @return string|null
*/
public function updateCard($addressBookId, $cardUri, $cardData) {
- $stmt = $this->pdo->prepare('UPDATE `' . $this->cardsTableName . '` SET carddata = ?, lastmodified = ? WHERE uri = ? AND addressbookid =?');
- $result = $stmt->execute(array($cardData, time(), $cardUri, $addressBookId));
+ $stmt = $this->pdo->prepare('UPDATE ' . $this->cardsTableName . ' SET carddata = ?, lastmodified = ? WHERE uri = ? AND addressbookid =?');
+ $stmt->execute(array($cardData, time(), $cardUri, $addressBookId));
- $stmt2 = $this->pdo->prepare('UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 WHERE id = ?');
+ $stmt2 = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 WHERE id = ?');
$stmt2->execute(array($addressBookId));
- return $stmt->rowCount()===1;
+ return '"' . md5($cardData) . '"';
}
/**
* Deletes a card
- *
- * @param mixed $addressBookId
- * @param string $cardUri
- * @return bool
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @return bool
*/
public function deleteCard($addressBookId, $cardUri) {
- $stmt = $this->pdo->prepare('DELETE FROM `' . $this->cardsTableName . '` WHERE addressbookid = ? AND uri = ?');
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ?');
$stmt->execute(array($addressBookId, $cardUri));
- $stmt2 = $this->pdo->prepare('UPDATE `' . $this->addressBooksTableName . '` SET ctag = ctag + 1 WHERE id = ?');
+ $stmt2 = $this->pdo->prepare('UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 WHERE id = ?');
$stmt2->execute(array($addressBookId));
return $stmt->rowCount()===1;
diff --git a/3rdparty/Sabre/CardDAV/Card.php b/3rdparty/Sabre/CardDAV/Card.php
index 2844eaf7ed6..d7c66333837 100644..100755
--- a/3rdparty/Sabre/CardDAV/Card.php
+++ b/3rdparty/Sabre/CardDAV/Card.php
@@ -2,10 +2,10 @@
/**
* The Card object represents a single Card from an addressbook
- *
+ *
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -13,29 +13,29 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
/**
* CardDAV backend
- *
- * @var Sabre_CardDAV_Backend_Abstract
+ *
+ * @var Sabre_CardDAV_Backend_Abstract
*/
private $carddavBackend;
/**
* Array with information about this Card
- *
- * @var array
+ *
+ * @var array
*/
private $cardData;
/**
- * Array with information about the containing addressbook
- *
- * @var array
+ * Array with information about the containing addressbook
+ *
+ * @var array
*/
private $addressBookInfo;
/**
- * Constructor
- *
- * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
+ * Constructor
+ *
+ * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
* @param array $addressBookInfo
* @param array $cardData
*/
@@ -48,9 +48,9 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
}
/**
- * Returns the uri for this object
- *
- * @return string
+ * Returns the uri for this object
+ *
+ * @return string
*/
public function getName() {
@@ -59,25 +59,26 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
}
/**
- * Returns the VCard-formatted object
- *
- * @return string
+ * Returns the VCard-formatted object
+ *
+ * @return string
*/
public function get() {
- $cardData = $this->cardData['carddata'];
- $s = fopen('php://temp','r+');
- fwrite($s, $cardData);
- rewind($s);
- return $s;
+ // Pre-populating 'carddata' is optional. If we don't yet have it
+ // already, we fetch it from the backend.
+ if (!isset($this->cardData['carddata'])) {
+ $this->cardData = $this->carddavBackend->getCard($this->addressBookInfo['id'], $this->cardData['uri']);
+ }
+ return $this->cardData['carddata'];
}
/**
- * Updates the VCard-formatted object
- *
- * @param string $cardData
- * @return void
+ * Updates the VCard-formatted object
+ *
+ * @param string $cardData
+ * @return void
*/
public function put($cardData) {
@@ -87,14 +88,17 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
// Converting to UTF-8, if needed
$cardData = Sabre_DAV_StringUtil::ensureUTF8($cardData);
- $this->carddavBackend->updateCard($this->addressBookInfo['id'],$this->cardData['uri'],$cardData);
+ $etag = $this->carddavBackend->updateCard($this->addressBookInfo['id'],$this->cardData['uri'],$cardData);
$this->cardData['carddata'] = $cardData;
+ $this->cardData['etag'] = $etag;
+
+ return $etag;
}
/**
* Deletes the card
- *
+ *
* @return void
*/
public function delete() {
@@ -104,9 +108,9 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
}
/**
- * Returns the mime content-type
- *
- * @return string
+ * Returns the mime content-type
+ *
+ * @return string
*/
public function getContentType() {
@@ -115,20 +119,24 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
}
/**
- * Returns an ETag for this object
- *
- * @return string
+ * Returns an ETag for this object
+ *
+ * @return string
*/
public function getETag() {
- return '"' . md5($this->cardData['carddata']) . '"';
+ if (isset($this->cardData['etag'])) {
+ return $this->cardData['etag'];
+ } else {
+ return '"' . md5($this->get()) . '"';
+ }
}
/**
* Returns the last modification date as a unix timestamp
- *
- * @return time
+ *
+ * @return time
*/
public function getLastModified() {
@@ -137,21 +145,25 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
}
/**
- * Returns the size of this object in bytes
- *
+ * Returns the size of this object in bytes
+ *
* @return int
*/
public function getSize() {
- return strlen($this->cardData['carddata']);
+ if (array_key_exists('size', $this->cardData)) {
+ return $this->cardData['size'];
+ } else {
+ return strlen($this->get());
+ }
}
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
public function getOwner() {
@@ -164,8 +176,8 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
public function getGroup() {
@@ -177,13 +189,13 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
@@ -205,9 +217,9 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
public function setACL(array $acl) {
@@ -216,5 +228,23 @@ class Sabre_CardDAV_Card extends Sabre_DAV_File implements Sabre_CardDAV_ICard,
}
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ return null;
+
+ }
+
}
diff --git a/3rdparty/Sabre/CardDAV/IAddressBook.php b/3rdparty/Sabre/CardDAV/IAddressBook.php
index a0dffb30aea..2bc275bcf74 100644..100755
--- a/3rdparty/Sabre/CardDAV/IAddressBook.php
+++ b/3rdparty/Sabre/CardDAV/IAddressBook.php
@@ -4,15 +4,15 @@
* AddressBook interface
*
* Implement this interface to allow a node to be recognized as an addressbook.
- *
+ *
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_CardDAV_IAddressBook extends Sabre_DAV_ICollection {
-
+
}
diff --git a/3rdparty/Sabre/CardDAV/ICard.php b/3rdparty/Sabre/CardDAV/ICard.php
index 25bcc551b73..a17299316c1 100644..100755
--- a/3rdparty/Sabre/CardDAV/ICard.php
+++ b/3rdparty/Sabre/CardDAV/ICard.php
@@ -1,18 +1,18 @@
<?php
/**
- * Card interface
+ * Card interface
+ *
+ * Extend the ICard interface to allow your custom nodes to be picked up as
+ * 'Cards'.
*
- * Extend the ICard interface to allow your custom nodes to be picked up as
- * 'Cards'.
- *
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-interface Sabre_CardDAV_ICard extends Sabre_DAV_IFile {
+interface Sabre_CardDAV_ICard extends Sabre_DAV_IFile {
}
diff --git a/3rdparty/Sabre/CardDAV/IDirectory.php b/3rdparty/Sabre/CardDAV/IDirectory.php
index e0d0797d285..22d4afeb24a 100644..100755
--- a/3rdparty/Sabre/CardDAV/IDirectory.php
+++ b/3rdparty/Sabre/CardDAV/IDirectory.php
@@ -3,7 +3,7 @@
/**
* IDirectory interface
*
- * Implement this interface to have an addressbook marked as a 'directory'. A
+ * Implement this interface to have an addressbook marked as a 'directory'. A
* directory is an (often) global addressbook.
*
* A full description can be found in the IETF draft:
@@ -11,7 +11,7 @@
*
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
diff --git a/3rdparty/Sabre/CardDAV/Plugin.php b/3rdparty/Sabre/CardDAV/Plugin.php
index 14c9c72b0d5..9ebec243eb0 100644..100755
--- a/3rdparty/Sabre/CardDAV/Plugin.php
+++ b/3rdparty/Sabre/CardDAV/Plugin.php
@@ -7,8 +7,8 @@
*
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
@@ -24,31 +24,34 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
const NS_CARDDAV = 'urn:ietf:params:xml:ns:carddav';
/**
- * Add urls to this property to have them automatically exposed as
+ * Add urls to this property to have them automatically exposed as
* 'directories' to the user.
- *
+ *
* @var array
*/
public $directories = array();
/**
- * Server class
+ * Server class
*
- * @var Sabre_DAV_Server
+ * @var Sabre_DAV_Server
*/
protected $server;
/**
- * Initializes the plugin
+ * Initializes the plugin
*
- * @param Sabre_DAV_Server $server
- * @return void
+ * @param Sabre_DAV_Server $server
+ * @return void
*/
public function initialize(Sabre_DAV_Server $server) {
/* Events */
$server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties'));
+ $server->subscribeEvent('updateProperties', array($this, 'updateProperties'));
$server->subscribeEvent('report', array($this,'report'));
+ $server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel'));
+ $server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
/* Namespaces */
$server->xmlNamespaces[self::NS_CARDDAV] = 'card';
@@ -56,11 +59,14 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
/* Mapping Interfaces to {DAV:}resourcetype values */
$server->resourceTypeMapping['Sabre_CardDAV_IAddressBook'] = '{' . self::NS_CARDDAV . '}addressbook';
$server->resourceTypeMapping['Sabre_CardDAV_IDirectory'] = '{' . self::NS_CARDDAV . '}directory';
-
+
/* Adding properties that may never be changed */
$server->protectedProperties[] = '{' . self::NS_CARDDAV . '}supported-address-data';
$server->protectedProperties[] = '{' . self::NS_CARDDAV . '}max-resource-size';
+ $server->protectedProperties[] = '{' . self::NS_CARDDAV . '}addressbook-home-set';
+ $server->protectedProperties[] = '{' . self::NS_CARDDAV . '}supported-collation-set';
+ $server->propertyMap['{http://calendarserver.org/ns/}me-card'] = 'Sabre_DAV_Property_Href';
$this->server = $server;
@@ -69,7 +75,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Returns a list of supported features.
*
- * This is used in the DAV: header in the OPTIONS and PROPFIND requests.
+ * This is used in the DAV: header in the OPTIONS and PROPFIND requests.
*
* @return array
*/
@@ -83,11 +89,11 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
* Returns a list of reports this plugin supports.
*
* This will be used in the {DAV:}supported-report-set property.
- * Note that you still need to subscribe to the 'report' event to actually
- * implement them
+ * Note that you still need to subscribe to the 'report' event to actually
+ * implement them
*
* @param string $uri
- * @return array
+ * @return array
*/
public function getSupportedReportSet($uri) {
@@ -104,22 +110,22 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
/**
- * Adds all CardDAV-specific properties
+ * Adds all CardDAV-specific properties
*
* @param string $path
- * @param Sabre_DAV_INode $node
+ * @param Sabre_DAV_INode $node
* @param array $requestedProperties
- * @param array $returnedProperties
+ * @param array $returnedProperties
* @return void
*/
- public function beforeGetProperties($path, Sabre_DAV_INode $node, array &$requestedProperties, array &$returnedProperties) {
+ public function beforeGetProperties($path, Sabre_DAV_INode $node, array &$requestedProperties, array &$returnedProperties) {
if ($node instanceof Sabre_DAVACL_IPrincipal) {
// calendar-home-set property
$addHome = '{' . self::NS_CARDDAV . '}addressbook-home-set';
if (in_array($addHome,$requestedProperties)) {
- $principalId = $node->getName();
+ $principalId = $node->getName();
$addressbookHomePath = self::ADDRESSBOOK_ROOT . '/' . $principalId . '/';
unset($requestedProperties[array_search($addHome, $requestedProperties)]);
$returnedProperties[200][$addHome] = new Sabre_DAV_Property_Href($addressbookHomePath);
@@ -135,8 +141,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
if ($node instanceof Sabre_CardDAV_ICard) {
- // The address-data property is not supposed to be a 'real'
- // property, but in large chunks of the spec it does act as such.
+ // The address-data property is not supposed to be a 'real'
+ // property, but in large chunks of the spec it does act as such.
// Therefore we simply expose it as a property.
$addressDataProp = '{' . self::NS_CARDDAV . '}address-data';
if (in_array($addressDataProp, $requestedProperties)) {
@@ -151,24 +157,95 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
}
+ if ($node instanceof Sabre_CardDAV_UserAddressBooks) {
+
+ $meCardProp = '{http://calendarserver.org/ns/}me-card';
+ if (in_array($meCardProp, $requestedProperties)) {
+
+ $props = $this->server->getProperties($node->getOwner(), array('{http://sabredav.org/ns}vcard-url'));
+ if (isset($props['{http://sabredav.org/ns}vcard-url'])) {
+
+ $returnedProperties[200][$meCardProp] = new Sabre_DAV_Property_Href(
+ $props['{http://sabredav.org/ns}vcard-url']
+ );
+ $pos = array_search($meCardProp, $requestedProperties);
+ unset($requestedProperties[$pos]);
+
+ }
+
+ }
+
+ }
+
}
/**
- * This functions handles REPORT requests specific to CardDAV
+ * This event is triggered when a PROPPATCH method is executed
*
- * @param string $reportName
+ * @param array $mutations
+ * @param array $result
+ * @param Sabre_DAV_INode $node
+ * @return void
+ */
+ public function updateProperties(&$mutations, &$result, $node) {
+
+ if (!$node instanceof Sabre_CardDAV_UserAddressBooks) {
+ return true;
+ }
+
+ $meCard = '{http://calendarserver.org/ns/}me-card';
+
+ // The only property we care about
+ if (!isset($mutations[$meCard]))
+ return true;
+
+ $value = $mutations[$meCard];
+ unset($mutations[$meCard]);
+
+ if ($value instanceof Sabre_DAV_Property_IHref) {
+ $value = $value->getHref();
+ $value = $this->server->calculateUri($value);
+ } elseif (!is_null($value)) {
+ $result[400][$meCard] = null;
+ return false;
+ }
+
+ $innerResult = $this->server->updateProperties(
+ $node->getOwner(),
+ array(
+ '{http://sabredav.org/ns}vcard-url' => $value,
+ )
+ );
+
+ $closureResult = false;
+ foreach($innerResult as $status => $props) {
+ if (is_array($props) && array_key_exists('{http://sabredav.org/ns}vcard-url', $props)) {
+ $result[$status][$meCard] = null;
+ $closureResult = ($status>=200 && $status<300);
+ }
+
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * This functions handles REPORT requests specific to CardDAV
+ *
+ * @param string $reportName
* @param DOMNode $dom
- * @return bool
+ * @return bool
*/
public function report($reportName,$dom) {
- switch($reportName) {
+ switch($reportName) {
case '{'.self::NS_CARDDAV.'}addressbook-multiget' :
$this->addressbookMultiGetReport($dom);
return false;
case '{'.self::NS_CARDDAV.'}addressbook-query' :
$this->addressBookQueryReport($dom);
- return false;
+ return false;
default :
return;
@@ -256,7 +333,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
$result = array();
foreach($validNodes as $validNode) {
- if ($depth==0) {
+
+ if ($depth==0) {
$href = $this->server->getRequestUri();
} else {
$href = $this->server->getRequestUri() . '/' . $validNode->getName();
@@ -265,7 +343,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
list($result[]) = $this->server->getPropertiesForPath($href, $query->requestedProperties, 0);
}
-
+
$this->server->httpResponse->sendStatus(207);
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
$this->server->httpResponse->sendBody($this->server->generateMultiStatus($result));
@@ -274,17 +352,15 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Validates if a vcard makes it throught a list of filters.
- *
- * @param string $vcardData
- * @param array $filters
- * @param string $test anyof or allof (which means OR or AND)
- * @return bool
+ *
+ * @param string $vcardData
+ * @param array $filters
+ * @param string $test anyof or allof (which means OR or AND)
+ * @return bool
*/
public function validateFilters($vcardData, array $filters, $test) {
$vcard = Sabre_VObject_Reader::read($vcardData);
-
- $success = true;
foreach($filters as $filter) {
@@ -299,10 +375,10 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
// We only need to check for existence
$success = $isDefined;
-
+
} else {
- $vProperties = $vcard->select($filter['name']);
+ $vProperties = $vcard->select($filter['name']);
$results = array();
if ($filter['param-filters']) {
@@ -328,7 +404,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
} // else
- // There are two conditions where we can already determine wether
+ // There are two conditions where we can already determine whether
// or not this filter succeeds.
if ($test==='anyof' && $success) {
return true;
@@ -339,29 +415,28 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
} // foreach
- // If we got all the way here, it means we haven't been able to
+ // If we got all the way here, it means we haven't been able to
// determine early if the test failed or not.
//
- // This implies for 'anyof' that the test failed, and for 'allof' that
+ // This implies for 'anyof' that the test failed, and for 'allof' that
// we succeeded. Sounds weird, but makes sense.
return $test==='allof';
}
/**
- * Validates if a param-filter can be applied to a specific property.
- *
- * @todo currently we're only validating the first parameter of the passed
+ * Validates if a param-filter can be applied to a specific property.
+ *
+ * @todo currently we're only validating the first parameter of the passed
* property. Any subsequence parameters with the same name are
* ignored.
- * @param Sabre_VObject_Property $vProperty
- * @param array $filters
- * @param string $test
- * @return bool
+ * @param array $vProperties
+ * @param array $filters
+ * @param string $test
+ * @return bool
*/
protected function validateParamFilters(array $vProperties, array $filters, $test) {
- $success = false;
foreach($filters as $filter) {
$isDefined = false;
@@ -377,17 +452,16 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
$success = true;
}
- // If there's no text-match, we can just check for existence
+ // If there's no text-match, we can just check for existence
} elseif (!$filter['text-match'] || !$isDefined) {
$success = $isDefined;
-
+
} else {
- $texts = array();
$success = false;
foreach($vProperties as $vProperty) {
- // If we got all the way here, we'll need to validate the
+ // If we got all the way here, we'll need to validate the
// text-match filter.
$success = Sabre_DAV_StringUtil::textMatch($vProperty[$filter['name']]->value, $filter['text-match']['value'], $filter['text-match']['collation'], $filter['text-match']['match-type']);
if ($success) break;
@@ -398,7 +472,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
} // else
- // There are two conditions where we can already determine wether
+ // There are two conditions where we can already determine whether
// or not this filter succeeds.
if ($test==='anyof' && $success) {
return true;
@@ -407,24 +481,24 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
return false;
}
- }
+ }
- // If we got all the way here, it means we haven't been able to
+ // If we got all the way here, it means we haven't been able to
// determine early if the test failed or not.
//
- // This implies for 'anyof' that the test failed, and for 'allof' that
+ // This implies for 'anyof' that the test failed, and for 'allof' that
// we succeeded. Sounds weird, but makes sense.
return $test==='allof';
}
/**
- * Validates if a text-filter can be applied to a specific property.
- *
+ * Validates if a text-filter can be applied to a specific property.
+ *
* @param array $texts
- * @param array $filters
- * @param string $test
- * @return bool
+ * @param array $filters
+ * @param string $test
+ * @return bool
*/
protected function validateTextMatches(array $texts, array $filters, $test) {
@@ -440,7 +514,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
if ($filter['negate-condition']) {
$success = !$success;
}
-
+
if ($success && $test==='anyof')
return true;
@@ -450,14 +524,64 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
- // If we got all the way here, it means we haven't been able to
+ // If we got all the way here, it means we haven't been able to
// determine early if the test failed or not.
//
- // This implies for 'anyof' that the test failed, and for 'allof' that
+ // This implies for 'anyof' that the test failed, and for 'allof' that
// we succeeded. Sounds weird, but makes sense.
return $test==='allof';
}
+ /**
+ * This method is used to generate HTML output for the
+ * Sabre_DAV_Browser_Plugin. This allows us to generate an interface users
+ * can use to create new calendars.
+ *
+ * @param Sabre_DAV_INode $node
+ * @param string $output
+ * @return bool
+ */
+ public function htmlActionsPanel(Sabre_DAV_INode $node, &$output) {
+
+ if (!$node instanceof Sabre_CardDAV_UserAddressBooks)
+ return;
+
+ $output.= '<tr><td colspan="2"><form method="post" action="">
+ <h3>Create new address book</h3>
+ <input type="hidden" name="sabreAction" value="mkaddressbook" />
+ <label>Name (uri):</label> <input type="text" name="name" /><br />
+ <label>Display name:</label> <input type="text" name="{DAV:}displayname" /><br />
+ <input type="submit" value="create" />
+ </form>
+ </td></tr>';
+
+ return false;
+
+ }
+
+ /**
+ * This method allows us to intercept the 'mkcalendar' sabreAction. This
+ * action enables the user to create new calendars from the browser plugin.
+ *
+ * @param string $uri
+ * @param string $action
+ * @param array $postVars
+ * @return bool
+ */
+ public function browserPostAction($uri, $action, array $postVars) {
+
+ if ($action!=='mkaddressbook')
+ return;
+
+ $resourceType = array('{DAV:}collection','{urn:ietf:params:xml:ns:carddav}addressbook');
+ $properties = array();
+ if (isset($postVars['{DAV:}displayname'])) {
+ $properties['{DAV:}displayname'] = $postVars['{DAV:}displayname'];
+ }
+ $this->server->createCollection($uri . '/' . $postVars['name'],$resourceType,$properties);
+ return false;
+
+ }
}
diff --git a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
index d57d3a6e7bd..36d9306e7aa 100644..100755
--- a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
+++ b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
@@ -4,11 +4,11 @@
* Supported-address-data property
*
* This property is a representation of the supported-address-data property
- * in the CardDAV namespace.
+ * in the CardDAV namespace.
*
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -16,15 +16,15 @@ class Sabre_CardDAV_Property_SupportedAddressData extends Sabre_DAV_Property {
/**
* supported versions
- *
- * @var array
+ *
+ * @var array
*/
protected $supportedData = array();
-
+
/**
- * Creates the property
- *
- * @param array $components
+ * Creates the property
+ *
+ * @param array|null $supportedData
*/
public function __construct(array $supportedData = null) {
@@ -35,22 +35,22 @@ class Sabre_CardDAV_Property_SupportedAddressData extends Sabre_DAV_Property {
);
}
- $this->supportedData = $supportedData;
+ $this->supportedData = $supportedData;
}
-
+
/**
- * Serializes the property in a DOMDocument
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property in a DOMDocument
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
$doc = $node->ownerDocument;
- $prefix =
+ $prefix =
isset($server->xmlNamespaces[Sabre_CardDAV_Plugin::NS_CARDDAV]) ?
$server->xmlNamespaces[Sabre_CardDAV_Plugin::NS_CARDDAV] :
'card';
diff --git a/3rdparty/Sabre/CardDAV/UserAddressBooks.php b/3rdparty/Sabre/CardDAV/UserAddressBooks.php
index e9f2de7f741..3f11fb11238 100644..100755
--- a/3rdparty/Sabre/CardDAV/UserAddressBooks.php
+++ b/3rdparty/Sabre/CardDAV/UserAddressBooks.php
@@ -7,7 +7,7 @@
*
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -15,47 +15,47 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
/**
* Principal uri
- *
- * @var array
+ *
+ * @var array
*/
protected $principalUri;
/**
- * carddavBackend
- *
- * @var Sabre_CardDAV_Backend_Abstract
+ * carddavBackend
+ *
+ * @var Sabre_CardDAV_Backend_Abstract
*/
protected $carddavBackend;
/**
- * Constructor
- *
- * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
- * @param string $principalUri
+ * Constructor
+ *
+ * @param Sabre_CardDAV_Backend_Abstract $carddavBackend
+ * @param string $principalUri
*/
public function __construct(Sabre_CardDAV_Backend_Abstract $carddavBackend, $principalUri) {
$this->carddavBackend = $carddavBackend;
$this->principalUri = $principalUri;
-
+
}
/**
- * Returns the name of this object
- *
+ * Returns the name of this object
+ *
* @return string
*/
public function getName() {
-
+
list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalUri);
- return $name;
+ return $name;
}
/**
- * Updates the name of this object
- *
- * @param string $name
+ * Updates the name of this object
+ *
+ * @param string $name
* @return void
*/
public function setName($name) {
@@ -65,8 +65,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
}
/**
- * Deletes this object
- *
+ * Deletes this object
+ *
* @return void
*/
public function delete() {
@@ -76,13 +76,13 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
}
/**
- * Returns the last modification date
- *
- * @return int
+ * Returns the last modification date
+ *
+ * @return int
*/
public function getLastModified() {
- return null;
+ return null;
}
@@ -90,9 +90,9 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
* Creates a new file under this object.
*
* This is currently not allowed
- *
- * @param string $filename
- * @param resource $data
+ *
+ * @param string $filename
+ * @param resource $data
* @return void
*/
public function createFile($filename, $data=null) {
@@ -105,8 +105,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
* Creates a new directory under this object.
*
* This is currently not allowed.
- *
- * @param string $filename
+ *
+ * @param string $filename
* @return void
*/
public function createDirectory($filename) {
@@ -116,8 +116,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
}
/**
- * Returns a single calendar, by name
- *
+ * Returns a single calendar, by name
+ *
* @param string $name
* @todo needs optimizing
* @return Sabre_CardDAV_AddressBook
@@ -129,14 +129,14 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
return $child;
}
- throw new Sabre_DAV_Exception_FileNotFound('Addressbook with name \'' . $name . '\' could not be found');
+ throw new Sabre_DAV_Exception_NotFound('Addressbook with name \'' . $name . '\' could not be found');
}
/**
- * Returns a list of addressbooks
- *
- * @return array
+ * Returns a list of addressbooks
+ *
+ * @return array
*/
public function getChildren() {
@@ -150,11 +150,11 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
}
/**
- * Creates a new addressbook
- *
+ * Creates a new addressbook
+ *
* @param string $name
- * @param array $resourceType
- * @param array $properties
+ * @param array $resourceType
+ * @param array $properties
* @return void
*/
public function createExtendedCollection($name, array $resourceType, array $properties) {
@@ -169,8 +169,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
public function getOwner() {
@@ -183,8 +183,8 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
public function getGroup() {
@@ -196,13 +196,13 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
@@ -225,9 +225,9 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
public function setACL(array $acl) {
@@ -236,5 +236,22 @@ class Sabre_CardDAV_UserAddressBooks extends Sabre_DAV_Collection implements Sab
}
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ return null;
+
+ }
}
diff --git a/3rdparty/Sabre/CardDAV/Version.php b/3rdparty/Sabre/CardDAV/Version.php
index 900fbf5e75c..811b929e397 100644..100755
--- a/3rdparty/Sabre/CardDAV/Version.php
+++ b/3rdparty/Sabre/CardDAV/Version.php
@@ -4,10 +4,10 @@
* Version Class
*
* This class contains the Sabre_CardDAV version information
- *
+ *
* @package Sabre
* @subpackage CardDAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -16,7 +16,7 @@ class Sabre_CardDAV_Version {
/**
* Full version number
*/
- const VERSION = '1.5.3';
+ const VERSION = '1.6.1';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CardDAV/includes.php b/3rdparty/Sabre/CardDAV/includes.php
new file mode 100755
index 00000000000..c3b8c04b077
--- /dev/null
+++ b/3rdparty/Sabre/CardDAV/includes.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * Sabre_CardDAV includes file
+ *
+ * Including this file will automatically include all files from the
+ * Sabre_CardDAV package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @subpackage CardDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+
+// Begin includes
+include __DIR__ . '/AddressBookQueryParser.php';
+include __DIR__ . '/AddressBookRoot.php';
+include __DIR__ . '/Backend/Abstract.php';
+include __DIR__ . '/Backend/PDO.php';
+include __DIR__ . '/IAddressBook.php';
+include __DIR__ . '/ICard.php';
+include __DIR__ . '/IDirectory.php';
+include __DIR__ . '/Plugin.php';
+include __DIR__ . '/Property/SupportedAddressData.php';
+include __DIR__ . '/UserAddressBooks.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/AddressBook.php';
+include __DIR__ . '/Card.php';
+// End includes
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
index 11bab8c7af7..1e89b84f9a1 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
@@ -8,9 +8,9 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author James David Low (http://jameslow.com/)
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IBackend {
@@ -28,6 +28,8 @@ abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IB
* This method should return true or false depending on if login
* succeeded.
*
+ * @param string $username
+ * @param string $password
* @return bool
*/
abstract protected function validateUserPass($username, $password);
@@ -47,13 +49,15 @@ abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IB
/**
* Authenticates the user based on the current request.
*
- * If authentication is succesful, true must be returned.
+ * If authentication is successful, true must be returned.
* If authentication fails, an exception must be thrown.
*
+ * @param Sabre_DAV_Server $server
+ * @param string $realm
* @throws Sabre_DAV_Exception_NotAuthenticated
* @return bool
*/
- public function authenticate(Sabre_DAV_Server $server,$realm) {
+ public function authenticate(Sabre_DAV_Server $server, $realm) {
$auth = new Sabre_HTTP_BasicAuth();
$auth->setHTTPRequest($server->httpRequest);
@@ -75,5 +79,5 @@ abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IB
}
-}
+}
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
index 5bdc72753ec..9833928b976 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
@@ -4,12 +4,12 @@
* HTTP Digest authentication backend class
*
* This class can be used by authentication objects wishing to use HTTP Digest
- * Most of the digest logic is handled, implementors just need to worry about
- * the getDigestHash method
+ * Most of the digest logic is handled, implementors just need to worry about
+ * the getDigestHash method
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -17,7 +17,7 @@ abstract class Sabre_DAV_Auth_Backend_AbstractDigest implements Sabre_DAV_Auth_I
/**
* This variable holds the currently logged in username.
- *
+ *
* @var array|null
*/
protected $currentUser;
@@ -25,24 +25,26 @@ abstract class Sabre_DAV_Auth_Backend_AbstractDigest implements Sabre_DAV_Auth_I
/**
* Returns a users digest hash based on the username and realm.
*
- * If the user was not known, null must be returned.
- *
+ * If the user was not known, null must be returned.
+ *
* @param string $realm
- * @param string $username
- * @return string|null
+ * @param string $username
+ * @return string|null
*/
- abstract public function getDigestHash($realm,$username);
+ abstract public function getDigestHash($realm, $username);
/**
* Authenticates the user based on the current request.
*
- * If authentication is succesful, true must be returned.
+ * If authentication is successful, true must be returned.
* If authentication fails, an exception must be thrown.
*
+ * @param Sabre_DAV_Server $server
+ * @param string $realm
* @throws Sabre_DAV_Exception_NotAuthenticated
- * @return bool
+ * @return bool
*/
- public function authenticate(Sabre_DAV_Server $server,$realm) {
+ public function authenticate(Sabre_DAV_Server $server, $realm) {
$digest = new Sabre_HTTP_DigestAuth();
@@ -83,9 +85,9 @@ abstract class Sabre_DAV_Auth_Backend_AbstractDigest implements Sabre_DAV_Auth_I
}
/**
- * Returns the currently logged in username.
- *
- * @return string|null
+ * Returns the currently logged in username.
+ *
+ * @return string|null
*/
public function getCurrentUser() {
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
index 6bcd76bdcb0..d4294ea4d86 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
@@ -4,34 +4,36 @@
* Apache authenticator
*
* This authentication backend assumes that authentication has been
- * conifgured in apache, rather than within SabreDAV.
+ * configured in apache, rather than within SabreDAV.
*
* Make sure apache is properly configured for this to work.
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Auth_Backend_Apache implements Sabre_DAV_Auth_IBackend {
/**
- * Current apache user
- *
- * @var string
+ * Current apache user
+ *
+ * @var string
*/
protected $remoteUser;
-
+
/**
* Authenticates the user based on the current request.
*
- * If authentication is succesful, true must be returned.
+ * If authentication is successful, true must be returned.
* If authentication fails, an exception must be thrown.
*
- * @return bool
+ * @param Sabre_DAV_Server $server
+ * @param string $realm
+ * @return bool
*/
- public function authenticate(Sabre_DAV_Server $server,$realm) {
+ public function authenticate(Sabre_DAV_Server $server, $realm) {
$remoteUser = $server->httpRequest->getRawServerValue('REMOTE_USER');
if (is_null($remoteUser)) {
@@ -47,7 +49,7 @@ class Sabre_DAV_Auth_Backend_Apache implements Sabre_DAV_Auth_IBackend {
* Returns information about the currently logged in user.
*
* If nobody is currently logged in, this method should return null.
- *
+ *
* @return array|null
*/
public function getCurrentUser() {
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/File.php b/3rdparty/Sabre/DAV/Auth/Backend/File.php
index db1f04c4772..de308d64a67 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/File.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/File.php
@@ -4,29 +4,28 @@
* This is an authentication backend that uses a file to manage passwords.
*
* The backend file must conform to Apache's htdigest format
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Auth_Backend_File extends Sabre_DAV_Auth_Backend_AbstractDigest {
/**
- * List of users
- *
+ * List of users
+ *
* @var array
*/
protected $users = array();
/**
- * Creates the backend object.
+ * Creates the backend object.
*
* If the filename argument is passed in, it will parse out the specified file fist.
- *
- * @param string $filename
- * @return void
+ *
+ * @param string|null $filename
*/
public function __construct($filename=null) {
@@ -38,22 +37,22 @@ class Sabre_DAV_Auth_Backend_File extends Sabre_DAV_Auth_Backend_AbstractDigest
/**
* Loads an htdigest-formatted file. This method can be called multiple times if
* more than 1 file is used.
- *
- * @param string $filename
+ *
+ * @param string $filename
* @return void
*/
public function loadFile($filename) {
foreach(file($filename,FILE_IGNORE_NEW_LINES) as $line) {
- if (substr_count($line, ":") !== 2)
+ if (substr_count($line, ":") !== 2)
throw new Sabre_DAV_Exception('Malformed htdigest file. Every line should contain 2 colons');
-
+
list($username,$realm,$A1) = explode(':',$line);
if (!preg_match('/^[a-zA-Z0-9]{32}$/', $A1))
throw new Sabre_DAV_Exception('Malformed htdigest file. Invalid md5 hash');
-
+
$this->users[$realm . ':' . $username] = $A1;
}
@@ -62,10 +61,10 @@ class Sabre_DAV_Auth_Backend_File extends Sabre_DAV_Auth_Backend_AbstractDigest
/**
* Returns a users' information
- *
- * @param string $realm
- * @param string $username
- * @return string
+ *
+ * @param string $realm
+ * @param string $username
+ * @return string
*/
public function getDigestHash($realm, $username) {
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
index 0301503601e..eac18a23fbb 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
@@ -4,38 +4,37 @@
* This is an authentication backend that uses a file to manage passwords.
*
* The backend file must conform to Apache's htdigest format
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Auth_Backend_PDO extends Sabre_DAV_Auth_Backend_AbstractDigest {
/**
- * Reference to PDO connection
- *
- * @var PDO
+ * Reference to PDO connection
+ *
+ * @var PDO
*/
protected $pdo;
/**
- * PDO table name we'll be using
- *
+ * PDO table name we'll be using
+ *
* @var string
*/
protected $tableName;
/**
- * Creates the backend object.
+ * Creates the backend object.
*
* If the filename argument is passed in, it will parse out the specified file fist.
- *
- * @param string $filename
- * @param string $tableName The PDO table name to use
- * @return void
+ *
+ * @param PDO $pdo
+ * @param string $tableName The PDO table name to use
*/
public function __construct(PDO $pdo, $tableName = 'users') {
@@ -45,15 +44,15 @@ class Sabre_DAV_Auth_Backend_PDO extends Sabre_DAV_Auth_Backend_AbstractDigest {
}
/**
- * Returns the digest hash for a user.
- *
- * @param string $realm
- * @param string $username
- * @return string|null
+ * Returns the digest hash for a user.
+ *
+ * @param string $realm
+ * @param string $username
+ * @return string|null
*/
public function getDigestHash($realm,$username) {
- $stmt = $this->pdo->prepare('SELECT username, digesta1 FROM `'.$this->tableName.'` WHERE username = ?');
+ $stmt = $this->pdo->prepare('SELECT username, digesta1 FROM '.$this->tableName.' WHERE username = ?');
$stmt->execute(array($username));
$result = $stmt->fetchAll();
diff --git a/3rdparty/Sabre/DAV/Auth/IBackend.php b/3rdparty/Sabre/DAV/Auth/IBackend.php
index 1f67af4c2d9..5be5d1bc93d 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/IBackend.php
+++ b/3rdparty/Sabre/DAV/Auth/IBackend.php
@@ -5,7 +5,7 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -14,18 +14,20 @@ interface Sabre_DAV_Auth_IBackend {
/**
* Authenticates the user based on the current request.
*
- * If authentication is succesful, true must be returned.
+ * If authentication is successful, true must be returned.
* If authentication fails, an exception must be thrown.
*
- * @return bool
+ * @param Sabre_DAV_Server $server
+ * @param string $realm
+ * @return bool
*/
- function authenticate(Sabre_DAV_Server $server,$realm);
+ function authenticate(Sabre_DAV_Server $server,$realm);
/**
* Returns information about the currently logged in username.
*
* If nobody is currently logged in, this method should return null.
- *
+ *
* @return string|null
*/
function getCurrentUser();
diff --git a/3rdparty/Sabre/DAV/Auth/Plugin.php b/3rdparty/Sabre/DAV/Auth/Plugin.php
index f3718fcf469..55a4e391674 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Plugin.php
+++ b/3rdparty/Sabre/DAV/Auth/Plugin.php
@@ -2,48 +2,47 @@
/**
* This plugin provides Authentication for a WebDAV server.
- *
+ *
* It relies on a Backend object, which provides user information.
*
* Additionally, it provides support for:
* * {DAV:}current-user-principal property from RFC5397
* * {DAV:}principal-collection-set property from RFC3744
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
/**
- * Reference to main server object
- *
- * @var Sabre_DAV_Server
+ * Reference to main server object
+ *
+ * @var Sabre_DAV_Server
*/
private $server;
/**
* Authentication backend
- *
- * @var Sabre_DAV_Auth_Backend_Abstract
+ *
+ * @var Sabre_DAV_Auth_IBackend
*/
private $authBackend;
/**
- * The authentication realm.
- *
- * @var string
+ * The authentication realm.
+ *
+ * @var string
*/
private $realm;
/**
- * __construct
- *
- * @param Sabre_DAV_Auth_Backend_Abstract $authBackend
- * @param string $realm
- * @return void
+ * __construct
+ *
+ * @param Sabre_DAV_Auth_IBackend $authBackend
+ * @param string $realm
*/
public function __construct(Sabre_DAV_Auth_IBackend $authBackend, $realm) {
@@ -53,9 +52,9 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Initializes the plugin. This function is automatically called by the server
- *
- * @param Sabre_DAV_Server $server
+ * Initializes the plugin. This function is automatically called by the server
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -67,11 +66,11 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Returns a plugin name.
- *
+ *
* Using this name other plugins will be able to access other plugins
- * using Sabre_DAV_Server::getPlugin
- *
- * @return string
+ * using Sabre_DAV_Server::getPlugin
+ *
+ * @return string
*/
public function getPluginName() {
@@ -81,10 +80,10 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Returns the current users' principal uri.
- *
- * If nobody is logged in, this will return null.
- *
- * @return string|null
+ *
+ * If nobody is logged in, this will return null.
+ *
+ * @return string|null
*/
public function getCurrentUser() {
@@ -97,10 +96,11 @@ class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
/**
* This method is called before any HTTP method and forces users to be authenticated
- *
+ *
* @param string $method
+ * @param string $uri
* @throws Sabre_DAV_Exception_NotAuthenticated
- * @return bool
+ * @return bool
*/
public function beforeMethod($method, $uri) {
diff --git a/3rdparty/Sabre/DAV/Browser/GuessContentType.php b/3rdparty/Sabre/DAV/Browser/GuessContentType.php
index ee8c698d782..b6c00d461cb 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/GuessContentType.php
+++ b/3rdparty/Sabre/DAV/Browser/GuessContentType.php
@@ -10,10 +10,10 @@
* There's really no accurate, fast and portable way to determine the contenttype
* so this extension does what the rest of the world does, and guesses it based
* on the file extension.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -43,9 +43,9 @@ class Sabre_DAV_Browser_GuessContentType extends Sabre_DAV_ServerPlugin {
);
/**
- * Initializes the plugin
- *
- * @param Sabre_DAV_Server $server
+ * Initializes the plugin
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -57,16 +57,16 @@ class Sabre_DAV_Browser_GuessContentType extends Sabre_DAV_ServerPlugin {
}
/**
- * Handler for teh afterGetProperties event
- *
- * @param string $path
- * @param array $properties
+ * Handler for teh afterGetProperties event
+ *
+ * @param string $path
+ * @param array $properties
* @return void
*/
public function afterGetProperties($path, &$properties) {
if (array_key_exists('{DAV:}getcontenttype', $properties[404])) {
-
+
list(, $fileName) = Sabre_DAV_URLUtil::splitPath($path);
$contentType = $this->getContentType($fileName);
@@ -81,9 +81,9 @@ class Sabre_DAV_Browser_GuessContentType extends Sabre_DAV_ServerPlugin {
/**
* Simple method to return the contenttype
- *
- * @param string $fileName
- * @return string
+ *
+ * @param string $fileName
+ * @return string
*/
protected function getContentType($fileName) {
diff --git a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
index a66b57a3a90..15884887641 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
+++ b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
@@ -1,30 +1,30 @@
<?php
/**
- * This is a simple plugin that will map any GET request for non-files to
+ * This is a simple plugin that will map any GET request for non-files to
* PROPFIND allprops-requests.
*
* This should allow easy debugging of PROPFIND
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Browser_MapGetToPropFind extends Sabre_DAV_ServerPlugin {
/**
- * reference to server class
- *
- * @var Sabre_DAV_Server
+ * reference to server class
+ *
+ * @var Sabre_DAV_Server
*/
protected $server;
/**
- * Initializes the plugin and subscribes to events
- *
- * @param Sabre_DAV_Server $server
+ * Initializes the plugin and subscribes to events
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -34,21 +34,22 @@ class Sabre_DAV_Browser_MapGetToPropFind extends Sabre_DAV_ServerPlugin {
}
/**
- * This method intercepts GET requests to non-files, and changes it into an HTTP PROPFIND request
- *
- * @param string $method
- * @return bool
+ * This method intercepts GET requests to non-files, and changes it into an HTTP PROPFIND request
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
*/
public function httpGetInterceptor($method, $uri) {
if ($method!='GET') return true;
-
+
$node = $this->server->tree->getNodeForPath($uri);
if ($node instanceof Sabre_DAV_IFile) return;
$this->server->invokeMethod('PROPFIND',$uri);
return false;
-
+
}
}
diff --git a/3rdparty/Sabre/DAV/Browser/Plugin.php b/3rdparty/Sabre/DAV/Browser/Plugin.php
index cd5617babb1..09bbdd2ae02 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/Plugin.php
+++ b/3rdparty/Sabre/DAV/Browser/Plugin.php
@@ -6,77 +6,126 @@
* This plugin provides a html representation, so that a WebDAV server may be accessed
* using a browser.
*
- * The class intercepts GET requests to collection resources and generates a simple
- * html index.
- *
+ * The class intercepts GET requests to collection resources and generates a simple
+ * html index.
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
/**
- * reference to server class
- *
- * @var Sabre_DAV_Server
+ * List of default icons for nodes.
+ *
+ * This is an array with class / interface names as keys, and asset names
+ * as values.
+ *
+ * The evaluation order is reversed. The last item in the list gets
+ * precendence.
+ *
+ * @var array
+ */
+ public $iconMap = array(
+ 'Sabre_DAV_IFile' => 'icons/file',
+ 'Sabre_DAV_ICollection' => 'icons/collection',
+ 'Sabre_DAVACL_IPrincipal' => 'icons/principal',
+ 'Sabre_CalDAV_ICalendar' => 'icons/calendar',
+ 'Sabre_CardDAV_IAddressBook' => 'icons/addressbook',
+ 'Sabre_CardDAV_ICard' => 'icons/card',
+ );
+
+ /**
+ * The file extension used for all icons
+ *
+ * @var string
+ */
+ public $iconExtension = '.png';
+
+ /**
+ * reference to server class
+ *
+ * @var Sabre_DAV_Server
*/
protected $server;
/**
- * enableEditing
- *
- * @var bool
+ * enablePost turns on the 'actions' panel, which allows people to create
+ * folders and upload files straight from a browser.
+ *
+ * @var bool
*/
protected $enablePost = true;
/**
+ * By default the browser plugin will generate a favicon and other images.
+ * To turn this off, set this property to false.
+ *
+ * @var bool
+ */
+ protected $enableAssets = true;
+
+ /**
* Creates the object.
*
* By default it will allow file creation and uploads.
* Specify the first argument as false to disable this
- *
- * @param bool $enablePost
- * @return void
+ *
+ * @param bool $enablePost
+ * @param bool $enableAssets
*/
- public function __construct($enablePost=true) {
+ public function __construct($enablePost=true, $enableAssets = true) {
- $this->enablePost = $enablePost;
+ $this->enablePost = $enablePost;
+ $this->enableAssets = $enableAssets;
}
/**
- * Initializes the plugin and subscribes to events
- *
- * @param Sabre_DAV_Server $server
+ * Initializes the plugin and subscribes to events
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
$this->server = $server;
$this->server->subscribeEvent('beforeMethod',array($this,'httpGetInterceptor'));
+ $this->server->subscribeEvent('onHTMLActionsPanel', array($this, 'htmlActionsPanel'),200);
if ($this->enablePost) $this->server->subscribeEvent('unknownMethod',array($this,'httpPOSTHandler'));
}
/**
- * This method intercepts GET requests to collections and returns the html
- *
- * @param string $method
- * @return bool
+ * This method intercepts GET requests to collections and returns the html
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
*/
public function httpGetInterceptor($method, $uri) {
- if ($method!='GET') return true;
+ if ($method !== 'GET') return true;
+
+ // We're not using straight-up $_GET, because we want everything to be
+ // unit testable.
+ $getVars = array();
+ parse_str($this->server->httpRequest->getQueryString(), $getVars);
+
+ if (isset($getVars['sabreAction']) && $getVars['sabreAction'] === 'asset' && isset($getVars['assetName'])) {
+ $this->serveAsset($getVars['assetName']);
+ return false;
+ }
- try {
+ try {
$node = $this->server->tree->getNodeForPath($uri);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
- // We're simply stopping when the file isn't found to not interfere
+ } catch (Sabre_DAV_Exception_NotFound $e) {
+ // We're simply stopping when the file isn't found to not interfere
// with other plugins.
return;
}
- if ($node instanceof Sabre_DAV_IFile)
+ if ($node instanceof Sabre_DAV_IFile)
return;
$this->server->httpResponse->sendStatus(200);
@@ -87,57 +136,71 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
);
return false;
-
+
}
/**
- * Handles POST requests for tree operations
- *
- * This method is not yet used.
- *
- * @param string $method
+ * Handles POST requests for tree operations.
+ *
+ * @param string $method
+ * @param string $uri
* @return bool
*/
public function httpPOSTHandler($method, $uri) {
- if ($method!='POST') return true;
- if (isset($_POST['sabreAction'])) switch($_POST['sabreAction']) {
+ if ($method!='POST') return;
+ $contentType = $this->server->httpRequest->getHeader('Content-Type');
+ list($contentType) = explode(';', $contentType);
+ if ($contentType !== 'application/x-www-form-urlencoded' &&
+ $contentType !== 'multipart/form-data') {
+ return;
+ }
+ $postVars = $this->server->httpRequest->getPostVars();
- case 'mkcol' :
- if (isset($_POST['name']) && trim($_POST['name'])) {
- // Using basename() because we won't allow slashes
- list(, $folderName) = Sabre_DAV_URLUtil::splitPath(trim($_POST['name']));
- $this->server->createDirectory($uri . '/' . $folderName);
- }
- break;
- case 'put' :
- if ($_FILES) $file = current($_FILES);
- else break;
- $newName = trim($file['name']);
- list(, $newName) = Sabre_DAV_URLUtil::splitPath(trim($file['name']));
- if (isset($_POST['name']) && trim($_POST['name']))
- $newName = trim($_POST['name']);
-
- // Making sure we only have a 'basename' component
- list(, $newName) = Sabre_DAV_URLUtil::splitPath($newName);
-
-
- if (is_uploaded_file($file['tmp_name'])) {
- $parent = $this->server->tree->getNodeForPath(trim($uri,'/'));
- $parent->createFile($newName,fopen($file['tmp_name'],'r'));
- }
+ if (!isset($postVars['sabreAction']))
+ return;
+
+ if ($this->server->broadcastEvent('onBrowserPostAction', array($uri, $postVars['sabreAction'], $postVars))) {
+
+ switch($postVars['sabreAction']) {
+
+ case 'mkcol' :
+ if (isset($postVars['name']) && trim($postVars['name'])) {
+ // Using basename() because we won't allow slashes
+ list(, $folderName) = Sabre_DAV_URLUtil::splitPath(trim($postVars['name']));
+ $this->server->createDirectory($uri . '/' . $folderName);
+ }
+ break;
+ case 'put' :
+ if ($_FILES) $file = current($_FILES);
+ else break;
+
+ list(, $newName) = Sabre_DAV_URLUtil::splitPath(trim($file['name']));
+ if (isset($postVars['name']) && trim($postVars['name']))
+ $newName = trim($postVars['name']);
+
+ // Making sure we only have a 'basename' component
+ list(, $newName) = Sabre_DAV_URLUtil::splitPath($newName);
+
+ if (is_uploaded_file($file['tmp_name'])) {
+ $this->server->createFile($uri . '/' . $newName, fopen($file['tmp_name'],'r'));
+ }
+ break;
+
+ }
}
$this->server->httpResponse->setHeader('Location',$this->server->httpRequest->getUri());
+ $this->server->httpResponse->sendStatus(302);
return false;
}
/**
- * Escapes a string for html.
- *
- * @param string $value
- * @return void
+ * Escapes a string for html.
+ *
+ * @param string $value
+ * @return string
*/
public function escapeHTML($value) {
@@ -146,118 +209,199 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Generates the html directory index for a given url
+ * Generates the html directory index for a given url
*
- * @param string $path
- * @return string
+ * @param string $path
+ * @return string
*/
public function generateDirectoryIndex($path) {
+ $version = '';
+ if (Sabre_DAV_Server::$exposeVersion) {
+ $version = Sabre_DAV_Version::VERSION ."-". Sabre_DAV_Version::STABILITY;
+ }
+
$html = "<html>
<head>
- <title>Index for " . $this->escapeHTML($path) . "/ - SabreDAV " . Sabre_DAV_Version::VERSION . "</title>
- <style type=\"text/css\"> body { Font-family: arial}</style>
-</head>
+ <title>Index for " . $this->escapeHTML($path) . "/ - SabreDAV " . $version . "</title>
+ <style type=\"text/css\">
+ body { Font-family: arial}
+ h1 { font-size: 150% }
+ </style>
+ ";
+
+ if ($this->enableAssets) {
+ $html.='<link rel="shortcut icon" href="'.$this->getAssetUrl('favicon.ico').'" type="image/vnd.microsoft.icon" />';
+ }
+
+ $html .= "</head>
<body>
<h1>Index for " . $this->escapeHTML($path) . "/</h1>
<table>
- <tr><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr>
- <tr><td colspan=\"4\"><hr /></td></tr>";
-
- $files = $this->server->getPropertiesForPath($path,array(
- '{DAV:}displayname',
- '{DAV:}resourcetype',
- '{DAV:}getcontenttype',
- '{DAV:}getcontentlength',
- '{DAV:}getlastmodified',
- ),1);
+ <tr><th width=\"24\"></th><th>Name</th><th>Type</th><th>Size</th><th>Last modified</th></tr>
+ <tr><td colspan=\"5\"><hr /></td></tr>";
- $parent = $this->server->tree->getNodeForPath($path);
+ $files = $this->server->getPropertiesForPath($path,array(
+ '{DAV:}displayname',
+ '{DAV:}resourcetype',
+ '{DAV:}getcontenttype',
+ '{DAV:}getcontentlength',
+ '{DAV:}getlastmodified',
+ ),1);
+ $parent = $this->server->tree->getNodeForPath($path);
- if ($path) {
- list($parentUri) = Sabre_DAV_URLUtil::splitPath($path);
- $fullPath = Sabre_DAV_URLUtil::encodePath($this->server->getBaseUri() . $parentUri);
+ if ($path) {
- $html.= "<tr>
-<td><a href=\"{$fullPath}\">..</a></td>
-<td>[parent]</td>
-<td></td>
-<td></td>
-</tr>";
+ list($parentUri) = Sabre_DAV_URLUtil::splitPath($path);
+ $fullPath = Sabre_DAV_URLUtil::encodePath($this->server->getBaseUri() . $parentUri);
- }
+ $icon = $this->enableAssets?'<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl('icons/parent' . $this->iconExtension) . '" width="24" alt="Parent" /></a>':'';
+ $html.= "<tr>
+ <td>$icon</td>
+ <td><a href=\"{$fullPath}\">..</a></td>
+ <td>[parent]</td>
+ <td></td>
+ <td></td>
+ </tr>";
- foreach($files as $k=>$file) {
+ }
- // This is the current directory, we can skip it
- if (rtrim($file['href'],'/')==$path) continue;
+ foreach($files as $file) {
+
+ // This is the current directory, we can skip it
+ if (rtrim($file['href'],'/')==$path) continue;
+
+ list(, $name) = Sabre_DAV_URLUtil::splitPath($file['href']);
+
+ $type = null;
+
+
+ if (isset($file[200]['{DAV:}resourcetype'])) {
+ $type = $file[200]['{DAV:}resourcetype']->getValue();
+
+ // resourcetype can have multiple values
+ if (!is_array($type)) $type = array($type);
+
+ foreach($type as $k=>$v) {
+
+ // Some name mapping is preferred
+ switch($v) {
+ case '{DAV:}collection' :
+ $type[$k] = 'Collection';
+ break;
+ case '{DAV:}principal' :
+ $type[$k] = 'Principal';
+ break;
+ case '{urn:ietf:params:xml:ns:carddav}addressbook' :
+ $type[$k] = 'Addressbook';
+ break;
+ case '{urn:ietf:params:xml:ns:caldav}calendar' :
+ $type[$k] = 'Calendar';
+ break;
+ case '{urn:ietf:params:xml:ns:caldav}schedule-inbox' :
+ $type[$k] = 'Schedule Inbox';
+ break;
+ case '{urn:ietf:params:xml:ns:caldav}schedule-outbox' :
+ $type[$k] = 'Schedule Outbox';
+ break;
+ case '{http://calendarserver.org/ns/}calendar-proxy-read' :
+ $type[$k] = 'Proxy-Read';
+ break;
+ case '{http://calendarserver.org/ns/}calendar-proxy-write' :
+ $type[$k] = 'Proxy-Write';
+ break;
+ }
- list(, $name) = Sabre_DAV_URLUtil::splitPath($file['href']);
+ }
+ $type = implode(', ', $type);
+ }
- $type = null;
+ // If no resourcetype was found, we attempt to use
+ // the contenttype property
+ if (!$type && isset($file[200]['{DAV:}getcontenttype'])) {
+ $type = $file[200]['{DAV:}getcontenttype'];
+ }
+ if (!$type) $type = 'Unknown';
+ $size = isset($file[200]['{DAV:}getcontentlength'])?(int)$file[200]['{DAV:}getcontentlength']:'';
+ $lastmodified = isset($file[200]['{DAV:}getlastmodified'])?$file[200]['{DAV:}getlastmodified']->getTime()->format(DateTime::ATOM):'';
- if (isset($file[200]['{DAV:}resourcetype'])) {
- $type = $file[200]['{DAV:}resourcetype']->getValue();
+ $fullPath = Sabre_DAV_URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path?$path . '/':'') . $name,'/'));
- // resourcetype can have multiple values
- if (!is_array($type)) $type = array($type);
+ $displayName = isset($file[200]['{DAV:}displayname'])?$file[200]['{DAV:}displayname']:$name;
- foreach($type as $k=>$v) {
+ $displayName = $this->escapeHTML($displayName);
+ $type = $this->escapeHTML($type);
- // Some name mapping is preferred
- switch($v) {
- case '{DAV:}collection' :
- $type[$k] = 'Collection';
- break;
- case '{DAV:}principal' :
- $type[$k] = 'Principal';
- break;
- case '{urn:ietf:params:xml:ns:carddav}addressbook' :
- $type[$k] = 'Addressbook';
- break;
- case '{urn:ietf:params:xml:ns:caldav}calendar' :
- $type[$k] = 'Calendar';
+ $icon = '';
+
+ if ($this->enableAssets) {
+ $node = $parent->getChild($name);
+ foreach(array_reverse($this->iconMap) as $class=>$iconName) {
+
+ if ($node instanceof $class) {
+ $icon = '<a href="' . $fullPath . '"><img src="' . $this->getAssetUrl($iconName . $this->iconExtension) . '" alt="" width="24" /></a>';
break;
+ }
+
+
}
}
- $type = implode(', ', $type);
- }
- // If no resourcetype was found, we attempt to use
- // the contenttype property
- if (!$type && isset($file[200]['{DAV:}getcontenttype'])) {
- $type = $file[200]['{DAV:}getcontenttype'];
+ $html.= "<tr>
+ <td>$icon</td>
+ <td><a href=\"{$fullPath}\">{$displayName}</a></td>
+ <td>{$type}</td>
+ <td>{$size}</td>
+ <td>{$lastmodified}</td>
+ </tr>";
+
}
- if (!$type) $type = 'Unknown';
- $size = isset($file[200]['{DAV:}getcontentlength'])?(int)$file[200]['{DAV:}getcontentlength']:'';
- $lastmodified = isset($file[200]['{DAV:}getlastmodified'])?$file[200]['{DAV:}getlastmodified']->getTime()->format(DateTime::ATOM):'';
+ $html.= "<tr><td colspan=\"5\"><hr /></td></tr>";
+
+ $output = '';
- $fullPath = Sabre_DAV_URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path?$path . '/':'') . $name,'/'));
+ if ($this->enablePost) {
+ $this->server->broadcastEvent('onHTMLActionsPanel',array($parent, &$output));
+ }
- $displayName = isset($file[200]['{DAV:}displayname'])?$file[200]['{DAV:}displayname']:$name;
+ $html.=$output;
- $name = $this->escapeHTML($name);
- $displayName = $this->escapeHTML($displayName);
- $type = $this->escapeHTML($type);
+ $html.= "</table>
+ <address>Generated by SabreDAV " . $version . " (c)2007-2012 <a href=\"http://code.google.com/p/sabredav/\">http://code.google.com/p/sabredav/</a></address>
+ </body>
+ </html>";
- $html.= "<tr>
-<td><a href=\"{$fullPath}\">{$displayName}</a></td>
-<td>{$type}</td>
-<td>{$size}</td>
-<td>{$lastmodified}</td>
-</tr>";
+ return $html;
}
- $html.= "<tr><td colspan=\"4\"><hr /></td></tr>";
+ /**
+ * This method is used to generate the 'actions panel' output for
+ * collections.
+ *
+ * This specifically generates the interfaces for creating new files, and
+ * creating new directories.
+ *
+ * @param Sabre_DAV_INode $node
+ * @param mixed $output
+ * @return void
+ */
+ public function htmlActionsPanel(Sabre_DAV_INode $node, &$output) {
+
+ if (!$node instanceof Sabre_DAV_ICollection)
+ return;
+
+ // We also know fairly certain that if an object is a non-extended
+ // SimpleCollection, we won't need to show the panel either.
+ if (get_class($node)==='Sabre_DAV_SimpleCollection')
+ return;
- if ($this->enablePost && $parent instanceof Sabre_DAV_ICollection) {
- $html.= '<tr><td><form method="post" action="">
+ $output.= '<tr><td colspan="2"><form method="post" action="">
<h3>Create new folder</h3>
<input type="hidden" name="sabreAction" value="mkcol" />
Name: <input type="text" name="name" /><br />
@@ -270,15 +414,75 @@ class Sabre_DAV_Browser_Plugin extends Sabre_DAV_ServerPlugin {
File: <input type="file" name="file" /><br />
<input type="submit" value="upload" />
</form>
- </td></tr>';
- }
+ </td></tr>';
+
+ }
- $html.= "</table>
- <address>Generated by SabreDAV " . Sabre_DAV_Version::VERSION ."-". Sabre_DAV_Version::STABILITY . " (c)2007-2011 <a href=\"http://code.google.com/p/sabredav/\">http://code.google.com/p/sabredav/</a></address>
-</body>
-</html>";
+ /**
+ * This method takes a path/name of an asset and turns it into url
+ * suiteable for http access.
+ *
+ * @param string $assetName
+ * @return string
+ */
+ protected function getAssetUrl($assetName) {
- return $html;
+ return $this->server->getBaseUri() . '?sabreAction=asset&assetName=' . urlencode($assetName);
+
+ }
+
+ /**
+ * This method returns a local pathname to an asset.
+ *
+ * @param string $assetName
+ * @return string
+ */
+ protected function getLocalAssetPath($assetName) {
+
+ // Making sure people aren't trying to escape from the base path.
+ $assetSplit = explode('/', $assetName);
+ if (in_array('..',$assetSplit)) {
+ throw new Sabre_DAV_Exception('Incorrect asset path');
+ }
+ $path = __DIR__ . '/assets/' . $assetName;
+ return $path;
+
+ }
+
+ /**
+ * This method reads an asset from disk and generates a full http response.
+ *
+ * @param string $assetName
+ * @return void
+ */
+ protected function serveAsset($assetName) {
+
+ $assetPath = $this->getLocalAssetPath($assetName);
+ if (!file_exists($assetPath)) {
+ throw new Sabre_DAV_Exception_NotFound('Could not find an asset with this name');
+ }
+ // Rudimentary mime type detection
+ switch(strtolower(substr($assetPath,strpos($assetPath,'.')+1))) {
+
+ case 'ico' :
+ $mime = 'image/vnd.microsoft.icon';
+ break;
+
+ case 'png' :
+ $mime = 'image/png';
+ break;
+
+ default:
+ $mime = 'application/octet-stream';
+ break;
+
+ }
+
+ $this->server->httpResponse->setHeader('Content-Type', $mime);
+ $this->server->httpResponse->setHeader('Content-Length', filesize($assetPath));
+ $this->server->httpResponse->setHeader('Cache-Control', 'public, max-age=1209600');
+ $this->server->httpResponse->sendStatus(200);
+ $this->server->httpResponse->sendBody(fopen($assetPath,'r'));
}
diff --git a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico
new file mode 100755
index 00000000000..2b2c10a22cc
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png
new file mode 100755
index 00000000000..c9acc84172d
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png
new file mode 100755
index 00000000000..3ecd6a800a0
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png
new file mode 100755
index 00000000000..2ce954866d8
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png
new file mode 100755
index 00000000000..156fa64fd50
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png
new file mode 100755
index 00000000000..3b98551cec3
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png
new file mode 100755
index 00000000000..156fa64fd50
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png
new file mode 100755
index 00000000000..f8988f828e6
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Client.php b/3rdparty/Sabre/DAV/Client.php
index fc6a6fff083..a8320dd9782 100644..100755
--- a/3rdparty/Sabre/DAV/Client.php
+++ b/3rdparty/Sabre/DAV/Client.php
@@ -3,14 +3,14 @@
/**
* SabreDAV DAV client
*
- * This client wraps around Curl to provide a convenient API to a WebDAV
+ * This client wraps around Curl to provide a convenient API to a WebDAV
* server.
*
* NOTE: This class is experimental, it's api will likely change in the future.
- *
+ *
* @package Sabre
* @subpackage DAVClient
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -26,22 +26,22 @@ class Sabre_DAV_Client {
/**
* Constructor
*
- * Settings are provided through the 'settings' argument. The following
+ * Settings are provided through the 'settings' argument. The following
* settings are supported:
*
* * baseUri
* * userName (optional)
* * password (optional)
* * proxy (optional)
- *
- * @param array $settings
+ *
+ * @param array $settings
*/
public function __construct(array $settings) {
if (!isset($settings['baseUri'])) {
throw new InvalidArgumentException('A baseUri must be provided');
}
-
+
$validSettings = array(
'baseUri',
'userName',
@@ -62,23 +62,23 @@ class Sabre_DAV_Client {
/**
* Does a PROPFIND request
*
- * The list of requested properties must be specified as an array, in clark
- * notation.
+ * The list of requested properties must be specified as an array, in clark
+ * notation.
*
- * The returned array will contain a list of filenames as keys, and
+ * The returned array will contain a list of filenames as keys, and
* properties as values.
*
- * The properties array will contain the list of properties. Only properties
- * that are actually returned from the server (without error) will be
+ * The properties array will contain the list of properties. Only properties
+ * that are actually returned from the server (without error) will be
* returned, anything else is discarded.
*
- * Depth should be either 0 or 1. A depth of 1 will cause a request to be
+ * Depth should be either 0 or 1. A depth of 1 will cause a request to be
* made to the server to also return all child resources.
*
- * @param string $url
- * @param array $properties
- * @param int $depth
- * @return array
+ * @param string $url
+ * @param array $properties
+ * @param int $depth
+ * @return array
*/
public function propFind($url, array $properties, $depth = 0) {
@@ -132,14 +132,14 @@ class Sabre_DAV_Client {
/**
* Updates a list of properties on the server
*
- * The list of properties must have clark-notation properties for the keys,
- * and the actual (string) value for the value. If the value is null, an
- * attempt is made to delete the property.
+ * The list of properties must have clark-notation properties for the keys,
+ * and the actual (string) value for the value. If the value is null, an
+ * attempt is made to delete the property.
*
- * @todo Must be building the request using the DOM, and does not yet
- * support complex properties.
- * @param string $url
- * @param array $properties
+ * @todo Must be building the request using the DOM, and does not yet
+ * support complex properties.
+ * @param string $url
+ * @param array $properties
* @return void
*/
public function propPatch($url, array $properties) {
@@ -175,7 +175,7 @@ class Sabre_DAV_Client {
$body.=" <x:" . $elementName . " xmlns:x=\"" . $namespace . "\">";
}
// Shitty.. i know
- $body.=htmlspecialchars($propValue, ENT_NOQUOTES, 'UTF-8');
+ $body.=htmlspecialchars($propValue, ENT_NOQUOTES, 'UTF-8');
if ($namespace === 'DAV:') {
$body.='</d:' . $elementName . '>' . "\n";
} else {
@@ -189,7 +189,7 @@ class Sabre_DAV_Client {
$body.= '</d:propertyupdate>';
- $response = $this->request('PROPPATCH', $url, $body, array(
+ $this->request('PROPPATCH', $url, $body, array(
'Content-Type' => 'application/xml'
));
@@ -198,11 +198,11 @@ class Sabre_DAV_Client {
/**
* Performs an HTTP options request
*
- * This method returns all the features from the 'DAV:' header as an array.
- * If there was no DAV header, or no contents this method will return an
- * empty array.
- *
- * @return array
+ * This method returns all the features from the 'DAV:' header as an array.
+ * If there was no DAV header, or no contents this method will return an
+ * empty array.
+ *
+ * @return array
*/
public function options() {
@@ -222,20 +222,20 @@ class Sabre_DAV_Client {
/**
* Performs an actual HTTP request, and returns the result.
*
- * If the specified url is relative, it will be expanded based on the base
+ * If the specified url is relative, it will be expanded based on the base
* url.
*
* The returned array contains 3 keys:
* * body - the response body
* * httpCode - a HTTP code (200, 404, etc)
- * * headers - a list of response http headers. The header names have
+ * * headers - a list of response http headers. The header names have
* been lowercased.
*
- * @param string $method
- * @param string $url
- * @param string $body
- * @param array $headers
- * @return array
+ * @param string $method
+ * @param string $url
+ * @param string $body
+ * @param array $headers
+ * @return array
*/
public function request($method, $url = '', $body = null, $headers = array()) {
@@ -243,14 +243,37 @@ class Sabre_DAV_Client {
$curlSettings = array(
CURLOPT_RETURNTRANSFER => true,
- CURLOPT_CUSTOMREQUEST => $method,
- CURLOPT_POSTFIELDS => $body,
// Return headers as part of the response
- CURLOPT_HEADER => true
+ CURLOPT_HEADER => true,
+ CURLOPT_POSTFIELDS => $body,
+ // Automatically follow redirects
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
);
+ switch ($method) {
+ case 'PUT':
+ $curlSettings[CURLOPT_PUT] = true;
+ break;
+ case 'HEAD' :
+
+ // do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
+ // requests when the Content-Length header is given - which in turn is perfectly valid according to HTTP
+ // specs...) cURL does unfortunately return an error in this case ("transfer closed transfer closed with
+ // ... bytes remaining to read") this can be circumvented by explicitly telling cURL to ignore the
+ // response body
+ $curlSettings[CURLOPT_NOBODY] = true;
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
+ break;
+
+ default:
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = $method;
+ break;
+
+ }
+
// Adding HTTP headers
- $nHeaders = array();
+ $nHeaders = array();
foreach($headers as $key=>$value) {
$nHeaders[] = $key . ': ' . $value;
@@ -277,17 +300,17 @@ class Sabre_DAV_Client {
$headerBlob = substr($response, 0, $curlInfo['header_size']);
$response = substr($response, $curlInfo['header_size']);
- // In the case of 100 Continue, or redirects we'll have multiple lists
- // of headers for each separate HTTP response. We can easily split this
+ // In the case of 100 Continue, or redirects we'll have multiple lists
+ // of headers for each separate HTTP response. We can easily split this
// because they are separated by \r\n\r\n
$headerBlob = explode("\r\n\r\n", trim($headerBlob, "\r\n"));
-
+
// We only care about the last set of headers
$headerBlob = $headerBlob[count($headerBlob)-1];
// Splitting headers
$headerBlob = explode("\r\n", $headerBlob);
-
+
$headers = array();
foreach($headerBlob as $header) {
$parts = explode(':', $header, 2);
@@ -304,10 +327,17 @@ class Sabre_DAV_Client {
if ($curlErrNo) {
throw new Sabre_DAV_Exception('[CURL] Error while making request: ' . $curlError . ' (error code: ' . $curlErrNo . ')');
- }
+ }
if ($response['statusCode']>=400) {
- throw new Sabre_DAV_Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
+ switch ($response['statusCode']) {
+ case 404:
+ throw new Sabre_DAV_Exception_NotFound('Resource ' . $url . ' not found.');
+ break;
+
+ default:
+ throw new Sabre_DAV_Exception('HTTP error response. (errorcode ' . $response['statusCode'] . ')');
+ }
}
return $response;
@@ -317,12 +347,12 @@ class Sabre_DAV_Client {
/**
* Wrapper for all curl functions.
*
- * The only reason this was split out in a separate method, is so it
- * becomes easier to unittest.
+ * The only reason this was split out in a separate method, is so it
+ * becomes easier to unittest.
*
* @param string $url
- * @param array $settings
- * @return
+ * @param array $settings
+ * @return array
*/
protected function curlRequest($url, $settings) {
@@ -339,20 +369,20 @@ class Sabre_DAV_Client {
}
/**
- * Returns the full url based on the given url (which may be relative). All
- * urls are expanded based on the base url as given by the server.
- *
- * @param string $url
- * @return string
+ * Returns the full url based on the given url (which may be relative). All
+ * urls are expanded based on the base url as given by the server.
+ *
+ * @param string $url
+ * @return string
*/
protected function getAbsoluteUrl($url) {
- // If the url starts with http:// or https://, the url is already absolute.
+ // If the url starts with http:// or https://, the url is already absolute.
if (preg_match('/^http(s?):\/\//', $url)) {
return $url;
}
- // If the url starts with a slash, we must calculate the url based off
+ // If the url starts with a slash, we must calculate the url based off
// the root of the base url.
if (strpos($url,'/') === 0) {
$parts = parse_url($this->baseUri);
@@ -366,7 +396,7 @@ class Sabre_DAV_Client {
/**
* Parses a WebDAV multistatus response body
- *
+ *
* This method returns an array with the following structure
*
* array(
@@ -387,7 +417,7 @@ class Sabre_DAV_Client {
*
*
* @param string $body xml body
- * @return array
+ * @return array
*/
public function parseMultiStatus($body) {
@@ -397,14 +427,13 @@ class Sabre_DAV_Client {
if ($responseXML===false) {
throw new InvalidArgumentException('The passed data is not valid XML');
}
-
- $responseXML->registerXPathNamespace('d','DAV:');
+
+ $responseXML->registerXPathNamespace('d', 'urn:DAV');
$propResult = array();
foreach($responseXML->xpath('d:response') as $response) {
-
- $response->registerXPathNamespace('d','DAV:');
+ $response->registerXPathNamespace('d', 'urn:DAV');
$href = $response->xpath('d:href');
$href = (string)$href[0];
@@ -412,11 +441,11 @@ class Sabre_DAV_Client {
foreach($response->xpath('d:propstat') as $propStat) {
- $propStat->registerXPathNamespace('d','DAV:');
+ $propStat->registerXPathNamespace('d', 'urn:DAV');
$status = $propStat->xpath('d:status');
list($httpVersion, $statusCode, $message) = explode(' ', (string)$status[0],3);
- $properties[$statusCode] = Sabre_DAV_XMLUtil::parseProperties(dom_import_simplexml($propStat), $this->propertyMap);
+ $properties[$statusCode] = Sabre_DAV_XMLUtil::parseProperties(dom_import_simplexml($propStat), $this->propertyMap);
}
diff --git a/3rdparty/Sabre/DAV/Collection.php b/3rdparty/Sabre/DAV/Collection.php
index 9da04c12792..776c22531b2 100644..100755
--- a/3rdparty/Sabre/DAV/Collection.php
+++ b/3rdparty/Sabre/DAV/Collection.php
@@ -4,12 +4,12 @@
* Collection class
*
* This is a helper class, that should aid in getting collections classes setup.
- * Most of its methods are implemented, and throw permission denied exceptions
- *
+ * Most of its methods are implemented, and throw permission denied exceptions
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_ICollection {
@@ -17,12 +17,12 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
/**
* Returns a child object, by its name.
*
- * This method makes use of the getChildren method to grab all the child nodes, and compares the name.
+ * This method makes use of the getChildren method to grab all the child nodes, and compares the name.
* Generally its wise to override this, as this can usually be optimized
- *
+ *
* @param string $name
- * @throws Sabre_DAV_Exception_FileNotFound
- * @return Sabre_DAV_INode
+ * @throws Sabre_DAV_Exception_NotFound
+ * @return Sabre_DAV_INode
*/
public function getChild($name) {
@@ -31,7 +31,7 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
if ($child->getName()==$name) return $child;
}
- throw new Sabre_DAV_Exception_FileNotFound('File not found: ' . $name);
+ throw new Sabre_DAV_Exception_NotFound('File not found: ' . $name);
}
@@ -39,9 +39,9 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
* Checks is a child-node exists.
*
* It is generally a good idea to try and override this. Usually it can be optimized.
- *
- * @param string $name
- * @return bool
+ *
+ * @param string $name
+ * @return bool
*/
public function childExists($name) {
@@ -50,7 +50,7 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
$this->getChild($name);
return true;
- } catch(Sabre_DAV_Exception_FileNotFound $e) {
+ } catch(Sabre_DAV_Exception_NotFound $e) {
return false;
@@ -59,12 +59,28 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
}
/**
- * Creates a new file in the directory
- *
- * @param string $name Name of the file
- * @param resource $data Initial payload, passed as a readable stream resource.
- * @throws Sabre_DAV_Exception_Forbidden
- * @return void
+ * Creates a new file in the directory
+ *
+ * Data will either be supplied as a stream resource, or in certain cases
+ * as a string. Keep in mind that you may have to support either.
+ *
+ * After succesful creation of the file, you may choose to return the ETag
+ * of the new file here.
+ *
+ * The returned ETag must be surrounded by double-quotes (The quotes should
+ * be part of the actual string).
+ *
+ * If you cannot accurately determine the ETag, you should not return it.
+ * If you don't store the file exactly as-is (you're transforming it
+ * somehow) you should also not return an ETag.
+ *
+ * This means that if a subsequent GET to this new file does not exactly
+ * return the same contents of what was submitted here, you are strongly
+ * recommended to omit the ETag.
+ *
+ * @param string $name Name of the file
+ * @param resource|string $data Initial payload
+ * @return null|string
*/
public function createFile($name, $data = null) {
@@ -73,9 +89,9 @@ abstract class Sabre_DAV_Collection extends Sabre_DAV_Node implements Sabre_DAV_
}
/**
- * Creates a new subdirectory
- *
- * @param string $name
+ * Creates a new subdirectory
+ *
+ * @param string $name
* @throws Sabre_DAV_Exception_Forbidden
* @return void
*/
diff --git a/3rdparty/Sabre/DAV/Directory.php b/3rdparty/Sabre/DAV/Directory.php
index 86af4827b3e..6db8febc02e 100644..100755
--- a/3rdparty/Sabre/DAV/Directory.php
+++ b/3rdparty/Sabre/DAV/Directory.php
@@ -8,7 +8,7 @@
* @package Sabre
* @subpackage DAV
* @deprecated Use Sabre_DAV_Collection instead
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
diff --git a/3rdparty/Sabre/DAV/Exception.php b/3rdparty/Sabre/DAV/Exception.php
index 61f8b87c0a6..a2cd6cf5820 100644..100755
--- a/3rdparty/Sabre/DAV/Exception.php
+++ b/3rdparty/Sabre/DAV/Exception.php
@@ -7,42 +7,42 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
/**
- * Main Exception class.
+ * Main Exception class.
*
- * This class defines a getHTTPCode method, which should return the appropriate HTTP code for the Exception occured.
+ * This class defines a getHTTPCode method, which should return the appropriate HTTP code for the Exception occurred.
* The default for this is 500.
*
* This class also allows you to generate custom xml data for your exceptions. This will be displayed
* in the 'error' element in the failing response.
*/
-class Sabre_DAV_Exception extends Exception {
+class Sabre_DAV_Exception extends Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
- public function getHTTPCode() {
+ public function getHTTPCode() {
return 500;
}
/**
- * This method allows the exception to include additonal information into the WebDAV error response
+ * This method allows the exception to include additional information into the WebDAV error response
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
}
@@ -50,14 +50,15 @@ class Sabre_DAV_Exception extends Exception {
* This method allows the exception to return any extra HTTP response headers.
*
* The headers must be returned as an array.
- *
- * @return array
+ *
+ * @param Sabre_DAV_Server $server
+ * @return array
*/
public function getHTTPHeaders(Sabre_DAV_Server $server) {
return array();
- }
+ }
}
diff --git a/3rdparty/Sabre/DAV/Exception/BadRequest.php b/3rdparty/Sabre/DAV/Exception/BadRequest.php
index 7025bb10317..b198648a754 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/BadRequest.php
+++ b/3rdparty/Sabre/DAV/Exception/BadRequest.php
@@ -4,24 +4,24 @@
* BadRequest
*
* The BadRequest is thrown when the user submitted an invalid HTTP request
- * BadRequest
- *
+ * BadRequest
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_BadRequest extends Sabre_DAV_Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
public function getHTTPCode() {
- return 400;
+ return 400;
}
diff --git a/3rdparty/Sabre/DAV/Exception/Conflict.php b/3rdparty/Sabre/DAV/Exception/Conflict.php
index 7eaa08178ae..6b0bd1fad73 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/Conflict.php
+++ b/3rdparty/Sabre/DAV/Exception/Conflict.php
@@ -8,14 +8,14 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_Conflict extends Sabre_DAV_Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
diff --git a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
index 279f63dfde7..6121868e69e 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
+++ b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
@@ -1,28 +1,28 @@
<?php
/**
- * ConflictingLock
+ * ConflictingLock
*
- * Similar to Exception_Locked, this exception thrown when a LOCK request
+ * Similar to Exception_Locked, this exception thrown when a LOCK request
* was made, on a resource which was already locked
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_ConflictingLock extends Sabre_DAV_Exception_Locked {
/**
- * This method allows the exception to include additonal information into the WebDAV error response
+ * This method allows the exception to include additional information into the WebDAV error response
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
if ($this->lock) {
$error = $errorNode->ownerDocument->createElementNS('DAV:','d:no-conflicting-lock');
$errorNode->appendChild($error);
diff --git a/3rdparty/Sabre/DAV/Exception/FileNotFound.php b/3rdparty/Sabre/DAV/Exception/FileNotFound.php
index b20e4a2fb3f..d76e400c93b 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/FileNotFound.php
+++ b/3rdparty/Sabre/DAV/Exception/FileNotFound.php
@@ -3,26 +3,17 @@
/**
* FileNotFound
*
- * This Exception is thrown when a Node couldn't be found. It returns HTTP error code 404
+ * Deprecated: Warning, this class is deprecated and will be removed in a
+ * future version of SabreDAV. Please use Sabre_DAV_Exception_NotFound instead.
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @deprecated Use Sabre_DAV_Exception_NotFound instead
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-class Sabre_DAV_Exception_FileNotFound extends Sabre_DAV_Exception {
-
- /**
- * Returns the HTTP statuscode for this exception
- *
- * @return int
- */
- public function getHTTPCode() {
-
- return 404;
-
- }
+class Sabre_DAV_Exception_FileNotFound extends Sabre_DAV_Exception_NotFound {
}
diff --git a/3rdparty/Sabre/DAV/Exception/Forbidden.php b/3rdparty/Sabre/DAV/Exception/Forbidden.php
index 167f3c2760a..20b1056e31b 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/Forbidden.php
+++ b/3rdparty/Sabre/DAV/Exception/Forbidden.php
@@ -4,17 +4,17 @@
* Forbidden
*
* This exception is thrown whenever a user tries to do an operation he's not allowed to
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_Forbidden extends Sabre_DAV_Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
diff --git a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
index 15007cdd352..1a15089b0a3 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
+++ b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
@@ -1,20 +1,20 @@
<?php
/**
- * InsufficientStorage
+ * InsufficientStorage
*
* This Exception can be thrown, when for example a harddisk is full or a quota is exceeded
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_InsufficientStorage extends Sabre_DAV_Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
diff --git a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
index f06810a25ef..2230f1d0811 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
+++ b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
@@ -1,26 +1,26 @@
<?php
/**
- * InvalidResourceType
+ * InvalidResourceType
*
* This exception is thrown when the user tried to create a new collection, with
* a special resourcetype value that was not recognized by the server.
*
* See RFC5689 section 3.3
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-class Sabre_DAV_Exception_InvalidResourceType extends Sabre_DAV_Exception_Forbidden {
+class Sabre_DAV_Exception_InvalidResourceType extends Sabre_DAV_Exception_Forbidden {
/**
- * This method allows the exception to include additonal information into the WebDAV error response
+ * This method allows the exception to include additional information into the WebDAV error response
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
@@ -29,5 +29,5 @@ class Sabre_DAV_Exception_InvalidResourceType extends Sabre_DAV_Exception_Forbid
$errorNode->appendChild($error);
}
-
+
}
diff --git a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
index 47032cffc75..80ab7aff65a 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
+++ b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
@@ -1,13 +1,13 @@
<?php
/**
- * LockTokenMatchesRequestUri
+ * LockTokenMatchesRequestUri
+ *
+ * This exception is thrown by UNLOCK if a supplied lock-token is invalid
*
- * This exception is thrown by UNLOCK if a supplied lock-token is invalid
- *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -23,10 +23,10 @@ class Sabre_DAV_Exception_LockTokenMatchesRequestUri extends Sabre_DAV_Exception
}
/**
- * This method allows the exception to include additonal information into the WebDAV error response
+ * This method allows the exception to include additional information into the WebDAV error response
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
diff --git a/3rdparty/Sabre/DAV/Exception/Locked.php b/3rdparty/Sabre/DAV/Exception/Locked.php
index b4bb2e0378c..976365ac1f8 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/Locked.php
+++ b/3rdparty/Sabre/DAV/Exception/Locked.php
@@ -1,32 +1,32 @@
<?php
/**
- * Locked
+ * Locked
*
* The 423 is thrown when a client tried to access a resource that was locked, without supplying a valid lock token
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_Locked extends Sabre_DAV_Exception {
/**
- * Lock information
- *
- * @var Sabre_DAV_Locks_LockInfo
+ * Lock information
+ *
+ * @var Sabre_DAV_Locks_LockInfo
*/
protected $lock;
/**
* Creates the exception
- *
+ *
* A LockInfo object should be passed if the user should be informed
* which lock actually has the file locked.
- *
- * @param Sabre_DAV_Locks_LockInfo $lock
+ *
+ * @param Sabre_DAV_Locks_LockInfo $lock
*/
public function __construct(Sabre_DAV_Locks_LockInfo $lock = null) {
@@ -35,7 +35,7 @@ class Sabre_DAV_Exception_Locked extends Sabre_DAV_Exception {
}
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
@@ -46,14 +46,14 @@ class Sabre_DAV_Exception_Locked extends Sabre_DAV_Exception {
}
/**
- * This method allows the exception to include additonal information into the WebDAV error response
+ * This method allows the exception to include additional information into the WebDAV error response
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
if ($this->lock) {
$error = $errorNode->ownerDocument->createElementNS('DAV:','d:lock-token-submitted');
$errorNode->appendChild($error);
diff --git a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
index 02c145ffeb6..31875751505 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
+++ b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
@@ -4,17 +4,17 @@
* MethodNotAllowed
*
* The 405 is thrown when a client tried to create a directory on an already existing directory
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_MethodNotAllowed extends Sabre_DAV_Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
@@ -28,8 +28,9 @@ class Sabre_DAV_Exception_MethodNotAllowed extends Sabre_DAV_Exception {
* This method allows the exception to return any extra HTTP response headers.
*
* The headers must be returned as an array.
- *
- * @return array
+ *
+ * @param Sabre_DAV_Server $server
+ * @return array
*/
public function getHTTPHeaders(Sabre_DAV_Server $server) {
diff --git a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
index 1faffddfa00..87ca624429f 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
+++ b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
@@ -5,22 +5,22 @@
*
* This exception is thrown when the client did not provide valid
* authentication credentials.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_NotAuthenticated extends Sabre_DAV_Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
public function getHTTPCode() {
-
+
return 401;
}
diff --git a/3rdparty/Sabre/DAV/Exception/NotFound.php b/3rdparty/Sabre/DAV/Exception/NotFound.php
new file mode 100755
index 00000000000..2b9da560d23
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Exception/NotFound.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * NotFound
+ *
+ * This Exception is thrown when a Node couldn't be found. It returns HTTP error code 404
+ *
+ * @package Sabre
+ * @subpackage DAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_DAV_Exception_NotFound extends Sabre_DAV_Exception {
+
+ /**
+ * Returns the HTTP statuscode for this exception
+ *
+ * @return int
+ */
+ public function getHTTPCode() {
+
+ return 404;
+
+ }
+
+}
+
diff --git a/3rdparty/Sabre/DAV/Exception/NotImplemented.php b/3rdparty/Sabre/DAV/Exception/NotImplemented.php
index cd7f609b09d..d017a19f559 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/NotImplemented.php
+++ b/3rdparty/Sabre/DAV/Exception/NotImplemented.php
@@ -4,22 +4,22 @@
* NotImplemented
*
* This exception is thrown when the client tried to call an unsupported HTTP method or other feature
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_NotImplemented extends Sabre_DAV_Exception {
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
public function getHTTPCode() {
-
+
return 501;
}
diff --git a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
new file mode 100755
index 00000000000..4982f45a4b5
--- /dev/null
+++ b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * Payment Required
+ *
+ * The PaymentRequired exception may be thrown in a case where a user must pay
+ * to access a certain resource or operation.
+ *
+ * @package Sabre
+ * @subpackage DAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_DAV_Exception_PaymentRequired extends Sabre_DAV_Exception {
+
+ /**
+ * Returns the HTTP statuscode for this exception
+ *
+ * @return int
+ */
+ public function getHTTPCode() {
+
+ return 402;
+
+ }
+
+}
diff --git a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
index ebcb9f5b9ac..213e9c52317 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
+++ b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
@@ -1,15 +1,15 @@
<?php
/**
- * PreconditionFailed
+ * PreconditionFailed
*
- * This exception is normally thrown when a client submitted a conditional request,
- * like for example an If, If-None-Match or If-Match header, which caused the HTTP
+ * This exception is normally thrown when a client submitted a conditional request,
+ * like for example an If, If-None-Match or If-Match header, which caused the HTTP
* request to not execute (the condition of the header failed)
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -17,47 +17,47 @@ class Sabre_DAV_Exception_PreconditionFailed extends Sabre_DAV_Exception {
/**
* When this exception is thrown, the header-name might be set.
- *
+ *
* This allows the exception-catching code to determine which HTTP header
* caused the exception.
- *
- * @var string
+ *
+ * @var string
*/
public $header = null;
/**
- * Create the exception
- *
- * @param string $message
- * @param string $header
+ * Create the exception
+ *
+ * @param string $message
+ * @param string $header
*/
public function __construct($message, $header=null) {
parent::__construct($message);
$this->header = $header;
- }
+ }
/**
- * Returns the HTTP statuscode for this exception
+ * Returns the HTTP statuscode for this exception
*
* @return int
*/
public function getHTTPCode() {
- return 412;
+ return 412;
}
/**
- * This method allows the exception to include additonal information into the WebDAV error response
+ * This method allows the exception to include additional information into the WebDAV error response
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
if ($this->header) {
$prop = $errorNode->ownerDocument->createElement('s:header');
$prop->nodeValue = $this->header;
diff --git a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php b/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
index e4ed601b16c..e86800f3038 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
+++ b/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
@@ -7,17 +7,17 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_ReportNotImplemented extends Sabre_DAV_Exception_NotImplemented {
/**
- * This method allows the exception to include additonal information into the WebDAV error response
+ * This method allows the exception to include additional information into the WebDAV error response
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
diff --git a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
index 37abbd729d1..29ee3654a7e 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
+++ b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
@@ -1,21 +1,21 @@
<?php
/**
- * RequestedRangeNotSatisfiable
+ * RequestedRangeNotSatisfiable
*
- * This exception is normally thrown when the user
+ * This exception is normally thrown when the user
* request a range that is out of the entity bounds.
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Exception_RequestedRangeNotSatisfiable extends Sabre_DAV_Exception {
/**
- * returns the http statuscode for this exception
+ * returns the http statuscode for this exception
*
* @return int
*/
diff --git a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
index 4c37d8997cf..9a4693b21a8 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
+++ b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
@@ -3,19 +3,19 @@
/**
* UnSupportedMediaType
*
- * The 415 Unsupported Media Type status code is generally sent back when the client
+ * The 415 Unsupported Media Type status code is generally sent back when the client
* tried to call an HTTP method, with a body the server didn't understand
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-class Sabre_DAV_Exception_UnsupportedMediaType extends Sabre_DAV_Exception {
+class Sabre_DAV_Exception_UnsupportedMediaType extends Sabre_DAV_Exception {
/**
- * returns the http statuscode for this exception
+ * returns the http statuscode for this exception
*
* @return int
*/
diff --git a/3rdparty/Sabre/DAV/FS/Directory.php b/3rdparty/Sabre/DAV/FS/Directory.php
index ebd6a6c505e..3af2d755583 100644..100755
--- a/3rdparty/Sabre/DAV/FS/Directory.php
+++ b/3rdparty/Sabre/DAV/FS/Directory.php
@@ -1,24 +1,39 @@
<?php
/**
- * Directory class
- *
+ * Directory class
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICollection, Sabre_DAV_IQuota {
/**
- * Creates a new file in the directory
- *
- * data is a readable stream resource
+ * Creates a new file in the directory
*
- * @param string $name Name of the file
- * @param resource $data Initial payload
- * @return void
+ * Data will either be supplied as a stream resource, or in certain cases
+ * as a string. Keep in mind that you may have to support either.
+ *
+ * After succesful creation of the file, you may choose to return the ETag
+ * of the new file here.
+ *
+ * The returned ETag must be surrounded by double-quotes (The quotes should
+ * be part of the actual string).
+ *
+ * If you cannot accurately determine the ETag, you should not return it.
+ * If you don't store the file exactly as-is (you're transforming it
+ * somehow) you should also not return an ETag.
+ *
+ * This means that if a subsequent GET to this new file does not exactly
+ * return the same contents of what was submitted here, you are strongly
+ * recommended to omit the ETag.
+ *
+ * @param string $name Name of the file
+ * @param resource|string $data Initial payload
+ * @return null|string
*/
public function createFile($name, $data = null) {
@@ -28,9 +43,9 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
}
/**
- * Creates a new subdirectory
- *
- * @param string $name
+ * Creates a new subdirectory
+ *
+ * @param string $name
* @return void
*/
public function createDirectory($name) {
@@ -41,17 +56,17 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
}
/**
- * Returns a specific child node, referenced by its name
- *
- * @param string $name
- * @throws Sabre_DAV_Exception_FileNotFound
- * @return Sabre_DAV_INode
+ * Returns a specific child node, referenced by its name
+ *
+ * @param string $name
+ * @throws Sabre_DAV_Exception_NotFound
+ * @return Sabre_DAV_INode
*/
public function getChild($name) {
$path = $this->path . '/' . $name;
- if (!file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located');
+ if (!file_exists($path)) throw new Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
if (is_dir($path)) {
@@ -66,9 +81,9 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
}
/**
- * Returns an array with all the child nodes
- *
- * @return Sabre_DAV_INode[]
+ * Returns an array with all the child nodes
+ *
+ * @return Sabre_DAV_INode[]
*/
public function getChildren() {
@@ -79,10 +94,10 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
}
/**
- * Checks if a child exists.
- *
- * @param string $name
- * @return bool
+ * Checks if a child exists.
+ *
+ * @param string $name
+ * @return bool
*/
public function childExists($name) {
@@ -92,8 +107,8 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
}
/**
- * Deletes all files in this directory, and then itself
- *
+ * Deletes all files in this directory, and then itself
+ *
* @return void
*/
public function delete() {
@@ -104,16 +119,16 @@ class Sabre_DAV_FS_Directory extends Sabre_DAV_FS_Node implements Sabre_DAV_ICol
}
/**
- * Returns available diskspace information
- *
- * @return array
+ * Returns available diskspace information
+ *
+ * @return array
*/
public function getQuotaInfo() {
return array(
disk_total_space($this->path)-disk_free_space($this->path),
disk_free_space($this->path)
- );
+ );
}
diff --git a/3rdparty/Sabre/DAV/FS/File.php b/3rdparty/Sabre/DAV/FS/File.php
index 262187d7e8a..6a8039fe303 100644..100755
--- a/3rdparty/Sabre/DAV/FS/File.php
+++ b/3rdparty/Sabre/DAV/FS/File.php
@@ -1,21 +1,21 @@
<?php
/**
- * File class
- *
+ * File class
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
/**
- * Updates the data
- *
- * @param resource $data
- * @return void
+ * Updates the data
+ *
+ * @param resource $data
+ * @return void
*/
public function put($data) {
@@ -24,9 +24,9 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
}
/**
- * Returns the data
- *
- * @return string
+ * Returns the data
+ *
+ * @return string
*/
public function get() {
@@ -37,7 +37,7 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
/**
* Delete the current file
*
- * @return void
+ * @return void
*/
public function delete() {
@@ -46,12 +46,12 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
}
/**
- * Returns the size of the node, in bytes
- *
- * @return int
+ * Returns the size of the node, in bytes
+ *
+ * @return int
*/
public function getSize() {
-
+
return filesize($this->path);
}
@@ -60,10 +60,10 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
* Returns the ETag for a file
*
* An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
- * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+ * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
*
* Return null if the ETag can not effectively be determined
- *
+ *
* @return mixed
*/
public function getETag() {
@@ -77,8 +77,8 @@ class Sabre_DAV_FS_File extends Sabre_DAV_FS_Node implements Sabre_DAV_IFile {
*
* If null is returned, we'll assume application/octet-stream
*
- * @return mixed
- */
+ * @return mixed
+ */
public function getContentType() {
return null;
diff --git a/3rdparty/Sabre/DAV/FS/Node.php b/3rdparty/Sabre/DAV/FS/Node.php
index b8d7bcfe846..1283e9d0fdc 100644..100755
--- a/3rdparty/Sabre/DAV/FS/Node.php
+++ b/3rdparty/Sabre/DAV/FS/Node.php
@@ -1,30 +1,29 @@
<?php
/**
- * Base node-class
+ * Base node-class
+ *
+ * The node class implements the method used by both the File and the Directory classes
*
- * The node class implements the method used by both the File and the Directory classes
- *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_FS_Node implements Sabre_DAV_INode {
/**
* The path to the current node
- *
- * @var string
+ *
+ * @var string
*/
- protected $path;
+ protected $path;
/**
- * Sets up the node, expects a full path name
- *
- * @param string $path
- * @return void
+ * Sets up the node, expects a full path name
+ *
+ * @param string $path
*/
public function __construct($path) {
@@ -35,9 +34,9 @@ abstract class Sabre_DAV_FS_Node implements Sabre_DAV_INode {
/**
- * Returns the name of the node
- *
- * @return string
+ * Returns the name of the node
+ *
+ * @return string
*/
public function getName() {
@@ -59,7 +58,7 @@ abstract class Sabre_DAV_FS_Node implements Sabre_DAV_INode {
$newPath = $parentPath . '/' . $newName;
rename($this->path,$newPath);
-
+
$this->path = $newPath;
}
@@ -67,9 +66,9 @@ abstract class Sabre_DAV_FS_Node implements Sabre_DAV_INode {
/**
- * Returns the last modification time, as a unix timestamp
- *
- * @return int
+ * Returns the last modification time, as a unix timestamp
+ *
+ * @return int
*/
public function getLastModified() {
diff --git a/3rdparty/Sabre/DAV/FSExt/Directory.php b/3rdparty/Sabre/DAV/FSExt/Directory.php
index c43d4385ac7..540057183b3 100644..100755
--- a/3rdparty/Sabre/DAV/FSExt/Directory.php
+++ b/3rdparty/Sabre/DAV/FSExt/Directory.php
@@ -1,22 +1,39 @@
<?php
/**
- * Directory class
- *
+ * Directory class
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DAV_ICollection, Sabre_DAV_IQuota {
/**
- * Creates a new file in the directory
- *
- * @param string $name Name of the file
- * @param resource $data Initial payload
- * @return void
+ * Creates a new file in the directory
+ *
+ * Data will either be supplied as a stream resource, or in certain cases
+ * as a string. Keep in mind that you may have to support either.
+ *
+ * After succesful creation of the file, you may choose to return the ETag
+ * of the new file here.
+ *
+ * The returned ETag must be surrounded by double-quotes (The quotes should
+ * be part of the actual string).
+ *
+ * If you cannot accurately determine the ETag, you should not return it.
+ * If you don't store the file exactly as-is (you're transforming it
+ * somehow) you should also not return an ETag.
+ *
+ * This means that if a subsequent GET to this new file does not exactly
+ * return the same contents of what was submitted here, you are strongly
+ * recommended to omit the ETag.
+ *
+ * @param string $name Name of the file
+ * @param resource|string $data Initial payload
+ * @return null|string
*/
public function createFile($name, $data = null) {
@@ -25,12 +42,14 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
$newPath = $this->path . '/' . $name;
file_put_contents($newPath,$data);
+ return '"' . md5_file($newPath) . '"';
+
}
/**
- * Creates a new subdirectory
- *
- * @param string $name
+ * Creates a new subdirectory
+ *
+ * @param string $name
* @return void
*/
public function createDirectory($name) {
@@ -43,18 +62,18 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
}
/**
- * Returns a specific child node, referenced by its name
- *
- * @param string $name
- * @throws Sabre_DAV_Exception_FileNotFound
- * @return Sabre_DAV_INode
+ * Returns a specific child node, referenced by its name
+ *
+ * @param string $name
+ * @throws Sabre_DAV_Exception_NotFound
+ * @return Sabre_DAV_INode
*/
public function getChild($name) {
$path = $this->path . '/' . $name;
- if (!file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File could not be located');
- if ($name=='.' || $name=='..') throw new Sabre_DAV_Exception_Forbidden('Permission denied to . and ..');
+ if (!file_exists($path)) throw new Sabre_DAV_Exception_NotFound('File could not be located');
+ if ($name=='.' || $name=='..') throw new Sabre_DAV_Exception_Forbidden('Permission denied to . and ..');
if (is_dir($path)) {
@@ -69,10 +88,10 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
}
/**
- * Checks if a child exists.
- *
- * @param string $name
- * @return bool
+ * Checks if a child exists.
+ *
+ * @param string $name
+ * @return bool
*/
public function childExists($name) {
@@ -85,9 +104,9 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
}
/**
- * Returns an array with all the child nodes
- *
- * @return Sabre_DAV_INode[]
+ * Returns an array with all the child nodes
+ *
+ * @return Sabre_DAV_INode[]
*/
public function getChildren() {
@@ -98,9 +117,9 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
}
/**
- * Deletes all files in this directory, and then itself
- *
- * @return void
+ * Deletes all files in this directory, and then itself
+ *
+ * @return bool
*/
public function delete() {
@@ -118,16 +137,16 @@ class Sabre_DAV_FSExt_Directory extends Sabre_DAV_FSExt_Node implements Sabre_DA
}
/**
- * Returns available diskspace information
- *
- * @return array
+ * Returns available diskspace information
+ *
+ * @return array
*/
public function getQuotaInfo() {
return array(
disk_total_space($this->path)-disk_free_space($this->path),
disk_free_space($this->path)
- );
+ );
}
diff --git a/3rdparty/Sabre/DAV/FSExt/File.php b/3rdparty/Sabre/DAV/FSExt/File.php
index 7a8e7a11f21..b93ce5aee21 100644..100755
--- a/3rdparty/Sabre/DAV/FSExt/File.php
+++ b/3rdparty/Sabre/DAV/FSExt/File.php
@@ -1,34 +1,35 @@
<?php
/**
- * File class
- *
+ * File class
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFile {
/**
- * Updates the data
+ * Updates the data
*
* data is a readable stream resource.
*
- * @param resource $data
- * @return void
+ * @param resource $data
+ * @return void
*/
public function put($data) {
file_put_contents($this->path,$data);
+ return '"' . md5_file($this->path) . '"';
}
/**
* Returns the data
*
- * @return string
+ * @return string
*/
public function get() {
@@ -39,7 +40,7 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
/**
* Delete the current file
*
- * @return void
+ * @return bool
*/
public function delete() {
@@ -52,9 +53,11 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
* Returns the ETag for a file
*
* An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
- * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+ * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
*
* Return null if the ETag can not effectively be determined
+ *
+ * @return string|null
*/
public function getETag() {
@@ -66,7 +69,9 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
* Returns the mime-type for a file
*
* If null is returned, we'll assume application/octet-stream
- */
+ *
+ * @return string|null
+ */
public function getContentType() {
return null;
@@ -74,9 +79,9 @@ class Sabre_DAV_FSExt_File extends Sabre_DAV_FSExt_Node implements Sabre_DAV_IFi
}
/**
- * Returns the size of the file, in bytes
- *
- * @return int
+ * Returns the size of the file, in bytes
+ *
+ * @return int
*/
public function getSize() {
diff --git a/3rdparty/Sabre/DAV/FSExt/Node.php b/3rdparty/Sabre/DAV/FSExt/Node.php
index 9e36222bfd3..68ca06beb7e 100644..100755
--- a/3rdparty/Sabre/DAV/FSExt/Node.php
+++ b/3rdparty/Sabre/DAV/FSExt/Node.php
@@ -1,95 +1,28 @@
<?php
/**
- * Base node-class
+ * Base node-class
+ *
+ * The node class implements the method used by both the File and the Directory classes
*
- * The node class implements the method used by both the File and the Directory classes
- *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_DAV_ILockable, Sabre_DAV_IProperties {
-
- /**
- * Returns all the locks on this node
- *
- * @return array
- */
- function getLocks() {
-
- $resourceData = $this->getResourceData();
- $locks = $resourceData['locks'];
- foreach($locks as $k=>$lock) {
- if (time() > $lock->timeout + $lock->created) unset($locks[$k]);
- }
- return $locks;
-
- }
-
- /**
- * Locks this node
- *
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return void
- */
- function lock(Sabre_DAV_Locks_LockInfo $lockInfo) {
-
- // We're making the lock timeout 30 minutes
- $lockInfo->timeout = 1800;
- $lockInfo->created = time();
-
- $resourceData = $this->getResourceData();
- if (!isset($resourceData['locks'])) $resourceData['locks'] = array();
- $current = null;
- foreach($resourceData['locks'] as $k=>$lock) {
- if ($lock->token === $lockInfo->token) $current = $k;
- }
- if (!is_null($current)) $resourceData['locks'][$current] = $lockInfo;
- else $resourceData['locks'][] = $lockInfo;
-
- $this->putResourceData($resourceData);
-
- }
-
- /**
- * Removes a lock from this node
- *
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
- */
- function unlock(Sabre_DAV_Locks_LockInfo $lockInfo) {
-
- //throw new Sabre_DAV_Exception('bla');
- $resourceData = $this->getResourceData();
- foreach($resourceData['locks'] as $k=>$lock) {
-
- if ($lock->token === $lockInfo->token) {
-
- unset($resourceData['locks'][$k]);
- $this->putResourceData($resourceData);
- return true;
-
- }
- }
- return false;
-
- }
+abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_DAV_IProperties {
/**
* Updates properties on this node,
*
- * @param array $mutations
+ * @param array $properties
* @see Sabre_DAV_IProperties::updateProperties
- * @return bool|array
+ * @return bool|array
*/
public function updateProperties($properties) {
$resourceData = $this->getResourceData();
-
- $result = array();
foreach($properties as $propertyName=>$propertyValue) {
@@ -101,11 +34,11 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
} else {
$resourceData['properties'][$propertyName] = $propertyValue;
}
-
+
}
$this->putResourceData($resourceData);
- return true;
+ return true;
}
/**
@@ -114,8 +47,8 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
* The properties list is a list of propertynames the client requested, encoded as xmlnamespace#tagName, for example: http://www.example.org/namespace#author
* If the array is empty, all properties should be returned
*
- * @param array $properties
- * @return void
+ * @param array $properties
+ * @return array
*/
function getProperties($properties) {
@@ -134,9 +67,9 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
}
/**
- * Returns the path to the resource file
- *
- * @return string
+ * Returns the path to the resource file
+ *
+ * @return string
*/
protected function getResourceInfoPath() {
@@ -146,14 +79,14 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
}
/**
- * Returns all the stored resource information
- *
- * @return array
+ * Returns all the stored resource information
+ *
+ * @return array
*/
protected function getResourceData() {
$path = $this->getResourceInfoPath();
- if (!file_exists($path)) return array('locks'=>array(), 'properties' => array());
+ if (!file_exists($path)) return array('properties' => array());
// opening up the file, and creating a shared lock
$handle = fopen($path,'r');
@@ -171,20 +104,19 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
// Unserializing and checking if the resource file contains data for this file
$data = unserialize($data);
if (!isset($data[$this->getName()])) {
- return array('locks'=>array(), 'properties' => array());
+ return array('properties' => array());
}
$data = $data[$this->getName()];
- if (!isset($data['locks'])) $data['locks'] = array();
if (!isset($data['properties'])) $data['properties'] = array();
return $data;
}
/**
- * Updates the resource information
- *
- * @param array $newData
+ * Updates the resource information
+ *
+ * @param array $newData
* @return void
*/
protected function putResourceData(array $newData) {
@@ -238,6 +170,9 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
}
+ /**
+ * @return bool
+ */
public function deleteResourceData() {
// When we're deleting this node, we also need to delete any resource information
@@ -264,6 +199,7 @@ abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_D
fwrite($handle,serialize($data));
fclose($handle);
+ return true;
}
public function delete() {
diff --git a/3rdparty/Sabre/DAV/File.php b/3rdparty/Sabre/DAV/File.php
index b74bd9525b3..3126bd8d364 100644..100755
--- a/3rdparty/Sabre/DAV/File.php
+++ b/3rdparty/Sabre/DAV/File.php
@@ -4,12 +4,12 @@
* File class
*
* This is a helper class, that should aid in getting file classes setup.
- * Most of its methods are implemented, and throw permission denied exceptions
- *
+ * Most of its methods are implemented, and throw permission denied exceptions
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_File extends Sabre_DAV_Node implements Sabre_DAV_IFile {
@@ -18,33 +18,33 @@ abstract class Sabre_DAV_File extends Sabre_DAV_Node implements Sabre_DAV_IFile
* Updates the data
*
* data is a readable stream resource.
- *
- * @param resource $data
- * @return void
+ *
+ * @param resource $data
+ * @return void
*/
- public function put($data) {
+ public function put($data) {
throw new Sabre_DAV_Exception_Forbidden('Permission denied to change data');
}
/**
- * Returns the data
+ * Returns the data
*
* This method may either return a string or a readable stream resource
*
- * @return mixed
+ * @return mixed
*/
- public function get() {
+ public function get() {
throw new Sabre_DAV_Exception_Forbidden('Permission denied to read this file');
}
-
+
/**
- * Returns the size of the file, in bytes.
- *
- * @return int
+ * Returns the size of the file, in bytes.
+ *
+ * @return int
*/
public function getSize() {
@@ -56,9 +56,11 @@ abstract class Sabre_DAV_File extends Sabre_DAV_Node implements Sabre_DAV_IFile
* Returns the ETag for a file
*
* An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
- * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+ * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
*
* Return null if the ETag can not effectively be determined
+ *
+ * @return string|null
*/
public function getETag() {
@@ -70,7 +72,9 @@ abstract class Sabre_DAV_File extends Sabre_DAV_Node implements Sabre_DAV_IFile
* Returns the mime-type for a file
*
* If null is returned, we'll assume application/octet-stream
- */
+ *
+ * @return string|null
+ */
public function getContentType() {
return null;
diff --git a/3rdparty/Sabre/DAV/ICollection.php b/3rdparty/Sabre/DAV/ICollection.php
index 0667d88899d..4626038a66e 100644..100755
--- a/3rdparty/Sabre/DAV/ICollection.php
+++ b/3rdparty/Sabre/DAV/ICollection.php
@@ -3,54 +3,70 @@
/**
* The ICollection Interface
*
- * This interface should be implemented by each class that represents a collection
- *
+ * This interface should be implemented by each class that represents a collection
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAV_ICollection extends Sabre_DAV_INode {
/**
- * Creates a new file in the directory
- *
- * data is a readable stream resource
+ * Creates a new file in the directory
*
- * @param string $name Name of the file
- * @param resource $data Initial payload
- * @return void
+ * Data will either be supplied as a stream resource, or in certain cases
+ * as a string. Keep in mind that you may have to support either.
+ *
+ * After succesful creation of the file, you may choose to return the ETag
+ * of the new file here.
+ *
+ * The returned ETag must be surrounded by double-quotes (The quotes should
+ * be part of the actual string).
+ *
+ * If you cannot accurately determine the ETag, you should not return it.
+ * If you don't store the file exactly as-is (you're transforming it
+ * somehow) you should also not return an ETag.
+ *
+ * This means that if a subsequent GET to this new file does not exactly
+ * return the same contents of what was submitted here, you are strongly
+ * recommended to omit the ETag.
+ *
+ * @param string $name Name of the file
+ * @param resource|string $data Initial payload
+ * @return null|string
*/
function createFile($name, $data = null);
/**
- * Creates a new subdirectory
- *
- * @param string $name
+ * Creates a new subdirectory
+ *
+ * @param string $name
* @return void
*/
function createDirectory($name);
/**
- * Returns a specific child node, referenced by its name
- *
- * @param string $name
- * @return Sabre_DAV_INode
+ * Returns a specific child node, referenced by its name
+ *
+ * @param string $name
+ * @return Sabre_DAV_INode
*/
function getChild($name);
/**
- * Returns an array with all the child nodes
- *
- * @return Sabre_DAV_INode[]
+ * Returns an array with all the child nodes
+ *
+ * @return Sabre_DAV_INode[]
*/
function getChildren();
/**
- * Checks if a child-node with the specified name exists
- *
- * @return bool
+ * Checks if a child-node with the specified name exists
+ *
+ * @param string $name
+ * @return bool
*/
function childExists($name);
diff --git a/3rdparty/Sabre/DAV/IExtendedCollection.php b/3rdparty/Sabre/DAV/IExtendedCollection.php
index b8db1ab2f26..6ec345f9a62 100644..100755
--- a/3rdparty/Sabre/DAV/IExtendedCollection.php
+++ b/3rdparty/Sabre/DAV/IExtendedCollection.php
@@ -5,11 +5,11 @@
*
* This interface can be used to create special-type of collection-resources
* as defined by RFC 5689.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAV_IExtendedCollection extends Sabre_DAV_ICollection {
@@ -17,7 +17,7 @@ interface Sabre_DAV_IExtendedCollection extends Sabre_DAV_ICollection {
/**
* Creates a new collection
*
- * @param string $name
+ * @param string $name
* @param array $resourceType
* @param array $properties
* @return void
diff --git a/3rdparty/Sabre/DAV/IFile.php b/3rdparty/Sabre/DAV/IFile.php
index 446ec86187b..478f822ae71 100644..100755
--- a/3rdparty/Sabre/DAV/IFile.php
+++ b/3rdparty/Sabre/DAV/IFile.php
@@ -1,34 +1,48 @@
<?php
/**
- * This interface represents a file or leaf in the tree.
+ * This interface represents a file in the directory tree
+ *
+ * A file is a bit of a broad definition. In general it implies that on
+ * this specific node a PUT or GET method may be performed, to either update,
+ * or retrieve the contents of the file.
*
- * The nature of a file is, as you might be aware of, that it doesn't contain sub-nodes and has contents
- *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAV_IFile extends Sabre_DAV_INode {
/**
- * Updates the data
- *
+ * Updates the data
+ *
* The data argument is a readable stream resource.
*
- * @param resource $data
- * @return void
+ * After a succesful put operation, you may choose to return an ETag. The
+ * etag must always be surrounded by double-quotes. These quotes must
+ * appear in the actual string you're returning.
+ *
+ * Clients may use the ETag from a PUT request to later on make sure that
+ * when they update the file, the contents haven't changed in the mean
+ * time.
+ *
+ * If you don't plan to store the file byte-by-byte, and you return a
+ * different object on a subsequent GET you are strongly recommended to not
+ * return an ETag, and just return null.
+ *
+ * @param resource $data
+ * @return string|null
*/
function put($data);
/**
- * Returns the data
- *
+ * Returns the data
+ *
* This method may either return a string or a readable stream resource
*
- * @return mixed
+ * @return mixed
*/
function get();
@@ -36,7 +50,7 @@ interface Sabre_DAV_IFile extends Sabre_DAV_INode {
* Returns the mime-type for a file
*
* If null is returned, we'll assume application/octet-stream
- *
+ *
* @return void
*/
function getContentType();
@@ -47,15 +61,15 @@ interface Sabre_DAV_IFile extends Sabre_DAV_INode {
* An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
*
* Return null if the ETag can not effectively be determined
- *
+ *
* @return void
*/
function getETag();
/**
- * Returns the size of the node, in bytes
- *
- * @return int
+ * Returns the size of the node, in bytes
+ *
+ * @return int
*/
function getSize();
diff --git a/3rdparty/Sabre/DAV/ILockable.php b/3rdparty/Sabre/DAV/ILockable.php
deleted file mode 100644
index f9fb3a70251..00000000000
--- a/3rdparty/Sabre/DAV/ILockable.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
- * Implement this class to support locking
- *
- * @package Sabre
- * @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
- * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
- */
-interface Sabre_DAV_ILockable extends Sabre_DAV_INode {
-
- /**
- * Returns an array with locks currently on the node
- *
- * @return Sabre_DAV_Locks_LockInfo[]
- */
- function getLocks();
-
- /**
- * Creates a new lock on the file.
- *
- * @param Sabre_DAV_Locks_LockInfo $lockInfo The lock information
- * @return void
- */
- function lock(Sabre_DAV_Locks_LockInfo $lockInfo);
-
- /**
- * Unlocks a file
- *
- * @param Sabre_DAV_Locks_LockInfo $lockInfo The lock information
- * @return void
- */
- function unlock(Sabre_DAV_Locks_LockInfo $lockInfo);
-
-}
-
diff --git a/3rdparty/Sabre/DAV/INode.php b/3rdparty/Sabre/DAV/INode.php
index c0b96bf5377..c57d3923105 100644..100755
--- a/3rdparty/Sabre/DAV/INode.php
+++ b/3rdparty/Sabre/DAV/INode.php
@@ -2,11 +2,11 @@
/**
* The INode interface is the base interface, and the parent class of both ICollection and IFile
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAV_INode {
@@ -14,14 +14,16 @@ interface Sabre_DAV_INode {
/**
* Deleted the current node
*
- * @return void
+ * @return void
*/
function delete();
/**
- * Returns the name of the node
- *
- * @return string
+ * Returns the name of the node.
+ *
+ * This is used to generate the url.
+ *
+ * @return string
*/
function getName();
@@ -34,9 +36,9 @@ interface Sabre_DAV_INode {
function setName($name);
/**
- * Returns the last modification time, as a unix timestamp
- *
- * @return int
+ * Returns the last modification time, as a unix timestamp
+ *
+ * @return int
*/
function getLastModified();
diff --git a/3rdparty/Sabre/DAV/IProperties.php b/3rdparty/Sabre/DAV/IProperties.php
index af17cad24af..38eaab16dad 100644..100755
--- a/3rdparty/Sabre/DAV/IProperties.php
+++ b/3rdparty/Sabre/DAV/IProperties.php
@@ -4,11 +4,11 @@
* IProperties interface
*
* Implement this interface to support custom WebDAV properties requested and sent from clients.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAV_IProperties extends Sabre_DAV_INode {
@@ -26,7 +26,7 @@ interface Sabre_DAV_IProperties extends Sabre_DAV_INode {
* If the operation was successful, true can be returned.
* If the operation failed, false can be returned.
*
- * Deletion of a non-existant property is always succesful.
+ * Deletion of a non-existent property is always successful.
*
* Lastly, it is optional to return detailed information about any
* failures. In this case an array should be returned with the following
@@ -41,12 +41,12 @@ interface Sabre_DAV_IProperties extends Sabre_DAV_INode {
* )
* )
*
- * In this example it was forbidden to update {DAV:}displayname.
+ * In this example it was forbidden to update {DAV:}displayname.
* (403 Forbidden), which in turn also caused {DAV:}owner to fail
* (424 Failed Dependency) because the request needs to be atomic.
*
- * @param array $mutations
- * @return bool|array
+ * @param array $mutations
+ * @return bool|array
*/
function updateProperties($mutations);
@@ -58,7 +58,7 @@ interface Sabre_DAV_IProperties extends Sabre_DAV_INode {
*
* If the array is empty, it means 'all properties' were requested.
*
- * @param array $properties
+ * @param array $properties
* @return void
*/
function getProperties($properties);
diff --git a/3rdparty/Sabre/DAV/IQuota.php b/3rdparty/Sabre/DAV/IQuota.php
index 8ff1a4597f8..3fe4c4eced4 100644..100755
--- a/3rdparty/Sabre/DAV/IQuota.php
+++ b/3rdparty/Sabre/DAV/IQuota.php
@@ -4,13 +4,13 @@
* IQuota interface
*
* Implement this interface to add the ability to return quota information. The ObjectTree
- * will check for quota information on any given node. If the information is not available it will
+ * will check for quota information on any given node. If the information is not available it will
* attempt to fetch the information from the root node.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAV_IQuota extends Sabre_DAV_ICollection {
@@ -21,7 +21,7 @@ interface Sabre_DAV_IQuota extends Sabre_DAV_ICollection {
* This method MUST return an array with 2 values, the first being the total used space,
* the second the available space (in bytes)
*/
- function getQuotaInfo();
+ function getQuotaInfo();
}
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
index b09f93ddac7..127e643a2b9 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
@@ -4,45 +4,45 @@
* The Lock manager allows you to handle all file-locks centrally.
*
* This is an alternative approach to doing this on a per-node basis
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_Locks_Backend_Abstract {
/**
- * Returns a list of Sabre_DAV_Locks_LockInfo objects
- *
+ * Returns a list of Sabre_DAV_Locks_LockInfo objects
+ *
* This method should return all the locks for a particular uri, including
* locks that might be set on a parent uri.
*
* If returnChildLocks is set to true, this method should also look for
* any locks in the subtree of the uri for locks.
*
- * @param string $uri
+ * @param string $uri
* @param bool $returnChildLocks
- * @return array
+ * @return array
*/
abstract function getLocks($uri, $returnChildLocks);
/**
- * Locks a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Locks a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
abstract function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo);
/**
- * Removes a lock from a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Removes a lock from a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
abstract function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo);
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/FS.php b/3rdparty/Sabre/DAV/Locks/Backend/FS.php
index 8653f55b1c6..02cab87fc82 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/FS.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/FS.php
@@ -1,28 +1,30 @@
<?php
/**
- * The Lock manager allows you to handle all file-locks centrally.
+ * This Lock Backend stores all its data in the filesystem in separate file per
+ * node.
*
- * This Lock Manager is now deprecated. It has a bug that allows parent
- * collections to be deletes when children deeper in the tree are locked.
+ * This Lock Manager is now deprecated. It has a bug that allows parent
+ * collections to be deletes when children deeper in the tree are locked.
+ *
+ * This also means that using this backend means you will not pass the Neon
+ * Litmus test.
*
* You are recommended to use either the PDO or the File backend instead.
*
- * This Lock Manager stores all its data in the filesystem.
- *
* @package Sabre
* @subpackage DAV
* @deprecated
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
/**
- * The default data directory
- *
- * @var string
+ * The default data directory
+ *
+ * @var string
*/
private $dataDir;
@@ -40,17 +42,17 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
/**
- * Returns a list of Sabre_DAV_Locks_LockInfo objects
- *
+ * Returns a list of Sabre_DAV_Locks_LockInfo objects
+ *
* This method should return all the locks for a particular uri, including
* locks that might be set on a parent uri.
*
* If returnChildLocks is set to true, this method should also look for
* any locks in the subtree of the uri for locks.
*
- * @param string $uri
+ * @param string $uri
* @param bool $returnChildLocks
- * @return array
+ * @return array
*/
public function getLocks($uri, $returnChildLocks) {
@@ -59,15 +61,15 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
foreach(explode('/',$uri) as $uriPart) {
- // weird algorithm that can probably be improved, but we're traversing the path top down
- if ($currentPath) $currentPath.='/';
+ // weird algorithm that can probably be improved, but we're traversing the path top down
+ if ($currentPath) $currentPath.='/';
$currentPath.=$uriPart;
$uriLocks = $this->getData($currentPath);
foreach($uriLocks as $uriLock) {
- // Unless we're on the leaf of the uri-tree we should ingore locks with depth 0
+ // Unless we're on the leaf of the uri-tree we should ignore locks with depth 0
if($uri==$currentPath || $uriLock->depth!=0) {
$uriLock->uri = $currentPath;
$lockList[] = $uriLock;
@@ -79,18 +81,18 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
// Checking if we can remove any of these locks
foreach($lockList as $k=>$lock) {
- if (time() > $lock->timeout + $lock->created) unset($lockList[$k]);
+ if (time() > $lock->timeout + $lock->created) unset($lockList[$k]);
}
return $lockList;
}
/**
- * Locks a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Locks a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
@@ -109,11 +111,11 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
}
/**
- * Removes a lock from a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Removes a lock from a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
@@ -136,7 +138,7 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
* Returns the stored data for a uri
*
* @param string $uri
- * @return array
+ * @return array
*/
protected function getData($uri) {
@@ -167,7 +169,7 @@ class Sabre_DAV_Locks_Backend_FS extends Sabre_DAV_Locks_Backend_Abstract {
* Updates the lock information
*
* @param string $uri
- * @param array $newData
+ * @param array $newData
* @return void
*/
protected function putData($uri,array $newData) {
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/File.php b/3rdparty/Sabre/DAV/Locks/Backend/File.php
index f65b20c4306..c33f963514b 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/File.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/File.php
@@ -3,30 +3,30 @@
/**
* The Lock manager allows you to handle all file-locks centrally.
*
- * This Lock Manager stores all its data in a single file.
+ * This Lock Manager stores all its data in a single file.
*
* Note that this is not nearly as robust as a database, you are encouraged
* to use the PDO backend instead.
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
/**
* The storage file
- *
- * @var string
+ *
+ * @var string
*/
private $locksFile;
/**
* Constructor
*
- * @param string $locksFile path to file
+ * @param string $locksFile path to file
*/
public function __construct($locksFile) {
@@ -35,24 +35,24 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
}
/**
- * Returns a list of Sabre_DAV_Locks_LockInfo objects
- *
+ * Returns a list of Sabre_DAV_Locks_LockInfo objects
+ *
* This method should return all the locks for a particular uri, including
* locks that might be set on a parent uri.
*
* If returnChildLocks is set to true, this method should also look for
* any locks in the subtree of the uri for locks.
*
- * @param string $uri
+ * @param string $uri
* @param bool $returnChildLocks
- * @return array
+ * @return array
*/
public function getLocks($uri, $returnChildLocks) {
$newLocks = array();
- $currentPath = '';
$locks = $this->getData();
+
foreach($locks as $lock) {
if ($lock->uri === $uri ||
@@ -70,29 +70,35 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
// Checking if we can remove any of these locks
foreach($newLocks as $k=>$lock) {
- if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]);
+ if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]);
}
return $newLocks;
}
/**
- * Locks a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Locks a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
- public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
+ public function lock($uri, Sabre_DAV_Locks_LockInfo $lockInfo) {
// We're making the lock timeout 30 minutes
$lockInfo->timeout = 1800;
$lockInfo->created = time();
$lockInfo->uri = $uri;
- $locks = $this->getLocks($uri,false);
+ $locks = $this->getData();
+
foreach($locks as $k=>$lock) {
- if ($lock->token == $lockInfo->token) unset($locks[$k]);
+ if (
+ ($lock->token == $lockInfo->token) ||
+ (time() > $lock->timeout + $lock->created)
+ ) {
+ unset($locks[$k]);
+ }
}
$locks[] = $lockInfo;
$this->putData($locks);
@@ -101,15 +107,15 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
}
/**
- * Removes a lock from a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Removes a lock from a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
- public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
+ public function unlock($uri, Sabre_DAV_Locks_LockInfo $lockInfo) {
- $locks = $this->getLocks($uri,false);
+ $locks = $this->getData();
foreach($locks as $k=>$lock) {
if ($lock->token == $lockInfo->token) {
@@ -127,7 +133,7 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
/**
* Loads the lockdata from the filesystem.
*
- * @return array
+ * @return array
*/
protected function getData() {
@@ -153,7 +159,7 @@ class Sabre_DAV_Locks_Backend_File extends Sabre_DAV_Locks_Backend_Abstract {
/**
* Saves the lockdata
*
- * @param array $newData
+ * @param array $newData
* @return void
*/
protected function putData(array $newData) {
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
index c3923af19d3..acce80638ec 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
@@ -5,34 +5,34 @@
*
* This Lock Manager stores all its data in a database. You must pass a PDO
* connection object in the constructor.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
/**
- * The PDO connection object
- *
- * @var pdo
+ * The PDO connection object
+ *
+ * @var pdo
*/
private $pdo;
/**
- * The PDO tablename this backend uses.
- *
+ * The PDO tablename this backend uses.
+ *
* @var string
*/
protected $tableName;
/**
- * Constructor
- *
+ * Constructor
+ *
* @param PDO $pdo
- * @param string $tableName
+ * @param string $tableName
*/
public function __construct(PDO $pdo, $tableName = 'locks') {
@@ -42,24 +42,24 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
}
/**
- * Returns a list of Sabre_DAV_Locks_LockInfo objects
- *
+ * Returns a list of Sabre_DAV_Locks_LockInfo objects
+ *
* This method should return all the locks for a particular uri, including
* locks that might be set on a parent uri.
*
* If returnChildLocks is set to true, this method should also look for
* any locks in the subtree of the uri for locks.
*
- * @param string $uri
+ * @param string $uri
* @param bool $returnChildLocks
- * @return array
+ * @return array
*/
public function getLocks($uri, $returnChildLocks) {
- // NOTE: the following 10 lines or so could be easily replaced by
- // pure sql. MySQL's non-standard string concatination prevents us
+ // NOTE: the following 10 lines or so could be easily replaced by
+ // pure sql. MySQL's non-standard string concatenation prevents us
// from doing this though.
- $query = 'SELECT owner, token, timeout, created, scope, depth, uri FROM `'.$this->tableName.'` WHERE ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)';
+ $query = 'SELECT owner, token, timeout, created, scope, depth, uri FROM '.$this->tableName.' WHERE ((created + timeout) > CAST(? AS UNSIGNED INTEGER)) AND ((uri = ?)';
$params = array(time(),$uri);
// We need to check locks for every part in the uri.
@@ -112,11 +112,11 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
}
/**
- * Locks a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Locks a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
public function lock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
@@ -127,15 +127,15 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
$locks = $this->getLocks($uri,false);
$exists = false;
- foreach($locks as $k=>$lock) {
+ foreach($locks as $lock) {
if ($lock->token == $lockInfo->token) $exists = true;
}
-
+
if ($exists) {
- $stmt = $this->pdo->prepare('UPDATE `'.$this->tableName.'` SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?');
+ $stmt = $this->pdo->prepare('UPDATE '.$this->tableName.' SET owner = ?, timeout = ?, scope = ?, depth = ?, uri = ?, created = ? WHERE token = ?');
$stmt->execute(array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token));
} else {
- $stmt = $this->pdo->prepare('INSERT INTO `'.$this->tableName.'` (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)');
+ $stmt = $this->pdo->prepare('INSERT INTO '.$this->tableName.' (owner,timeout,scope,depth,uri,created,token) VALUES (?,?,?,?,?,?,?)');
$stmt->execute(array($lockInfo->owner,$lockInfo->timeout,$lockInfo->scope,$lockInfo->depth,$uri,$lockInfo->created,$lockInfo->token));
}
@@ -146,15 +146,15 @@ class Sabre_DAV_Locks_Backend_PDO extends Sabre_DAV_Locks_Backend_Abstract {
/**
- * Removes a lock from a uri
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return bool
+ * Removes a lock from a uri
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
public function unlock($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
- $stmt = $this->pdo->prepare('DELETE FROM `'.$this->tableName.'` WHERE uri = ? AND token = ?');
+ $stmt = $this->pdo->prepare('DELETE FROM '.$this->tableName.' WHERE uri = ? AND token = ?');
$stmt->execute(array($uri,$lockInfo->token));
return $stmt->rowCount()===1;
diff --git a/3rdparty/Sabre/DAV/Locks/LockInfo.php b/3rdparty/Sabre/DAV/Locks/LockInfo.php
index 6a064466f40..9df014a4281 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/LockInfo.php
+++ b/3rdparty/Sabre/DAV/Locks/LockInfo.php
@@ -5,11 +5,11 @@
*
* An object of the LockInfo class holds all the information relevant to a
* single lock.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Locks_LockInfo {
@@ -30,37 +30,37 @@ class Sabre_DAV_Locks_LockInfo {
const TIMEOUT_INFINITE = -1;
/**
- * The owner of the lock
- *
- * @var string
+ * The owner of the lock
+ *
+ * @var string
*/
public $owner;
/**
- * The locktoken
- *
- * @var string
+ * The locktoken
+ *
+ * @var string
*/
public $token;
/**
- * How long till the lock is expiring
- *
- * @var int
+ * How long till the lock is expiring
+ *
+ * @var int
*/
public $timeout;
/**
- * UNIX Timestamp of when this lock was created
- *
- * @var int
+ * UNIX Timestamp of when this lock was created
+ *
+ * @var int
*/
public $created;
/**
- * Exclusive or shared lock
- *
- * @var int
+ * Exclusive or shared lock
+ *
+ * @var int
*/
public $scope = self::EXCLUSIVE;
@@ -72,7 +72,7 @@ class Sabre_DAV_Locks_LockInfo {
/**
* The uri this lock locks
*
- * TODO: This value is not always set
+ * TODO: This value is not always set
* @var mixed
*/
public $uri;
diff --git a/3rdparty/Sabre/DAV/Locks/Plugin.php b/3rdparty/Sabre/DAV/Locks/Plugin.php
index 461e2847e0a..fd956950b8a 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Plugin.php
+++ b/3rdparty/Sabre/DAV/Locks/Plugin.php
@@ -9,38 +9,37 @@
* $lockBackend = new Sabre_DAV_Locks_Backend_File('./mylockdb');
* $lockPlugin = new Sabre_DAV_Locks_Plugin($lockBackend);
* $server->addPlugin($lockPlugin);
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
/**
- * locksBackend
- *
- * @var Sabre_DAV_Locks_Backend_Abstract
+ * locksBackend
+ *
+ * @var Sabre_DAV_Locks_Backend_Abstract
*/
private $locksBackend;
/**
* server
- *
- * @var Sabre_DAV_Server
+ *
+ * @var Sabre_DAV_Server
*/
private $server;
/**
- * __construct
- *
- * @param Sabre_DAV_Locks_Backend_Abstract $locksBackend
- * @return void
+ * __construct
+ *
+ * @param Sabre_DAV_Locks_Backend_Abstract $locksBackend
*/
public function __construct(Sabre_DAV_Locks_Backend_Abstract $locksBackend = null) {
- $this->locksBackend = $locksBackend;
+ $this->locksBackend = $locksBackend;
}
@@ -48,8 +47,8 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
* Initializes the plugin
*
* This method is automatically called by the Server class after addPlugin.
- *
- * @param Sabre_DAV_Server $server
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -63,11 +62,11 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Returns a plugin name.
- *
+ *
* Using this name other plugins will be able to access other plugins
- * using Sabre_DAV_Server::getPlugin
- *
- * @return string
+ * using Sabre_DAV_Server::getPlugin
+ *
+ * @return string
*/
public function getPluginName() {
@@ -76,20 +75,21 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * This method is called by the Server if the user used an HTTP method
+ * This method is called by the Server if the user used an HTTP method
* the server didn't recognize.
*
* This plugin intercepts the LOCK and UNLOCK methods.
- *
- * @param string $method
- * @return bool
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
*/
public function unknownMethod($method, $uri) {
- switch($method) {
+ switch($method) {
- case 'LOCK' : $this->httpLock($uri); return false;
- case 'UNLOCK' : $this->httpUnlock($uri); return false;
+ case 'LOCK' : $this->httpLock($uri); return false;
+ case 'UNLOCK' : $this->httpUnlock($uri); return false;
}
@@ -98,26 +98,20 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
/**
* This method is called after most properties have been found
* it allows us to add in any Lock-related properties
- *
- * @param string $path
- * @param array $properties
- * @return bool
+ *
+ * @param string $path
+ * @param array $newProperties
+ * @return bool
*/
- public function afterGetProperties($path,&$newProperties) {
+ public function afterGetProperties($path, &$newProperties) {
foreach($newProperties[404] as $propName=>$discard) {
- $node = null;
-
switch($propName) {
case '{DAV:}supportedlock' :
$val = false;
if ($this->locksBackend) $val = true;
- else {
- if (!$node) $node = $this->server->tree->getNodeForPath($path);
- if ($node instanceof Sabre_DAV_ILockable) $val = true;
- }
$newProperties[200][$propName] = new Sabre_DAV_Property_SupportedLock($val);
unset($newProperties[404][$propName]);
break;
@@ -141,10 +135,10 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
* handled.
*
* This plugin uses that feature to intercept access to locked resources.
- *
+ *
* @param string $method
* @param string $uri
- * @return bool
+ * @return bool
*/
public function beforeMethod($method, $uri) {
@@ -187,18 +181,17 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
* Use this method to tell the server this plugin defines additional
* HTTP methods.
*
- * This method is passed a uri. It should only return HTTP methods that are
+ * This method is passed a uri. It should only return HTTP methods that are
* available for the specified uri.
*
* @param string $uri
- * @return array
+ * @return array
*/
public function getHTTPMethods($uri) {
- if ($this->locksBackend ||
- $this->server->tree->getNodeForPath($uri) instanceof Sabre_DAV_ILocks) {
+ if ($this->locksBackend)
return array('LOCK','UNLOCK');
- }
+
return array();
}
@@ -208,8 +201,8 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
*
* In this case this is only the number 2. The 2 in the Dav: header
* indicates the server supports locks.
- *
- * @return array
+ *
+ * @return array
*/
public function getFeatures() {
@@ -218,49 +211,23 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Returns all lock information on a particular uri
- *
+ * Returns all lock information on a particular uri
+ *
* This function should return an array with Sabre_DAV_Locks_LockInfo objects. If there are no locks on a file, return an empty array.
*
- * Additionally there is also the possibility of locks on parent nodes, so we'll need to traverse every part of the tree
+ * Additionally there is also the possibility of locks on parent nodes, so we'll need to traverse every part of the tree
* If the $returnChildLocks argument is set to true, we'll also traverse all the children of the object
* for any possible locks and return those as well.
*
- * @param string $uri
+ * @param string $uri
* @param bool $returnChildLocks
- * @return array
+ * @return array
*/
public function getLocks($uri, $returnChildLocks = false) {
$lockList = array();
- $currentPath = '';
- foreach(explode('/',$uri) as $uriPart) {
- $uriLocks = array();
- if ($currentPath) $currentPath.='/';
- $currentPath.=$uriPart;
-
- try {
-
- $node = $this->server->tree->getNodeForPath($currentPath);
- if ($node instanceof Sabre_DAV_ILockable) $uriLocks = $node->getLocks();
-
- } catch (Sabre_DAV_Exception_FileNotFound $e){
- // In case the node didn't exist, this could be a lock-null request
- }
-
- foreach($uriLocks as $uriLock) {
-
- // Unless we're on the leaf of the uri-tree we should ignore locks with depth 0
- if($uri==$currentPath || $uriLock->depth!=0) {
- $uriLock->uri = $currentPath;
- $lockList[] = $uriLock;
- }
-
- }
-
- }
- if ($this->locksBackend)
+ if ($this->locksBackend)
$lockList = array_merge($lockList,$this->locksBackend->getLocks($uri, $returnChildLocks));
return $lockList;
@@ -271,13 +238,13 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
* Locks an uri
*
* The WebDAV lock request can be operated to either create a new lock on a file, or to refresh an existing lock
- * If a new lock is created, a full XML body should be supplied, containing information about the lock such as the type
+ * If a new lock is created, a full XML body should be supplied, containing information about the lock such as the type
* of lock (shared or exclusive) and the owner of the lock
*
* If a lock is to be refreshed, no body should be supplied and there should be a valid If header containing the lock
*
- * Additionally, a lock can be requested for a non-existant file. In these case we're obligated to create an empty file as per RFC4918:S7.3
- *
+ * Additionally, a lock can be requested for a non-existent file. In these case we're obligated to create an empty file as per RFC4918:S7.3
+ *
* @param string $uri
* @return void
*/
@@ -297,7 +264,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
if ($body = $this->server->httpRequest->getBody(true)) {
// This is a new lock request
$lockInfo = $this->parseLockRequest($body);
- $lockInfo->depth = $this->server->getHTTPDepth();
+ $lockInfo->depth = $this->server->getHTTPDepth();
$lockInfo->uri = $uri;
if($lastLock && $lockInfo->scope != Sabre_DAV_Locks_LockInfo::SHARED) throw new Sabre_DAV_Exception_ConflictingLock($lastLock);
@@ -306,11 +273,11 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
// This must have been a lock refresh
$lockInfo = $lastLock;
- // The resource could have been locked through another uri.
+ // The resource could have been locked through another uri.
if ($uri!=$lockInfo->uri) $uri = $lockInfo->uri;
} else {
-
+
// There was neither a lock refresh nor a new lock request
throw new Sabre_DAV_Exception_BadRequest('An xml body is required for lock requests');
@@ -322,16 +289,16 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
// If we got this far.. we should go check if this node actually exists. If this is not the case, we need to create it first
try {
- $node = $this->server->tree->getNodeForPath($uri);
-
+ $this->server->tree->getNodeForPath($uri);
+
// We need to call the beforeWriteContent event for RFC3744
$this->server->broadcastEvent('beforeWriteContent',array($uri));
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
-
+ } catch (Sabre_DAV_Exception_NotFound $e) {
+
// It didn't, lets create it
- $this->server->createFile($uri,fopen('php://memory','r'));
- $newFile = true;
+ $this->server->createFile($uri,fopen('php://memory','r'));
+ $newFile = true;
}
@@ -362,7 +329,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
$locks = $this->getLocks($uri);
- // Windows sometimes forgets to include < and > in the Lock-Token
+ // Windows sometimes forgets to include < and > in the Lock-Token
// header
if ($lockToken[0]!=='<') $lockToken = '<' . $lockToken . '>';
@@ -370,7 +337,6 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
if ('<opaquelocktoken:' . $lock->token . '>' == $lockToken) {
- $this->server->broadcastEvent('beforeUnlock',array($uri, $lock));
$this->unlockNode($uri,$lock);
$this->server->httpResponse->setHeader('Content-Length','0');
$this->server->httpResponse->sendStatus(204);
@@ -390,21 +356,15 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
*
* All the locking information is supplied in the lockInfo object. The object has a suggested timeout, but this can be safely ignored
* It is important that if the existing timeout is ignored, the property is overwritten, as this needs to be sent back to the client
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return void
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
public function lockNode($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
if (!$this->server->broadcastEvent('beforeLock',array($uri,$lockInfo))) return;
- try {
- $node = $this->server->tree->getNodeForPath($uri);
- if ($node instanceof Sabre_DAV_ILockable) return $node->lock($lockInfo);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
- // In case the node didn't exist, this could be a lock-null request
- }
if ($this->locksBackend) return $this->locksBackend->lock($uri,$lockInfo);
throw new Sabre_DAV_Exception_MethodNotAllowed('Locking support is not enabled for this resource. No Locking backend was found so if you didn\'t expect this error, please check your configuration.');
@@ -414,29 +374,22 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
* Unlocks a uri
*
* This method removes a lock from a uri. It is assumed all the supplied information is correct and verified
- *
- * @param string $uri
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return void
+ *
+ * @param string $uri
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return bool
*/
public function unlockNode($uri,Sabre_DAV_Locks_LockInfo $lockInfo) {
if (!$this->server->broadcastEvent('beforeUnlock',array($uri,$lockInfo))) return;
- try {
- $node = $this->server->tree->getNodeForPath($uri);
- if ($node instanceof Sabre_DAV_ILockable) return $node->unlock($lockInfo);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
- // In case the node didn't exist, this could be a lock-null request
- }
-
if ($this->locksBackend) return $this->locksBackend->unlock($uri,$lockInfo);
}
/**
- * Returns the contents of the HTTP Timeout header.
- *
+ * Returns the contents of the HTTP Timeout header.
+ *
* The method formats the header into an integer.
*
* @return int
@@ -444,7 +397,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
public function getTimeoutHeader() {
$header = $this->server->httpRequest->getHeader('Timeout');
-
+
if ($header) {
if (stripos($header,'second-')===0) $header = (int)(substr($header,7));
@@ -462,16 +415,16 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Generates the response for successfull LOCK requests
- *
- * @param Sabre_DAV_Locks_LockInfo $lockInfo
- * @return string
+ * Generates the response for successful LOCK requests
+ *
+ * @param Sabre_DAV_Locks_LockInfo $lockInfo
+ * @return string
*/
protected function generateLockResponse(Sabre_DAV_Locks_LockInfo $lockInfo) {
$dom = new DOMDocument('1.0','utf-8');
$dom->formatOutput = true;
-
+
$prop = $dom->createElementNS('DAV:','d:prop');
$dom->appendChild($prop);
@@ -484,10 +437,10 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
return $dom->saveXML();
}
-
+
/**
* validateLock should be called when a write operation is about to happen
- * It will check if the requested url is locked, and see if the correct lock tokens are passed
+ * It will check if the requested url is locked, and see if the correct lock tokens are passed
*
* @param mixed $urls List of relevant urls. Can be an array, a string or nothing at all for the current request uri
* @param mixed $lastLock This variable will be populated with the last checked lock object (Sabre_DAV_Locks_LockInfo)
@@ -511,13 +464,13 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
$locks = $this->getLocks($url, $checkChildLocks);
- // If there were no conditions, but there were locks, we fail
+ // If there were no conditions, but there were locks, we fail
if (!$conditions && $locks) {
reset($locks);
$lastLock = current($locks);
return false;
}
-
+
// If there were no locks or conditions, we go to the next url
if (!$locks && !$conditions) continue;
@@ -542,7 +495,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
// key 2 can contain an etag
if ($conditionToken[2]) {
- $uri = $conditionUri?$conditionUri:$this->server->getRequestUri();
+ $uri = $conditionUri?$conditionUri:$this->server->getRequestUri();
$node = $this->server->tree->getNodeForPath($uri);
$etagValid = $node->getETag()==$conditionToken[2];
@@ -609,23 +562,23 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
* This method is created to extract information from the WebDAV HTTP 'If:' header
*
* The If header can be quite complex, and has a bunch of features. We're using a regex to extract all relevant information
- * The function will return an array, containg structs with the following keys
+ * The function will return an array, containing structs with the following keys
*
- * * uri - the uri the condition applies to. If this is returned as an
+ * * uri - the uri the condition applies to. If this is returned as an
* empty string, this implies it's referring to the request url.
- * * tokens - The lock token. another 2 dimensional array containg 2 elements (0 = true/false.. If this is a negative condition its set to false, 1 = the actual token)
+ * * tokens - The lock token. another 2 dimensional array containing 2 elements (0 = true/false.. If this is a negative condition its set to false, 1 = the actual token)
* * etag - an etag, if supplied
- *
- * @return void
+ *
+ * @return array
*/
public function getIfConditions() {
- $header = $this->server->httpRequest->getHeader('If');
+ $header = $this->server->httpRequest->getHeader('If');
if (!$header) return array();
$matches = array();
- $regex = '/(?:\<(?P<uri>.*?)\>\s)?\((?P<not>Not\s)?(?:\<(?P<token>[^\>]*)\>)?(?:\s?)(?:\[(?P<etag>[^\]]*)\])?\)/im';
+ $regex = '/(?:\<(?P<uri>.*?)\>\s)?\((?P<not>Not\s)?(?:\<(?P<token>[^\>]*)\>)?(?:\s?)(?:\[(?P<etag>[^\]]*)\])?\)/im';
preg_match_all($regex,$header,$matches,PREG_SET_ORDER);
$conditions = array();
@@ -636,7 +589,7 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
'uri' => $match['uri'],
'tokens' => array(
array($match['not']?0:1,$match['token'],isset($match['etag'])?$match['etag']:'')
- ),
+ ),
);
if (!$condition['uri'] && count($conditions)) $conditions[count($conditions)-1]['tokens'][] = array(
@@ -655,9 +608,9 @@ class Sabre_DAV_Locks_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Parses a webdav lock xml body, and returns a new Sabre_DAV_Locks_LockInfo object
- *
- * @param string $body
+ * Parses a webdav lock xml body, and returns a new Sabre_DAV_Locks_LockInfo object
+ *
+ * @param string $body
* @return Sabre_DAV_Locks_LockInfo
*/
protected function parseLockRequest($body) {
diff --git a/3rdparty/Sabre/DAV/Mount/Plugin.php b/3rdparty/Sabre/DAV/Mount/Plugin.php
index f93a1aa25a1..b37a90ae993 100644..100755
--- a/3rdparty/Sabre/DAV/Mount/Plugin.php
+++ b/3rdparty/Sabre/DAV/Mount/Plugin.php
@@ -4,25 +4,25 @@
* This plugin provides support for RFC4709: Mounting WebDAV servers
*
* Simply append ?mount to any collection to generate the davmount response.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
*/
class Sabre_DAV_Mount_Plugin extends Sabre_DAV_ServerPlugin {
/**
- * Reference to Server class
- *
- * @var Sabre_DAV_Server
+ * Reference to Server class
+ *
+ * @var Sabre_DAV_Server
*/
private $server;
/**
- * Initializes the plugin and registers event handles
- *
- * @param Sabre_DAV_Server $server
+ * Initializes the plugin and registers event handles
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -35,9 +35,10 @@ class Sabre_DAV_Mount_Plugin extends Sabre_DAV_ServerPlugin {
/**
* 'beforeMethod' event handles. This event handles intercepts GET requests ending
* with ?mount
- *
- * @param string $method
- * @return void
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
*/
public function beforeMethod($method, $uri) {
@@ -57,13 +58,13 @@ class Sabre_DAV_Mount_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Generates the davmount response
- *
- * @param string $uri absolute uri
+ * Generates the davmount response
+ *
+ * @param string $uri absolute uri
* @return void
*/
public function davMount($uri) {
-
+
$this->server->httpResponse->sendStatus(200);
$this->server->httpResponse->setHeader('Content-Type','application/davmount+xml');
ob_start();
diff --git a/3rdparty/Sabre/DAV/Node.php b/3rdparty/Sabre/DAV/Node.php
index 0510df5fdf2..070b7176afd 100644..100755
--- a/3rdparty/Sabre/DAV/Node.php
+++ b/3rdparty/Sabre/DAV/Node.php
@@ -3,22 +3,22 @@
/**
* Node class
*
- * This is a helper class, that should aid in getting nodes setup.
- *
+ * This is a helper class, that should aid in getting nodes setup.
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_Node implements Sabre_DAV_INode {
/**
- * Returns the last modification time
+ * Returns the last modification time
*
* In this case, it will simply return the current time
*
- * @return int
+ * @return int
*/
public function getLastModified() {
@@ -30,7 +30,7 @@ abstract class Sabre_DAV_Node implements Sabre_DAV_INode {
* Deleted the current node
*
* @throws Sabre_DAV_Exception_Forbidden
- * @return void
+ * @return void
*/
public function delete() {
@@ -40,7 +40,7 @@ abstract class Sabre_DAV_Node implements Sabre_DAV_INode {
/**
* Renames the node
- *
+ *
* @throws Sabre_DAV_Exception_Forbidden
* @param string $name The new name
* @return void
diff --git a/3rdparty/Sabre/DAV/ObjectTree.php b/3rdparty/Sabre/DAV/ObjectTree.php
index f12a3683705..bce51463900 100644..100755
--- a/3rdparty/Sabre/DAV/ObjectTree.php
+++ b/3rdparty/Sabre/DAV/ObjectTree.php
@@ -3,27 +3,27 @@
/**
* ObjectTree class
*
- * This implementation of the Tree class makes use of the INode, IFile and ICollection API's
- *
+ * This implementation of the Tree class makes use of the INode, IFile and ICollection API's
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
/**
- * The root node
- *
+ * The root node
+ *
* @var Sabre_DAV_ICollection
*/
protected $rootNode;
/**
- * This is the node cache. Accessed nodes are stored here
- *
- * @var array
+ * This is the node cache. Accessed nodes are stored here
+ *
+ * @var array
*/
protected $cache = array();
@@ -31,9 +31,8 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
* Creates the object
*
* This method expects the rootObject to be passed as a parameter
- *
- * @param Sabre_DAV_ICollection $rootNode
- * @return void
+ *
+ * @param Sabre_DAV_ICollection $rootNode
*/
public function __construct(Sabre_DAV_ICollection $rootNode) {
@@ -42,10 +41,10 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
}
/**
- * Returns the INode object for the requested path
- *
- * @param string $path
- * @return Sabre_DAV_INode
+ * Returns the INode object for the requested path
+ *
+ * @param string $path
+ * @return Sabre_DAV_INode
*/
public function getNodeForPath($path) {
@@ -54,17 +53,17 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
//if (!$path || $path=='.') return $this->rootNode;
$currentNode = $this->rootNode;
- $i=0;
- // We're splitting up the path variable into folder/subfolder components and traverse to the correct node..
+
+ // We're splitting up the path variable into folder/subfolder components and traverse to the correct node..
foreach(explode('/',$path) as $pathPart) {
// If this part of the path is just a dot, it actually means we can skip it
if ($pathPart=='.' || $pathPart=='') continue;
if (!($currentNode instanceof Sabre_DAV_ICollection))
- throw new Sabre_DAV_Exception_FileNotFound('Could not find node at path: ' . $path);
+ throw new Sabre_DAV_Exception_NotFound('Could not find node at path: ' . $path);
- $currentNode = $currentNode->getChild($pathPart);
+ $currentNode = $currentNode->getChild($pathPart);
}
@@ -76,8 +75,8 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
/**
* This function allows you to check if a node exists.
*
- * @param string $path
- * @return bool
+ * @param string $path
+ * @return bool
*/
public function nodeExists($path) {
@@ -92,7 +91,7 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
if (!$parentNode instanceof Sabre_DAV_ICollection) return false;
return $parentNode->childExists($base);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
return false;
@@ -101,10 +100,10 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
}
/**
- * Returns a list of childnodes for a given path.
- *
- * @param string $path
- * @return array
+ * Returns a list of childnodes for a given path.
+ *
+ * @param string $path
+ * @return array
*/
public function getChildren($path) {
@@ -127,14 +126,14 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
* * node creations
* * copy
* * move
- * * renaming nodes
- *
+ * * renaming nodes
+ *
* If Tree classes implement a form of caching, this will allow
* them to make sure caches will be expired.
- *
+ *
* If a path is passed, it is assumed that the entire subtree is dirty
*
- * @param string $path
+ * @param string $path
* @return void
*/
public function markDirty($path) {
@@ -145,7 +144,7 @@ class Sabre_DAV_ObjectTree extends Sabre_DAV_Tree {
foreach($this->cache as $nodePath=>$node) {
if ($nodePath == $path || strpos($nodePath,$path.'/')===0)
unset($this->cache[$nodePath]);
-
+
}
}
diff --git a/3rdparty/Sabre/DAV/Property.php b/3rdparty/Sabre/DAV/Property.php
index 577535b0127..1cfada3236c 100644..100755
--- a/3rdparty/Sabre/DAV/Property.php
+++ b/3rdparty/Sabre/DAV/Property.php
@@ -4,16 +4,16 @@
* Abstract property class
*
* Extend this class to create custom complex properties
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_Property {
- abstract function serialize(Sabre_DAV_Server $server, DOMElement $prop);
+ abstract function serialize(Sabre_DAV_Server $server, DOMElement $prop);
static function unserialize(DOMElement $prop) {
diff --git a/3rdparty/Sabre/DAV/Property/GetLastModified.php b/3rdparty/Sabre/DAV/Property/GetLastModified.php
index 4a812629971..bd63f573140 100644..100755
--- a/3rdparty/Sabre/DAV/Property/GetLastModified.php
+++ b/3rdparty/Sabre/DAV/Property/GetLastModified.php
@@ -2,33 +2,32 @@
/**
* This property represents the {DAV:}getlastmodified property.
- *
+ *
* Although this is normally a simple property, windows requires us to add
* some new attributes.
*
- * This class uses unix timestamps internally, and converts them to RFC 1123 times for
+ * This class uses unix timestamps internally, and converts them to RFC 1123 times for
* serialization
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_GetLastModified extends Sabre_DAV_Property {
/**
- * time
- *
- * @var int
+ * time
+ *
+ * @var int
*/
public $time;
/**
- * __construct
- *
- * @param int|DateTime $time
- * @return void
+ * __construct
+ *
+ * @param int|DateTime $time
*/
public function __construct($time) {
@@ -46,9 +45,10 @@ class Sabre_DAV_Property_GetLastModified extends Sabre_DAV_Property {
}
/**
- * serialize
- *
- * @param DOMElement $prop
+ * serialize
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $prop
* @return void
*/
public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
@@ -56,14 +56,14 @@ class Sabre_DAV_Property_GetLastModified extends Sabre_DAV_Property {
$doc = $prop->ownerDocument;
$prop->setAttribute('xmlns:b','urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/');
$prop->setAttribute('b:dt','dateTime.rfc1123');
- $prop->nodeValue = $this->time->format(DateTime::RFC1123);
+ $prop->nodeValue = Sabre_HTTP_Util::toHTTPDate($this->time);
}
/**
- * getTime
- *
- * @return DateTime
+ * getTime
+ *
+ * @return DateTime
*/
public function getTime() {
diff --git a/3rdparty/Sabre/DAV/Property/Href.php b/3rdparty/Sabre/DAV/Property/Href.php
index 3294ff2ac68..dac564f24d7 100644..100755
--- a/3rdparty/Sabre/DAV/Property/Href.php
+++ b/3rdparty/Sabre/DAV/Property/Href.php
@@ -3,36 +3,36 @@
/**
* Href property
*
- * The href property represpents a url within a {DAV:}href element.
+ * The href property represents a url within a {DAV:}href element.
* This is used by many WebDAV extensions, but not really within the WebDAV core spec
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
/**
- * href
- *
- * @var string
+ * href
+ *
+ * @var string
*/
private $href;
/**
- * Automatically prefix the url with the server base directory
- *
- * @var bool
+ * Automatically prefix the url with the server base directory
+ *
+ * @var bool
*/
private $autoPrefix = true;
/**
- * __construct
- *
- * @param string $href
- * @return void
+ * __construct
+ *
+ * @param string $href
+ * @param bool $autoPrefix
*/
public function __construct($href, $autoPrefix = true) {
@@ -42,9 +42,9 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
}
/**
- * Returns the uri
- *
- * @return string
+ * Returns the uri
+ *
+ * @return string
*/
public function getHref() {
@@ -56,12 +56,12 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
* Serializes this property.
*
* It will additionally prepend the href property with the server's base uri.
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $dom
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $dom
* @return void
*/
- public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
+ public function serialize(Sabre_DAV_Server $server, DOMElement $dom) {
$prefix = $server->xmlNamespaces['DAV:'];
@@ -72,13 +72,13 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
}
/**
- * Unserializes this property from a DOM Element
+ * Unserializes this property from a DOM Element
*
* This method returns an instance of this class.
* It will only decode {DAV:}href values. For non-compatible elements null will be returned.
*
- * @param DOMElement $dom
- * @return Sabre_DAV_Property_Href
+ * @param DOMElement $dom
+ * @return Sabre_DAV_Property_Href
*/
static function unserialize(DOMElement $dom) {
@@ -86,6 +86,6 @@ class Sabre_DAV_Property_Href extends Sabre_DAV_Property implements Sabre_DAV_Pr
return new self($dom->firstChild->textContent,false);
}
- }
+ }
}
diff --git a/3rdparty/Sabre/DAV/Property/HrefList.php b/3rdparty/Sabre/DAV/Property/HrefList.php
index 76a5512901c..7a52272e885 100644..100755
--- a/3rdparty/Sabre/DAV/Property/HrefList.php
+++ b/3rdparty/Sabre/DAV/Property/HrefList.php
@@ -3,35 +3,35 @@
/**
* HrefList property
*
- * This property contains multiple {DAV:}href elements, each containing a url.
- *
+ * This property contains multiple {DAV:}href elements, each containing a url.
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
/**
- * hrefs
- *
- * @var array
+ * hrefs
+ *
+ * @var array
*/
private $hrefs;
/**
- * Automatically prefix the url with the server base directory
- *
- * @var bool
+ * Automatically prefix the url with the server base directory
+ *
+ * @var bool
*/
private $autoPrefix = true;
/**
- * __construct
- *
+ * __construct
+ *
* @param array $hrefs
- * @param bool $autoPrefix
+ * @param bool $autoPrefix
*/
public function __construct(array $hrefs, $autoPrefix = true) {
@@ -41,9 +41,9 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
}
/**
- * Returns the uris
- *
- * @return array
+ * Returns the uris
+ *
+ * @return array
*/
public function getHrefs() {
@@ -55,9 +55,9 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
* Serializes this property.
*
* It will additionally prepend the href property with the server's base uri.
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $dom
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $dom
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
@@ -73,13 +73,13 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
}
/**
- * Unserializes this property from a DOM Element
+ * Unserializes this property from a DOM Element
*
* This method returns an instance of this class.
* It will only decode {DAV:}href values.
*
- * @param DOMElement $dom
- * @return Sabre_DAV_Property_Href
+ * @param DOMElement $dom
+ * @return Sabre_DAV_Property_Href
*/
static function unserialize(DOMElement $dom) {
@@ -91,6 +91,6 @@ class Sabre_DAV_Property_HrefList extends Sabre_DAV_Property {
}
return new self($hrefs, false);
- }
+ }
}
diff --git a/3rdparty/Sabre/DAV/Property/IHref.php b/3rdparty/Sabre/DAV/Property/IHref.php
index 29d76a44fcd..5c0409064cb 100644..100755
--- a/3rdparty/Sabre/DAV/Property/IHref.php
+++ b/3rdparty/Sabre/DAV/Property/IHref.php
@@ -9,16 +9,16 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAV_Property_IHref {
/**
- * getHref
- *
- * @return string
+ * getHref
+ *
+ * @return string
*/
function getHref();
diff --git a/3rdparty/Sabre/DAV/Property/LockDiscovery.php b/3rdparty/Sabre/DAV/Property/LockDiscovery.php
index 05c7470b4ed..2ded5649a44 100644..100755
--- a/3rdparty/Sabre/DAV/Property/LockDiscovery.php
+++ b/3rdparty/Sabre/DAV/Property/LockDiscovery.php
@@ -4,26 +4,26 @@
* Represents {DAV:}lockdiscovery property
*
* This property contains all the open locks on a given resource
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
/**
- * locks
- *
- * @var array
+ * locks
+ *
+ * @var array
*/
public $locks;
-
+
/**
- * Should we show the locktoken as well?
- *
- * @var bool
+ * Should we show the locktoken as well?
+ *
+ * @var bool
*/
public $revealLockToken;
@@ -36,13 +36,12 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
static public $hideLockRoot = false;
/**
- * __construct
- *
- * @param array $locks
- * @param bool $revealLockToken
- * @return void
+ * __construct
+ *
+ * @param array $locks
+ * @param bool $revealLockToken
*/
- public function __construct($locks,$revealLockToken = false) {
+ public function __construct($locks, $revealLockToken = false) {
$this->locks = $locks;
$this->revealLockToken = $revealLockToken;
@@ -50,12 +49,13 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
}
/**
- * serialize
- *
- * @param DOMElement $prop
+ * serialize
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $prop
* @return void
*/
- public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
+ public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
$doc = $prop->ownerDocument;
@@ -74,7 +74,7 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
$lockType->appendChild($doc->createElementNS('DAV:','d:write'));
- /* {DAV:}lockroot */
+ /* {DAV:}lockroot */
if (!self::$hideLockRoot) {
$lockRoot = $doc->createElementNS('DAV:','d:lockroot');
$activeLock->appendChild($lockRoot);
@@ -91,7 +91,7 @@ class Sabre_DAV_Property_LockDiscovery extends Sabre_DAV_Property {
$activeLock->appendChild($lockToken);
$lockToken->appendChild($doc->createElementNS('DAV:','d:href','opaquelocktoken:' . $lock->token));
}
-
+
$activeLock->appendChild($doc->createElementNS('DAV:','d:owner',$lock->owner));
}
diff --git a/3rdparty/Sabre/DAV/Property/ResourceType.php b/3rdparty/Sabre/DAV/Property/ResourceType.php
index 2c606c22d60..f6269611e54 100644..100755
--- a/3rdparty/Sabre/DAV/Property/ResourceType.php
+++ b/3rdparty/Sabre/DAV/Property/ResourceType.php
@@ -4,28 +4,27 @@
* This class represents the {DAV:}resourcetype property
*
* Normally for files this is empty, and for collection {DAV:}collection.
- * However, other specs define different values for this.
- *
+ * However, other specs define different values for this.
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
/**
- * resourceType
- *
+ * resourceType
+ *
* @var array
*/
public $resourceType = array();
/**
- * __construct
- *
- * @param mixed $resourceType
- * @return void
+ * __construct
+ *
+ * @param mixed $resourceType
*/
public function __construct($resourceType = array()) {
@@ -33,7 +32,7 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
$this->resourceType = array();
elseif ($resourceType === Sabre_DAV_Server::NODE_DIRECTORY)
$this->resourceType = array('{DAV:}collection');
- elseif (is_array($resourceType))
+ elseif (is_array($resourceType))
$this->resourceType = $resourceType;
else
$this->resourceType = array($resourceType);
@@ -41,25 +40,26 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
}
/**
- * serialize
- *
- * @param DOMElement $prop
+ * serialize
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $prop
* @return void
*/
- public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
+ public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
$propName = null;
$rt = $this->resourceType;
-
+
foreach($rt as $resourceType) {
- if (preg_match('/^{([^}]*)}(.*)$/',$resourceType,$propName)) {
-
+ if (preg_match('/^{([^}]*)}(.*)$/',$resourceType,$propName)) {
+
if (isset($server->xmlNamespaces[$propName[1]])) {
$prop->appendChild($prop->ownerDocument->createElement($server->xmlNamespaces[$propName[1]] . ':' . $propName[2]));
} else {
$prop->appendChild($prop->ownerDocument->createElementNS($propName[1],'custom:' . $propName[2]));
}
-
+
}
}
@@ -69,8 +69,8 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
* Returns the values in clark-notation
*
* For example array('{DAV:}collection')
- *
- * @return array
+ *
+ * @return array
*/
public function getValue() {
@@ -79,10 +79,10 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
}
/**
- * Checks if the principal contains a certain value
- *
- * @param string $type
- * @return bool
+ * Checks if the principal contains a certain value
+ *
+ * @param string $type
+ * @return bool
*/
public function is($type) {
@@ -104,10 +104,10 @@ class Sabre_DAV_Property_ResourceType extends Sabre_DAV_Property {
}
/**
- * Unserializes a DOM element into a ResourceType property.
- *
- * @param DOMElement $dom
- * @return void
+ * Unserializes a DOM element into a ResourceType property.
+ *
+ * @param DOMElement $dom
+ * @return Sabre_DAV_Property_ResourceType
*/
static public function unserialize(DOMElement $dom) {
diff --git a/3rdparty/Sabre/DAV/Property/Response.php b/3rdparty/Sabre/DAV/Property/Response.php
index 7d3a2db0387..88afbcfb26d 100644..100755
--- a/3rdparty/Sabre/DAV/Property/Response.php
+++ b/3rdparty/Sabre/DAV/Property/Response.php
@@ -1,53 +1,52 @@
<?php
/**
- * Response property
- *
+ * Response property
+ *
* This class represents the {DAV:}response XML element.
- * This is used by the Server class to encode individual items within a multistatus
+ * This is used by the Server class to encode individual items within a multistatus
* response.
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
/**
- * Url for the response
- *
- * @var string
+ * Url for the response
+ *
+ * @var string
*/
private $href;
/**
- * Propertylist, ordered by HTTP status code
- *
- * @var array
+ * Propertylist, ordered by HTTP status code
+ *
+ * @var array
*/
private $responseProperties;
/**
* The responseProperties argument is a list of properties
* within an array with keys representing HTTP status codes
- *
- * @param string $href
- * @param array $responseProperties
- * @return void
+ *
+ * @param string $href
+ * @param array $responseProperties
*/
- public function __construct($href,array $responseProperties) {
+ public function __construct($href, array $responseProperties) {
$this->href = $href;
- $this->responseProperties = $responseProperties;
+ $this->responseProperties = $responseProperties;
}
/**
- * Returns the url
- *
- * @return string
+ * Returns the url
+ *
+ * @return string
*/
public function getHref() {
@@ -56,9 +55,9 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
}
/**
- * Returns the property list
- *
- * @return array
+ * Returns the property list
+ *
+ * @return array
*/
public function getResponseProperties() {
@@ -67,19 +66,19 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
}
/**
- * serialize
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $dom
+ * serialize
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $dom
* @return void
*/
- public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
+ public function serialize(Sabre_DAV_Server $server, DOMElement $dom) {
$document = $dom->ownerDocument;
$properties = $this->responseProperties;
-
+
$xresponse = $document->createElement('d:response');
- $dom->appendChild($xresponse);
+ $dom->appendChild($xresponse);
$uri = Sabre_DAV_URLUtil::encodePath($this->href);
@@ -87,7 +86,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
$uri = $server->getBaseUri() . $uri;
$xresponse->appendChild($document->createElement('d:href',$uri));
-
+
// The properties variable is an array containing properties, grouped by
// HTTP status
foreach($properties as $httpStatus=>$propertyGroup) {
@@ -111,7 +110,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
$propName = null;
preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName);
-
+
// special case for empty namespaces
if ($propName[1]=='') {
@@ -125,7 +124,7 @@ class Sabre_DAV_Property_Response extends Sabre_DAV_Property implements Sabre_DA
$nsList[$propName[1]] = 'x' . count($nsList);
}
- // If the namespace was defined in the top-level xml namespaces, it means
+ // If the namespace was defined in the top-level xml namespaces, it means
// there was already a namespace declaration, and we don't have to worry about it.
if (isset($server->xmlNamespaces[$propName[1]])) {
$currentProperty = $document->createElement($nsList[$propName[1]] . ':' . $propName[2]);
diff --git a/3rdparty/Sabre/DAV/Property/ResponseList.php b/3rdparty/Sabre/DAV/Property/ResponseList.php
index cd70b12861d..cae923afbf9 100644..100755
--- a/3rdparty/Sabre/DAV/Property/ResponseList.php
+++ b/3rdparty/Sabre/DAV/Property/ResponseList.php
@@ -1,33 +1,32 @@
<?php
/**
- * ResponseList property
- *
+ * ResponseList property
+ *
* This class represents multiple {DAV:}response XML elements.
- * This is used by the Server class to encode items within a multistatus
+ * This is used by the Server class to encode items within a multistatus
* response.
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_ResponseList extends Sabre_DAV_Property {
/**
- * Response objects.
- *
- * @var array
+ * Response objects.
+ *
+ * @var array
*/
private $responses;
/**
- * The only valid argument is a list of Sabre_DAV_Property_Response
+ * The only valid argument is a list of Sabre_DAV_Property_Response
* objects.
- *
- * @param array $responses;
- * @return void
+ *
+ * @param array $responses;
*/
public function __construct($responses) {
@@ -41,10 +40,10 @@ class Sabre_DAV_Property_ResponseList extends Sabre_DAV_Property {
}
/**
- * serialize
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $dom
+ * serialize
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $dom
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $dom) {
diff --git a/3rdparty/Sabre/DAV/Property/SupportedLock.php b/3rdparty/Sabre/DAV/Property/SupportedLock.php
index 01e63f58d9d..4e3aaf23a1a 100644..100755
--- a/3rdparty/Sabre/DAV/Property/SupportedLock.php
+++ b/3rdparty/Sabre/DAV/Property/SupportedLock.php
@@ -5,27 +5,26 @@
*
* This property contains information about what kind of locks
* this server supports.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_SupportedLock extends Sabre_DAV_Property {
/**
- * supportsLocks
- *
+ * supportsLocks
+ *
* @var mixed
*/
public $supportsLocks = false;
/**
- * __construct
- *
- * @param mixed $supportsLocks
- * @return void
+ * __construct
+ *
+ * @param mixed $supportsLocks
*/
public function __construct($supportsLocks) {
@@ -34,9 +33,10 @@ class Sabre_DAV_Property_SupportedLock extends Sabre_DAV_Property {
}
/**
- * serialize
- *
- * @param DOMElement $prop
+ * serialize
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $prop
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
diff --git a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
index acd9219c0f7..e62699f3b5a 100644..100755
--- a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
+++ b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
@@ -5,18 +5,18 @@
*
* This property is defined in RFC3253, but since it's
* so common in other webdav-related specs, it is part of the core server.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
/**
- * List of reports
- *
+ * List of reports
+ *
* @var array
*/
protected $reports = array();
@@ -28,13 +28,12 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
* should be valid report-types in clark-notation.
*
* Either a string or an array of strings must be passed.
- *
- * @param mixed $reports
- * @return void
+ *
+ * @param mixed $reports
*/
public function __construct($reports = null) {
- if (!is_null($reports))
+ if (!is_null($reports))
$this->addReport($reports);
}
@@ -44,8 +43,8 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
*
* The report must be a string in clark-notation.
* Multiple reports can be specified as an array.
- *
- * @param mixed $report
+ *
+ * @param mixed $report
* @return void
*/
public function addReport($report) {
@@ -54,7 +53,7 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
foreach($report as $r) {
- if (!preg_match('/^{([^}]*)}(.*)$/',$r))
+ if (!preg_match('/^{([^}]*)}(.*)$/',$r))
throw new Sabre_DAV_Exception('Reportname must be in clark-notation');
$this->reports[] = $r;
@@ -65,8 +64,8 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
/**
* Returns the list of supported reports
- *
- * @return array
+ *
+ * @return array
*/
public function getValue() {
@@ -75,16 +74,16 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
}
/**
- * Serializes the node
+ * Serializes the node
*
* @param Sabre_DAV_Server $server
- * @param DOMElement $prop
+ * @param DOMElement $prop
* @return void
*/
- public function serialize(Sabre_DAV_Server $server,DOMElement $prop) {
+ public function serialize(Sabre_DAV_Server $server, DOMElement $prop) {
foreach($this->reports as $reportName) {
-
+
$supportedReport = $prop->ownerDocument->createElement('d:supported-report');
$prop->appendChild($supportedReport);
@@ -92,9 +91,9 @@ class Sabre_DAV_Property_SupportedReportSet extends Sabre_DAV_Property {
$supportedReport->appendChild($report);
preg_match('/^{([^}]*)}(.*)$/',$reportName,$matches);
-
+
list(, $namespace, $element) = $matches;
-
+
$prefix = isset($server->xmlNamespaces[$namespace])?$server->xmlNamespaces[$namespace]:null;
if ($prefix) {
diff --git a/3rdparty/Sabre/DAV/Server.php b/3rdparty/Sabre/DAV/Server.php
index 3d76d4f1918..4284c127b6e 100644..100755
--- a/3rdparty/Sabre/DAV/Server.php
+++ b/3rdparty/Sabre/DAV/Server.php
@@ -2,11 +2,11 @@
/**
* Main DAV server class
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Server {
@@ -26,9 +26,6 @@ class Sabre_DAV_Server {
*/
const NODE_DIRECTORY = 2;
- const PROP_SET = 1;
- const PROP_REMOVE = 2;
-
/**
* XML namespace for all SabreDAV related elements
*/
@@ -36,42 +33,42 @@ class Sabre_DAV_Server {
/**
* The tree object
- *
- * @var Sabre_DAV_Tree
+ *
+ * @var Sabre_DAV_Tree
*/
public $tree;
/**
- * The base uri
- *
- * @var string
+ * The base uri
+ *
+ * @var string
*/
- protected $baseUri = null;
+ protected $baseUri = null;
/**
- * httpResponse
- *
- * @var Sabre_HTTP_Response
+ * httpResponse
+ *
+ * @var Sabre_HTTP_Response
*/
public $httpResponse;
/**
* httpRequest
- *
- * @var Sabre_HTTP_Request
+ *
+ * @var Sabre_HTTP_Request
*/
public $httpRequest;
/**
- * The list of plugins
- *
- * @var array
+ * The list of plugins
+ *
+ * @var array
*/
protected $plugins = array();
/**
- * This array contains a list of callbacks we should call when certain events are triggered
- *
+ * This array contains a list of callbacks we should call when certain events are triggered
+ *
* @var array
*/
protected $eventSubscriptions = array();
@@ -81,7 +78,7 @@ class Sabre_DAV_Server {
*
* If you are defining your own custom namespace, add it here to reduce
* bandwidth and improve legibility of xml bodies.
- *
+ *
* @var array
*/
public $xmlNamespaces = array(
@@ -90,9 +87,9 @@ class Sabre_DAV_Server {
);
/**
- * The propertymap can be used to map properties from
+ * The propertymap can be used to map properties from
* requests to property classes.
- *
+ *
* @var array
*/
public $propertyMap = array(
@@ -125,23 +122,32 @@ class Sabre_DAV_Server {
* This is a flag that allow or not showing file, line and code
* of the exception in the returned XML
*
- * @var bool
+ * @var bool
*/
public $debugExceptions = false;
/**
- * This property allows you to automatically add the 'resourcetype' value
+ * This property allows you to automatically add the 'resourcetype' value
* based on a node's classname or interface.
*
- * The preset ensures that {DAV:}collection is automaticlly added for nodes
+ * The preset ensures that {DAV:}collection is automaticlly added for nodes
* implementing Sabre_DAV_ICollection.
- *
+ *
* @var array
*/
public $resourceTypeMapping = array(
'Sabre_DAV_ICollection' => '{DAV:}collection',
);
+ /**
+ * If this setting is turned off, SabreDAV's version number will be hidden
+ * from various places.
+ *
+ * Some people feel this is a good security measure.
+ *
+ * @var bool
+ */
+ static public $exposeVersion = true;
/**
* Sets up the server
@@ -150,14 +156,13 @@ class Sabre_DAV_Server {
* use it as the directory tree. If a Sabre_DAV_INode is passed, it
* will create a Sabre_DAV_ObjectTree and use the node as the root.
*
- * If nothing is passed, a Sabre_DAV_SimpleCollection is created in
+ * If nothing is passed, a Sabre_DAV_SimpleCollection is created in
* a Sabre_DAV_ObjectTree.
*
* If an array is passed, we automatically create a root node, and use
- * the nodes in the array as top-level children.
- *
- * @param Sabre_DAV_Tree $tree The tree object
- * @return void
+ * the nodes in the array as top-level children.
+ *
+ * @param Sabre_DAV_Tree|Sabre_DAV_INode|null $treeOrNode The tree object
*/
public function __construct($treeOrNode = null) {
@@ -190,7 +195,7 @@ class Sabre_DAV_Server {
}
/**
- * Starts the DAV Server
+ * Starts the DAV Server
*
* @return void
*/
@@ -218,7 +223,9 @@ class Sabre_DAV_Server {
$error->appendChild($DOM->createElement('s:stacktrace',$e->getTraceAsString()));
}
- $error->appendChild($DOM->createElement('s:sabredav-version',Sabre_DAV_Version::VERSION));
+ if (self::$exposeVersion) {
+ $error->appendChild($DOM->createElement('s:sabredav-version',Sabre_DAV_Version::VERSION));
+ }
if($e instanceof Sabre_DAV_Exception) {
@@ -233,7 +240,7 @@ class Sabre_DAV_Server {
}
$headers['Content-Type'] = 'application/xml; charset=utf-8';
-
+
$this->httpResponse->sendStatus($httpCode);
$this->httpResponse->setHeaders($headers);
$this->httpResponse->sendBody($DOM->saveXML());
@@ -244,24 +251,24 @@ class Sabre_DAV_Server {
/**
* Sets the base server uri
- *
+ *
* @param string $uri
* @return void
*/
public function setBaseUri($uri) {
// If the baseUri does not end with a slash, we must add it
- if ($uri[strlen($uri)-1]!=='/')
+ if ($uri[strlen($uri)-1]!=='/')
$uri.='/';
- $this->baseUri = $uri;
+ $this->baseUri = $uri;
}
/**
* Returns the base responding uri
- *
- * @return string
+ *
+ * @return string
*/
public function getBaseUri() {
@@ -272,11 +279,11 @@ class Sabre_DAV_Server {
/**
* This method attempts to detect the base uri.
- * Only the PATH_INFO variable is considered.
- *
- * If this variable is not set, the root (/) is assumed.
+ * Only the PATH_INFO variable is considered.
*
- * @return void
+ * If this variable is not set, the root (/) is assumed.
+ *
+ * @return string
*/
public function guessBaseUri() {
@@ -303,21 +310,21 @@ class Sabre_DAV_Server {
return rtrim($baseUri,'/') . '/';
}
- throw new Sabre_DAV_Exception('The REQUEST_URI ('. $uri . ') did not end with the contents of PATH_INFO (' . $pathInfo . '). This server might be misconfigured.');
+ throw new Sabre_DAV_Exception('The REQUEST_URI ('. $uri . ') did not end with the contents of PATH_INFO (' . $pathInfo . '). This server might be misconfigured.');
- }
+ }
- // The last fallback is that we're just going to assume the server root.
+ // The last fallback is that we're just going to assume the server root.
return '/';
}
/**
* Adds a plugin to the server
- *
+ *
* For more information, console the documentation of Sabre_DAV_ServerPlugin
*
- * @param Sabre_DAV_ServerPlugin $plugin
+ * @param Sabre_DAV_ServerPlugin $plugin
* @return void
*/
public function addPlugin(Sabre_DAV_ServerPlugin $plugin) {
@@ -333,11 +340,11 @@ class Sabre_DAV_Server {
* This function returns null if the plugin was not found.
*
* @param string $name
- * @return Sabre_DAV_ServerPlugin
+ * @return Sabre_DAV_ServerPlugin
*/
public function getPlugin($name) {
- if (isset($this->plugins[$name]))
+ if (isset($this->plugins[$name]))
return $this->plugins[$name];
// This is a fallback and deprecated.
@@ -350,9 +357,9 @@ class Sabre_DAV_Server {
}
/**
- * Returns all plugins
- *
- * @return array
+ * Returns all plugins
+ *
+ * @return array
*/
public function getPlugins() {
@@ -361,7 +368,6 @@ class Sabre_DAV_Server {
}
-
/**
* Subscribe to an event.
*
@@ -371,9 +377,9 @@ class Sabre_DAV_Server {
*
* This is for example used to make sure that the authentication plugin
* is triggered before anything else. If it's not needed to change this
- * number, it is recommended to ommit.
- *
- * @param string $event
+ * number, it is recommended to ommit.
+ *
+ * @param string $event
* @param callback $callback
* @param int $priority
* @return void
@@ -398,7 +404,7 @@ class Sabre_DAV_Server {
*
* @param string $eventName
* @param array $arguments
- * @return bool
+ * @return bool
*/
public function broadcastEvent($eventName,$arguments = array()) {
@@ -418,7 +424,7 @@ class Sabre_DAV_Server {
}
/**
- * Handles a http request, and execute a method based on its name
+ * Handles a http request, and execute a method based on its name
*
* @param string $method
* @param string $uri
@@ -426,7 +432,7 @@ class Sabre_DAV_Server {
*/
public function invokeMethod($method, $uri) {
- $method = strtoupper($method);
+ $method = strtoupper($method);
if (!$this->broadcastEvent('beforeMethod',array($method, $uri))) return;
@@ -453,7 +459,7 @@ class Sabre_DAV_Server {
if ($this->broadcastEvent('unknownMethod',array($method, $uri))) {
// Unsupported method
- throw new Sabre_DAV_Exception_NotImplemented();
+ throw new Sabre_DAV_Exception_NotImplemented('There was no handler found for this "' . $method . '" method');
}
}
@@ -461,9 +467,9 @@ class Sabre_DAV_Server {
}
// {{{ HTTP Method implementations
-
+
/**
- * HTTP OPTIONS
+ * HTTP OPTIONS
*
* @param string $uri
* @return void
@@ -476,11 +482,13 @@ class Sabre_DAV_Server {
$features = array('1','3', 'extended-mkcol');
foreach($this->plugins as $plugin) $features = array_merge($features,$plugin->getFeatures());
-
+
$this->httpResponse->setHeader('DAV',implode(', ',$features));
$this->httpResponse->setHeader('MS-Author-Via','DAV');
$this->httpResponse->setHeader('Accept-Ranges','bytes');
- $this->httpResponse->setHeader('X-Sabre-Version',Sabre_DAV_Version::VERSION);
+ if (self::$exposeVersion) {
+ $this->httpResponse->setHeader('X-Sabre-Version',Sabre_DAV_Version::VERSION);
+ }
$this->httpResponse->setHeader('Content-Length',0);
$this->httpResponse->sendStatus(200);
@@ -492,13 +500,13 @@ class Sabre_DAV_Server {
* This method simply fetches the contents of a uri, like normal
*
* @param string $uri
- * @return void
+ * @return bool
*/
protected function httpGet($uri) {
$node = $this->tree->getNodeForPath($uri,0);
- if (!$this->checkPreconditions(true)) return false;
+ if (!$this->checkPreconditions(true)) return false;
if (!($node instanceof Sabre_DAV_IFile)) throw new Sabre_DAV_Exception_NotImplemented('GET is only implemented on File objects');
$body = $node->get();
@@ -535,7 +543,7 @@ class Sabre_DAV_Server {
} else {
$nodeSize = null;
}
-
+
$this->httpResponse->setHeaders($httpHeaders);
$range = $this->getHTTPRange();
@@ -545,12 +553,12 @@ class Sabre_DAV_Server {
// If ifRange is set, and range is specified, we first need to check
// the precondition.
if ($nodeSize && $range && $ifRange) {
-
+
// if IfRange is parsable as a date we'll treat it as a DateTime
// otherwise, we must treat it as an etag.
try {
$ifRangeDate = new DateTime($ifRange);
-
+
// It's a date. We must check if the entity is modified since
// the specified date.
if (!isset($httpHeaders['Last-Modified'])) $ignoreRangeHeader = true;
@@ -560,8 +568,8 @@ class Sabre_DAV_Server {
}
} catch (Exception $e) {
-
- // It's an entity. We can do a simple comparison.
+
+ // It's an entity. We can do a simple comparison.
if (!isset($httpHeaders['ETag'])) $ignoreRangeHeader = true;
elseif ($httpHeaders['ETag']!==$ifRange) $ignoreRangeHeader = true;
}
@@ -575,7 +583,7 @@ class Sabre_DAV_Server {
$start = $range[0];
$end = $range[1]?$range[1]:$nodeSize-1;
- if($start >= $nodeSize)
+ if($start >= $nodeSize)
throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('The start offset (' . $range[0] . ') exceeded the size of the entity (' . $nodeSize . ')');
if($end < $start) throw new Sabre_DAV_Exception_RequestedRangeNotSatisfiable('The end offset (' . $range[1] . ') is lower than the start offset (' . $range[0] . ')');
@@ -625,7 +633,7 @@ class Sabre_DAV_Server {
$node = $this->tree->getNodeForPath($uri);
/* This information is only collection for File objects.
- * Ideally we want to throw 405 Method Not Allowed for every
+ * Ideally we want to throw 405 Method Not Allowed for every
* non-file, but MS Office does not like this
*/
if ($node instanceof Sabre_DAV_IFile) {
@@ -640,7 +648,7 @@ class Sabre_DAV_Server {
}
/**
- * HTTP Delete
+ * HTTP Delete
*
* The HTTP delete method, deletes a given uri
*
@@ -651,6 +659,7 @@ class Sabre_DAV_Server {
if (!$this->broadcastEvent('beforeUnbind',array($uri))) return;
$this->tree->delete($uri);
+ $this->broadcastEvent('afterUnbind',array($uri));
$this->httpResponse->sendStatus(204);
$this->httpResponse->setHeader('Content-Length','0');
@@ -659,13 +668,13 @@ class Sabre_DAV_Server {
/**
- * WebDAV PROPFIND
+ * WebDAV PROPFIND
*
* This WebDAV method requests information about an uri resource, or a list of resources
* If a client wants to receive the properties for a single resource it will add an HTTP Depth: header with a 0 value
* If the value is 1, it means that it also expects a list of sub-resources (e.g.: files in a directory)
*
- * The request body contains an XML data structure that has a list of properties the client understands
+ * The request body contains an XML data structure that has a list of properties the client understands
* The response body is also an xml document, containing information about every uri resource and the requested properties
*
* It has to return a HTTP 207 Multi-status status code
@@ -679,7 +688,7 @@ class Sabre_DAV_Server {
$requestedProperties = $this->parsePropfindRequest($this->httpRequest->getBody(true));
$depth = $this->getHTTPDepth(1);
- // The only two options for the depth of a propfind is 0 or 1
+ // The only two options for the depth of a propfind is 0 or 1
if ($depth!=0) $depth = 1;
$newProperties = $this->getPropertiesForPath($uri,$requestedProperties,$depth);
@@ -688,8 +697,8 @@ class Sabre_DAV_Server {
$this->httpResponse->sendStatus(207);
$this->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
- // Normally this header is only needed for OPTIONS responses, however..
- // iCal seems to also depend on these being set for PROPFIND. Since
+ // Normally this header is only needed for OPTIONS responses, however..
+ // iCal seems to also depend on these being set for PROPFIND. Since
// this is not harmful, we'll add it.
$features = array('1','3', 'extended-mkcol');
foreach($this->plugins as $plugin) $features = array_merge($features,$plugin->getFeatures());
@@ -712,7 +721,7 @@ class Sabre_DAV_Server {
protected function httpPropPatch($uri) {
$newProperties = $this->parsePropPatchRequest($this->httpRequest->getBody(true));
-
+
$result = $this->updateProperties($uri, $newProperties);
$this->httpResponse->sendStatus(207);
@@ -725,14 +734,14 @@ class Sabre_DAV_Server {
}
/**
- * HTTP PUT method
- *
+ * HTTP PUT method
+ *
* This HTTP method updates a file, or creates a new one.
*
- * If a new resource was created, a 201 Created status code should be returned. If an existing resource is updated, it's a 200 Ok
+ * If a new resource was created, a 201 Created status code should be returned. If an existing resource is updated, it's a 204 No Content
*
* @param string $uri
- * @return void
+ * @return bool
*/
protected function httpPut($uri) {
@@ -768,13 +777,13 @@ class Sabre_DAV_Server {
// Intercepting the Finder problem
if (($expected = $this->httpRequest->getHeader('X-Expected-Entity-Length')) && $expected > 0) {
-
+
/**
- Many webservers will not cooperate well with Finder PUT requests,
+ Many webservers will not cooperate well with Finder PUT requests,
because it uses 'Chunked' transfer encoding for the request body.
- The symptom of this problem is that Finder sends files to the
- server, but they arrive as 0-lenght files in PHP.
+ The symptom of this problem is that Finder sends files to the
+ server, but they arrive as 0-length files in PHP.
If we don't do anything, the user might think they are uploading
files successfully, but they end up empty on the server. Instead,
@@ -808,29 +817,36 @@ class Sabre_DAV_Server {
}
- if ($this->tree->nodeExists($uri)) {
+ if ($this->tree->nodeExists($uri)) {
$node = $this->tree->getNodeForPath($uri);
-
+
// Checking If-None-Match and related headers.
if (!$this->checkPreconditions()) return;
-
+
// If the node is a collection, we'll deny it
if (!($node instanceof Sabre_DAV_IFile)) throw new Sabre_DAV_Exception_Conflict('PUT is not allowed on non-files.');
- if (!$this->broadcastEvent('beforeWriteContent',array($this->getRequestUri()))) return false;
+ if (!$this->broadcastEvent('beforeWriteContent',array($uri, $node, &$body))) return false;
+
+ $etag = $node->put($body);
+
+ $this->broadcastEvent('afterWriteContent',array($uri, $node));
- $node->put($body);
$this->httpResponse->setHeader('Content-Length','0');
+ if ($etag) $this->httpResponse->setHeader('ETag',$etag);
$this->httpResponse->sendStatus(204);
} else {
+ $etag = null;
// If we got here, the resource didn't exist yet.
- if (!$this->createFile($this->getRequestUri(),$body)) {
+ if (!$this->createFile($this->getRequestUri(),$body,$etag)) {
// For one reason or another the file was not created.
return;
}
+
$this->httpResponse->setHeader('Content-Length','0');
+ if ($etag) $this->httpResponse->setHeader('ETag', $etag);
$this->httpResponse->sendStatus(201);
}
@@ -855,7 +871,7 @@ class Sabre_DAV_Server {
$contentType = $this->httpRequest->getHeader('Content-Type');
if (strpos($contentType,'application/xml')!==0 && strpos($contentType,'text/xml')!==0) {
- // We must throw 415 for unsupport mkcol bodies
+ // We must throw 415 for unsupported mkcol bodies
throw new Sabre_DAV_Exception_UnsupportedMediaType('The request body for the MKCOL request must have an xml Content-Type');
}
@@ -863,7 +879,7 @@ class Sabre_DAV_Server {
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($requestBody);
if (Sabre_DAV_XMLUtil::toClarkNotation($dom->firstChild)!=='{DAV:}mkcol') {
- // We must throw 415 for unsupport mkcol bodies
+ // We must throw 415 for unsupported mkcol bodies
throw new Sabre_DAV_Exception_UnsupportedMediaType('The request body for the MKCOL request must be a {DAV:}mkcol request construct.');
}
@@ -875,7 +891,7 @@ class Sabre_DAV_Server {
$properties = array_merge($properties, Sabre_DAV_XMLUtil::parseProperties($childNode, $this->propertyMap));
}
- if (!isset($properties['{DAV:}resourcetype']))
+ if (!isset($properties['{DAV:}resourcetype']))
throw new Sabre_DAV_Exception_BadRequest('The mkcol request must include a {DAV:}resourcetype property');
$resourceType = $properties['{DAV:}resourcetype']->getValue();
@@ -918,19 +934,21 @@ class Sabre_DAV_Server {
$moveInfo = $this->getCopyAndMoveInfo();
// If the destination is part of the source tree, we must fail
- if ($moveInfo['destination']==$uri)
+ if ($moveInfo['destination']==$uri)
throw new Sabre_DAV_Exception_Forbidden('Source and destination uri are identical.');
if ($moveInfo['destinationExists']) {
if (!$this->broadcastEvent('beforeUnbind',array($moveInfo['destination']))) return false;
$this->tree->delete($moveInfo['destination']);
+ $this->broadcastEvent('afterUnbind',array($moveInfo['destination']));
}
if (!$this->broadcastEvent('beforeUnbind',array($uri))) return false;
if (!$this->broadcastEvent('beforeBind',array($moveInfo['destination']))) return false;
$this->tree->move($uri,$moveInfo['destination']);
+ $this->broadcastEvent('afterUnbind',array($uri));
$this->broadcastEvent('afterBind',array($moveInfo['destination']));
// If a resource was overwritten we should send a 204, otherwise a 201
@@ -946,13 +964,13 @@ class Sabre_DAV_Server {
* A lot of the actual request processing is done in getCopyMoveInfo
*
* @param string $uri
- * @return void
+ * @return bool
*/
protected function httpCopy($uri) {
$copyInfo = $this->getCopyAndMoveInfo();
// If the destination is part of the source tree, we must fail
- if ($copyInfo['destination']==$uri)
+ if ($copyInfo['destination']==$uri)
throw new Sabre_DAV_Exception_Forbidden('Source and destination uri are identical.');
if ($copyInfo['destinationExists']) {
@@ -998,13 +1016,13 @@ class Sabre_DAV_Server {
}
// }}}
- // {{{ HTTP/WebDAV protocol helpers
+ // {{{ HTTP/WebDAV protocol helpers
/**
- * Returns an array with all the supported HTTP methods for a specific uri.
+ * Returns an array with all the supported HTTP methods for a specific uri.
*
- * @param string $uri
- * @return array
+ * @param string $uri
+ * @return array
*/
public function getAllowedMethods($uri) {
@@ -1023,13 +1041,13 @@ class Sabre_DAV_Server {
// The MKCOL is only allowed on an unmapped uri
try {
- $node = $this->tree->getNodeForPath($uri);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ $this->tree->getNodeForPath($uri);
+ } catch (Sabre_DAV_Exception_NotFound $e) {
$methods[] = 'MKCOL';
}
// We're also checking if any of the plugins register any new methods
- foreach($this->plugins as $plugin) $methods = array_merge($methods,$plugin->getHTTPMethods($uri));
+ foreach($this->plugins as $plugin) $methods = array_merge($methods, $plugin->getHTTPMethods($uri));
array_unique($methods);
return $methods;
@@ -1037,8 +1055,8 @@ class Sabre_DAV_Server {
}
/**
- * Gets the uri for the request, keeping the base uri into consideration
- *
+ * Gets the uri for the request, keeping the base uri into consideration
+ *
* @return string
*/
public function getRequestUri() {
@@ -1048,9 +1066,9 @@ class Sabre_DAV_Server {
}
/**
- * Calculates the uri for a request, making sure that the base uri is stripped out
- *
- * @param string $uri
+ * Calculates the uri for a request, making sure that the base uri is stripped out
+ *
+ * @param string $uri
* @throws Sabre_DAV_Exception_Forbidden A permission denied exception is thrown whenever there was an attempt to supply a uri outside of the base uri
* @return string
*/
@@ -1068,9 +1086,9 @@ class Sabre_DAV_Server {
return trim(Sabre_DAV_URLUtil::decodePath(substr($uri,strlen($this->getBaseUri()))),'/');
- // A special case, if the baseUri was accessed without a trailing
- // slash, we'll accept it as well.
- } elseif ($uri.'/' === $this->getBaseUri()) {
+ // A special case, if the baseUri was accessed without a trailing
+ // slash, we'll accept it as well.
+ } elseif ($uri.'/' === $this->getBaseUri()) {
return '';
@@ -1086,10 +1104,10 @@ class Sabre_DAV_Server {
* Returns the HTTP depth header
*
* This method returns the contents of the HTTP depth request header. If the depth header was 'infinity' it will return the Sabre_DAV_Server::DEPTH_INFINITY object
- * It is possible to supply a default depth value, which is used when the depth header has invalid content, or is completely non-existant
- *
- * @param mixed $default
- * @return int
+ * It is possible to supply a default depth value, which is used when the depth header has invalid content, or is completely non-existent
+ *
+ * @param mixed $default
+ * @return int
*/
public function getHTTPDepth($default = self::DEPTH_INFINITY) {
@@ -1100,7 +1118,7 @@ class Sabre_DAV_Server {
if ($depth == 'infinity') return self::DEPTH_INFINITY;
-
+
// If its an unknown value. we'll grab the default
if (!ctype_digit($depth)) return $default;
@@ -1118,14 +1136,14 @@ class Sabre_DAV_Server {
* The second number is the offset of the last byte in the range.
*
* If the second offset is null, it should be treated as the offset of the last byte of the entity
- * If the first offset is null, the second offset should be used to retrieve the last x bytes of the entity
+ * If the first offset is null, the second offset should be used to retrieve the last x bytes of the entity
*
- * return $mixed
+ * @return array|null
*/
public function getHTTPRange() {
$range = $this->httpRequest->getHeader('range');
- if (is_null($range)) return null;
+ if (is_null($range)) return null;
// Matching "Range: bytes=1234-5678: both numbers are optional
@@ -1143,15 +1161,15 @@ class Sabre_DAV_Server {
/**
* Returns information about Copy and Move requests
- *
- * This function is created to help getting information about the source and the destination for the
- * WebDAV MOVE and COPY HTTP request. It also validates a lot of information and throws proper exceptions
- *
+ *
+ * This function is created to help getting information about the source and the destination for the
+ * WebDAV MOVE and COPY HTTP request. It also validates a lot of information and throws proper exceptions
+ *
* The returned value is an array with the following keys:
* * destination - Destination path
- * * destinationExists - Wether or not the destination is an existing url (and should therefore be overwritten)
+ * * destinationExists - Whether or not the destination is an existing url (and should therefore be overwritten)
*
- * @return array
+ * @return array
*/
public function getCopyAndMoveInfo() {
@@ -1170,7 +1188,7 @@ class Sabre_DAV_Server {
try {
$destinationParent = $this->tree->getNodeForPath($destinationDir);
if (!($destinationParent instanceof Sabre_DAV_ICollection)) throw new Sabre_DAV_Exception_UnsupportedMediaType('The destination node is not a collection');
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
// If the destination parent node is not found, we throw a 409
throw new Sabre_DAV_Exception_Conflict('The destination node is not found');
@@ -1179,12 +1197,12 @@ class Sabre_DAV_Server {
try {
$destinationNode = $this->tree->getNodeForPath($destination);
-
+
// If this succeeded, it means the destination already exists
// we'll need to throw precondition failed in case overwrite is false
if (!$overwrite) throw new Sabre_DAV_Exception_PreconditionFailed('The destination node already exists, and the overwrite header is set to false','Overwrite');
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
// Destination didn't exist, we're all good
$destinationNode = false;
@@ -1220,22 +1238,50 @@ class Sabre_DAV_Server {
}
/**
+ * A kid-friendly way to fetch properties for a node's children.
+ *
+ * The returned array will be indexed by the path of the of child node.
+ * Only properties that are actually found will be returned.
+ *
+ * The parent node will not be returned.
+ *
+ * @param string $path
+ * @param array $propertyNames
+ * @return array
+ */
+ public function getPropertiesForChildren($path, $propertyNames) {
+
+ $result = array();
+ foreach($this->getPropertiesForPath($path,$propertyNames,1) as $k=>$row) {
+
+ // Skipping the parent path
+ if ($k === 0) continue;
+
+ $result[$row['href']] = $row[200];
+
+ }
+ return $result;
+
+ }
+
+ /**
* Returns a list of HTTP headers for a particular resource
*
- * The generated http headers are based on properties provided by the
+ * The generated http headers are based on properties provided by the
* resource. The method basically provides a simple mapping between
* DAV property and HTTP header.
*
* The headers are intended to be used for HEAD and GET requests.
- *
+ *
* @param string $path
+ * @return array
*/
public function getHTTPHeaders($path) {
$propertyMap = array(
'{DAV:}getcontenttype' => 'Content-Type',
'{DAV:}getcontentlength' => 'Content-Length',
- '{DAV:}getlastmodified' => 'Last-Modified',
+ '{DAV:}getlastmodified' => 'Last-Modified',
'{DAV:}getetag' => 'ETag',
);
@@ -1245,40 +1291,40 @@ class Sabre_DAV_Server {
foreach($propertyMap as $property=>$header) {
if (!isset($properties[$property])) continue;
- if (is_scalar($properties[$property])) {
+ if (is_scalar($properties[$property])) {
$headers[$header] = $properties[$property];
- // GetLastModified gets special cased
+ // GetLastModified gets special cased
} elseif ($properties[$property] instanceof Sabre_DAV_Property_GetLastModified) {
- $headers[$header] = $properties[$property]->getTime()->format(DateTime::RFC1123);
+ $headers[$header] = Sabre_HTTP_Util::toHTTPDate($properties[$property]->getTime());
}
}
return $headers;
-
+
}
/**
* Returns a list of properties for a given path
- *
+ *
* The path that should be supplied should have the baseUrl stripped out
* The list of properties should be supplied in Clark notation. If the list is empty
* 'allprops' is assumed.
*
* If a depth of 1 is requested child elements will also be returned.
*
- * @param string $path
+ * @param string $path
* @param array $propertyNames
- * @param int $depth
+ * @param int $depth
* @return array
*/
- public function getPropertiesForPath($path,$propertyNames = array(),$depth = 0) {
+ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0) {
if ($depth!=0) $depth = 1;
$returnPropertyList = array();
-
+
$parentNode = $this->tree->getNodeForPath($path);
$nodes = array(
$path => $parentNode
@@ -1286,11 +1332,11 @@ class Sabre_DAV_Server {
if ($depth==1 && $parentNode instanceof Sabre_DAV_ICollection) {
foreach($this->tree->getChildren($path) as $childNode)
$nodes[$path . '/' . $childNode->getName()] = $childNode;
- }
-
+ }
+
// If the propertyNames array is empty, it means all properties are requested.
// We shouldn't actually return everything we know though, and only return a
- // sensible list.
+ // sensible list.
$allProperties = count($propertyNames)==0;
foreach($nodes as $myPath=>$node) {
@@ -1315,8 +1361,8 @@ class Sabre_DAV_Server {
);
}
- // If the resourceType was not part of the list, we manually add it
- // and mark it for removal. We need to know the resourcetype in order
+ // If the resourceType was not part of the list, we manually add it
+ // and mark it for removal. We need to know the resourcetype in order
// to make certain decisions about the entry.
// WebDAV dictates we should add a / and the end of href's for collections
$removeRT = false;
@@ -1326,32 +1372,39 @@ class Sabre_DAV_Server {
}
$result = $this->broadcastEvent('beforeGetProperties',array($myPath, $node, &$currentPropertyNames, &$newProperties));
- // If this method explicitly returned false, we must ignore this
- // node as it is inacessible.
+ // If this method explicitly returned false, we must ignore this
+ // node as it is inaccessible.
if ($result===false) continue;
if (count($currentPropertyNames) > 0) {
- if ($node instanceof Sabre_DAV_IProperties)
+ if ($node instanceof Sabre_DAV_IProperties)
$newProperties['200'] = $newProperties[200] + $node->getProperties($currentPropertyNames);
}
foreach($currentPropertyNames as $prop) {
-
+
if (isset($newProperties[200][$prop])) continue;
switch($prop) {
case '{DAV:}getlastmodified' : if ($node->getLastModified()) $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified()); break;
- case '{DAV:}getcontentlength' : if ($node instanceof Sabre_DAV_IFile) $newProperties[200][$prop] = (int)$node->getSize(); break;
- case '{DAV:}quota-used-bytes' :
+ case '{DAV:}getcontentlength' :
+ if ($node instanceof Sabre_DAV_IFile) {
+ $size = $node->getSize();
+ if (!is_null($size)) {
+ $newProperties[200][$prop] = (int)$node->getSize();
+ }
+ }
+ break;
+ case '{DAV:}quota-used-bytes' :
if ($node instanceof Sabre_DAV_IQuota) {
$quotaInfo = $node->getQuotaInfo();
$newProperties[200][$prop] = $quotaInfo[0];
}
break;
- case '{DAV:}quota-available-bytes' :
+ case '{DAV:}quota-available-bytes' :
if ($node instanceof Sabre_DAV_IQuota) {
$quotaInfo = $node->getQuotaInfo();
$newProperties[200][$prop] = $quotaInfo[1];
@@ -1364,7 +1417,7 @@ class Sabre_DAV_Server {
foreach($this->plugins as $plugin) {
$reports = array_merge($reports, $plugin->getSupportedReportSet($myPath));
}
- $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports);
+ $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports);
break;
case '{DAV:}resourcetype' :
$newProperties[200]['{DAV:}resourcetype'] = new Sabre_DAV_Property_ResourceType();
@@ -1379,14 +1432,14 @@ class Sabre_DAV_Server {
if (!$allProperties && !isset($newProperties[200][$prop])) $newProperties[404][$prop] = null;
}
-
+
$this->broadcastEvent('afterGetProperties',array(trim($myPath,'/'),&$newProperties));
- $newProperties['href'] = trim($myPath,'/');
+ $newProperties['href'] = trim($myPath,'/');
// Its is a WebDAV recommendation to add a trailing slash to collectionnames.
// Apple's iCal also requires a trailing slash for principals (rfc 3744).
- // Therefore we add a trailing / for any non-file. This might need adjustments
+ // Therefore we add a trailing / for any non-file. This might need adjustments
// if we find there are other edge cases.
if ($myPath!='' && isset($newProperties[200]['{DAV:}resourcetype']) && count($newProperties[200]['{DAV:}resourcetype']->getValue())>0) $newProperties['href'] .='/';
@@ -1397,7 +1450,7 @@ class Sabre_DAV_Server {
$returnPropertyList[] = $newProperties;
}
-
+
return $returnPropertyList;
}
@@ -1406,27 +1459,31 @@ class Sabre_DAV_Server {
* This method is invoked by sub-systems creating a new file.
*
* Currently this is done by HTTP PUT and HTTP LOCK (in the Locks_Plugin).
- * It was important to get this done through a centralized function,
+ * It was important to get this done through a centralized function,
* allowing plugins to intercept this using the beforeCreateFile event.
*
* This method will return true if the file was actually created
- *
- * @param string $uri
- * @param resource $data
- * @return bool
+ *
+ * @param string $uri
+ * @param resource $data
+ * @param string $etag
+ * @return bool
*/
- public function createFile($uri,$data) {
+ public function createFile($uri,$data, &$etag = null) {
list($dir,$name) = Sabre_DAV_URLUtil::splitPath($uri);
if (!$this->broadcastEvent('beforeBind',array($uri))) return false;
- if (!$this->broadcastEvent('beforeCreateFile',array($uri,$data))) return false;
$parent = $this->tree->getNodeForPath($dir);
- $parent->createFile($name,$data);
+
+ if (!$this->broadcastEvent('beforeCreateFile',array($uri, &$data, $parent))) return false;
+
+ $etag = $parent->createFile($name,$data);
$this->tree->markDirty($dir);
$this->broadcastEvent('afterBind',array($uri));
+ $this->broadcastEvent('afterCreateFile',array($uri, $parent));
return true;
}
@@ -1434,7 +1491,7 @@ class Sabre_DAV_Server {
/**
* This method is invoked by sub-systems creating a new directory.
*
- * @param string $uri
+ * @param string $uri
* @return void
*/
public function createDirectory($uri) {
@@ -1447,14 +1504,14 @@ class Sabre_DAV_Server {
* Use this method to create a new collection
*
* The {DAV:}resourcetype is specified using the resourceType array.
- * At the very least it must contain {DAV:}collection.
+ * At the very least it must contain {DAV:}collection.
*
* The properties array can contain a list of additional properties.
- *
- * @param string $uri The new uri
- * @param array $resourceType The resourceType(s)
+ *
+ * @param string $uri The new uri
+ * @param array $resourceType The resourceType(s)
* @param array $properties A list of properties
- * @return void
+ * @return array|null
*/
public function createCollection($uri, array $resourceType, array $properties) {
@@ -1471,7 +1528,7 @@ class Sabre_DAV_Server {
$parent = $this->tree->getNodeForPath($parentUri);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
throw new Sabre_DAV_Exception_Conflict('Parent node does not exist');
@@ -1491,14 +1548,14 @@ class Sabre_DAV_Server {
// If we got here.. it means there's already a node on that url, and we need to throw a 405
throw new Sabre_DAV_Exception_MethodNotAllowed('The resource you tried to create already exists');
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
// This is correct
}
-
+
if (!$this->broadcastEvent('beforeBind',array($uri))) return;
- // There are 2 modes of operation. The standard collection
+ // There are 2 modes of operation. The standard collection
// creates the directory, and then updates properties
// the extended collection can create it directly.
if ($parent instanceof Sabre_DAV_IExtendedCollection) {
@@ -1513,7 +1570,7 @@ class Sabre_DAV_Server {
}
$parent->createDirectory($newName);
- $rollBack = false;
+ $rollBack = false;
$exception = null;
$errorResult = null;
@@ -1544,7 +1601,7 @@ class Sabre_DAV_Server {
return $errorResult;
}
-
+
}
$this->tree->markDirty($parentUri);
$this->broadcastEvent('afterBind',array($uri));
@@ -1557,29 +1614,29 @@ class Sabre_DAV_Server {
* The properties array must be a list of properties. Array-keys are
* property names in clarknotation, array-values are it's values.
* If a property must be deleted, the value should be null.
- *
- * Note that this request should either completely succeed, or
+ *
+ * Note that this request should either completely succeed, or
* completely fail.
*
* The response is an array with statuscodes for keys, which in turn
* contain arrays with propertynames. This response can be used
* to generate a multistatus body.
- *
- * @param string $uri
- * @param array $properties
- * @return array
+ *
+ * @param string $uri
+ * @param array $properties
+ * @return array
*/
public function updateProperties($uri, array $properties) {
// we'll start by grabbing the node, this will throw the appropriate
- // exceptions if it doesn't.
+ // exceptions if it doesn't.
$node = $this->tree->getNodeForPath($uri);
-
+
$result = array(
200 => array(),
403 => array(),
424 => array(),
- );
+ );
$remainingProperties = $properties;
$hasError = false;
@@ -1684,14 +1741,15 @@ class Sabre_DAV_Server {
* the appropriate HTTP response headers are already set.
*
* Normally this method will throw 412 Precondition Failed for failures
- * related to If-None-Match, If-Match and If-Unmodified Since. It will
+ * related to If-None-Match, If-Match and If-Unmodified Since. It will
* set the status to 304 Not Modified for If-Modified_since.
*
- * If the $handleAsGET argument is set to true, it will also return 304
+ * If the $handleAsGET argument is set to true, it will also return 304
* Not Modified for failure of the If-None-Match precondition. This is the
* desired behaviour for HTTP GET and HTTP HEAD requests.
*
- * @return bool
+ * @param bool $handleAsGET
+ * @return bool
*/
public function checkPreconditions($handleAsGET = false) {
@@ -1708,7 +1766,7 @@ class Sabre_DAV_Server {
// request succeed if a resource exists at that url.
try {
$node = $this->tree->getNodeForPath($uri);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
throw new Sabre_DAV_Exception_PreconditionFailed('An If-Match header was specified and the resource did not exist','If-Match');
}
@@ -1722,7 +1780,7 @@ class Sabre_DAV_Server {
// Stripping any extra spaces
$ifMatchItem = trim($ifMatchItem,' ');
-
+
$etag = $node->getETag();
if ($etag===$ifMatchItem) {
$haveMatch = true;
@@ -1744,7 +1802,7 @@ class Sabre_DAV_Server {
if (!$node) {
try {
$node = $this->tree->getNodeForPath($uri);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
$nodeExists = false;
}
}
@@ -1758,10 +1816,10 @@ class Sabre_DAV_Server {
$etag = $node->getETag();
foreach($ifNoneMatch as $ifNoneMatchItem) {
-
+
// Stripping any extra spaces
$ifNoneMatchItem = trim($ifNoneMatchItem,' ');
-
+
if ($etag===$ifNoneMatchItem) $haveMatch = true;
}
@@ -1781,7 +1839,7 @@ class Sabre_DAV_Server {
}
if (!$ifNoneMatch && ($ifModifiedSince = $this->httpRequest->getHeader('If-Modified-Since'))) {
-
+
// The If-Modified-Since header contains a date. We
// will only return the entity if it has been changed since
// that date. If it hasn't been changed, we return a 304
@@ -1799,23 +1857,24 @@ class Sabre_DAV_Server {
$lastMod = new DateTime('@' . $lastMod);
if ($lastMod <= $date) {
$this->httpResponse->sendStatus(304);
+ $this->httpResponse->setHeader('Last-Modified', Sabre_HTTP_Util::toHTTPDate($lastMod));
return false;
- }
+ }
}
}
}
if ($ifUnmodifiedSince = $this->httpRequest->getHeader('If-Unmodified-Since')) {
-
+
// The If-Unmodified-Since will allow allow the request if the
// entity has not changed since the specified date.
$date = Sabre_HTTP_Util::parseHTTPDate($ifUnmodifiedSince);
-
+
// We must only check the date if it's valid
if ($date) {
if (is_null($node)) {
$node = $this->tree->getNodeForPath($uri);
- }
+ }
$lastMod = $node->getLastModified();
if ($lastMod) {
$lastMod = new DateTime('@' . $lastMod);
@@ -1830,16 +1889,15 @@ class Sabre_DAV_Server {
}
- // }}}
- // {{{ XML Readers & Writers
-
-
+ // }}}
+ // {{{ XML Readers & Writers
+
+
/**
- * Generates a WebDAV propfind response body based on a list of nodes
- *
+ * Generates a WebDAV propfind response body based on a list of nodes
+ *
* @param array $fileProperties The list with nodes
- * @param array $requestedProperties The properties that should be returned
- * @return string
+ * @return string
*/
public function generateMultiStatus(array $fileProperties) {
@@ -1859,7 +1917,7 @@ class Sabre_DAV_Server {
$href = $entry['href'];
unset($entry['href']);
-
+
$response = new Sabre_DAV_Property_Response($href,$entry);
$response->serialize($this,$multiStatus);
@@ -1878,7 +1936,7 @@ class Sabre_DAV_Server {
* The keys in the returned array contain the property name (e.g.: {DAV:}displayname,
* and the value contains the property value. If a property is to be removed the value
* will be null.
- *
+ *
* @param string $body xml body
* @return array list of properties in need of updating or deletion
*/
@@ -1886,17 +1944,17 @@ class Sabre_DAV_Server {
//We'll need to change the DAV namespace declaration to something else in order to make it parsable
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
-
+
$newProperties = array();
foreach($dom->firstChild->childNodes as $child) {
- if ($child->nodeType !== XML_ELEMENT_NODE) continue;
+ if ($child->nodeType !== XML_ELEMENT_NODE) continue;
$operation = Sabre_DAV_XMLUtil::toClarkNotation($child);
if ($operation!=='{DAV:}set' && $operation!=='{DAV:}remove') continue;
-
+
$innerProperties = Sabre_DAV_XMLUtil::parseProperties($child, $this->propertyMap);
foreach($innerProperties as $propertyName=>$propertyValue) {
@@ -1920,9 +1978,9 @@ class Sabre_DAV_Server {
*
* This will either be a list of properties, or an empty array; in which case
* an {DAV:}allprop was requested.
- *
- * @param string $body
- * @return array
+ *
+ * @param string $body
+ * @return array
*/
public function parsePropFindRequest($body) {
@@ -1931,7 +1989,7 @@ class Sabre_DAV_Server {
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
$elem = $dom->getElementsByTagNameNS('urn:DAV','propfind')->item(0);
- return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem));
+ return array_keys(Sabre_DAV_XMLUtil::parseProperties($elem));
}
diff --git a/3rdparty/Sabre/DAV/ServerPlugin.php b/3rdparty/Sabre/DAV/ServerPlugin.php
index 6909f600c21..131863d13fb 100644..100755
--- a/3rdparty/Sabre/DAV/ServerPlugin.php
+++ b/3rdparty/Sabre/DAV/ServerPlugin.php
@@ -3,12 +3,12 @@
/**
* The baseclass for all server plugins.
*
- * Plugins can modify or extend the servers behaviour.
- *
+ * Plugins can modify or extend the servers behaviour.
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_ServerPlugin {
@@ -20,18 +20,18 @@ abstract class Sabre_DAV_ServerPlugin {
* addPlugin is called.
*
* This method should set up the requires event subscriptions.
- *
- * @param Sabre_DAV_Server $server
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
abstract public function initialize(Sabre_DAV_Server $server);
-
+
/**
- * This method should return a list of server-features.
+ * This method should return a list of server-features.
*
* This is for example 'versioning' and is added to the DAV: header
* in an OPTIONS response.
- *
+ *
* @return array
*/
public function getFeatures() {
@@ -44,11 +44,11 @@ abstract class Sabre_DAV_ServerPlugin {
* Use this method to tell the server this plugin defines additional
* HTTP methods.
*
- * This method is passed a uri. It should only return HTTP methods that are
+ * This method is passed a uri. It should only return HTTP methods that are
* available for the specified uri.
*
* @param string $uri
- * @return array
+ * @return array
*/
public function getHTTPMethods($uri) {
@@ -58,11 +58,11 @@ abstract class Sabre_DAV_ServerPlugin {
/**
* Returns a plugin name.
- *
+ *
* Using this name other plugins will be able to access other plugins
- * using Sabre_DAV_Server::getPlugin
- *
- * @return string
+ * using Sabre_DAV_Server::getPlugin
+ *
+ * @return string
*/
public function getPluginName() {
@@ -74,11 +74,11 @@ abstract class Sabre_DAV_ServerPlugin {
* Returns a list of reports this plugin supports.
*
* This will be used in the {DAV:}supported-report-set property.
- * Note that you still need to subscribe to the 'report' event to actually
- * implement them
- *
+ * Note that you still need to subscribe to the 'report' event to actually
+ * implement them
+ *
* @param string $uri
- * @return array
+ * @return array
*/
public function getSupportedReportSet($uri) {
diff --git a/3rdparty/Sabre/DAV/SimpleCollection.php b/3rdparty/Sabre/DAV/SimpleCollection.php
index 223d05fed55..4acf971caa5 100644..100755
--- a/3rdparty/Sabre/DAV/SimpleCollection.php
+++ b/3rdparty/Sabre/DAV/SimpleCollection.php
@@ -8,23 +8,23 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
/**
- * List of childnodes
+ * List of childnodes
*
* @var array
*/
protected $children = array();
/**
- * Name of this resource
- *
- * @var string
+ * Name of this resource
+ *
+ * @var string
*/
protected $name;
@@ -33,10 +33,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
*
* The name of the node must be passed, child nodes can also be bassed.
* This nodes must be instances of Sabre_DAV_INode
- *
- * @param string $name
- * @param array $children
- * @return void
+ *
+ * @param string $name
+ * @param array $children
*/
public function __construct($name,array $children = array()) {
@@ -51,9 +50,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
}
/**
- * Adds a new childnode to this collection
- *
- * @param Sabre_DAV_INode $child
+ * Adds a new childnode to this collection
+ *
+ * @param Sabre_DAV_INode $child
* @return void
*/
public function addChild(Sabre_DAV_INode $child) {
@@ -63,9 +62,9 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
}
/**
- * Returns the name of the collection
- *
- * @return string
+ * Returns the name of the collection
+ *
+ * @return string
*/
public function getName() {
@@ -76,24 +75,24 @@ class Sabre_DAV_SimpleCollection extends Sabre_DAV_Collection {
/**
* Returns a child object, by its name.
*
- * This method makes use of the getChildren method to grab all the child nodes, and compares the name.
+ * This method makes use of the getChildren method to grab all the child nodes, and compares the name.
* Generally its wise to override this, as this can usually be optimized
- *
+ *
* @param string $name
- * @throws Sabre_DAV_Exception_FileNotFound
- * @return Sabre_DAV_INode
+ * @throws Sabre_DAV_Exception_NotFound
+ * @return Sabre_DAV_INode
*/
public function getChild($name) {
if (isset($this->children[$name])) return $this->children[$name];
- throw new Sabre_DAV_Exception_FileNotFound('File not found: ' . $name . ' in \'' . $this->getName() . '\'');
+ throw new Sabre_DAV_Exception_NotFound('File not found: ' . $name . ' in \'' . $this->getName() . '\'');
}
/**
- * Returns a list of children for this collection
- *
- * @return array
+ * Returns a list of children for this collection
+ *
+ * @return array
*/
public function getChildren() {
diff --git a/3rdparty/Sabre/DAV/SimpleDirectory.php b/3rdparty/Sabre/DAV/SimpleDirectory.php
index 516a3aa907c..621222ebc53 100644..100755
--- a/3rdparty/Sabre/DAV/SimpleDirectory.php
+++ b/3rdparty/Sabre/DAV/SimpleDirectory.php
@@ -11,8 +11,8 @@
* @package Sabre
* @subpackage DAV
* @deprecated Use Sabre_DAV_SimpleCollection instead.
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_SimpleDirectory extends Sabre_DAV_SimpleCollection {
diff --git a/3rdparty/Sabre/DAV/SimpleFile.php b/3rdparty/Sabre/DAV/SimpleFile.php
index 304dff1c5ec..58330d6861d 100644..100755
--- a/3rdparty/Sabre/DAV/SimpleFile.php
+++ b/3rdparty/Sabre/DAV/SimpleFile.php
@@ -3,47 +3,48 @@
/**
* SimpleFile
*
- * The 'SimpleFile' class is used to easily add read-only immutable files to
- * the directory structure. One usecase would be to add a 'readme.txt' to a
+ * The 'SimpleFile' class is used to easily add read-only immutable files to
+ * the directory structure. One usecase would be to add a 'readme.txt' to a
* root of a webserver with some standard content.
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
/**
- * File contents
+ * File contents
*
- * @var string
+ * @var string
*/
protected $contents = array();
/**
- * Name of this resource
- *
- * @var string
+ * Name of this resource
+ *
+ * @var string
*/
protected $name;
/**
* A mimetype, such as 'text/plain' or 'text/html'
- *
- * @var string
+ *
+ * @var string
*/
protected $mimeType;
/**
* Creates this node
*
- * The name of the node must be passed, as well as the contents of the
+ * The name of the node must be passed, as well as the contents of the
* file.
- *
- * @param string $name
- * @param string $contents
+ *
+ * @param string $name
+ * @param string $contents
+ * @param string|null $mimeType
*/
public function __construct($name, $contents, $mimeType = null) {
@@ -57,8 +58,8 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
* Returns the node name for this file.
*
* This name is used to construct the url.
- *
- * @return string
+ *
+ * @return string
*/
public function getName() {
@@ -67,7 +68,7 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
}
/**
- * Returns the data
+ * Returns the data
*
* This method may either return a string or a readable stream resource
*
@@ -75,14 +76,14 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
*/
public function get() {
- return $this->contents;
+ return $this->contents;
}
/**
- * Returns the size of the file, in bytes.
- *
- * @return int
+ * Returns the size of the file, in bytes.
+ *
+ * @return int
*/
public function getSize() {
@@ -94,13 +95,14 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
* Returns the ETag for a file
*
* An ETag is a unique identifier representing the current version of the file. If the file changes, the ETag MUST change.
- * The ETag is an arbritrary string, but MUST be surrounded by double-quotes.
+ * The ETag is an arbitrary string, but MUST be surrounded by double-quotes.
*
* Return null if the ETag can not effectively be determined
+ * @return string
*/
public function getETag() {
- return '"' . md5($this->contents) . '"';
+ return '"' . md5($this->contents) . '"';
}
@@ -108,13 +110,12 @@ class Sabre_DAV_SimpleFile extends Sabre_DAV_File {
* Returns the mime-type for a file
*
* If null is returned, we'll assume application/octet-stream
- */
+ * @return string
+ */
public function getContentType() {
- return $this->mimeType;
+ return $this->mimeType;
}
}
-
-?>
diff --git a/3rdparty/Sabre/DAV/StringUtil.php b/3rdparty/Sabre/DAV/StringUtil.php
index 440cf6866ca..b126a94c825 100644..100755
--- a/3rdparty/Sabre/DAV/StringUtil.php
+++ b/3rdparty/Sabre/DAV/StringUtil.php
@@ -3,14 +3,14 @@
/**
* String utility
*
- * This class is mainly used to implement the 'text-match' filter, used by both
- * the CalDAV calendar-query REPORT, and CardDAV addressbook-query REPORT.
+ * This class is mainly used to implement the 'text-match' filter, used by both
+ * the CalDAV calendar-query REPORT, and CardDAV addressbook-query REPORT.
* Because they both need it, it was decided to put it in Sabre_DAV instead.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_StringUtil {
@@ -18,11 +18,11 @@ class Sabre_DAV_StringUtil {
/**
* Checks if a needle occurs in a haystack ;)
*
- * @param string $haystack
- * @param string $needle
- * @param string $collation
- * @param string $matchType
- * @return bool
+ * @param string $haystack
+ * @param string $needle
+ * @param string $collation
+ * @param string $matchType
+ * @return bool
*/
static public function textMatch($haystack, $needle, $collation, $matchType = 'contains') {
@@ -37,7 +37,7 @@ class Sabre_DAV_StringUtil {
case 'i;octet' :
// Do nothing
- break;
+ break;
case 'i;unicode-casemap' :
$haystack = mb_strtoupper($haystack, 'UTF-8');
@@ -63,18 +63,18 @@ class Sabre_DAV_StringUtil {
throw new Sabre_DAV_Exception_BadRequest('Match-type: ' . $matchType . ' is not supported');
}
-
+
}
/**
- * This method takes an input string, checks if it's not valid UTF-8 and
+ * This method takes an input string, checks if it's not valid UTF-8 and
* attempts to convert it to UTF-8 if it's not.
*
- * Note that currently this can only convert ISO-8559-1 to UTF-8 (latin-1),
+ * Note that currently this can only convert ISO-8559-1 to UTF-8 (latin-1),
* anything else will likely fail.
*
- * @param string $input
- * @return string
+ * @param string $input
+ * @return string
*/
static public function ensureUTF8($input) {
@@ -84,7 +84,7 @@ class Sabre_DAV_StringUtil {
return utf8_encode($input);
} else {
return $input;
- }
+ }
}
diff --git a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
index e8276af5613..36096e67775 100644..100755
--- a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
+++ b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
@@ -22,8 +22,8 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
@@ -31,7 +31,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
/**
* This is the list of patterns we intercept.
* If new patterns are added, they must be valid patterns for preg_match.
- *
+ *
* @var array
*/
public $temporaryFilePatterns = array(
@@ -43,19 +43,19 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
'/^\.dat(.*)$/', // Smultron seems to create these
'/^~lock.(.*)#$/', // Windows 7 lockfiles
);
-
+
/**
* This is the directory where this plugin
* will store it's files.
- *
- * @var string
+ *
+ * @var string
*/
private $dataDir;
/**
* A reference to the main Server class
- *
- * @var Sabre_DAV_Server
+ *
+ * @var Sabre_DAV_Server
*/
private $server;
@@ -65,9 +65,8 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
* Make sure you specify a directory for your files. If you don't, we
* will use PHP's directory for session-storage instead, and you might
* not want that.
- *
- * @param string $dataDir
- * @return void
+ *
+ * @param string|null $dataDir
*/
public function __construct($dataDir = null) {
@@ -75,15 +74,15 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
if (!is_dir($dataDir)) mkdir($dataDir);
$this->dataDir = $dataDir;
- }
+ }
/**
* Initialize the plugin
*
* This is called automatically be the Server class after this plugin is
* added with Sabre_DAV_Server::addPlugin()
- *
- * @param Sabre_DAV_Server $server
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -97,11 +96,12 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
/**
* This method is called before any HTTP method handler
*
- * This method intercepts any GET, DELETE, PUT and PROPFIND calls to
+ * This method intercepts any GET, DELETE, PUT and PROPFIND calls to
* filenames that are known to match the 'temporary file' regex.
- *
- * @param string $method
- * @return bool
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
*/
public function beforeMethod($method, $uri) {
@@ -125,33 +125,33 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
/**
* This method is invoked if some subsystem creates a new file.
*
- * This is used to deal with HTTP LOCK requests which create a new
+ * This is used to deal with HTTP LOCK requests which create a new
* file.
- *
- * @param string $uri
- * @param resource $data
- * @return bool
+ *
+ * @param string $uri
+ * @param resource $data
+ * @return bool
*/
public function beforeCreateFile($uri,$data) {
if ($tempPath = $this->isTempFile($uri)) {
-
+
$hR = $this->server->httpResponse;
$hR->setHeader('X-Sabre-Temp','true');
file_put_contents($tempPath,$data);
return false;
}
- return true;
+ return true;
}
/**
* This method will check if the url matches the temporary file pattern
- * if it does, it will return an path based on $this->dataDir for the
+ * if it does, it will return an path based on $this->dataDir for the
* temporary file storage.
- *
- * @param string $path
- * @return boolean|string
+ *
+ * @param string $path
+ * @return boolean|string
*/
protected function isTempFile($path) {
@@ -161,7 +161,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
foreach($this->temporaryFilePatterns as $tempFile) {
if (preg_match($tempFile,$tempPath)) {
- return $this->dataDir . '/sabredav_' . md5($path) . '.tempfile';
+ return $this->getDataDir() . '/sabredav_' . md5($path) . '.tempfile';
}
}
@@ -175,9 +175,9 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
* This method handles the GET method for temporary files.
* If the file doesn't exist, it will return false which will kick in
* the regular system for the GET method.
- *
- * @param string $tempLocation
- * @return bool
+ *
+ * @param string $tempLocation
+ * @return bool
*/
public function httpGet($tempLocation) {
@@ -195,9 +195,9 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
/**
* This method handles the PUT method.
- *
- * @param string $tempLocation
- * @return bool
+ *
+ * @param string $tempLocation
+ * @return bool
*/
public function httpPut($tempLocation) {
@@ -205,7 +205,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
$hR->setHeader('X-Sabre-Temp','true');
$newFile = !file_exists($tempLocation);
-
+
if (!$newFile && ($this->server->httpRequest->getHeader('If-None-Match'))) {
throw new Sabre_DAV_Exception_PreconditionFailed('The resource already exists, and an If-None-Match header was supplied');
}
@@ -219,11 +219,11 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
/**
* This method handles the DELETE method.
*
- * If the file didn't exist, it will return false, which will make the
+ * If the file didn't exist, it will return false, which will make the
* standard HTTP DELETE handler kick in.
- *
- * @param string $tempLocation
- * @return bool
+ *
+ * @param string $tempLocation
+ * @return bool
*/
public function httpDelete($tempLocation) {
@@ -238,25 +238,26 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
}
/**
- * This method handles the PROPFIND method.
+ * This method handles the PROPFIND method.
*
* It's a very lazy method, it won't bother checking the request body
* for which properties were requested, and just sends back a default
* set of properties.
*
- * @param string $tempLocation
- * @return void
+ * @param string $tempLocation
+ * @param string $uri
+ * @return bool
*/
public function httpPropfind($tempLocation, $uri) {
if (!file_exists($tempLocation)) return true;
-
+
$hR = $this->server->httpResponse;
$hR->setHeader('X-Sabre-Temp','true');
$hR->sendStatus(207);
$hR->setHeader('Content-Type','application/xml; charset=utf-8');
- $requestedProps = $this->server->parsePropFindRequest($this->server->httpRequest->getBody(true));
+ $this->server->parsePropFindRequest($this->server->httpRequest->getBody(true));
$properties = array(
'href' => $uri,
@@ -264,7 +265,7 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
'{DAV:}getlastmodified' => new Sabre_DAV_Property_GetLastModified(filemtime($tempLocation)),
'{DAV:}getcontentlength' => filesize($tempLocation),
'{DAV:}resourcetype' => new Sabre_DAV_Property_ResourceType(null),
- '{'.Sabre_DAV_Server::NS_SABREDAV.'}tempFile' => true,
+ '{'.Sabre_DAV_Server::NS_SABREDAV.'}tempFile' => true,
),
);
@@ -276,4 +277,13 @@ class Sabre_DAV_TemporaryFileFilterPlugin extends Sabre_DAV_ServerPlugin {
}
+ /**
+ * This method returns the directory where the temporary files should be stored.
+ *
+ * @return string
+ */
+ protected function getDataDir()
+ {
+ return $this->dataDir;
+ }
}
diff --git a/3rdparty/Sabre/DAV/Tree.php b/3rdparty/Sabre/DAV/Tree.php
index 98e6f62c9e5..50216394155 100644..100755
--- a/3rdparty/Sabre/DAV/Tree.php
+++ b/3rdparty/Sabre/DAV/Tree.php
@@ -1,34 +1,34 @@
<?php
/**
- * Abstract tree object
- *
+ * Abstract tree object
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAV_Tree {
-
+
/**
* This function must return an INode object for a path
- * If a Path doesn't exist, thrown an Exception_FileNotFound
- *
- * @param string $path
- * @throws Exception_FileNotFound
- * @return Sabre_DAV_INode
+ * If a Path doesn't exist, thrown a Exception_NotFound
+ *
+ * @param string $path
+ * @throws Sabre_DAV_Exception_NotFound
+ * @return Sabre_DAV_INode
*/
abstract function getNodeForPath($path);
/**
* This function allows you to check if a node exists.
*
- * Implementors of this class should override this method to make
+ * Implementors of this class should override this method to make
* it cheaper.
- *
- * @param string $path
- * @return bool
+ *
+ * @param string $path
+ * @return bool
*/
public function nodeExists($path) {
@@ -37,7 +37,7 @@ abstract class Sabre_DAV_Tree {
$this->getNodeForPath($path);
return true;
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
return false;
@@ -50,12 +50,12 @@ abstract class Sabre_DAV_Tree {
*
* @param string $sourcePath The source location
* @param string $destinationPath The full destination path
- * @return void
+ * @return void
*/
public function copy($sourcePath, $destinationPath) {
$sourceNode = $this->getNodeForPath($sourcePath);
-
+
// grab the dirname and basename components
list($destinationDir, $destinationName) = Sabre_DAV_URLUtil::splitPath($destinationPath);
@@ -67,9 +67,9 @@ abstract class Sabre_DAV_Tree {
}
/**
- * Moves a file from one location to another
- *
- * @param string $sourcePath The path to the file which should be moved
+ * Moves a file from one location to another
+ *
+ * @param string $sourcePath The path to the file which should be moved
* @param string $destinationPath The full destination path, so not just the destination parent node
* @return int
*/
@@ -91,26 +91,26 @@ abstract class Sabre_DAV_Tree {
}
/**
- * Deletes a node from the tree
- *
- * @param string $path
+ * Deletes a node from the tree
+ *
+ * @param string $path
* @return void
*/
public function delete($path) {
$node = $this->getNodeForPath($path);
$node->delete();
-
+
list($parent) = Sabre_DAV_URLUtil::splitPath($path);
$this->markDirty($parent);
}
/**
- * Returns a list of childnodes for a given path.
- *
- * @param string $path
- * @return array
+ * Returns a list of childnodes for a given path.
+ *
+ * @param string $path
+ * @return array
*/
public function getChildren($path) {
@@ -127,14 +127,14 @@ abstract class Sabre_DAV_Tree {
* * node creations
* * copy
* * move
- * * renaming nodes
- *
+ * * renaming nodes
+ *
* If Tree classes implement a form of caching, this will allow
* them to make sure caches will be expired.
- *
+ *
* If a path is passed, it is assumed that the entire subtree is dirty
*
- * @param string $path
+ * @param string $path
* @return void
*/
public function markDirty($path) {
@@ -143,10 +143,11 @@ abstract class Sabre_DAV_Tree {
}
/**
- * copyNode
- *
- * @param Sabre_DAV_INode $source
- * @param Sabre_DAV_ICollection $destination
+ * copyNode
+ *
+ * @param Sabre_DAV_INode $source
+ * @param Sabre_DAV_ICollection $destinationParent
+ * @param string $destinationName
* @return void
*/
protected function copyNode(Sabre_DAV_INode $source,Sabre_DAV_ICollection $destinationParent,$destinationName = null) {
@@ -163,14 +164,14 @@ abstract class Sabre_DAV_Tree {
fwrite($stream,$data);
rewind($stream);
$data = $stream;
- }
+ }
$destinationParent->createFile($destinationName,$data);
$destination = $destinationParent->getChild($destinationName);
} elseif ($source instanceof Sabre_DAV_ICollection) {
$destinationParent->createDirectory($destinationName);
-
+
$destination = $destinationParent->getChild($destinationName);
foreach($source->getChildren() as $child) {
diff --git a/3rdparty/Sabre/DAV/Tree/Filesystem.php b/3rdparty/Sabre/DAV/Tree/Filesystem.php
index 5c611047e07..85a9ee317be 100644..100755
--- a/3rdparty/Sabre/DAV/Tree/Filesystem.php
+++ b/3rdparty/Sabre/DAV/Tree/Filesystem.php
@@ -1,12 +1,12 @@
<?php
/**
- * Sabre_DAV_Tree_Filesystem
- *
+ * Sabre_DAV_Tree_Filesystem
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
@@ -14,7 +14,7 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
/**
* Base url on the filesystem.
*
- * @var string
+ * @var string
*/
protected $basePath;
@@ -22,9 +22,8 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
* Creates this tree
*
* Supply the path you'd like to share.
- *
- * @param string $basePath
- * @return void
+ *
+ * @param string $basePath
*/
public function __construct($basePath) {
@@ -33,16 +32,16 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
}
/**
- * Returns a new node for the given path
- *
- * @param string $path
- * @return void
+ * Returns a new node for the given path
+ *
+ * @param string $path
+ * @return Sabre_DAV_FS_Node
*/
public function getNodeForPath($path) {
$realPath = $this->getRealPath($path);
- if (!file_exists($realPath)) throw new Sabre_DAV_Exception_FileNotFound('File at location ' . $realPath . ' not found');
- if (is_dir($realPath)) {
+ if (!file_exists($realPath)) throw new Sabre_DAV_Exception_NotFound('File at location ' . $realPath . ' not found');
+ if (is_dir($realPath)) {
return new Sabre_DAV_FS_Directory($path);
} else {
return new Sabre_DAV_FS_File($path);
@@ -51,10 +50,10 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
}
/**
- * Returns the real filesystem path for a webdav url.
- *
- * @param string $publicPath
- * @return string
+ * Returns the real filesystem path for a webdav url.
+ *
+ * @param string $publicPath
+ * @return string
*/
protected function getRealPath($publicPath) {
@@ -67,24 +66,24 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
*
* This method must work recursively and delete the destination
* if it exists
- *
- * @param string $source
- * @param string $destination
+ *
+ * @param string $source
+ * @param string $destination
* @return void
*/
public function copy($source,$destination) {
$source = $this->getRealPath($source);
$destination = $this->getRealPath($destination);
- $this->realCopy($source,$destination);
+ $this->realCopy($source,$destination);
}
/**
- * Used by self::copy
- *
- * @param string $source
- * @param string $destination
+ * Used by self::copy
+ *
+ * @param string $source
+ * @param string $destination
* @return void
*/
protected function realCopy($source,$destination) {
@@ -107,9 +106,9 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
* Moves a file or directory recursively.
*
* If the destination exists, delete it first.
- *
- * @param string $source
- * @param string $destination
+ *
+ * @param string $source
+ * @param string $destination
* @return void
*/
public function move($source,$destination) {
diff --git a/3rdparty/Sabre/DAV/URLUtil.php b/3rdparty/Sabre/DAV/URLUtil.php
index 8f38749264b..794665a44f6 100644..100755
--- a/3rdparty/Sabre/DAV/URLUtil.php
+++ b/3rdparty/Sabre/DAV/URLUtil.php
@@ -11,11 +11,11 @@
* Specifically, it was found that GVFS (gnome's webdav client) does not like encoding of ( and
* ). Since these are reserved, but don't have a reserved meaning in url, these characters are
* kept as-is.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_URLUtil {
@@ -24,46 +24,42 @@ class Sabre_DAV_URLUtil {
* Encodes the path of a url.
*
* slashes (/) are treated as path-separators.
- *
- * @param string $path
- * @return string
+ *
+ * @param string $path
+ * @return string
*/
static function encodePath($path) {
- $valid_chars = '/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.~()';
- $newStr = '';
- for( $i=0; isset($path[$i]); ++$i ) {
- if( strpos($valid_chars,($c=$path[$i]))===false ) $newStr .= '%'.sprintf('%02x',ord($c));
- else $newStr .= $c;
- }
- return $newStr;
-
+ return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)\/])/',function($match) {
+
+ return '%'.sprintf('%02x',ord($match[0]));
+
+ }, $path);
+
}
/**
* Encodes a 1 segment of a path
*
* Slashes are considered part of the name, and are encoded as %2f
- *
- * @param string $pathSegment
- * @return string
+ *
+ * @param string $pathSegment
+ * @return string
*/
static function encodePathSegment($pathSegment) {
- $valid_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-.~()';
- $newStr = '';
- for( $i=0; isset($pathSegment[$i]); ++$i ) {
- if( strpos($valid_chars,($c=$pathSegment[$i]))===false ) $newStr .= '%'.sprintf('%02x',ord($c));
- else $newStr .= $c;
- }
- return $newStr;
+ return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)])/',function($match) {
+
+ return '%'.sprintf('%02x',ord($match[0]));
+
+ }, $pathSegment);
}
/**
* Decodes a url-encoded path
*
- * @param string $path
- * @return string
+ * @param string $path
+ * @return string
*/
static function decodePath($path) {
@@ -74,17 +70,17 @@ class Sabre_DAV_URLUtil {
/**
* Decodes a url-encoded path segment
*
- * @param string $path
- * @return string
+ * @param string $path
+ * @return string
*/
static function decodePathSegment($path) {
- $path = urldecode($path);
+ $path = rawurldecode($path);
$encoding = mb_detect_encoding($path, array('UTF-8','ISO-8859-1'));
switch($encoding) {
- case 'ISO-8859-1' :
+ case 'ISO-8859-1' :
$path = utf8_encode($path);
}
@@ -94,7 +90,7 @@ class Sabre_DAV_URLUtil {
}
/**
- * Returns the 'dirname' and 'basename' for a path.
+ * Returns the 'dirname' and 'basename' for a path.
*
* The reason there is a custom function for this purpose, is because
* basename() is locale aware (behaviour changes if C locale or a UTF-8 locale is used)
@@ -108,8 +104,8 @@ class Sabre_DAV_URLUtil {
* If there is no dirname, it will return an empty string. Any / appearing at the end of the
* string is stripped off.
*
- * @param string $path
- * @return array
+ * @param string $path
+ * @return array
*/
static function splitPath($path) {
diff --git a/3rdparty/Sabre/DAV/UUIDUtil.php b/3rdparty/Sabre/DAV/UUIDUtil.php
index e42a536ad8a..f0eebe598e5 100644..100755
--- a/3rdparty/Sabre/DAV/UUIDUtil.php
+++ b/3rdparty/Sabre/DAV/UUIDUtil.php
@@ -4,13 +4,13 @@
* UUID Utility
*
* This class has static methods to generate and validate UUID's.
- * UUIDs are used a decent amount within various *DAV standards, so it made
+ * UUIDs are used a decent amount within various *DAV standards, so it made
* sense to include it.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_UUIDUtil {
@@ -18,10 +18,10 @@ class Sabre_DAV_UUIDUtil {
/**
* Returns a pseudo-random v4 UUID
*
- * This function is based on a comment by Andrew Moore on php.net
- *
+ * This function is based on a comment by Andrew Moore on php.net
+ *
* @see http://www.php.net/manual/en/function.uniqid.php#94959
- * @return void
+ * @return string
*/
static function getUUID() {
@@ -48,9 +48,9 @@ class Sabre_DAV_UUIDUtil {
/**
* Checks if a string is a valid UUID.
- *
- * @param string $uuid
- * @return bool
+ *
+ * @param string $uuid
+ * @return bool
*/
static function validateUUID($uuid) {
diff --git a/3rdparty/Sabre/DAV/Version.php b/3rdparty/Sabre/DAV/Version.php
index 6bece1985e4..5e5d15e4039 100644..100755
--- a/3rdparty/Sabre/DAV/Version.php
+++ b/3rdparty/Sabre/DAV/Version.php
@@ -2,10 +2,10 @@
/**
* This class contains the SabreDAV version constants.
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -14,7 +14,7 @@ class Sabre_DAV_Version {
/**
* Full version number
*/
- const VERSION = '1.5.4';
+ const VERSION = '1.6.2';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/DAV/XMLUtil.php b/3rdparty/Sabre/DAV/XMLUtil.php
index bd05be4b229..60eff3b159a 100644..100755
--- a/3rdparty/Sabre/DAV/XMLUtil.php
+++ b/3rdparty/Sabre/DAV/XMLUtil.php
@@ -2,32 +2,32 @@
/**
* XML utilities for WebDAV
- *
+ *
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_XMLUtil {
/**
* Returns the 'clark notation' for an element.
- *
+ *
* For example, and element encoded as:
* <b:myelem xmlns:b="http://www.example.org/" />
* will be returned as:
* {http://www.example.org}myelem
*
* This format is used throughout the SabreDAV sourcecode.
- * Elements encoded with the urn:DAV namespace will
+ * Elements encoded with the urn:DAV namespace will
* be returned as if they were in the DAV: namespace. This is to avoid
* compatibility problems.
*
* This function will return null if a nodetype other than an Element is passed.
*
- * @param DOMElement $dom
- * @return string
+ * @param DOMNode $dom
+ * @return string
*/
static function toClarkNotation(DOMNode $dom) {
@@ -35,21 +35,21 @@ class Sabre_DAV_XMLUtil {
// Mapping back to the real namespace, in case it was dav
if ($dom->namespaceURI=='urn:DAV') $ns = 'DAV:'; else $ns = $dom->namespaceURI;
-
+
// Mapping to clark notation
return '{' . $ns . '}' . $dom->localName;
}
/**
- * Parses a clark-notation string, and returns the namespace and element
+ * Parses a clark-notation string, and returns the namespace and element
* name components.
*
* If the string was invalid, it will throw an InvalidArgumentException.
- *
+ *
* @param string $str
- * @throws InvalidArgumentException
- * @return array
+ * @throws InvalidArgumentException
+ * @return array
*/
static function parseClarkNotation($str) {
@@ -70,6 +70,9 @@ class Sabre_DAV_XMLUtil {
*
* This is unfortunately needed, because the DAV: namespace violates the xml namespaces
* spec, and causes the DOM to throw errors
+ *
+ * @param string $xmlDocument
+ * @return array|string|null
*/
static function convertDAVNamespace($xmlDocument) {
@@ -83,17 +86,17 @@ class Sabre_DAV_XMLUtil {
* This method provides a generic way to load a DOMDocument for WebDAV use.
*
* This method throws a Sabre_DAV_Exception_BadRequest exception for any xml errors.
- * It does not preserve whitespace, and it converts the DAV: namespace to urn:DAV.
- *
+ * It does not preserve whitespace, and it converts the DAV: namespace to urn:DAV.
+ *
* @param string $xml
- * @throws Sabre_DAV_Exception_BadRequest
- * @return DOMDocument
+ * @throws Sabre_DAV_Exception_BadRequest
+ * @return DOMDocument
*/
static function loadDOMDocument($xml) {
if (empty($xml))
throw new Sabre_DAV_Exception_BadRequest('Empty XML document sent');
-
+
// The BitKinex client sends xml documents as UTF-16. PHP 5.3.1 (and presumably lower)
// does not support this, so we must intercept this and convert to UTF-8.
if (substr($xml,0,12) === "\x3c\x00\x3f\x00\x78\x00\x6d\x00\x6c\x00\x20\x00") {
@@ -111,7 +114,7 @@ class Sabre_DAV_XMLUtil {
// Retaining old error setting
$oldErrorSetting = libxml_use_internal_errors(true);
- // Clearing any previous errors
+ // Clearing any previous errors
libxml_clear_errors();
$dom = new DOMDocument();
@@ -135,7 +138,7 @@ class Sabre_DAV_XMLUtil {
/**
* Parses all WebDAV properties out of a DOM Element
*
- * Generally WebDAV properties are encloded in {DAV:}prop elements. This
+ * Generally WebDAV properties are enclosed in {DAV:}prop elements. This
* method helps by going through all these and pulling out the actual
* propertynames, making them array keys and making the property values,
* well.. the array values.
@@ -145,7 +148,7 @@ class Sabre_DAV_XMLUtil {
*
* Complex values are supported through the propertyMap argument. The
* propertyMap should have the clark-notation properties as it's keys, and
- * classnames as values.
+ * classnames as values.
*
* When any of these properties are found, the unserialize() method will be
* (statically) called. The result of this method is used as the value.
@@ -168,7 +171,7 @@ class Sabre_DAV_XMLUtil {
$propertyName = Sabre_DAV_XMLUtil::toClarkNotation($propNodeData);
if (isset($propertyMap[$propertyName])) {
- $propList[$propertyName] = call_user_func(array($propertyMap[$propertyName],'unserialize'),$propNodeData);
+ $propList[$propertyName] = call_user_func(array($propertyMap[$propertyName],'unserialize'),$propNodeData);
} else {
$propList[$propertyName] = $propNodeData->textContent;
}
diff --git a/3rdparty/Sabre/DAV/includes.php b/3rdparty/Sabre/DAV/includes.php
new file mode 100755
index 00000000000..6a4890677ea
--- /dev/null
+++ b/3rdparty/Sabre/DAV/includes.php
@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * Sabre_DAV includes file
+ *
+ * Including this file will automatically include all files from the Sabre_DAV
+ * package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @subpackage DAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+
+// Begin includes
+include __DIR__ . '/Auth/IBackend.php';
+include __DIR__ . '/Client.php';
+include __DIR__ . '/Exception.php';
+include __DIR__ . '/INode.php';
+include __DIR__ . '/IProperties.php';
+include __DIR__ . '/Locks/Backend/Abstract.php';
+include __DIR__ . '/Locks/Backend/File.php';
+include __DIR__ . '/Locks/Backend/FS.php';
+include __DIR__ . '/Locks/Backend/PDO.php';
+include __DIR__ . '/Locks/LockInfo.php';
+include __DIR__ . '/Node.php';
+include __DIR__ . '/Property/IHref.php';
+include __DIR__ . '/Property.php';
+include __DIR__ . '/Server.php';
+include __DIR__ . '/ServerPlugin.php';
+include __DIR__ . '/StringUtil.php';
+include __DIR__ . '/TemporaryFileFilterPlugin.php';
+include __DIR__ . '/Tree.php';
+include __DIR__ . '/URLUtil.php';
+include __DIR__ . '/UUIDUtil.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/XMLUtil.php';
+include __DIR__ . '/Auth/Backend/AbstractBasic.php';
+include __DIR__ . '/Auth/Backend/AbstractDigest.php';
+include __DIR__ . '/Auth/Backend/Apache.php';
+include __DIR__ . '/Auth/Backend/File.php';
+include __DIR__ . '/Auth/Backend/PDO.php';
+include __DIR__ . '/Auth/Plugin.php';
+include __DIR__ . '/Browser/GuessContentType.php';
+include __DIR__ . '/Browser/MapGetToPropFind.php';
+include __DIR__ . '/Browser/Plugin.php';
+include __DIR__ . '/Exception/BadRequest.php';
+include __DIR__ . '/Exception/Conflict.php';
+include __DIR__ . '/Exception/Forbidden.php';
+include __DIR__ . '/Exception/InsufficientStorage.php';
+include __DIR__ . '/Exception/InvalidResourceType.php';
+include __DIR__ . '/Exception/Locked.php';
+include __DIR__ . '/Exception/LockTokenMatchesRequestUri.php';
+include __DIR__ . '/Exception/MethodNotAllowed.php';
+include __DIR__ . '/Exception/NotAuthenticated.php';
+include __DIR__ . '/Exception/NotFound.php';
+include __DIR__ . '/Exception/NotImplemented.php';
+include __DIR__ . '/Exception/PaymentRequired.php';
+include __DIR__ . '/Exception/PreconditionFailed.php';
+include __DIR__ . '/Exception/ReportNotImplemented.php';
+include __DIR__ . '/Exception/RequestedRangeNotSatisfiable.php';
+include __DIR__ . '/Exception/UnsupportedMediaType.php';
+include __DIR__ . '/FS/Node.php';
+include __DIR__ . '/FSExt/Node.php';
+include __DIR__ . '/ICollection.php';
+include __DIR__ . '/IExtendedCollection.php';
+include __DIR__ . '/IFile.php';
+include __DIR__ . '/IQuota.php';
+include __DIR__ . '/Locks/Plugin.php';
+include __DIR__ . '/Mount/Plugin.php';
+include __DIR__ . '/ObjectTree.php';
+include __DIR__ . '/Property/GetLastModified.php';
+include __DIR__ . '/Property/Href.php';
+include __DIR__ . '/Property/HrefList.php';
+include __DIR__ . '/Property/LockDiscovery.php';
+include __DIR__ . '/Property/ResourceType.php';
+include __DIR__ . '/Property/Response.php';
+include __DIR__ . '/Property/ResponseList.php';
+include __DIR__ . '/Property/SupportedLock.php';
+include __DIR__ . '/Property/SupportedReportSet.php';
+include __DIR__ . '/Tree/Filesystem.php';
+include __DIR__ . '/Collection.php';
+include __DIR__ . '/Directory.php';
+include __DIR__ . '/Exception/ConflictingLock.php';
+include __DIR__ . '/Exception/FileNotFound.php';
+include __DIR__ . '/File.php';
+include __DIR__ . '/FS/Directory.php';
+include __DIR__ . '/FS/File.php';
+include __DIR__ . '/FSExt/Directory.php';
+include __DIR__ . '/FSExt/File.php';
+include __DIR__ . '/SimpleCollection.php';
+include __DIR__ . '/SimpleDirectory.php';
+include __DIR__ . '/SimpleFile.php';
+// End includes
diff --git a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
index a361e054610..e05b7749805 100644..100755
--- a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
+++ b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
@@ -3,53 +3,52 @@
/**
* Principals Collection
*
- * This is a helper class that easily allows you to create a collection that
+ * This is a helper class that easily allows you to create a collection that
* has a childnode for every principal.
- *
- * To use this class, simply implement the getChildForPrincipal method.
+ *
+ * To use this class, simply implement the getChildForPrincipal method.
*
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collection {
/**
- * Node or 'directory' name.
- *
- * @var string
+ * Node or 'directory' name.
+ *
+ * @var string
*/
protected $path;
/**
- * Principal backend
- *
- * @var Sabre_DAVACL_IPrincipalBackend
+ * Principal backend
+ *
+ * @var Sabre_DAVACL_IPrincipalBackend
*/
protected $principalBackend;
/**
* If this value is set to true, it effectively disables listing of users
- * it still allows user to find other users if they have an exact url.
- *
- * @var bool
+ * it still allows user to find other users if they have an exact url.
+ *
+ * @var bool
*/
public $disableListing = false;
/**
* Creates the object
*
- * This object must be passed the principal backend. This object will
- * filter all principals from a specfied prefix ($principalPrefix). The
- * default is 'principals', if your principals are stored in a different
+ * This object must be passed the principal backend. This object will
+ * filter all principals from a specified prefix ($principalPrefix). The
+ * default is 'principals', if your principals are stored in a different
* collection, override $principalPrefix
- *
- *
- * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
+ *
+ *
+ * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
* @param string $principalPrefix
- * @param string $nodeName
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, $principalPrefix = 'principals') {
@@ -64,28 +63,28 @@ abstract class Sabre_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collec
* The passed array contains principal information, and is guaranteed to
* at least contain a uri item. Other properties may or may not be
* supplied by the authentication backend.
- *
- * @param array $principalInfo
+ *
+ * @param array $principalInfo
* @return Sabre_DAVACL_IPrincipal
*/
abstract function getChildForPrincipal(array $principalInfo);
/**
- * Returns the name of this collection.
- *
- * @return string
+ * Returns the name of this collection.
+ *
+ * @return string
*/
public function getName() {
list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalPrefix);
- return $name;
+ return $name;
}
/**
- * Return the list of users
- *
- * @return void
+ * Return the list of users
+ *
+ * @return array
*/
public function getChildren() {
@@ -99,23 +98,57 @@ abstract class Sabre_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collec
}
- return $children;
+ return $children;
}
/**
* Returns a child object, by its name.
- *
+ *
* @param string $name
- * @throws Sabre_DAV_Exception_FileNotFound
+ * @throws Sabre_DAV_Exception_NotFound
* @return Sabre_DAV_IPrincipal
*/
public function getChild($name) {
$principalInfo = $this->principalBackend->getPrincipalByPath($this->principalPrefix . '/' . $name);
- if (!$principalInfo) throw new Sabre_DAV_Exception_FileNotFound('Principal with name ' . $name . ' not found');
+ if (!$principalInfo) throw new Sabre_DAV_Exception_NotFound('Principal with name ' . $name . ' not found');
return $this->getChildForPrincipal($principalInfo);
}
+ /**
+ * This method is used to search for principals matching a set of
+ * properties.
+ *
+ * This search is specifically used by RFC3744's principal-property-search
+ * REPORT. You should at least allow searching on
+ * http://sabredav.org/ns}email-address.
+ *
+ * The actual search should be a unicode-non-case-sensitive search. The
+ * keys in searchProperties are the WebDAV property names, while the values
+ * are the property values to search on.
+ *
+ * If multiple properties are being searched on, the search should be
+ * AND'ed.
+ *
+ * This method should simply return a list of 'child names', which may be
+ * used to call $this->getChild in the future.
+ *
+ * @param array $searchProperties
+ * @return array
+ */
+ public function searchPrincipals(array $searchProperties) {
+
+ $result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties);
+ $r = array();
+
+ foreach($result as $row) {
+ list(, $r[]) = Sabre_DAV_URLUtil::splitPath($row);
+ }
+
+ return $r;
+
+ }
+
}
diff --git a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
index d10aeb4345c..4b9f93b0036 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
+++ b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
@@ -1,12 +1,12 @@
<?php
/**
- * Sabre_DAVACL_Exception_AceConflict
- *
+ * Sabre_DAVACL_Exception_AceConflict
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Exception_AceConflict extends Sabre_DAV_Exception_Conflict {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_AceConflict extends Sabre_DAV_Exception_Conflict {
* Adds in extra information in the xml response.
*
* This method adds the {DAV:}no-ace-conflict element as defined in rfc3744
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
$doc = $errorNode->ownerDocument;
-
+
$np = $doc->createElementNS('DAV:','d:no-ace-conflict');
$errorNode->appendChild($np);
}
}
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
index 024ab6641f3..9b055dd9709 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
@@ -1,60 +1,61 @@
<?php
/**
- * NeedPrivileges
+ * NeedPrivileges
*
* The 403-need privileges is thrown when a user didn't have the appropriate
* permissions to perform an operation
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @version $Id$
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Exception_NeedPrivileges extends Sabre_DAV_Exception_Forbidden {
/**
- * The relevant uri
- *
- * @var string
+ * The relevant uri
+ *
+ * @var string
*/
protected $uri;
/**
- * The privileges the user didn't have.
- *
- * @var array
+ * The privileges the user didn't have.
+ *
+ * @var array
*/
protected $privileges;
/**
- * Constructor
- *
- * @param string $uri
- * @param array $privileges
+ * Constructor
+ *
+ * @param string $uri
+ * @param array $privileges
*/
public function __construct($uri,array $privileges) {
$this->uri = $uri;
$this->privileges = $privileges;
+ parent::__construct('User did not have the required privileges (' . implode(',', $privileges) . ') for path "' . $uri . '"');
+
}
/**
* Adds in extra information in the xml response.
*
* This method adds the {DAV:}need-privileges element as defined in rfc3744
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
$doc = $errorNode->ownerDocument;
-
+
$np = $doc->createElementNS('DAV:','d:need-privileges');
$errorNode->appendChild($np);
diff --git a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
index 60f49ebff4a..f44e3e32281 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
@@ -2,11 +2,11 @@
/**
* Sabre_DAVACL_Exception_NoAbstract
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Exception_NoAbstract extends Sabre_DAV_Exception_PreconditionFailed {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_NoAbstract extends Sabre_DAV_Exception_Precondition
* Adds in extra information in the xml response.
*
* This method adds the {DAV:}no-abstract element as defined in rfc3744
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
$doc = $errorNode->ownerDocument;
-
+
$np = $doc->createElementNS('DAV:','d:no-abstract');
$errorNode->appendChild($np);
}
}
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
index e056dc9e4f7..8d1e38ca1b4 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
@@ -2,11 +2,11 @@
/**
* Sabre_DAVACL_Exception_NotRecognizedPrincipal
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Exception_NotRecognizedPrincipal extends Sabre_DAV_Exception_PreconditionFailed {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_NotRecognizedPrincipal extends Sabre_DAV_Exception_
* Adds in extra information in the xml response.
*
* This method adds the {DAV:}recognized-principal element as defined in rfc3744
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
$doc = $errorNode->ownerDocument;
-
+
$np = $doc->createElementNS('DAV:','d:recognized-principal');
$errorNode->appendChild($np);
}
}
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
index 27db7cdd7dd..3b5d012d7fa 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
@@ -2,11 +2,11 @@
/**
* Sabre_DAVACL_Exception_NotSupportedPrivilege
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Exception_NotSupportedPrivilege extends Sabre_DAV_Exception_PreconditionFailed {
@@ -15,20 +15,18 @@ class Sabre_DAVACL_Exception_NotSupportedPrivilege extends Sabre_DAV_Exception_P
* Adds in extra information in the xml response.
*
* This method adds the {DAV:}not-supported-privilege element as defined in rfc3744
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $errorNode
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $errorNode
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
-
+
$doc = $errorNode->ownerDocument;
-
+
$np = $doc->createElementNS('DAV:','d:not-supported-privilege');
$errorNode->appendChild($np);
}
}
-
-?>
diff --git a/3rdparty/Sabre/DAVACL/IACL.php b/3rdparty/Sabre/DAVACL/IACL.php
index 506be4248d7..003e6993483 100644..100755
--- a/3rdparty/Sabre/DAVACL/IACL.php
+++ b/3rdparty/Sabre/DAVACL/IACL.php
@@ -4,11 +4,11 @@
* ACL-enabled node
*
* If you want to add WebDAV ACL to a node, you must implement this class
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
@@ -16,8 +16,8 @@ interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
function getOwner();
@@ -26,8 +26,8 @@ interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
function getGroup();
@@ -35,24 +35,39 @@ interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
function getACL();
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
function setACL(array $acl);
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ function getSupportedPrivilegeSet();
+
+
}
diff --git a/3rdparty/Sabre/DAVACL/IPrincipal.php b/3rdparty/Sabre/DAVACL/IPrincipal.php
index 7868811db76..fc7605bf625 100644..100755
--- a/3rdparty/Sabre/DAVACL/IPrincipal.php
+++ b/3rdparty/Sabre/DAVACL/IPrincipal.php
@@ -2,50 +2,50 @@
/**
* IPrincipal interface
- *
+ *
* Implement this interface to define your own principals
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAVACL_IPrincipal extends Sabre_DAV_INode {
/**
- * Returns a list of altenative urls for a principal
- *
+ * Returns a list of alternative urls for a principal
+ *
* This can for example be an email address, or ldap url.
- *
- * @return array
+ *
+ * @return array
*/
function getAlternateUriSet();
/**
- * Returns the full principal url
- *
- * @return string
+ * Returns the full principal url
+ *
+ * @return string
*/
function getPrincipalUrl();
/**
* Returns the list of group members
- *
+ *
* If this principal is a group, this function should return
- * all member principal uri's for the group.
- *
+ * all member principal uri's for the group.
+ *
* @return array
*/
function getGroupMemberSet();
/**
* Returns the list of groups this principal is member of
- *
+ *
* If this principal is a member of a (list of) groups, this function
- * should return a list of principal uri's for it's members.
- *
- * @return array
+ * should return a list of principal uri's for it's members.
+ *
+ * @return array
*/
function getGroupMembership();
@@ -54,11 +54,11 @@ interface Sabre_DAVACL_IPrincipal extends Sabre_DAV_INode {
*
* If this principal is a group, this method sets all the group members.
* The list of members is always overwritten, never appended to.
- *
- * This method should throw an exception if the members could not be set.
- *
- * @param array $principals
- * @return void
+ *
+ * This method should throw an exception if the members could not be set.
+ *
+ * @param array $principals
+ * @return void
*/
function setGroupMemberSet(array $principals);
@@ -66,9 +66,9 @@ interface Sabre_DAVACL_IPrincipal extends Sabre_DAV_INode {
* Returns the displayname
*
* This should be a human readable name for the principal.
- * If none is available, return the nodename.
- *
- * @return string
+ * If none is available, return the nodename.
+ *
+ * @return string
*/
function getDisplayName();
diff --git a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
index 8899f6f80df..e798bf890c0 100644..100755
--- a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
+++ b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
@@ -3,14 +3,14 @@
/**
* Implement this interface to create your own principal backends.
*
- * Creating backends for principals is entirely optional. You can also
- * implement Sabre_DAVACL_IPrincipal directly. This interface is used solely by
+ * Creating backends for principals is entirely optional. You can also
+ * implement Sabre_DAVACL_IPrincipal directly. This interface is used solely by
* Sabre_DAVACL_AbstractPrincipalCollection.
*
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
interface Sabre_DAVACL_IPrincipalBackend {
@@ -18,56 +18,136 @@ interface Sabre_DAVACL_IPrincipalBackend {
/**
* Returns a list of principals based on a prefix.
*
- * This prefix will often contain something like 'principals'. You are only
+ * This prefix will often contain something like 'principals'. You are only
* expected to return principals that are in this base path.
*
- * You are expected to return at least a 'uri' for every user, you can
+ * You are expected to return at least a 'uri' for every user, you can
* return any additional properties if you wish so. Common properties are:
- * {DAV:}displayname
- * {http://sabredav.org/ns}email-address - This is a custom SabreDAV
- * field that's actualy injected in a number of other properties. If
+ * {DAV:}displayname
+ * {http://sabredav.org/ns}email-address - This is a custom SabreDAV
+ * field that's actually injected in a number of other properties. If
* you have an email address, use this property.
- *
- * @param string $prefixPath
- * @return array
+ *
+ * @param string $prefixPath
+ * @return array
*/
function getPrincipalsByPrefix($prefixPath);
/**
* Returns a specific principal, specified by it's path.
- * The returned structure should be the exact same as from
- * getPrincipalsByPrefix.
- *
- * @param string $path
- * @return array
+ * The returned structure should be the exact same as from
+ * getPrincipalsByPrefix.
+ *
+ * @param string $path
+ * @return array
*/
function getPrincipalByPath($path);
/**
- * Returns the list of members for a group-principal
- *
- * @param string $principal
- * @return array
+ * Updates one ore more webdav properties on a principal.
+ *
+ * The list of mutations is supplied as an array. Each key in the array is
+ * a propertyname, such as {DAV:}displayname.
+ *
+ * Each value is the actual value to be updated. If a value is null, it
+ * must be deleted.
+ *
+ * This method should be atomic. It must either completely succeed, or
+ * completely fail. Success and failure can simply be returned as 'true' or
+ * 'false'.
+ *
+ * It is also possible to return detailed failure information. In that case
+ * an array such as this should be returned:
+ *
+ * array(
+ * 200 => array(
+ * '{DAV:}prop1' => null,
+ * ),
+ * 201 => array(
+ * '{DAV:}prop2' => null,
+ * ),
+ * 403 => array(
+ * '{DAV:}prop3' => null,
+ * ),
+ * 424 => array(
+ * '{DAV:}prop4' => null,
+ * ),
+ * );
+ *
+ * In this previous example prop1 was successfully updated or deleted, and
+ * prop2 was succesfully created.
+ *
+ * prop3 failed to update due to '403 Forbidden' and because of this prop4
+ * also could not be updated with '424 Failed dependency'.
+ *
+ * This last example was actually incorrect. While 200 and 201 could appear
+ * in 1 response, if there's any error (403) the other properties should
+ * always fail with 423 (failed dependency).
+ *
+ * But anyway, if you don't want to scratch your head over this, just
+ * return true or false.
+ *
+ * @param string $path
+ * @param array $mutations
+ * @return array|bool
+ */
+ function updatePrincipal($path, $mutations);
+
+ /**
+ * This method is used to search for principals matching a set of
+ * properties.
+ *
+ * This search is specifically used by RFC3744's principal-property-search
+ * REPORT. You should at least allow searching on
+ * http://sabredav.org/ns}email-address.
+ *
+ * The actual search should be a unicode-non-case-sensitive search. The
+ * keys in searchProperties are the WebDAV property names, while the values
+ * are the property values to search on.
+ *
+ * If multiple properties are being searched on, the search should be
+ * AND'ed.
+ *
+ * This method should simply return an array with full principal uri's.
+ *
+ * If somebody attempted to search on a property the backend does not
+ * support, you should simply return 0 results.
+ *
+ * You can also just return 0 results if you choose to not support
+ * searching at all, but keep in mind that this may stop certain features
+ * from working.
+ *
+ * @param string $prefixPath
+ * @param array $searchProperties
+ * @return array
+ */
+ function searchPrincipals($prefixPath, array $searchProperties);
+
+ /**
+ * Returns the list of members for a group-principal
+ *
+ * @param string $principal
+ * @return array
*/
function getGroupMemberSet($principal);
/**
- * Returns the list of groups a principal is a member of
- *
- * @param string $principal
- * @return array
+ * Returns the list of groups a principal is a member of
+ *
+ * @param string $principal
+ * @return array
*/
function getGroupMembership($principal);
/**
* Updates the list of group members for a group principal.
*
- * The principals should be passed as a list of uri's.
- *
- * @param string $principal
- * @param array $members
+ * The principals should be passed as a list of uri's.
+ *
+ * @param string $principal
+ * @param array $members
* @return void
*/
- function setGroupMemberSet($principal, array $members);
+ function setGroupMemberSet($principal, array $members);
}
diff --git a/3rdparty/Sabre/DAVACL/Plugin.php b/3rdparty/Sabre/DAVACL/Plugin.php
index b964bdb5dec..5c828c6d97b 100644..100755
--- a/3rdparty/Sabre/DAVACL/Plugin.php
+++ b/3rdparty/Sabre/DAVACL/Plugin.php
@@ -6,14 +6,14 @@
* This plugin provides funcitonality to enforce ACL permissions.
* ACL is defined in RFC3744.
*
- * In addition it also provides support for the {DAV:}current-user-principal
- * property, defined in RFC5397 and the {DAV:}expand-property report, as
- * defined in RFC3253.
- *
+ * In addition it also provides support for the {DAV:}current-user-principal
+ * property, defined in RFC5397 and the {DAV:}expand-property report, as
+ * defined in RFC3253.
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
@@ -40,16 +40,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
const R_RECURSIVEPARENTS = 3;
/**
- * Reference to server object.
- *
- * @var Sabre_DAV_Server
+ * Reference to server object.
+ *
+ * @var Sabre_DAV_Server
*/
protected $server;
/**
* List of urls containing principal collections.
- * Modify this if your principals are located elsewhere.
- *
+ * Modify this if your principals are located elsewhere.
+ *
* @var array
*/
public $principalCollectionSet = array(
@@ -57,14 +57,14 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
);
/**
- * By default ACL is only enforced for nodes that have ACL support (the
- * ones that implement Sabre_DAVACL_IACL). For any other node, access is
+ * By default ACL is only enforced for nodes that have ACL support (the
+ * ones that implement Sabre_DAVACL_IACL). For any other node, access is
* always granted.
*
- * To override this behaviour you can turn this setting off. This is useful
+ * To override this behaviour you can turn this setting off. This is useful
* if you plan to fully support ACL in the entire tree.
*
- * @var bool
+ * @var bool
*/
public $allowAccessToNodesWithoutACL = true;
@@ -72,28 +72,50 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* By default nodes that are inaccessible by the user, can still be seen
* in directory listings (PROPFIND on parent with Depth: 1)
*
- * In certain cases it's desirable to hide inaccessible nodes. Setting this
+ * In certain cases it's desirable to hide inaccessible nodes. Setting this
* to true will cause these nodes to be hidden from directory listings.
- *
- * @var bool
+ *
+ * @var bool
*/
public $hideNodesFromListings = false;
/**
- * This string is prepended to the username of the currently logged in
- * user. This allows the plugin to determine the principal path based on
+ * This string is prepended to the username of the currently logged in
+ * user. This allows the plugin to determine the principal path based on
* the username.
- *
+ *
* @var string
*/
public $defaultUsernamePath = 'principals';
/**
+ * This list of properties are the properties a client can search on using
+ * the {DAV:}principal-property-search report.
+ *
+ * The keys are the property names, values are descriptions.
+ *
+ * @var array
+ */
+ public $principalSearchPropertySet = array(
+ '{DAV:}displayname' => 'Display name',
+ '{http://sabredav.org/ns}email-address' => 'Email address',
+ );
+
+ /**
+ * Any principal uri's added here, will automatically be added to the list
+ * of ACL's. They will effectively receive {DAV:}all privileges, as a
+ * protected privilege.
+ *
+ * @var array
+ */
+ public $adminPrincipals = array();
+
+ /**
* Returns a list of features added by this plugin.
*
* This list is used in the response of a HTTP OPTIONS request.
- *
- * @return array
+ *
+ * @return array
*/
public function getFeatures() {
@@ -102,10 +124,10 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Returns a list of available methods for a given url
- *
- * @param string $uri
- * @return array
+ * Returns a list of available methods for a given url
+ *
+ * @param string $uri
+ * @return array
*/
public function getMethods($uri) {
@@ -115,11 +137,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Returns a plugin name.
- *
+ *
* Using this name other plugins will be able to access other plugins
- * using Sabre_DAV_Server::getPlugin
- *
- * @return string
+ * using Sabre_DAV_Server::getPlugin
+ *
+ * @return string
*/
public function getPluginName() {
@@ -131,37 +153,38 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* Returns a list of reports this plugin supports.
*
* This will be used in the {DAV:}supported-report-set property.
- * Note that you still need to subscribe to the 'report' event to actually
- * implement them
- *
+ * Note that you still need to subscribe to the 'report' event to actually
+ * implement them
+ *
* @param string $uri
- * @return array
+ * @return array
*/
public function getSupportedReportSet($uri) {
return array(
'{DAV:}expand-property',
'{DAV:}principal-property-search',
- '{DAV:}principal-search-property-set',
+ '{DAV:}principal-search-property-set',
);
}
/**
- * Checks if the current user has the specified privilege(s).
- *
+ * Checks if the current user has the specified privilege(s).
+ *
* You can specify a single privilege, or a list of privileges.
* This method will throw an exception if the privilege is not available
* and return true otherwise.
*
* @param string $uri
* @param array|string $privileges
- * @param bool $throwExceptions if set to false, this method won't through exceptions.
+ * @param int $recursion
+ * @param bool $throwExceptions if set to false, this method won't through exceptions.
* @throws Sabre_DAVACL_Exception_NeedPrivileges
- * @return bool
+ * @return bool
*/
- public function checkPrivileges($uri,$privileges,$recursion = self::R_PARENT, $throwExceptions = true) {
+ public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
if (!is_array($privileges)) $privileges = array($privileges);
@@ -171,7 +194,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
if ($this->allowAccessToNodesWithoutACL) {
return true;
} else {
- if ($throwExceptions)
+ if ($throwExceptions)
throw new Sabre_DAVACL_Exception_NeedPrivileges($uri,$privileges);
else
return false;
@@ -189,7 +212,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
if ($failed) {
- if ($throwExceptions)
+ if ($throwExceptions)
throw new Sabre_DAVACL_Exception_NeedPrivileges($uri,$failed);
else
return false;
@@ -202,9 +225,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* Returns the standard users' principal.
*
* This is one authorative principal url for the current user.
- * This method will return null if the user wasn't logged in.
- *
- * @return string|null
+ * This method will return null if the user wasn't logged in.
+ *
+ * @return string|null
*/
public function getCurrentUserPrincipal() {
@@ -220,9 +243,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Returns a list of principals that's associated to the current
- * user, either directly or through group membership.
- *
- * @return array
+ * user, either directly or through group membership.
+ *
+ * @return array
*/
public function getCurrentUserPrincipals() {
@@ -236,7 +259,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
while(count($check)) {
$principal = array_shift($check);
-
+
$node = $this->server->tree->getNodeForPath($principal);
if ($node instanceof Sabre_DAVACL_IPrincipal) {
foreach($node->getGroupMembership() as $groupMember) {
@@ -262,11 +285,38 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* Returns the supported privilege structure for this ACL plugin.
*
* See RFC3744 for more details. Currently we default on a simple,
- * standard structure.
- *
- * @return array
+ * standard structure.
+ *
+ * You can either get the list of privileges by a uri (path) or by
+ * specifying a Node.
+ *
+ * @param string|Sabre_DAV_INode $node
+ * @return array
*/
- public function getSupportedPrivilegeSet() {
+ public function getSupportedPrivilegeSet($node) {
+
+ if (is_string($node)) {
+ $node = $this->server->tree->getNodeForPath($node);
+ }
+
+ if ($node instanceof Sabre_DAVACL_IACL) {
+ $result = $node->getSupportedPrivilegeSet();
+
+ if ($result)
+ return $result;
+ }
+
+ return self::getDefaultSupportedPrivilegeSet();
+
+ }
+
+ /**
+ * Returns a fairly standard set of privileges, which may be useful for
+ * other systems to use as a basis.
+ *
+ * @return array
+ */
+ static function getDefaultSupportedPrivilegeSet() {
return array(
'privilege' => '{DAV:}all',
@@ -314,7 +364,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
),
),
), // {DAV:}write
- ),
+ ),
); // {DAV:}all
}
@@ -329,12 +379,13 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* - aggregates
* - abstract
* - concrete
- *
- * @return array
+ *
+ * @param string|Sabre_DAV_INode $node
+ * @return array
*/
- final public function getFlatPrivilegeSet() {
+ final public function getFlatPrivilegeSet($node) {
- $privs = $this->getSupportedPrivilegeSet();
+ $privs = $this->getSupportedPrivilegeSet($node);
$flat = array();
$this->getFPSTraverse($privs, null, $flat);
@@ -346,9 +397,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Traverses the privilege set tree for reordering
*
- * This function is solely used by getFlatPrivilegeSet, and would have been
+ * This function is solely used by getFlatPrivilegeSet, and would have been
* a closure if it wasn't for the fact I need to support PHP 5.2.
- *
+ *
+ * @param array $priv
+ * @param $concrete
+ * @param array $flat
* @return void
*/
final private function getFPSTraverse($priv, $concrete, &$flat) {
@@ -368,7 +422,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
if (isset($priv['aggregates'])) {
foreach($priv['aggregates'] as $subPriv) {
-
+
$this->getFPSTraverse($subPriv, $myPriv['concrete'], $flat);
}
@@ -382,8 +436,8 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
*
* Either a uri or a Sabre_DAV_INode may be passed.
*
- * null will be returned if the node doesn't support ACLs.
- *
+ * null will be returned if the node doesn't support ACLs.
+ *
* @param string|Sabre_DAV_INode $node
* @return array
*/
@@ -392,10 +446,18 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
if (is_string($node)) {
$node = $this->server->tree->getNodeForPath($node);
}
- if ($node instanceof Sabre_DAVACL_IACL) {
- return $node->getACL();
+ if (!$node instanceof Sabre_DAVACL_IACL) {
+ return null;
}
- return null;
+ $acl = $node->getACL();
+ foreach($this->adminPrincipals as $adminPrincipal) {
+ $acl[] = array(
+ 'principal' => $adminPrincipal,
+ 'privilege' => '{DAV:}all',
+ 'protected' => true,
+ );
+ }
+ return $acl;
}
@@ -405,10 +467,10 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
*
* Either a uri or a Sabre_DAV_INode may be passed.
*
- * null will be returned if the node doesn't support ACLs.
- *
- * @param string|Sabre_DAV_INode $node
- * @return array
+ * null will be returned if the node doesn't support ACLs.
+ *
+ * @param string|Sabre_DAV_INode $node
+ * @return array
*/
public function getCurrentUserPrivilegeSet($node) {
@@ -417,6 +479,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
$acl = $this->getACL($node);
+
if (is_null($acl)) return null;
$principals = $this->getCurrentUserPrincipals();
@@ -425,27 +488,121 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
foreach($acl as $ace) {
- if (in_array($ace['principal'], $principals)) {
- $collected[] = $ace;
+ $principal = $ace['principal'];
+
+ switch($principal) {
+
+ case '{DAV:}owner' :
+ $owner = $node->getOwner();
+ if ($owner && in_array($owner, $principals)) {
+ $collected[] = $ace;
+ }
+ break;
+
+
+ // 'all' matches for every user
+ case '{DAV:}all' :
+
+ // 'authenticated' matched for every user that's logged in.
+ // Since it's not possible to use ACL while not being logged
+ // in, this is also always true.
+ case '{DAV:}authenticated' :
+ $collected[] = $ace;
+ break;
+
+ // 'unauthenticated' can never occur either, so we simply
+ // ignore these.
+ case '{DAV:}unauthenticated' :
+ break;
+
+ default :
+ if (in_array($ace['principal'], $principals)) {
+ $collected[] = $ace;
+ }
+ break;
+
}
+
+
}
// Now we deduct all aggregated privileges.
- $flat = $this->getFlatPrivilegeSet();
+ $flat = $this->getFlatPrivilegeSet($node);
$collected2 = array();
- foreach($collected as $privilege) {
+ while(count($collected)) {
+
+ $current = array_pop($collected);
+ $collected2[] = $current['privilege'];
- $collected2[] = $privilege['privilege'];
- foreach($flat[$privilege['privilege']]['aggregates'] as $subPriv) {
- if (!in_array($subPriv, $collected2))
- $collected2[] = $subPriv;
+ foreach($flat[$current['privilege']]['aggregates'] as $subPriv) {
+ $collected2[] = $subPriv;
+ $collected[] = $flat[$subPriv];
}
}
- return $collected2;
+ return array_values(array_unique($collected2));
+
+ }
+
+ /**
+ * Principal property search
+ *
+ * This method can search for principals matching certain values in
+ * properties.
+ *
+ * This method will return a list of properties for the matched properties.
+ *
+ * @param array $searchProperties The properties to search on. This is a
+ * key-value list. The keys are property
+ * names, and the values the strings to
+ * match them on.
+ * @param array $requestedProperties This is the list of properties to
+ * return for every match.
+ * @param string $collectionUri The principal collection to search on.
+ * If this is ommitted, the standard
+ * principal collection-set will be used.
+ * @return array This method returns an array structure similar to
+ * Sabre_DAV_Server::getPropertiesForPath. Returned
+ * properties are index by a HTTP status code.
+ *
+ */
+ public function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null) {
+
+ if (!is_null($collectionUri)) {
+ $uris = array($collectionUri);
+ } else {
+ $uris = $this->principalCollectionSet;
+ }
+
+ $lookupResults = array();
+ foreach($uris as $uri) {
+
+ $principalCollection = $this->server->tree->getNodeForPath($uri);
+ if (!$principalCollection instanceof Sabre_DAVACL_AbstractPrincipalCollection) {
+ // Not a principal collection, we're simply going to ignore
+ // this.
+ continue;
+ }
+
+ $results = $principalCollection->searchPrincipals($searchProperties);
+ foreach($results as $result) {
+ $lookupResults[] = rtrim($uri,'/') . '/' . $result;
+ }
+
+ }
+
+ $matches = array();
+
+ foreach($lookupResults as $lookupResult) {
+
+ list($matches[]) = $this->server->getPropertiesForPath($lookupResult, $requestedProperties, 0);
+
+ }
+
+ return $matches;
}
@@ -453,8 +610,8 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* Sets up the plugin
*
* This method is automatically called by the server class.
- *
- * @param Sabre_DAV_Server $server
+ *
+ * @param Sabre_DAV_Server $server
* @return void
*/
public function initialize(Sabre_DAV_Server $server) {
@@ -485,11 +642,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
'{DAV:}group'
);
- // Automatically mapping nodes implementing IPrincipal to the
+ // Automatically mapping nodes implementing IPrincipal to the
// {DAV:}principal resourcetype.
$server->resourceTypeMapping['Sabre_DAVACL_IPrincipal'] = '{DAV:}principal';
- // Mapping the group-member-set property to the HrefList property
+ // Mapping the group-member-set property to the HrefList property
// class.
$server->propertyMap['{DAV:}group-member-set'] = 'Sabre_DAV_Property_HrefList';
@@ -499,10 +656,10 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/* {{{ Event handlers */
/**
- * Triggered before any method is handled
- *
- * @param string $method
- * @param string $uri
+ * Triggered before any method is handled
+ *
+ * @param string $method
+ * @param string $uri
* @return void
*/
public function beforeMethod($method, $uri) {
@@ -523,14 +680,14 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
case 'PUT' :
case 'LOCK' :
- case 'UNLOCK' :
- // This method requires the write-content priv if the node
- // already exists, and bind on the parent if the node is being
- // created.
- // The bind privilege is handled in the beforeBind event.
+ case 'UNLOCK' :
+ // This method requires the write-content priv if the node
+ // already exists, and bind on the parent if the node is being
+ // created.
+ // The bind privilege is handled in the beforeBind event.
$this->checkPrivileges($uri,'{DAV:}write-content');
break;
-
+
case 'PROPPATCH' :
$this->checkPrivileges($uri,'{DAV:}write-properties');
@@ -543,16 +700,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
case 'COPY' :
case 'MOVE' :
// Copy requires read privileges on the entire source tree.
- // If the target exists write-content normally needs to be
- // checked, however, we're deleting the node beforehand and
- // creating a new one after, so this is handled by the
+ // If the target exists write-content normally needs to be
+ // checked, however, we're deleting the node beforehand and
+ // creating a new one after, so this is handled by the
// beforeUnbind event.
- //
- // The creation of the new node is handled by the beforeBind
+ //
+ // The creation of the new node is handled by the beforeBind
// event.
//
- // If MOVE is used beforeUnbind will also be used to check if
- // the sourcenode can be deleted.
+ // If MOVE is used beforeUnbind will also be used to check if
+ // the sourcenode can be deleted.
$this->checkPrivileges($uri,'{DAV:}read',self::R_RECURSIVE);
break;
@@ -563,11 +720,11 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/**
* Triggered before a new node is created.
- *
+ *
* This allows us to check permissions for any operation that creates a
* new node, such as PUT, MKCOL, MKCALENDAR, LOCK, COPY and MOVE.
- *
- * @param string $uri
+ *
+ * @param string $uri
* @return void
*/
public function beforeBind($uri) {
@@ -578,12 +735,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Triggered before a node is deleted
- *
- * This allows us to check permissions for any operation that will delete
- * an existing node.
- *
- * @param string $uri
+ * Triggered before a node is deleted
+ *
+ * This allows us to check permissions for any operation that will delete
+ * an existing node.
+ *
+ * @param string $uri
* @return void
*/
public function beforeUnbind($uri) {
@@ -594,26 +751,26 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * Triggered before a node is unlocked.
- *
- * @param string $uri
+ * Triggered before a node is unlocked.
+ *
+ * @param string $uri
* @param Sabre_DAV_Locks_LockInfo $lock
- * @TODO: not yet implemented
+ * @TODO: not yet implemented
* @return void
*/
public function beforeUnlock($uri, Sabre_DAV_Locks_LockInfo $lock) {
-
+
}
/**
- * Triggered before properties are looked up in specific nodes.
- *
- * @param string $uri
- * @param Sabre_DAV_INode $node
- * @param array $requestedProperties
+ * Triggered before properties are looked up in specific nodes.
+ *
+ * @param string $uri
+ * @param Sabre_DAV_INode $node
+ * @param array $requestedProperties
* @param array $returnedProperties
- * @TODO really should be broken into multiple methods, or even a class.
+ * @TODO really should be broken into multiple methods, or even a class.
* @return void
*/
public function beforeGetProperties($uri, Sabre_DAV_INode $node, &$requestedProperties, &$returnedProperties) {
@@ -633,7 +790,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
return;
- }
+ }
/* Adding principal properties */
if ($node instanceof Sabre_DAVACL_IPrincipal) {
@@ -692,7 +849,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
if (false !== ($index = array_search('{DAV:}supported-privilege-set', $requestedProperties))) {
unset($requestedProperties[$index]);
- $returnedProperties[200]['{DAV:}supported-privilege-set'] = new Sabre_DAVACL_Property_SupportedPrivilegeSet($this->getSupportedPrivilegeSet());
+ $returnedProperties[200]['{DAV:}supported-privilege-set'] = new Sabre_DAVACL_Property_SupportedPrivilegeSet($this->getSupportedPrivilegeSet($node));
}
if (false !== ($index = array_search('{DAV:}current-user-privilege-set', $requestedProperties))) {
@@ -730,16 +887,24 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
+ /* The acl-restrictions property contains information on how privileges
+ * must behave.
+ */
+ if (false !== ($index = array_search('{DAV:}acl-restrictions', $requestedProperties))) {
+ unset($requestedProperties[$index]);
+ $returnedProperties[200]['{DAV:}acl-restrictions'] = new Sabre_DAVACL_Property_AclRestrictions();
+ }
+
}
/**
- * This method intercepts PROPPATCH methods and make sure the
- * group-member-set is updated correctly.
- *
- * @param array $propertyDelta
- * @param array $result
- * @param Sabre_DAV_INode $node
- * @return void
+ * This method intercepts PROPPATCH methods and make sure the
+ * group-member-set is updated correctly.
+ *
+ * @param array $propertyDelta
+ * @param array $result
+ * @param Sabre_DAV_INode $node
+ * @return bool
*/
public function updateProperties(&$propertyDelta, &$result, Sabre_DAV_INode $node) {
@@ -763,18 +928,18 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
$node->setGroupMemberSet($memberSet);
-
+
$result[200]['{DAV:}group-member-set'] = null;
unset($propertyDelta['{DAV:}group-member-set']);
}
/**
- * This method handels HTTP REPORT requests
- *
- * @param string $reportName
- * @param DOMNode $dom
- * @return void
+ * This method handels HTTP REPORT requests
+ *
+ * @param string $reportName
+ * @param DOMNode $dom
+ * @return bool
*/
public function report($reportName, $dom) {
@@ -785,7 +950,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
return false;
case '{DAV:}principal-search-property-set' :
$this->principalSearchPropertySetReport($dom);
- return false;
+ return false;
case '{DAV:}expand-property' :
$this->expandPropertyReport($dom);
return false;
@@ -795,12 +960,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
- * This event is triggered for any HTTP method that is not known by the
- * webserver.
+ * This event is triggered for any HTTP method that is not known by the
+ * webserver.
*
- * @param string $method
- * @param string $uri
- * @return void
+ * @param string $method
+ * @param string $uri
+ * @return bool
*/
public function unknownMethod($method, $uri) {
@@ -817,12 +982,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* @param string $uri
* @return void
*/
- public function httpACL($uri) {
+ public function httpACL($uri) {
$body = $this->server->httpRequest->getBody(true);
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
- $newAcl =
+ $newAcl =
Sabre_DAVACL_Property_Acl::unserialize($dom->firstChild)
->getPrivileges();
@@ -839,13 +1004,13 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
$oldAcl = $this->getACL($node);
- $supportedPrivileges = $this->getFlatPrivilegeSet();
+ $supportedPrivileges = $this->getFlatPrivilegeSet($node);
- /* Checking if protected principals from the existing principal set are
+ /* Checking if protected principals from the existing principal set are
not overwritten. */
- foreach($oldAcl as $k=>$oldAce) {
+ foreach($oldAcl as $oldAce) {
- if (!isset($oldAce['protected']) || !$oldAce['protected']) continue;
+ if (!isset($oldAce['protected']) || !$oldAce['protected']) continue;
$found = false;
foreach($newAcl as $newAce) {
@@ -853,16 +1018,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
$newAce['privilege'] === $oldAce['privilege'] &&
$newAce['principal'] === $oldAce['principal'] &&
$newAce['protected']
- )
+ )
$found = true;
}
- if (!$found)
+ if (!$found)
throw new Sabre_DAVACL_Exception_AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
}
- foreach($newAcl as $k=>$newAce) {
+ foreach($newAcl as $newAce) {
// Do we recognize the privilege
if (!isset($supportedPrivileges[$newAce['privilege']])) {
@@ -876,12 +1041,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
// Looking up the principal
try {
$principal = $this->server->tree->getNodeForPath($newAce['principal']);
- } catch (Sabre_DAV_Exception_FileNotFound $e) {
+ } catch (Sabre_DAV_Exception_NotFound $e) {
throw new Sabre_DAVACL_Exception_NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist');
}
if (!($principal instanceof Sabre_DAVACL_IPrincipal)) {
throw new Sabre_DAVACL_Exception_NotRecognizedPrincipal('The specified uri (' . $newAce['principal'] . ') is not a principal');
- }
+ }
}
$node->setACL($newAcl);
@@ -893,7 +1058,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/* Reports {{{ */
/**
- * The expand-property report is defined in RFC3253 section 3-8.
+ * The expand-property report is defined in RFC3253 section 3-8.
*
* This report is very similar to a standard PROPFIND. The difference is
* that it has the additional ability to look at properties containing a
@@ -903,7 +1068,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* Other rfc's, such as ACL rely on this report, so it made sense to put
* it in this plugin.
*
- * @param DOMElement $dom
+ * @param DOMElement $dom
* @return void
*/
protected function expandPropertyReport($dom) {
@@ -940,9 +1105,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/**
* This method is used by expandPropertyReport to parse
* out the entire HTTP request.
- *
- * @param DOMElement $node
- * @return array
+ *
+ * @param DOMElement $node
+ * @return array
*/
protected function parseExpandPropertyReportRequest($node) {
@@ -950,9 +1115,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
do {
if (Sabre_DAV_XMLUtil::toClarkNotation($node)!=='{DAV:}property') continue;
-
+
if ($node->firstChild) {
-
+
$children = $this->parseExpandPropertyReportRequest($node->firstChild);
} else {
@@ -965,7 +1130,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
if (!$namespace) $namespace = 'DAV:';
$propName = '{'.$namespace.'}' . $node->getAttribute('name');
- $requestedProperties[$propName] = $children;
+ $requestedProperties[$propName] = $children;
} while ($node = $node->nextSibling);
@@ -979,11 +1144,12 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
*
* @param array $path
* @param array $requestedProperties the list of required properties
- * @param array $depth
+ * @param int $depth
+ * @return array
*/
- protected function expandProperties($path,array $requestedProperties,$depth) {
+ protected function expandProperties($path, array $requestedProperties, $depth) {
- $foundProperties = $this->server->getPropertiesForPath($path,array_keys($requestedProperties),$depth);
+ $foundProperties = $this->server->getPropertiesForPath($path, array_keys($requestedProperties), $depth);
$result = array();
@@ -993,7 +1159,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
// We're only traversing if sub-properties were requested
if(count($childRequestedProperties)===0) continue;
-
+
// We only have to do the expansion if the property was found
// and it contains an href element.
if (!array_key_exists($propertyName,$node[200])) continue;
@@ -1006,7 +1172,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
$childProps = array();
foreach($hrefs as $href) {
- $childProps = array_merge($childProps, $this->expandProperties($href,$childRequestedProperties,0));
+ $childProps = array_merge($childProps, $this->expandProperties($href, $childRequestedProperties, 0));
}
$node[200][$propertyName] = new Sabre_DAV_Property_ResponseList($childProps);
@@ -1022,27 +1188,23 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/**
* principalSearchPropertySetReport
*
- * This method responsible for handing the
+ * This method responsible for handing the
* {DAV:}principal-search-property-set report. This report returns a list
* of properties the client may search on, using the
* {DAV:}principal-property-search report.
- *
- * @param DOMDocument $dom
+ *
+ * @param DOMDocument $dom
* @return void
*/
protected function principalSearchPropertySetReport(DOMDocument $dom) {
- $searchProperties = array(
- '{DAV:}displayname' => 'display name'
- );
-
$httpDepth = $this->server->getHTTPDepth(0);
if ($httpDepth!==0) {
throw new Sabre_DAV_Exception_BadRequest('This report is only defined when Depth: 0');
}
-
- if ($dom->firstChild->hasChildNodes())
- throw new Sabre_DAV_Exception_BadRequest('The principal-search-property-set report element is not allowed to have child elements');
+
+ if ($dom->firstChild->hasChildNodes())
+ throw new Sabre_DAV_Exception_BadRequest('The principal-search-property-set report element is not allowed to have child elements');
$dom = new DOMDocument('1.0','utf-8');
$dom->formatOutput = true;
@@ -1055,16 +1217,16 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
}
- $nsList = $this->server->xmlNamespaces;
+ $nsList = $this->server->xmlNamespaces;
- foreach($searchProperties as $propertyName=>$description) {
+ foreach($this->principalSearchPropertySet as $propertyName=>$description) {
$psp = $dom->createElement('d:principal-search-property');
$root->appendChild($psp);
$prop = $dom->createElement('d:prop');
$psp->appendChild($prop);
-
+
$propName = null;
preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName);
@@ -1088,78 +1250,25 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
/**
* principalPropertySearchReport
*
- * This method is reponsible for handing the
- * {DAV:}principal-property-search report. This report can be used for
+ * This method is responsible for handing the
+ * {DAV:}principal-property-search report. This report can be used for
* clients to search for groups of principals, based on the value of one
* or more properties.
- *
- * @param DOMDocument $dom
+ *
+ * @param DOMDocument $dom
* @return void
*/
protected function principalPropertySearchReport(DOMDocument $dom) {
- $searchableProperties = array(
- '{DAV:}displayname' => 'display name'
-
- );
-
list($searchProperties, $requestedProperties, $applyToPrincipalCollectionSet) = $this->parsePrincipalPropertySearchReportRequest($dom);
- $result = array();
-
- if ($applyToPrincipalCollectionSet) {
- $uris = array();
- } else {
- $uris = array($this->server->getRequestUri());
- }
-
- $lookupResults = array();
- foreach($uris as $uri) {
-
- $p = array_keys($searchProperties);
- $p[] = '{DAV:}resourcetype';
- $r = $this->server->getPropertiesForPath($uri, $p, 1);
-
- // The first item in the results is the parent, so we get rid of it.
- array_shift($r);
- $lookupResults = array_merge($lookupResults, $r);
- }
-
- $matches = array();
-
- foreach($lookupResults as $lookupResult) {
-
- // We're only looking for principals
- if (!isset($lookupResult[200]['{DAV:}resourcetype']) ||
- (!($lookupResult[200]['{DAV:}resourcetype'] instanceof Sabre_DAV_Property_ResourceType)) ||
- !$lookupResult[200]['{DAV:}resourcetype']->is('{DAV:}principal')) continue;
-
- foreach($searchProperties as $searchProperty=>$searchValue) {
- if (!isset($searchableProperties[$searchProperty])) {
- // If a property is not 'searchable', the spec dictates
- // this is not a match.
- continue;
- }
-
- if (isset($lookupResult[200][$searchProperty]) &&
- mb_stripos($lookupResult[200][$searchProperty], $searchValue, 0, 'UTF-8')!==false) {
- $matches[] = $lookupResult['href'];
- }
-
- }
-
+ $uri = null;
+ if (!$applyToPrincipalCollectionSet) {
+ $uri = $this->server->getRequestUri();
}
+ $result = $this->principalSearch($searchProperties, $requestedProperties, $uri);
- $matchProperties = array();
-
- foreach($matches as $match) {
-
- list($result) = $this->server->getPropertiesForPath($match, $requestedProperties, 0);
- $matchProperties[] = $result;
-
- }
-
- $xml = $this->server->generateMultiStatus($matchProperties);
+ $xml = $this->server->generateMultiStatus($result);
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
$this->server->httpResponse->sendStatus(207);
$this->server->httpResponse->sendBody($xml);
@@ -1175,9 +1284,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
* This method returns an array with two elements:
* 1. an array with properties to search on, and their values
* 2. a list of propertyvalues that should be returned for the request.
- *
- * @param DOMDocument $dom
- * @return array
+ *
+ * @param DOMDocument $dom
+ * @return array
*/
protected function parsePrincipalPropertySearchReportRequest($dom) {
@@ -1193,8 +1302,9 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
// Parsing the search request
foreach($dom->firstChild->childNodes as $searchNode) {
- if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode) == '{DAV:}apply-to-principal-collection-set')
+ if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode) == '{DAV:}apply-to-principal-collection-set') {
$applyToPrincipalCollectionSet = true;
+ }
if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode)!=='{DAV:}property-search')
continue;
@@ -1208,7 +1318,7 @@ class Sabre_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
case '{DAV:}prop' :
$property = Sabre_DAV_XMLUtil::parseProperties($searchNode);
- reset($property);
+ reset($property);
$propertyName = key($property);
break;
diff --git a/3rdparty/Sabre/DAVACL/Principal.php b/3rdparty/Sabre/DAVACL/Principal.php
index 790603c900f..51c6658afd6 100644..100755
--- a/3rdparty/Sabre/DAVACL/Principal.php
+++ b/3rdparty/Sabre/DAVACL/Principal.php
@@ -4,17 +4,17 @@
* Principal class
*
* This class is a representation of a simple principal
- *
- * Many WebDAV specs require a user to show up in the directory
- * structure.
+ *
+ * Many WebDAV specs require a user to show up in the directory
+ * structure.
*
* This principal also has basic ACL settings, only allowing the principal
- * access it's own principal.
- *
+ * access it's own principal.
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPrincipal, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
@@ -22,20 +22,21 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
/**
* Struct with principal information.
*
- * @var array
+ * @var array
*/
protected $principalProperties;
/**
- * Principal backend
- *
- * @var Sabre_DAVACL_IPrincipalBackend
+ * Principal backend
+ *
+ * @var Sabre_DAVACL_IPrincipalBackend
*/
protected $principalBackend;
/**
- * Creates the principal object
+ * Creates the principal object
*
+ * @param Sabre_DAVACL_IPrincipalBackend $principalBackend
* @param array $principalProperties
*/
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, array $principalProperties = array()) {
@@ -49,22 +50,22 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
}
/**
- * Returns the full principal url
- *
- * @return string
+ * Returns the full principal url
+ *
+ * @return string
*/
public function getPrincipalUrl() {
return $this->principalProperties['uri'];
- }
+ }
/**
- * Returns a list of altenative urls for a principal
- *
+ * Returns a list of alternative urls for a principal
+ *
* This can for example be an email address, or ldap url.
- *
- * @return array
+ *
+ * @return array
*/
public function getAlternateUriSet() {
@@ -79,16 +80,16 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
$uris[] = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address'];
}
- return array_unique($uris);
+ return array_unique($uris);
}
/**
* Returns the list of group members
- *
+ *
* If this principal is a group, this function should return
- * all member principal uri's for the group.
- *
+ * all member principal uri's for the group.
+ *
* @return array
*/
public function getGroupMemberSet() {
@@ -99,11 +100,11 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
/**
* Returns the list of groups this principal is member of
- *
+ *
* If this principal is a member of a (list of) groups, this function
- * should return a list of principal uri's for it's members.
- *
- * @return array
+ * should return a list of principal uri's for it's members.
+ *
+ * @return array
*/
public function getGroupMembership() {
@@ -117,11 +118,11 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
*
* If this principal is a group, this method sets all the group members.
* The list of members is always overwritten, never appended to.
- *
- * This method should throw an exception if the members could not be set.
- *
- * @param array $principals
- * @return void
+ *
+ * This method should throw an exception if the members could not be set.
+ *
+ * @param array $groupMembers
+ * @return void
*/
public function setGroupMemberSet(array $groupMembers) {
@@ -132,22 +133,21 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
/**
* Returns this principals name.
- *
- * @return string
+ *
+ * @return string
*/
public function getName() {
$uri = $this->principalProperties['uri'];
list(, $name) = Sabre_DAV_URLUtil::splitPath($uri);
-
return $name;
}
/**
- * Returns the name of the user
- *
- * @return void
+ * Returns the name of the user
+ *
+ * @return string
*/
public function getDisplayName() {
@@ -160,16 +160,16 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
}
/**
- * Returns a list of properties
- *
- * @param array $requestedProperties
- * @return void
+ * Returns a list of properties
+ *
+ * @param array $requestedProperties
+ * @return array
*/
public function getProperties($requestedProperties) {
$newProperties = array();
foreach($requestedProperties as $propName) {
-
+
if (isset($this->principalProperties[$propName])) {
$newProperties[$propName] = $this->principalProperties[$propName];
}
@@ -177,29 +177,27 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
}
return $newProperties;
-
+
}
/**
* Updates this principals properties.
- *
- * Currently this is not supported
*
- * @param array $properties
+ * @param array $mutations
* @see Sabre_DAV_IProperties::updateProperties
- * @return bool|array
+ * @return bool|array
*/
- public function updateProperties($properties) {
+ public function updateProperties($mutations) {
- return false;
+ return $this->principalBackend->updatePrincipal($this->principalProperties['uri'], $mutations);
}
/**
* Returns the owner principal
*
- * This must be a url to a principal, or null if there's no owner
- *
+ * This must be a url to a principal, or null if there's no owner
+ *
* @return string|null
*/
public function getOwner() {
@@ -213,8 +211,8 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
* Returns a group principal
*
* This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ *
+ * @return string|null
*/
public function getGroup() {
@@ -226,20 +224,20 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
* currently the only supported privileges
* * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
*/
public function getACL() {
return array(
array(
'privilege' => '{DAV:}read',
- 'principal' => $this->principalProperties['uri'],
+ 'principal' => $this->getPrincipalUrl(),
'protected' => true,
),
);
@@ -249,9 +247,9 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
/**
* Updates the ACL
*
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
+ * This method will receive a list of new ACE's.
+ *
+ * @param array $acl
* @return void
*/
public function setACL(array $acl) {
@@ -260,4 +258,22 @@ class Sabre_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPri
}
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ public function getSupportedPrivilegeSet() {
+
+ return null;
+
+ }
+
}
diff --git a/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
index 55bd1903c9b..a76b4a9d727 100644..100755
--- a/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
+++ b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
@@ -3,46 +3,80 @@
/**
* PDO principal backend
*
- * This is a simple principal backend that maps exactly to the users table, as
+ * This is a simple principal backend that maps exactly to the users table, as
* used by Sabre_DAV_Auth_Backend_PDO.
*
- * It assumes all principals are in a single collection. The default collection
+ * It assumes all principals are in a single collection. The default collection
* is 'principals/', but this can be overriden.
*
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBackend {
/**
- * pdo
- *
- * @var PDO
+ * pdo
+ *
+ * @var PDO
*/
protected $pdo;
/**
- * PDO table name for 'principals'
- *
- * @var string
+ * PDO table name for 'principals'
+ *
+ * @var string
*/
protected $tableName;
/**
- * PDO table name for 'group members'
- *
- * @var string
+ * PDO table name for 'group members'
+ *
+ * @var string
*/
protected $groupMembersTableName;
/**
+ * A list of additional fields to support
+ *
+ * @var array
+ */
+ protected $fieldMap = array(
+
+ /**
+ * This property can be used to display the users' real name.
+ */
+ '{DAV:}displayname' => array(
+ 'dbField' => 'displayname',
+ ),
+
+ /**
+ * This property is actually used by the CardDAV plugin, where it gets
+ * mapped to {http://calendarserver.orgi/ns/}me-card.
+ *
+ * The reason we don't straight-up use that property, is because
+ * me-card is defined as a property on the users' addressbook
+ * collection.
+ */
+ '{http://sabredav.org/ns}vcard-url' => array(
+ 'dbField' => 'vcardurl',
+ ),
+ /**
+ * This is the users' primary email-address.
+ */
+ '{http://sabredav.org/ns}email-address' => array(
+ 'dbField' => 'email',
+ ),
+ );
+
+ /**
* Sets up the backend.
- *
+ *
* @param PDO $pdo
- * @param string $tableName
+ * @param string $tableName
+ * @param string $groupMembersTableName
*/
public function __construct(PDO $pdo, $tableName = 'principals', $groupMembersTableName = 'groupmembers') {
@@ -50,27 +84,35 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
$this->tableName = $tableName;
$this->groupMembersTableName = $groupMembersTableName;
- }
+ }
/**
* Returns a list of principals based on a prefix.
*
- * This prefix will often contain something like 'principals'. You are only
+ * This prefix will often contain something like 'principals'. You are only
* expected to return principals that are in this base path.
*
- * You are expected to return at least a 'uri' for every user, you can
+ * You are expected to return at least a 'uri' for every user, you can
* return any additional properties if you wish so. Common properties are:
- * {DAV:}displayname
- * {http://sabredav.org/ns}email-address - This is a custom SabreDAV
+ * {DAV:}displayname
+ * {http://sabredav.org/ns}email-address - This is a custom SabreDAV
* field that's actualy injected in a number of other properties. If
* you have an email address, use this property.
- *
- * @param string $prefixPath
- * @return array
+ *
+ * @param string $prefixPath
+ * @return array
*/
public function getPrincipalsByPrefix($prefixPath) {
- $result = $this->pdo->query('SELECT uri, email, displayname FROM `'. $this->tableName . '`');
+
+ $fields = array(
+ 'uri',
+ );
+
+ foreach($this->fieldMap as $key=>$value) {
+ $fields[] = $value['dbField'];
+ }
+ $result = $this->pdo->query('SELECT '.implode(',', $fields).' FROM '. $this->tableName);
$principals = array();
@@ -80,11 +122,15 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']);
if ($rowPrefix !== $prefixPath) continue;
- $principals[] = array(
+ $principal = array(
'uri' => $row['uri'],
- '{DAV:}displayname' => $row['displayname']?$row['displayname']:basename($row['uri']),
- '{http://sabredav.org/ns}email-address' => $row['email'],
);
+ foreach($this->fieldMap as $key=>$value) {
+ if ($row[$value['dbField']]) {
+ $principal[$key] = $row[$value['dbField']];
+ }
+ }
+ $principals[] = $principal;
}
@@ -94,43 +140,218 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
/**
* Returns a specific principal, specified by it's path.
- * The returned structure should be the exact same as from
- * getPrincipalsByPrefix.
- *
- * @param string $path
- * @return array
+ * The returned structure should be the exact same as from
+ * getPrincipalsByPrefix.
+ *
+ * @param string $path
+ * @return array
*/
public function getPrincipalByPath($path) {
- $stmt = $this->pdo->prepare('SELECT id, uri, email, displayname FROM `'.$this->tableName.'` WHERE uri = ?');
- $stmt->execute(array($path));
+ $fields = array(
+ 'id',
+ 'uri',
+ );
- $users = array();
+ foreach($this->fieldMap as $key=>$value) {
+ $fields[] = $value['dbField'];
+ }
+ $stmt = $this->pdo->prepare('SELECT '.implode(',', $fields).' FROM '. $this->tableName . ' WHERE uri = ?');
+ $stmt->execute(array($path));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) return;
- return array(
+ $principal = array(
'id' => $row['id'],
'uri' => $row['uri'],
- '{DAV:}displayname' => $row['displayname']?$row['displayname']:basename($row['uri']),
- '{http://sabredav.org/ns}email-address' => $row['email'],
);
+ foreach($this->fieldMap as $key=>$value) {
+ if ($row[$value['dbField']]) {
+ $principal[$key] = $row[$value['dbField']];
+ }
+ }
+ return $principal;
+
+ }
+
+ /**
+ * Updates one ore more webdav properties on a principal.
+ *
+ * The list of mutations is supplied as an array. Each key in the array is
+ * a propertyname, such as {DAV:}displayname.
+ *
+ * Each value is the actual value to be updated. If a value is null, it
+ * must be deleted.
+ *
+ * This method should be atomic. It must either completely succeed, or
+ * completely fail. Success and failure can simply be returned as 'true' or
+ * 'false'.
+ *
+ * It is also possible to return detailed failure information. In that case
+ * an array such as this should be returned:
+ *
+ * array(
+ * 200 => array(
+ * '{DAV:}prop1' => null,
+ * ),
+ * 201 => array(
+ * '{DAV:}prop2' => null,
+ * ),
+ * 403 => array(
+ * '{DAV:}prop3' => null,
+ * ),
+ * 424 => array(
+ * '{DAV:}prop4' => null,
+ * ),
+ * );
+ *
+ * In this previous example prop1 was successfully updated or deleted, and
+ * prop2 was succesfully created.
+ *
+ * prop3 failed to update due to '403 Forbidden' and because of this prop4
+ * also could not be updated with '424 Failed dependency'.
+ *
+ * This last example was actually incorrect. While 200 and 201 could appear
+ * in 1 response, if there's any error (403) the other properties should
+ * always fail with 423 (failed dependency).
+ *
+ * But anyway, if you don't want to scratch your head over this, just
+ * return true or false.
+ *
+ * @param string $path
+ * @param array $mutations
+ * @return array|bool
+ */
+ public function updatePrincipal($path, $mutations) {
+
+ $updateAble = array();
+ foreach($mutations as $key=>$value) {
+
+ // We are not aware of this field, we must fail.
+ if (!isset($this->fieldMap[$key])) {
+
+ $response = array(
+ 403 => array(
+ $key => null,
+ ),
+ 424 => array(),
+ );
+
+ // Adding the rest to the response as a 424
+ foreach($mutations as $subKey=>$subValue) {
+ if ($subKey !== $key) {
+ $response[424][$subKey] = null;
+ }
+ }
+ return $response;
+ }
+
+ $updateAble[$this->fieldMap[$key]['dbField']] = $value;
+
+ }
+
+ // No fields to update
+ $query = "UPDATE " . $this->tableName . " SET ";
+
+ $first = true;
+ foreach($updateAble as $key => $value) {
+ if (!$first) {
+ $query.= ', ';
+ }
+ $first = false;
+ $query.= "$key = :$key ";
+ }
+ $query.='WHERE uri = :uri';
+ $stmt = $this->pdo->prepare($query);
+ $updateAble['uri'] = $path;
+ $stmt->execute($updateAble);
+
+ return true;
}
/**
- * Returns the list of members for a group-principal
- *
- * @param string $principal
- * @return array
+ * This method is used to search for principals matching a set of
+ * properties.
+ *
+ * This search is specifically used by RFC3744's principal-property-search
+ * REPORT. You should at least allow searching on
+ * http://sabredav.org/ns}email-address.
+ *
+ * The actual search should be a unicode-non-case-sensitive search. The
+ * keys in searchProperties are the WebDAV property names, while the values
+ * are the property values to search on.
+ *
+ * If multiple properties are being searched on, the search should be
+ * AND'ed.
+ *
+ * This method should simply return an array with full principal uri's.
+ *
+ * If somebody attempted to search on a property the backend does not
+ * support, you should simply return 0 results.
+ *
+ * You can also just return 0 results if you choose to not support
+ * searching at all, but keep in mind that this may stop certain features
+ * from working.
+ *
+ * @param string $prefixPath
+ * @param array $searchProperties
+ * @return array
+ */
+ public function searchPrincipals($prefixPath, array $searchProperties) {
+
+ $query = 'SELECT uri FROM ' . $this->tableName . ' WHERE 1=1 ';
+ $values = array();
+ foreach($searchProperties as $property => $value) {
+
+ switch($property) {
+
+ case '{DAV:}displayname' :
+ $query.=' AND displayname LIKE ?';
+ $values[] = '%' . $value . '%';
+ break;
+ case '{http://sabredav.org/ns}email-address' :
+ $query.=' AND email LIKE ?';
+ $values[] = '%' . $value . '%';
+ break;
+ default :
+ // Unsupported property
+ return array();
+
+ }
+
+ }
+ $stmt = $this->pdo->prepare($query);
+ $stmt->execute($values);
+
+ $principals = array();
+ while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+
+ // Checking if the principal is in the prefix
+ list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']);
+ if ($rowPrefix !== $prefixPath) continue;
+
+ $principals[] = $row['uri'];
+
+ }
+
+ return $principals;
+
+ }
+
+ /**
+ * Returns the list of members for a group-principal
+ *
+ * @param string $principal
+ * @return array
*/
public function getGroupMemberSet($principal) {
$principal = $this->getPrincipalByPath($principal);
if (!$principal) throw new Sabre_DAV_Exception('Principal not found');
- $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM `'.$this->groupMembersTableName.'` AS groupmembers LEFT JOIN `'.$this->tableName.'` AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?');
+ $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?');
$stmt->execute(array($principal['id']));
$result = array();
@@ -138,21 +359,21 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
$result[] = $row['uri'];
}
return $result;
-
+
}
/**
- * Returns the list of groups a principal is a member of
- *
- * @param string $principal
- * @return array
+ * Returns the list of groups a principal is a member of
+ *
+ * @param string $principal
+ * @return array
*/
public function getGroupMembership($principal) {
$principal = $this->getPrincipalByPath($principal);
if (!$principal) throw new Sabre_DAV_Exception('Principal not found');
- $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM `'.$this->groupMembersTableName.'` AS groupmembers LEFT JOIN `'.$this->tableName.'` AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?');
+ $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?');
$stmt->execute(array($principal['id']));
$result = array();
@@ -166,16 +387,16 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
/**
* Updates the list of group members for a group principal.
*
- * The principals should be passed as a list of uri's.
- *
- * @param string $principal
- * @param array $members
+ * The principals should be passed as a list of uri's.
+ *
+ * @param string $principal
+ * @param array $members
* @return void
*/
public function setGroupMemberSet($principal, array $members) {
// Grabbing the list of principal id's.
- $stmt = $this->pdo->prepare('SELECT id, uri FROM `'.$this->tableName.'` WHERE uri IN (? ' . str_repeat(', ? ', count($members)) . ');');
+ $stmt = $this->pdo->prepare('SELECT id, uri FROM '.$this->tableName.' WHERE uri IN (? ' . str_repeat(', ? ', count($members)) . ');');
$stmt->execute(array_merge(array($principal), $members));
$memberIds = array();
@@ -191,12 +412,12 @@ class Sabre_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBacken
if (!$principalId) throw new Sabre_DAV_Exception('Principal not found');
// Wiping out old members
- $stmt = $this->pdo->prepare('DELETE FROM `'.$this->groupMembersTableName.'` WHERE principal_id = ?;');
+ $stmt = $this->pdo->prepare('DELETE FROM '.$this->groupMembersTableName.' WHERE principal_id = ?;');
$stmt->execute(array($principalId));
foreach($memberIds as $memberId) {
- $stmt = $this->pdo->prepare('INSERT INTO `'.$this->groupMembersTableName.'` (principal_id, member_id) VALUES (?, ?);');
+ $stmt = $this->pdo->prepare('INSERT INTO '.$this->groupMembersTableName.' (principal_id, member_id) VALUES (?, ?);');
$stmt->execute(array($principalId, $memberId));
}
diff --git a/3rdparty/Sabre/DAVACL/PrincipalCollection.php b/3rdparty/Sabre/DAVACL/PrincipalCollection.php
index 4d22bf8aa75..c3e4cb83f23 100644..100755
--- a/3rdparty/Sabre/DAVACL/PrincipalCollection.php
+++ b/3rdparty/Sabre/DAVACL/PrincipalCollection.php
@@ -7,11 +7,11 @@
* Sabre_DAV_Auth_Backend to determine which users are available on the list.
*
* The users are instances of Sabre_DAV_Auth_Principal
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_PrincipalCollection extends Sabre_DAVACL_AbstractPrincipalCollection {
@@ -22,9 +22,9 @@ class Sabre_DAVACL_PrincipalCollection extends Sabre_DAVACL_AbstractPrincipalCol
* The passed array contains principal information, and is guaranteed to
* at least contain a uri item. Other properties may or may not be
* supplied by the authentication backend.
- *
- * @param array $principal
- * @return Sabre_DAV_INode
+ *
+ * @param array $principal
+ * @return Sabre_DAV_INode
*/
public function getChildForPrincipal(array $principal) {
diff --git a/3rdparty/Sabre/DAVACL/Property/Acl.php b/3rdparty/Sabre/DAVACL/Property/Acl.php
index e41e7411310..05e1a690b3c 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/Acl.php
+++ b/3rdparty/Sabre/DAVACL/Property/Acl.php
@@ -1,47 +1,47 @@
<?php
/**
- * This class represents the {DAV:}acl property
- *
+ * This class represents the {DAV:}acl property
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
/**
- * List of privileges
- *
- * @var array
+ * List of privileges
+ *
+ * @var array
*/
private $privileges;
/**
- * Wether or not the server base url is required to be prefixed when
- * serializing the property.
- *
- * @var boolean
+ * Whether or not the server base url is required to be prefixed when
+ * serializing the property.
+ *
+ * @var boolean
*/
private $prefixBaseUrl;
/**
* Constructor
*
- * This object requires a structure similar to the return value from
+ * This object requires a structure similar to the return value from
* Sabre_DAVACL_Plugin::getACL().
*
- * Each privilege is a an array with at least a 'privilege' property, and a
- * 'principal' property. A privilege may have a 'protected' property as
- * well.
+ * Each privilege is a an array with at least a 'privilege' property, and a
+ * 'principal' property. A privilege may have a 'protected' property as
+ * well.
*
- * The prefixBaseUrl should be set to false, if the supplied principal urls
- * are already full urls. If this is kept to true, the servers base url
- * will automatically be prefixed.
+ * The prefixBaseUrl should be set to false, if the supplied principal urls
+ * are already full urls. If this is kept to true, the servers base url
+ * will automatically be prefixed.
*
- * @param bool $prefixBaseUrl
- * @param array $privileges
+ * @param bool $prefixBaseUrl
+ * @param array $privileges
*/
public function __construct(array $privileges, $prefixBaseUrl = true) {
@@ -51,9 +51,9 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
}
/**
- * Returns the list of privileges for this property
- *
- * @return array
+ * Returns the list of privileges for this property
+ *
+ * @return array
*/
public function getPrivileges() {
@@ -62,10 +62,10 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
}
/**
- * Serializes the property into a DOMElement
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property into a DOMElement
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -80,10 +80,10 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
}
/**
- * Unserializes the {DAV:}acl xml element.
- *
- * @param DOMElement $dom
- * @return Sabre_DAVACL_Property_Acl
+ * Unserializes the {DAV:}acl xml element.
+ *
+ * @param DOMElement $dom
+ * @return Sabre_DAVACL_Property_Acl
*/
static public function unserialize(DOMElement $dom) {
@@ -98,11 +98,22 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
}
$principal = Sabre_DAVACL_Property_Principal::unserialize($principal->item(0));
- if ($principal->getType()!==Sabre_DAVACL_Property_Principal::HREF) {
- throw new Sabre_DAV_Exception_NotImplemented('Currently only uri based principals are support, {DAV:}all, {DAV:}unauthenticated and {DAV:}authenticated are not implemented yet');
+ switch($principal->getType()) {
+ case Sabre_DAVACL_Property_Principal::HREF :
+ $principal = $principal->getHref();
+ break;
+ case Sabre_DAVACL_Property_Principal::AUTHENTICATED :
+ $principal = '{DAV:}authenticated';
+ break;
+ case Sabre_DAVACL_Property_Principal::UNAUTHENTICATED :
+ $principal = '{DAV:}unauthenticated';
+ break;
+ case Sabre_DAVACL_Property_Principal::ALL :
+ $principal = '{DAV:}all';
+ break;
+
}
- $principal = $principal->getHref();
$protected = false;
if ($xace->getElementsByTagNameNS('urn:DAV','protected')->length > 0) {
@@ -140,7 +151,7 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
'privilege' => $privilegeName,
);
- }
+ }
}
@@ -149,12 +160,12 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
}
/**
- * Serializes a single access control entry.
- *
- * @param DOMDocument $doc
- * @param DOMElement $node
+ * Serializes a single access control entry.
+ *
+ * @param DOMDocument $doc
+ * @param DOMElement $node
* @param array $ace
- * @param Sabre_DAV_Server $server
+ * @param Sabre_DAV_Server $server
* @return void
*/
private function serializeAce($doc,$node,$ace, $server) {
@@ -164,7 +175,19 @@ class Sabre_DAVACL_Property_Acl extends Sabre_DAV_Property {
$principal = $doc->createElementNS('DAV:','d:principal');
$xace->appendChild($principal);
- $principal->appendChild($doc->createElementNS('DAV:','d:href',($this->prefixBaseUrl?$server->getBaseUri():'') . $ace['principal'] . '/'));
+ switch($ace['principal']) {
+ case '{DAV:}authenticated' :
+ $principal->appendChild($doc->createElementNS('DAV:','d:authenticated'));
+ break;
+ case '{DAV:}unauthenticated' :
+ $principal->appendChild($doc->createElementNS('DAV:','d:unauthenticated'));
+ break;
+ case '{DAV:}all' :
+ $principal->appendChild($doc->createElementNS('DAV:','d:all'));
+ break;
+ default:
+ $principal->appendChild($doc->createElementNS('DAV:','d:href',($this->prefixBaseUrl?$server->getBaseUri():'') . $ace['principal'] . '/'));
+ }
$grant = $doc->createElementNS('DAV:','d:grant');
$xace->appendChild($grant);
diff --git a/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
new file mode 100755
index 00000000000..a8b054956dd
--- /dev/null
+++ b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * AclRestrictions property
+ *
+ * This property represents {DAV:}acl-restrictions, as defined in RFC3744.
+ *
+ * @package Sabre
+ * @subpackage DAVACL
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_DAVACL_Property_AclRestrictions extends Sabre_DAV_Property {
+
+ /**
+ * Serializes the property into a DOMElement
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $elem
+ * @return void
+ */
+ public function serialize(Sabre_DAV_Server $server,DOMElement $elem) {
+
+ $doc = $elem->ownerDocument;
+
+ $elem->appendChild($doc->createElementNS('DAV:','d:grant-only'));
+ $elem->appendChild($doc->createElementNS('DAV:','d:no-invert'));
+
+ }
+
+}
diff --git a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
index 72274597b31..94a29640615 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
+++ b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
@@ -2,31 +2,31 @@
/**
* CurrentUserPrivilegeSet
- *
- * This class represents the current-user-privilege-set property. When
- * requested, it contain all the privileges a user has on a specific node.
- *
+ *
+ * This class represents the current-user-privilege-set property. When
+ * requested, it contain all the privileges a user has on a specific node.
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Property_CurrentUserPrivilegeSet extends Sabre_DAV_Property {
/**
- * List of privileges
- *
- * @var array
+ * List of privileges
+ *
+ * @var array
*/
private $privileges;
/**
* Creates the object
*
- * Pass the privileges in clark-notation
- *
- * @param array $privileges
+ * Pass the privileges in clark-notation
+ *
+ * @param array $privileges
*/
public function __construct(array $privileges) {
@@ -35,10 +35,10 @@ class Sabre_DAVACL_Property_CurrentUserPrivilegeSet extends Sabre_DAV_Property {
}
/**
- * Serializes the property in the DOM
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property in the DOM
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -53,11 +53,11 @@ class Sabre_DAVACL_Property_CurrentUserPrivilegeSet extends Sabre_DAV_Property {
}
/**
- * Serializes one privilege
- *
- * @param DOMDocument $doc
- * @param DOMElement $node
- * @param string $privName
+ * Serializes one privilege
+ *
+ * @param DOMDocument $doc
+ * @param DOMElement $node
+ * @param string $privName
* @return void
*/
protected function serializePriv($doc,$node,$privName) {
diff --git a/3rdparty/Sabre/DAVACL/Property/Principal.php b/3rdparty/Sabre/DAVACL/Property/Principal.php
index dad9a3550fb..c36328a58e0 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/Principal.php
+++ b/3rdparty/Sabre/DAVACL/Property/Principal.php
@@ -4,12 +4,12 @@
* Principal property
*
* The principal property represents a principal from RFC3744 (ACL).
- * The property can be used to specify a principal or pseudo principals.
+ * The property can be used to specify a principal or pseudo principals.
*
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
@@ -25,16 +25,21 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
const AUTHENTICATED = 2;
/**
- * Specific princpals can be specified with the HREF
+ * Specific principals can be specified with the HREF
*/
const HREF = 3;
/**
+ * Everybody, basically
+ */
+ const ALL = 4;
+
+ /**
* Principal-type
*
* Must be one of the UNAUTHENTICATED, AUTHENTICATED or HREF constants.
- *
- * @var int
+ *
+ * @var int
*/
private $type;
@@ -42,8 +47,8 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
* Url to principal
*
* This value is only used for the HREF principal type.
- *
- * @var string
+ *
+ * @var string
*/
private $href;
@@ -53,10 +58,9 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
* The 'type' argument must be one of the type constants defined in this class.
*
* 'href' is only required for the HREF type.
- *
- * @param int $type
- * @param string $href
- * @return void
+ *
+ * @param int $type
+ * @param string|null $href
*/
public function __construct($type, $href = null) {
@@ -70,9 +74,9 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
}
/**
- * Returns the principal type
- *
- * @return int
+ * Returns the principal type
+ *
+ * @return int
*/
public function getType() {
@@ -81,8 +85,8 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
}
/**
- * Returns the principal uri.
- *
+ * Returns the principal uri.
+ *
* @return string
*/
public function getHref() {
@@ -92,10 +96,10 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
}
/**
- * Serializes the property into a DOMElement.
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property into a DOMElement.
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server, DOMElement $node) {
@@ -124,10 +128,10 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
}
/**
- * Deserializes a DOM element into a property object.
- *
- * @param DOMElement $dom
- * @return Sabre_DAV_Property_Principal
+ * Deserializes a DOM element into a property object.
+ *
+ * @param DOMElement $dom
+ * @return Sabre_DAV_Property_Principal
*/
static public function unserialize(DOMElement $dom) {
@@ -144,6 +148,8 @@ class Sabre_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabr
return new self(self::AUTHENTICATED);
case '{DAV:}href':
return new self(self::HREF, $parent->textContent);
+ case '{DAV:}all':
+ return new self(self::ALL);
default :
throw new Sabre_DAV_Exception_BadRequest('Unexpected element (' . Sabre_DAV_XMLUtil::toClarkNotation($parent) . '). Could not deserialize');
diff --git a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
index 93c3895035d..276d57ae093 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
+++ b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
@@ -3,32 +3,32 @@
/**
* SupportedPrivilegeSet property
*
- * This property encodes the {DAV:}supported-privilege-set property, as defined
+ * This property encodes the {DAV:}supported-privilege-set property, as defined
* in rfc3744. Please consult the rfc for details about it's structure.
*
- * This class expects a structure like the one given from
- * Sabre_DAVACL_Plugin::getSupportedPrivilegeSet as the argument in its
+ * This class expects a structure like the one given from
+ * Sabre_DAVACL_Plugin::getSupportedPrivilegeSet as the argument in its
* constructor.
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
/**
- * privileges
- *
- * @var array
+ * privileges
+ *
+ * @var array
*/
private $privileges;
/**
- * Constructor
- *
- * @param array $privileges
+ * Constructor
+ *
+ * @param array $privileges
*/
public function __construct(array $privileges) {
@@ -37,10 +37,10 @@ class Sabre_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
}
/**
- * Serializes the property into a domdocument.
- *
- * @param Sabre_DAV_Server $server
- * @param DOMElement $node
+ * Serializes the property into a domdocument.
+ *
+ * @param Sabre_DAV_Server $server
+ * @param DOMElement $node
* @return void
*/
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
@@ -53,11 +53,11 @@ class Sabre_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
/**
* Serializes a property
*
- * This is a recursive function.
- *
- * @param DOMDocument $doc
- * @param DOMElement $node
- * @param array $privilege
+ * This is a recursive function.
+ *
+ * @param DOMDocument $doc
+ * @param DOMElement $node
+ * @param array $privilege
* @return void
*/
private function serializePriv($doc,$node,$privilege) {
@@ -81,7 +81,7 @@ class Sabre_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
$xsp->appendChild($doc->createElementNS('DAV:','d:description',$privilege['description']));
}
- if (isset($privilege['aggregates'])) {
+ if (isset($privilege['aggregates'])) {
foreach($privilege['aggregates'] as $subPrivilege) {
$this->serializePriv($doc,$xsp,$subPrivilege);
}
diff --git a/3rdparty/Sabre/DAVACL/Version.php b/3rdparty/Sabre/DAVACL/Version.php
index 124463e311e..9950f748741 100644..100755
--- a/3rdparty/Sabre/DAVACL/Version.php
+++ b/3rdparty/Sabre/DAVACL/Version.php
@@ -2,10 +2,10 @@
/**
* This class contains the SabreDAV version constants.
- *
+ *
* @package Sabre
* @subpackage DAVACL
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -14,7 +14,7 @@ class Sabre_DAVACL_Version {
/**
* Full version number
*/
- const VERSION = '1.5.2';
+ const VERSION = '1.6.0';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/DAVACL/includes.php b/3rdparty/Sabre/DAVACL/includes.php
new file mode 100755
index 00000000000..28fa3eed225
--- /dev/null
+++ b/3rdparty/Sabre/DAVACL/includes.php
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * Sabre_DAVACL includes file
+ *
+ * Including this file will automatically include all files from the
+ * Sabre_DAVACL package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @subpackage DAVACL
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+
+// Begin includes
+include __DIR__ . '/AbstractPrincipalCollection.php';
+include __DIR__ . '/Exception/AceConflict.php';
+include __DIR__ . '/Exception/NeedPrivileges.php';
+include __DIR__ . '/Exception/NoAbstract.php';
+include __DIR__ . '/Exception/NotRecognizedPrincipal.php';
+include __DIR__ . '/Exception/NotSupportedPrivilege.php';
+include __DIR__ . '/IACL.php';
+include __DIR__ . '/IPrincipal.php';
+include __DIR__ . '/IPrincipalBackend.php';
+include __DIR__ . '/Plugin.php';
+include __DIR__ . '/Principal.php';
+include __DIR__ . '/PrincipalBackend/PDO.php';
+include __DIR__ . '/PrincipalCollection.php';
+include __DIR__ . '/Property/Acl.php';
+include __DIR__ . '/Property/AclRestrictions.php';
+include __DIR__ . '/Property/CurrentUserPrivilegeSet.php';
+include __DIR__ . '/Property/Principal.php';
+include __DIR__ . '/Property/SupportedPrivilegeSet.php';
+include __DIR__ . '/Version.php';
+// End includes
diff --git a/3rdparty/Sabre/HTTP/AWSAuth.php b/3rdparty/Sabre/HTTP/AWSAuth.php
index 5e4668cd94d..fb8245c8cbf 100644..100755
--- a/3rdparty/Sabre/HTTP/AWSAuth.php
+++ b/3rdparty/Sabre/HTTP/AWSAuth.php
@@ -4,34 +4,34 @@
* HTTP AWS Authentication handler
*
* Use this class to leverage amazon's AWS authentication header
- *
+ *
* @package Sabre
- * @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @subpackage HTTP
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
/**
- * The signature supplied by the HTTP client
- *
- * @var string
+ * The signature supplied by the HTTP client
+ *
+ * @var string
*/
private $signature = null;
/**
- * The accesskey supplied by the HTTP client
- *
- * @var string
+ * The accesskey supplied by the HTTP client
+ *
+ * @var string
*/
private $accessKey = null;
/**
* An error code, if any
*
- * This value will be filled with one of the ERR_* contants
- *
+ * This value will be filled with one of the ERR_* constants
+ *
* @var int
*/
public $errorCode = 0;
@@ -46,8 +46,8 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
* Gathers all information from the headers
*
* This method needs to be called prior to anything else.
- *
- * @return bool
+ *
+ * @return bool
*/
public function init() {
@@ -66,9 +66,9 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
}
/**
- * Returns the username for the request
- *
- * @return string
+ * Returns the username for the request
+ *
+ * @return string
*/
public function getAccessKey() {
@@ -78,8 +78,9 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
/**
* Validates the signature based on the secretKey
- *
- * @return bool
+ *
+ * @param string $secretKey
+ * @return bool
*/
public function validate($secretKey) {
@@ -89,7 +90,7 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
// We need to validate the integrity of the request
$body = $this->httpRequest->getBody(true);
$this->httpRequest->setBody($body,true);
-
+
if ($contentMD5!=base64_encode(md5($body,true))) {
// content-md5 header did not match md5 signature of body
$this->errorCode = self::ERR_MD5CHECKSUMWRONG;
@@ -98,10 +99,10 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
}
- if (!$requestDate = $this->httpRequest->getHeader('x-amz-date'))
+ if (!$requestDate = $this->httpRequest->getHeader('x-amz-date'))
$requestDate = $this->httpRequest->getHeader('Date');
- if (!$this->validateRFC2616Date($requestDate))
+ if (!$this->validateRFC2616Date($requestDate))
return false;
$amzHeaders = $this->getAmzHeaders();
@@ -109,10 +110,10 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
$signature = base64_encode(
$this->hmacsha1($secretKey,
$this->httpRequest->getMethod() . "\n" .
- $contentMD5 . "\n" .
+ $contentMD5 . "\n" .
$this->httpRequest->getHeader('Content-type') . "\n" .
$requestDate . "\n" .
- $amzHeaders .
+ $amzHeaders .
$this->httpRequest->getURI()
)
);
@@ -146,14 +147,14 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
/**
* Makes sure the supplied value is a valid RFC2616 date.
*
- * If we would just use strtotime to get a valid timestamp, we have no way of checking if a
+ * If we would just use strtotime to get a valid timestamp, we have no way of checking if a
* user just supplied the word 'now' for the date header.
*
- * This function also makes sure the Date header is within 15 minutes of the operating
+ * This function also makes sure the Date header is within 15 minutes of the operating
* system date, to prevent replay attacks.
- *
- * @param string $dateHeader
- * @return bool
+ *
+ * @param string $dateHeader
+ * @return bool
*/
protected function validateRFC2616Date($dateHeader) {
@@ -177,11 +178,11 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
return $date;
}
-
+
/**
- * Returns a list of AMZ headers
- *
- * @return void
+ * Returns a list of AMZ headers
+ *
+ * @return string
*/
protected function getAmzHeaders() {
@@ -193,7 +194,7 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
}
}
ksort($amzHeaders);
-
+
$headerStr = '';
foreach($amzHeaders as $h=>$v) {
$headerStr.=$h.':'.$v;
@@ -204,11 +205,11 @@ class Sabre_HTTP_AWSAuth extends Sabre_HTTP_AbstractAuth {
}
/**
- * Generates an HMAC-SHA1 signature
- *
- * @param string $key
- * @param string $message
- * @return string
+ * Generates an HMAC-SHA1 signature
+ *
+ * @param string $key
+ * @param string $message
+ * @return string
*/
private function hmacsha1($key, $message) {
diff --git a/3rdparty/Sabre/HTTP/AbstractAuth.php b/3rdparty/Sabre/HTTP/AbstractAuth.php
index eb528f6fdee..3bccabcd1c1 100644..100755
--- a/3rdparty/Sabre/HTTP/AbstractAuth.php
+++ b/3rdparty/Sabre/HTTP/AbstractAuth.php
@@ -4,10 +4,10 @@
* HTTP Authentication baseclass
*
* This class has the common functionality for BasicAuth and DigestAuth
- *
+ *
* @package Sabre
- * @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @subpackage HTTP
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -17,29 +17,29 @@ abstract class Sabre_HTTP_AbstractAuth {
* The realm will be displayed in the dialog boxes
*
* This identifier can be changed through setRealm()
- *
+ *
* @var string
*/
protected $realm = 'SabreDAV';
/**
- * HTTP response helper
- *
- * @var Sabre_HTTP_Response
+ * HTTP response helper
+ *
+ * @var Sabre_HTTP_Response
*/
protected $httpResponse;
/**
- * HTTP request helper
- *
- * @var Sabre_HTTP_Request
+ * HTTP request helper
+ *
+ * @var Sabre_HTTP_Request
*/
protected $httpRequest;
/**
- * __construct
- *
+ * __construct
+ *
*/
public function __construct() {
@@ -49,9 +49,9 @@ abstract class Sabre_HTTP_AbstractAuth {
}
/**
- * Sets an alternative HTTP response object
- *
- * @param Sabre_HTTP_Response $response
+ * Sets an alternative HTTP response object
+ *
+ * @param Sabre_HTTP_Response $response
* @return void
*/
public function setHTTPResponse(Sabre_HTTP_Response $response) {
@@ -61,9 +61,9 @@ abstract class Sabre_HTTP_AbstractAuth {
}
/**
- * Sets an alternative HTTP request object
- *
- * @param Sabre_HTTP_Request $request
+ * Sets an alternative HTTP request object
+ *
+ * @param Sabre_HTTP_Request $request
* @return void
*/
public function setHTTPRequest(Sabre_HTTP_Request $request) {
@@ -78,8 +78,8 @@ abstract class Sabre_HTTP_AbstractAuth {
*
* The realm is often displayed in authentication dialog boxes
* Commonly an application name displayed here
- *
- * @param string $realm
+ *
+ * @param string $realm
* @return void
*/
public function setRealm($realm) {
@@ -91,7 +91,7 @@ abstract class Sabre_HTTP_AbstractAuth {
/**
* Returns the realm
*
- * @return string
+ * @return string
*/
public function getRealm() {
@@ -106,6 +106,6 @@ abstract class Sabre_HTTP_AbstractAuth {
*
* @return void
*/
- abstract public function requireLogin();
+ abstract public function requireLogin();
}
diff --git a/3rdparty/Sabre/HTTP/BasicAuth.php b/3rdparty/Sabre/HTTP/BasicAuth.php
index 35c22d22dc3..a747cc6a31b 100644..100755
--- a/3rdparty/Sabre/HTTP/BasicAuth.php
+++ b/3rdparty/Sabre/HTTP/BasicAuth.php
@@ -4,11 +4,11 @@
* HTTP Basic Authentication handler
*
* Use this class for easy http authentication setup
- *
+ *
* @package Sabre
- * @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @subpackage HTTP
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
@@ -22,7 +22,7 @@ class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
*
* If nothing was supplied, 'false' will be returned
*
- * @return mixed
+ * @return mixed
*/
public function getUserPass() {
@@ -33,12 +33,18 @@ class Sabre_HTTP_BasicAuth extends Sabre_HTTP_AbstractAuth {
}
- // Most other webservers
+ // Most other webservers
$auth = $this->httpRequest->getHeader('Authorization');
+ // Apache could prefix environment variables with REDIRECT_ when urls
+ // are passed through mod_rewrite
+ if (!$auth) {
+ $auth = $this->httpRequest->getRawServerValue('REDIRECT_HTTP_AUTHORIZATION');
+ }
+
if (!$auth) return false;
- if (strpos(strtolower($auth),'basic')!==0) return false;
+ if (strpos(strtolower($auth),'basic')!==0) return false;
return explode(':', base64_decode(substr($auth, 6)));
diff --git a/3rdparty/Sabre/HTTP/DigestAuth.php b/3rdparty/Sabre/HTTP/DigestAuth.php
index 5e755929571..ee7f05c08ed 100644..100755
--- a/3rdparty/Sabre/HTTP/DigestAuth.php
+++ b/3rdparty/Sabre/HTTP/DigestAuth.php
@@ -10,18 +10,18 @@
* 2. Call the setRealm() method with the realm you plan to use
* 3. Call the init method function.
* 4. Call the getUserName() function. This function may return false if no
- * authentication information was supplied. Based on the username you
+ * authentication information was supplied. Based on the username you
* should check your internal database for either the associated password,
* or the so-called A1 hash of the digest.
* 5. Call either validatePassword() or validateA1(). This will return true
- * or false.
+ * or false.
* 6. To make sure an authentication prompt is displayed, call the
* requireLogin() method.
- *
- *
+ *
+ *
* @package Sabre
- * @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @subpackage HTTP
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -40,7 +40,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
protected $qop = self::QOP_AUTH;
/**
- * Initializes the object
+ * Initializes the object
*/
public function __construct() {
@@ -54,7 +54,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
* Gathers all information from the headers
*
* This method needs to be called prior to anything else.
- *
+ *
* @return void
*/
public function init() {
@@ -73,11 +73,11 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
*
* Multiple values can be specified using logical OR.
*
- * QOP_AUTHINT ensures integrity of the request body, but this is not
- * supported by most HTTP clients. QOP_AUTHINT also requires the entire
+ * QOP_AUTHINT ensures integrity of the request body, but this is not
+ * supported by most HTTP clients. QOP_AUTHINT also requires the entire
* request body to be md5'ed, which can put strains on CPU and memory.
*
- * @param int $qop
+ * @param int $qop
* @return void
*/
public function setQOP($qop) {
@@ -91,8 +91,8 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
*
* The A1 parameter should be md5($username . ':' . $realm . ':' . $password);
*
- * @param string $A1
- * @return bool
+ * @param string $A1
+ * @return bool
*/
public function validateA1($A1) {
@@ -104,9 +104,9 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
/**
* Validates authentication through a password. The actual password must be provided here.
* It is strongly recommended not store the password in plain-text and use validateA1 instead.
- *
- * @param string $password
- * @return bool
+ *
+ * @param string $password
+ * @return bool
*/
public function validatePassword($password) {
@@ -116,9 +116,9 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
}
/**
- * Returns the username for the request
- *
- * @return string
+ * Returns the username for the request
+ *
+ * @return string
*/
public function getUsername() {
@@ -127,14 +127,14 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
}
/**
- * Validates the digest challenge
- *
- * @return bool
+ * Validates the digest challenge
+ *
+ * @return bool
*/
protected function validate() {
$A2 = $this->httpRequest->getMethod() . ':' . $this->digestParts['uri'];
-
+
if ($this->digestParts['qop']=='auth-int') {
// Making sure we support this qop value
if (!($this->qop & self::QOP_AUTHINT)) return false;
@@ -144,16 +144,16 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
$A2 .= ':' . md5($body);
} else {
- // We need to make sure we support this qop value
- if (!($this->qop & self::QOP_AUTH)) return false;
+ // We need to make sure we support this qop value
+ if (!($this->qop & self::QOP_AUTH)) return false;
}
$A2 = md5($A2);
- $validResponse = md5("{$this->A1}:{$this->digestParts['nonce']}:{$this->digestParts['nc']}:{$this->digestParts['cnonce']}:{$this->digestParts['qop']}:{$A2}");
+ $validResponse = md5("{$this->A1}:{$this->digestParts['nonce']}:{$this->digestParts['nc']}:{$this->digestParts['cnonce']}:{$this->digestParts['qop']}:{$A2}");
return $this->digestParts['response']==$validResponse;
-
+
}
@@ -186,7 +186,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
*
* If the header could not be found, null will be returned
*
- * @return mixed
+ * @return mixed
*/
public function getDigest() {
@@ -197,6 +197,12 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
// most other servers
$digest = $this->httpRequest->getHeader('Authorization');
+ // Apache could prefix environment variables with REDIRECT_ when urls
+ // are passed through mod_rewrite
+ if (!$digest) {
+ $digest = $this->httpRequest->getRawServerValue('REDIRECT_HTTP_AUTHORIZATION');
+ }
+
if ($digest && strpos(strtolower($digest),'digest')===0) {
return substr($digest,7);
} else {
@@ -208,11 +214,11 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
/**
* Parses the different pieces of the digest string into an array.
- *
+ *
* This method returns false if an incomplete digest was supplied
*
- * @param string $digest
- * @return mixed
+ * @param string $digest
+ * @return mixed
*/
protected function parseDigest($digest) {
@@ -227,7 +233,7 @@ class Sabre_HTTP_DigestAuth extends Sabre_HTTP_AbstractAuth {
unset($needed_parts[$m[1]]);
}
- return $needed_parts ? false : $data;
+ return $needed_parts ? false : $data;
}
diff --git a/3rdparty/Sabre/HTTP/Request.php b/3rdparty/Sabre/HTTP/Request.php
index 95a64171aab..4746ef77704 100644..100755
--- a/3rdparty/Sabre/HTTP/Request.php
+++ b/3rdparty/Sabre/HTTP/Request.php
@@ -6,74 +6,85 @@
* This object can be used to easily access information about an HTTP request.
* It can additionally be used to create 'mock' requests.
*
- * This class mostly operates indepentend, but because of the nature of a single
- * request per run it can operate as a singleton. For more information check out
+ * This class mostly operates independent, but because of the nature of a single
+ * request per run it can operate as a singleton. For more information check out
* the behaviour around 'defaultInputStream'.
*
* @package Sabre
- * @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @subpackage HTTP
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_HTTP_Request {
/**
* PHP's $_SERVER data
- *
- * @var string
+ *
+ * @var array
*/
protected $_SERVER;
/**
+ * PHP's $_POST data
+ *
+ * @var array
+ */
+ protected $_POST;
+
+ /**
* The request body, if any.
*
* This is stored in the form of a stream resource.
*
- * @var resource
+ * @var resource
*/
protected $body = null;
/**
* This will be set as the 'default' inputStream for a specific HTTP request
- * We sometimes need to retain, or rebuild this if we need multiple runs
+ * We sometimes need to retain, or rebuild this if we need multiple runs
* of parsing the original HTTP request.
- *
- * @var resource
+ *
+ * @var resource
*/
static $defaultInputStream=null;
/**
* Sets up the object
*
- * The serverData array can be used to override usage of PHP's
- * global _SERVER variable.
- *
- * @param array $serverData
+ * The serverData and postData array can be used to override usage of PHP's
+ * global _SERVER and _POST variable respectively.
+ *
+ * @param array $serverData
+ * @param array $postData
*/
- public function __construct($serverData = null) {
+ public function __construct(array $serverData = null, array $postData = null) {
if ($serverData) $this->_SERVER = $serverData;
else $this->_SERVER =& $_SERVER;
+ if ($postData) $this->_POST = $postData;
+ else $this->_POST =& $_POST;
+
}
/**
* Returns the value for a specific http header.
*
* This method returns null if the header did not exist.
- *
- * @param string $name
- * @return string
+ *
+ * @param string $name
+ * @return string
*/
public function getHeader($name) {
$name = strtoupper(str_replace(array('-'),array('_'),$name));
if (isset($this->_SERVER['HTTP_' . $name])) {
return $this->_SERVER['HTTP_' . $name];
- }
+ }
- // There's a few headers that seem to end up in the top-level
+ // There's a few headers that seem to end up in the top-level
// server array.
switch($name) {
case 'CONTENT_TYPE' :
@@ -92,9 +103,9 @@ class Sabre_HTTP_Request {
* Returns all (known) HTTP headers.
*
* All headers are converted to lower-case, and additionally all underscores
- * are automatically converted to dashes
- *
- * @return array
+ * are automatically converted to dashes
+ *
+ * @return array
*/
public function getHeaders() {
@@ -122,9 +133,9 @@ class Sabre_HTTP_Request {
/**
* Returns the HTTP request method
*
- * This is for example POST or GET
+ * This is for example POST or GET
*
- * @return string
+ * @return string
*/
public function getMethod() {
@@ -135,18 +146,18 @@ class Sabre_HTTP_Request {
/**
* Returns the requested uri
*
- * @return string
+ * @return string
*/
public function getUri() {
-
+
return $this->_SERVER['REQUEST_URI'];
}
/**
- * Will return protocol + the hostname + the uri
- *
- * @return void
+ * Will return protocol + the hostname + the uri
+ *
+ * @return string
*/
public function getAbsoluteUri() {
@@ -157,9 +168,9 @@ class Sabre_HTTP_Request {
}
/**
- * Returns everything after the ? from the current url
- *
- * @return string
+ * Returns everything after the ? from the current url
+ *
+ * @return string
*/
public function getQueryString() {
@@ -168,13 +179,13 @@ class Sabre_HTTP_Request {
}
/**
- * Returns the HTTP request body body
+ * Returns the HTTP request body body
*
* This method returns a readable stream resource.
- * If the asString parameter is set to true, a string is sent instead.
+ * If the asString parameter is set to true, a string is sent instead.
*
* @param bool asString
- * @return resource
+ * @return resource
*/
public function getBody($asString = false) {
@@ -196,14 +207,14 @@ class Sabre_HTTP_Request {
}
/**
- * Sets the contents of the HTTP request body
- *
+ * Sets the contents of the HTTP request body
+ *
* This method can either accept a string, or a readable stream resource.
*
- * If the setAsDefaultInputStream is set to true, it means for this run of the
+ * If the setAsDefaultInputStream is set to true, it means for this run of the
* script the supplied body will be used instead of php://input.
*
- * @param mixed $body
+ * @param mixed $body
* @param bool $setAsDefaultInputStream
* @return void
*/
@@ -226,12 +237,26 @@ class Sabre_HTTP_Request {
}
/**
- * Returns a specific item from the _SERVER array.
+ * Returns PHP's _POST variable.
+ *
+ * The reason this is in a method is so it can be subclassed and
+ * overridden.
+ *
+ * @return array
+ */
+ public function getPostVars() {
+
+ return $this->_POST;
+
+ }
+
+ /**
+ * Returns a specific item from the _SERVER array.
*
* Do not rely on this feature, it is for internal use only.
*
- * @param string $field
- * @return string
+ * @param string $field
+ * @return string
*/
public function getRawServerValue($field) {
diff --git a/3rdparty/Sabre/HTTP/Response.php b/3rdparty/Sabre/HTTP/Response.php
index dce6feac553..ffe9bda2082 100644..100755
--- a/3rdparty/Sabre/HTTP/Response.php
+++ b/3rdparty/Sabre/HTTP/Response.php
@@ -1,20 +1,20 @@
<?php
/**
- * Sabre_HTTP_Response
- *
+ * Sabre_HTTP_Response
+ *
* @package Sabre
* @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_HTTP_Response {
/**
- * Returns a full HTTP status message for an HTTP status code
- *
- * @param int $code
+ * Returns a full HTTP status message for an HTTP status code
+ *
+ * @param int $code
* @return string
*/
public function getStatusMessage($code) {
@@ -64,6 +64,9 @@ class Sabre_HTTP_Response {
423 => 'Locked', // RFC 4918
424 => 'Failed Dependency', // RFC 4918
426 => 'Upgrade required',
+ 428 => 'Precondition required', // draft-nottingham-http-new-status
+ 429 => 'Too Many Requests', // draft-nottingham-http-new-status
+ 431 => 'Request Header Fields Too Large', // draft-nottingham-http-new-status
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
@@ -71,25 +74,26 @@ class Sabre_HTTP_Response {
504 => 'Gateway Timeout',
505 => 'HTTP Version not supported',
506 => 'Variant Also Negotiates',
- 507 => 'Unsufficient Storage', // RFC 4918
+ 507 => 'Insufficient Storage', // RFC 4918
508 => 'Loop Detected', // RFC 5842
509 => 'Bandwidth Limit Exceeded', // non-standard
510 => 'Not extended',
- );
+ 511 => 'Network Authentication Required', // draft-nottingham-http-new-status
+ );
return 'HTTP/1.1 ' . $code . ' ' . $msg[$code];
}
/**
- * Sends an HTTP status header to the client
- *
- * @param int $code HTTP status code
- * @return void
+ * Sends an HTTP status header to the client
+ *
+ * @param int $code HTTP status code
+ * @return bool
*/
public function sendStatus($code) {
- if (!headers_sent())
+ if (!headers_sent())
return header($this->getStatusMessage($code));
else return false;
@@ -97,15 +101,16 @@ class Sabre_HTTP_Response {
/**
* Sets an HTTP header for the response
- *
- * @param string $name
- * @param string $value
- * @return void
+ *
+ * @param string $name
+ * @param string $value
+ * @param bool $replace
+ * @return bool
*/
public function setHeader($name, $value, $replace = true) {
$value = str_replace(array("\r","\n"),array('\r','\n'),$value);
- if (!headers_sent())
+ if (!headers_sent())
return header($name . ': ' . $value, $replace);
else return false;
@@ -115,8 +120,8 @@ class Sabre_HTTP_Response {
* Sets a bunch of HTTP Headers
*
* headersnames are specified as keys, value in the array value
- *
- * @param array $headers
+ *
+ * @param array $headers
* @return void
*/
public function setHeaders(array $headers) {
@@ -130,14 +135,14 @@ class Sabre_HTTP_Response {
* Sends the entire response body
*
* This method can accept either an open filestream, or a string.
- *
- * @param mixed $body
+ *
+ * @param mixed $body
* @return void
*/
public function sendBody($body) {
if (is_resource($body)) {
-
+
fpassthru($body);
} else {
diff --git a/3rdparty/Sabre/HTTP/Util.php b/3rdparty/Sabre/HTTP/Util.php
index 8a6bd7df487..67bdd489e1e 100644..100755
--- a/3rdparty/Sabre/HTTP/Util.php
+++ b/3rdparty/Sabre/HTTP/Util.php
@@ -1,11 +1,11 @@
<?php
/**
- * HTTP utility methods
- *
+ * HTTP utility methods
+ *
* @package Sabre
* @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @author Paul Voegler
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
@@ -16,9 +16,9 @@ class Sabre_HTTP_Util {
* Parses a RFC2616-compatible date string
*
* This method returns false if the date is invalid
- *
- * @param string $dateHeader
- * @return bool|DateTime
+ *
+ * @param string $dateHeader
+ * @return bool|DateTime
*/
static function parseHTTPDate($dateHeader) {
@@ -42,7 +42,7 @@ class Sabre_HTTP_Util {
$rfc1123_date = $wkday . ', ' . $date1 . ' ' . $time . ' GMT';
//allowed date formats by RFC 2616
$HTTP_date = "($rfc1123_date|$rfc850_date|$asctime_date)";
-
+
//allow for space around the string and strip it
$dateHeader = trim($dateHeader, ' ');
if (!preg_match('/^' . $HTTP_date . '$/', $dateHeader))
@@ -58,7 +58,24 @@ class Sabre_HTTP_Util {
if ($realDate !== false && $realDate >= 0)
return new DateTime('@' . $realDate, new DateTimeZone('UTC'));
- return false;
+ }
+
+ /**
+ * Transforms a DateTime object to HTTP's most common date format.
+ *
+ * We're serializing it as the RFC 1123 date, which, for HTTP must be
+ * specified as GMT.
+ *
+ * @param DateTime $dateTime
+ * @return string
+ */
+ static function toHTTPDate(DateTime $dateTime) {
+
+ // We need to clone it, as we don't want to affect the existing
+ // DateTime.
+ $dateTime = clone $dateTime;
+ $dateTime->setTimeZone(new DateTimeZone('GMT'));
+ return $dateTime->format('D, d M Y H:i:s \G\M\T');
}
diff --git a/3rdparty/Sabre/HTTP/Version.php b/3rdparty/Sabre/HTTP/Version.php
index 67be232fc26..23dc7f8a7a1 100644..100755
--- a/3rdparty/Sabre/HTTP/Version.php
+++ b/3rdparty/Sabre/HTTP/Version.php
@@ -2,10 +2,10 @@
/**
* This class contains the Sabre_HTTP version constants.
- *
+ *
* @package Sabre
- * @subpackage HTTP
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @subpackage HTTP
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -14,7 +14,7 @@ class Sabre_HTTP_Version {
/**
* Full version number
*/
- const VERSION = '1.5.3';
+ const VERSION = '1.6.2';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/HTTP/includes.php b/3rdparty/Sabre/HTTP/includes.php
new file mode 100755
index 00000000000..9d34bf3a8be
--- /dev/null
+++ b/3rdparty/Sabre/HTTP/includes.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * Sabre_HTTP includes file
+ *
+ * Including this file will automatically include all files from the Sabre_HTTP
+ * package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
+ *
+ * @package Sabre
+ * @subpackage HTTP
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+
+// Begin includes
+include __DIR__ . '/AbstractAuth.php';
+include __DIR__ . '/AWSAuth.php';
+include __DIR__ . '/BasicAuth.php';
+include __DIR__ . '/DigestAuth.php';
+include __DIR__ . '/Request.php';
+include __DIR__ . '/Response.php';
+include __DIR__ . '/Util.php';
+include __DIR__ . '/Version.php';
+// End includes
diff --git a/3rdparty/Sabre/LICENCE b/3rdparty/Sabre/LICENCE
deleted file mode 100644
index 3d07eaace83..00000000000
--- a/3rdparty/Sabre/LICENCE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (C) 2007-2011 Rooftop Solutions.
-Copyright (C) 2007-2009 FileMobile inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the SabreDAV nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
diff --git a/3rdparty/Sabre/VObject/Component.php b/3rdparty/Sabre/VObject/Component.php
index 47cf9f3d812..b78a26133fa 100644..100755
--- a/3rdparty/Sabre/VObject/Component.php
+++ b/3rdparty/Sabre/VObject/Component.php
@@ -4,39 +4,73 @@
* VObject Component
*
* This class represents a VCALENDAR/VCARD component. A component is for example
- * VEVENT, VTODO and also VCALENDAR. It starts with BEGIN:COMPONENTNAME and
+ * VEVENT, VTODO and also VCALENDAR. It starts with BEGIN:COMPONENTNAME and
* ends with END:COMPONENTNAME
*
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Component extends Sabre_VObject_Element {
/**
- * Name, for example VEVENT
- *
- * @var string
+ * Name, for example VEVENT
+ *
+ * @var string
*/
public $name;
/**
- * Children properties and components
- *
+ * Children properties and components
+ *
* @var array
*/
public $children = array();
+ /**
+ * If coponents are added to this map, they will be automatically mapped
+ * to their respective classes, if parsed by the reader or constructed with
+ * the 'create' method.
+ *
+ * @var array
+ */
+ static public $classMap = array(
+ 'VCALENDAR' => 'Sabre_VObject_Component_VCalendar',
+ 'VEVENT' => 'Sabre_VObject_Component_VEvent',
+ 'VTODO' => 'Sabre_VObject_Component_VTodo',
+ 'VJOURNAL' => 'Sabre_VObject_Component_VJournal',
+ 'VALARM' => 'Sabre_VObject_Component_VAlarm',
+ );
+
+ /**
+ * Creates the new component by name, but in addition will also see if
+ * there's a class mapped to the property name.
+ *
+ * @param string $name
+ * @param string $value
+ * @return Sabre_VObject_Component
+ */
+ static public function create($name, $value = null) {
+
+ $name = strtoupper($name);
+
+ if (isset(self::$classMap[$name])) {
+ return new self::$classMap[$name]($name, $value);
+ } else {
+ return new self($name, $value);
+ }
+
+ }
/**
* Creates a new component.
*
- * By default this object will iterate over its own children, but this can
+ * By default this object will iterate over its own children, but this can
* be overridden with the iterator argument
- *
- * @param string $name
+ *
+ * @param string $name
* @param Sabre_VObject_ElementList $iterator
*/
public function __construct($name, Sabre_VObject_ElementList $iterator = null) {
@@ -47,23 +81,65 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
}
/**
- * Turns the object back into a serialized blob.
- *
- * @return string
+ * Turns the object back into a serialized blob.
+ *
+ * @return string
*/
public function serialize() {
$str = "BEGIN:" . $this->name . "\r\n";
+
+ /**
+ * Gives a component a 'score' for sorting purposes.
+ *
+ * This is solely used by the childrenSort method.
+ *
+ * A higher score means the item will be higher in the list
+ *
+ * @param Sabre_VObject_Node $n
+ * @return int
+ */
+ $sortScore = function($n) {
+
+ if ($n instanceof Sabre_VObject_Component) {
+ // We want to encode VTIMEZONE first, this is a personal
+ // preference.
+ if ($n->name === 'VTIMEZONE') {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ // VCARD version 4.0 wants the VERSION property to appear first
+ if ($n->name === 'VERSION') {
+ return 3;
+ } else {
+ return 2;
+ }
+ }
+
+ };
+
+ usort($this->children, function($a, $b) use ($sortScore) {
+
+ $sA = $sortScore($a);
+ $sB = $sortScore($b);
+
+ if ($sA === $sB) return 0;
+
+ return ($sA > $sB) ? -1 : 1;
+
+ });
+
foreach($this->children as $child) $str.=$child->serialize();
$str.= "END:" . $this->name . "\r\n";
-
+
return $str;
}
-
/**
- * Adds a new componenten or element
+ * Adds a new component or element
*
* You can call this method with the following syntaxes:
*
@@ -71,10 +147,10 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
* add(string $name, $value)
*
* The first version adds an Element
- * The second adds a property as a string.
- *
- * @param mixed $item
- * @param mixed $itemValue
+ * The second adds a property as a string.
+ *
+ * @param mixed $item
+ * @param mixed $itemValue
* @return void
*/
public function add($item, $itemValue = null) {
@@ -90,12 +166,12 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
if (!is_scalar($itemValue)) {
throw new InvalidArgumentException('The second argument must be scalar');
}
- $item = new Sabre_VObject_Property($item,$itemValue);
+ $item = Sabre_VObject_Property::create($item,$itemValue);
$item->parent = $this;
$this->children[] = $item;
} else {
-
+
throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
}
@@ -103,9 +179,9 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
}
/**
- * Returns an iterable list of children
- *
- * @return Sabre_VObject_ElementList
+ * Returns an iterable list of children
+ *
+ * @return Sabre_VObject_ElementList
*/
public function children() {
@@ -116,18 +192,18 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
/**
* Returns an array with elements that match the specified name.
*
- * This function is also aware of MIME-Directory groups (as they appear in
- * vcards). This means that if a property is grouped as "HOME.EMAIL", it
- * will also be returned when searching for just "EMAIL". If you want to
- * search for a property in a specific group, you can select on the entire
- * string ("HOME.EMAIL"). If you want to search on a specific property that
+ * This function is also aware of MIME-Directory groups (as they appear in
+ * vcards). This means that if a property is grouped as "HOME.EMAIL", it
+ * will also be returned when searching for just "EMAIL". If you want to
+ * search for a property in a specific group, you can select on the entire
+ * string ("HOME.EMAIL"). If you want to search on a specific property that
* has not been assigned a group, specify ".EMAIL".
*
- * Keys are retained from the 'children' array, which may be confusing in
- * certain cases.
+ * Keys are retained from the 'children' array, which may be confusing in
+ * certain cases.
*
- * @param string $name
- * @return array
+ * @param string $name
+ * @return array
*/
public function select($name) {
@@ -144,7 +220,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
strtoupper($child->name) === $name &&
(is_null($group) || ( $child instanceof Sabre_VObject_Property && strtoupper($child->group) === $group))
) {
-
+
$result[$key] = $child;
}
@@ -155,16 +231,35 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
}
+ /**
+ * This method only returns a list of sub-components. Properties are
+ * ignored.
+ *
+ * @return array
+ */
+ public function getComponents() {
+
+ $result = array();
+ foreach($this->children as $child) {
+ if ($child instanceof Sabre_VObject_Component) {
+ $result[] = $child;
+ }
+ }
+
+ return $result;
+
+ }
+
/* Magic property accessors {{{ */
/**
- * Using 'get' you will either get a propery or component,
+ * Using 'get' you will either get a property or component,
*
* If there were no child-elements found with the specified name,
* null is returned.
- *
- * @param string $name
- * @return void
+ *
+ * @param string $name
+ * @return Sabre_VObject_Property
*/
public function __get($name) {
@@ -173,6 +268,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
return null;
} else {
$firstMatch = current($matches);
+ /** @var $firstMatch Sabre_VObject_Property */
$firstMatch->setIterator(new Sabre_VObject_ElementList(array_values($matches)));
return $firstMatch;
}
@@ -180,10 +276,10 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
}
/**
- * This method checks if a sub-element with the specified name exists.
- *
- * @param string $name
- * @return bool
+ * This method checks if a sub-element with the specified name exists.
+ *
+ * @param string $name
+ * @return bool
*/
public function __isset($name) {
@@ -200,7 +296,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
*
* If the item already exists, it will be removed. If you want to add
* a new item with the same name, always use the add() method.
- *
+ *
* @param string $name
* @param mixed $value
* @return void
@@ -218,7 +314,7 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
$this->children[] = $value;
}
} elseif (is_scalar($value)) {
- $property = new Sabre_VObject_Property($name,$value);
+ $property = Sabre_VObject_Property::create($name,$value);
$property->parent = $this;
if (!is_null($overWrite)) {
$this->children[$overWrite] = $property;
@@ -232,9 +328,9 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
}
/**
- * Removes all properties and components within this component.
- *
- * @param string $name
+ * Removes all properties and components within this component.
+ *
+ * @param string $name
* @return void
*/
public function __unset($name) {
@@ -251,4 +347,19 @@ class Sabre_VObject_Component extends Sabre_VObject_Element {
/* }}} */
+ /**
+ * This method is automatically called when the object is cloned.
+ * Specifically, this will ensure all child elements are also cloned.
+ *
+ * @return void
+ */
+ public function __clone() {
+
+ foreach($this->children as $key=>$child) {
+ $this->children[$key] = clone $child;
+ $this->children[$key]->parent = $this;
+ }
+
+ }
+
}
diff --git a/3rdparty/Sabre/VObject/Component/VAlarm.php b/3rdparty/Sabre/VObject/Component/VAlarm.php
new file mode 100755
index 00000000000..ebb4a9b18f6
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VAlarm.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * VAlarm component
+ *
+ * This component contains some additional functionality specific for VALARMs.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
+
+ /**
+ * Returns a DateTime object when this alarm is going to trigger.
+ *
+ * This ignores repeated alarm, only the first trigger is returned.
+ *
+ * @return DateTime
+ */
+ public function getEffectiveTriggerTime() {
+
+ $trigger = $this->TRIGGER;
+ if(!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
+ $triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($this->TRIGGER);
+ $related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
+
+ $parentComponent = $this->parent;
+ if ($related === 'START') {
+ $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
+ $effectiveTrigger->add($triggerDuration);
+ } else {
+ if ($parentComponent->name === 'VTODO') {
+ $endProp = 'DUE';
+ } elseif ($parentComponent->name === 'VEVENT') {
+ $endProp = 'DTEND';
+ } else {
+ throw new Sabre_DAV_Exception('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
+ }
+
+ if (isset($parentComponent->$endProp)) {
+ $effectiveTrigger = clone $parentComponent->$endProp->getDateTime();
+ $effectiveTrigger->add($triggerDuration);
+ } elseif (isset($parentComponent->DURATION)) {
+ $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
+ $duration = Sabre_VObject_DateTimeParser::parseDuration($parentComponent->DURATION);
+ $effectiveTrigger->add($duration);
+ $effectiveTrigger->add($triggerDuration);
+ } else {
+ $effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
+ $effectiveTrigger->add($triggerDuration);
+ }
+ }
+ } else {
+ $effectiveTrigger = $trigger->getDateTime();
+ }
+ return $effectiveTrigger;
+
+ }
+
+ /**
+ * Returns true or false depending on if the event falls in the specified
+ * time-range. This is used for filtering purposes.
+ *
+ * The rules used to determine if an event falls within the specified
+ * time-range is based on the CalDAV specification.
+ *
+ * @param DateTime $start
+ * @param DateTime $end
+ * @return bool
+ */
+ public function isInTimeRange(DateTime $start, DateTime $end) {
+
+ $effectiveTrigger = $this->getEffectiveTriggerTime();
+
+ if (isset($this->DURATION)) {
+ $duration = Sabre_VObject_DateTimeParser::parseDuration($this->DURATION);
+ $repeat = (string)$this->repeat;
+ if (!$repeat) {
+ $repeat = 1;
+ }
+
+ $period = new DatePeriod($effectiveTrigger, $duration, (int)$repeat);
+
+ foreach($period as $occurrence) {
+
+ if ($start <= $occurrence && $end > $occurrence) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return ($start <= $effectiveTrigger && $end > $effectiveTrigger);
+ }
+
+ }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/Component/VCalendar.php b/3rdparty/Sabre/VObject/Component/VCalendar.php
new file mode 100755
index 00000000000..f3be29afdbb
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VCalendar.php
@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * The VCalendar component
+ *
+ * This component adds functionality to a component, specific for a VCALENDAR.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
+
+ /**
+ * Returns a list of all 'base components'. For instance, if an Event has
+ * a recurrence rule, and one instance is overridden, the overridden event
+ * will have the same UID, but will be excluded from this list.
+ *
+ * VTIMEZONE components will always be excluded.
+ *
+ * @param string $componentName filter by component name
+ * @return array
+ */
+ public function getBaseComponents($componentName = null) {
+
+ $components = array();
+ foreach($this->children as $component) {
+
+ if (!$component instanceof Sabre_VObject_Component)
+ continue;
+
+ if (isset($component->{'RECURRENCE-ID'}))
+ continue;
+
+ if ($componentName && $component->name !== strtoupper($componentName))
+ continue;
+
+ if ($component->name === 'VTIMEZONE')
+ continue;
+
+ $components[] = $component;
+
+ }
+
+ return $components;
+
+ }
+
+ /**
+ * If this calendar object, has events with recurrence rules, this method
+ * can be used to expand the event into multiple sub-events.
+ *
+ * Each event will be stripped from it's recurrence information, and only
+ * the instances of the event in the specified timerange will be left
+ * alone.
+ *
+ * In addition, this method will cause timezone information to be stripped,
+ * and normalized to UTC.
+ *
+ * This method will alter the VCalendar. This cannot be reversed.
+ *
+ * This functionality is specifically used by the CalDAV standard. It is
+ * possible for clients to request expand events, if they are rather simple
+ * clients and do not have the possibility to calculate recurrences.
+ *
+ * @param DateTime $start
+ * @param DateTime $end
+ * @return void
+ */
+ public function expand(DateTime $start, DateTime $end) {
+
+ $newEvents = array();
+
+ foreach($this->select('VEVENT') as $key=>$vevent) {
+
+ if (isset($vevent->{'RECURRENCE-ID'})) {
+ unset($this->children[$key]);
+ continue;
+ }
+
+
+ if (!$vevent->rrule) {
+ unset($this->children[$key]);
+ if ($vevent->isInTimeRange($start, $end)) {
+ $newEvents[] = $vevent;
+ }
+ continue;
+ }
+
+ $uid = (string)$vevent->uid;
+ if (!$uid) {
+ throw new LogicException('Event did not have a UID!');
+ }
+
+ $it = new Sabre_VObject_RecurrenceIterator($this, $vevent->uid);
+ $it->fastForward($start);
+
+ while($it->valid() && $it->getDTStart() < $end) {
+
+ if ($it->getDTEnd() > $start) {
+
+ $newEvents[] = $it->getEventObject();
+
+ }
+ $it->next();
+
+ }
+ unset($this->children[$key]);
+
+ }
+
+ foreach($newEvents as $newEvent) {
+
+ foreach($newEvent->children as $child) {
+ if ($child instanceof Sabre_VObject_Property_DateTime &&
+ $child->getDateType() == Sabre_VObject_Property_DateTime::LOCALTZ) {
+ $child->setDateTime($child->getDateTime(),Sabre_VObject_Property_DateTime::UTC);
+ }
+ }
+
+ $this->add($newEvent);
+
+ }
+
+ // Removing all VTIMEZONE components
+ unset($this->VTIMEZONE);
+
+ }
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Component/VEvent.php b/3rdparty/Sabre/VObject/Component/VEvent.php
new file mode 100755
index 00000000000..4cc1e36d7d6
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VEvent.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * VEvent component
+ *
+ * This component contains some additional functionality specific for VEVENT's.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component {
+
+ /**
+ * Returns true or false depending on if the event falls in the specified
+ * time-range. This is used for filtering purposes.
+ *
+ * The rules used to determine if an event falls within the specified
+ * time-range is based on the CalDAV specification.
+ *
+ * @param DateTime $start
+ * @param DateTime $end
+ * @return bool
+ */
+ public function isInTimeRange(DateTime $start, DateTime $end) {
+
+ if ($this->RRULE) {
+ $it = new Sabre_VObject_RecurrenceIterator($this);
+ $it->fastForward($start);
+
+ // We fast-forwarded to a spot where the end-time of the
+ // recurrence instance exceeded the start of the requested
+ // time-range.
+ //
+ // If the starttime of the recurrence did not exceed the
+ // end of the time range as well, we have a match.
+ return ($it->getDTStart() < $end && $it->getDTEnd() > $start);
+
+ }
+
+ $effectiveStart = $this->DTSTART->getDateTime();
+ if (isset($this->DTEND)) {
+ $effectiveEnd = $this->DTEND->getDateTime();
+ // If this was an all-day event, we should just increase the
+ // end-date by 1. Otherwise the event will last until the second
+ // the date changed, by increasing this by 1 day the event lasts
+ // all of the last day as well.
+ if ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) {
+ $effectiveEnd->modify('+1 day');
+ }
+ } elseif (isset($this->DURATION)) {
+ $effectiveEnd = clone $effectiveStart;
+ $effectiveEnd->add( Sabre_VObject_DateTimeParser::parseDuration($this->DURATION) );
+ } elseif ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) {
+ $effectiveEnd = clone $effectiveStart;
+ $effectiveEnd->modify('+1 day');
+ } else {
+ $effectiveEnd = clone $effectiveStart;
+ }
+ return (
+ ($start <= $effectiveEnd) && ($end > $effectiveStart)
+ );
+
+ }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/Component/VJournal.php b/3rdparty/Sabre/VObject/Component/VJournal.php
new file mode 100755
index 00000000000..22b3ec921e5
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VJournal.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * VJournal component
+ *
+ * This component contains some additional functionality specific for VJOURNALs.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_Component_VJournal extends Sabre_VObject_Component {
+
+ /**
+ * Returns true or false depending on if the event falls in the specified
+ * time-range. This is used for filtering purposes.
+ *
+ * The rules used to determine if an event falls within the specified
+ * time-range is based on the CalDAV specification.
+ *
+ * @param DateTime $start
+ * @param DateTime $end
+ * @return bool
+ */
+ public function isInTimeRange(DateTime $start, DateTime $end) {
+
+ $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
+ if ($dtstart) {
+ $effectiveEnd = clone $dtstart;
+ if ($this->DTSTART->getDateType() == Sabre_VObject_Element_DateTime::DATE) {
+ $effectiveEnd->modify('+1 day');
+ }
+
+ return ($start <= $effectiveEnd && $end > $dtstart);
+
+ }
+ return false;
+
+
+ }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/Component/VTodo.php b/3rdparty/Sabre/VObject/Component/VTodo.php
new file mode 100755
index 00000000000..79d06298d7f
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Component/VTodo.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * VTodo component
+ *
+ * This component contains some additional functionality specific for VTODOs.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_Component_VTodo extends Sabre_VObject_Component {
+
+ /**
+ * Returns true or false depending on if the event falls in the specified
+ * time-range. This is used for filtering purposes.
+ *
+ * The rules used to determine if an event falls within the specified
+ * time-range is based on the CalDAV specification.
+ *
+ * @param DateTime $start
+ * @param DateTime $end
+ * @return bool
+ */
+ public function isInTimeRange(DateTime $start, DateTime $end) {
+
+ $dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
+ $duration = isset($this->DURATION)?Sabre_VObject_DateTimeParser::parseDuration($this->DURATION):null;
+ $due = isset($this->DUE)?$this->DUE->getDateTime():null;
+ $completed = isset($this->COMPLETED)?$this->COMPLETED->getDateTime():null;
+ $created = isset($this->CREATED)?$this->CREATED->getDateTime():null;
+
+ if ($dtstart) {
+ if ($duration) {
+ $effectiveEnd = clone $dtstart;
+ $effectiveEnd->add($duration);
+ return $start <= $effectiveEnd && $end > $dtstart;
+ } elseif ($due) {
+ return
+ ($start < $due || $start <= $dtstart) &&
+ ($end > $dtstart || $end >= $due);
+ } else {
+ return $start <= $dtstart && $end > $dtstart;
+ }
+ }
+ if ($due) {
+ return ($start < $due && $end >= $due);
+ }
+ if ($completed && $created) {
+ return
+ ($start <= $created || $start <= $completed) &&
+ ($end >= $created || $end >= $completed);
+ }
+ if ($completed) {
+ return ($start <= $completed && $end >= $completed);
+ }
+ if ($created) {
+ return ($end > $created);
+ }
+ return true;
+
+ }
+
+}
+
+?>
diff --git a/3rdparty/Sabre/VObject/DateTimeParser.php b/3rdparty/Sabre/VObject/DateTimeParser.php
new file mode 100755
index 00000000000..1e2d54ef3a9
--- /dev/null
+++ b/3rdparty/Sabre/VObject/DateTimeParser.php
@@ -0,0 +1,177 @@
+<?php
+
+/**
+ * DateTimeParser
+ *
+ * This class is responsible for parsing the several different date and time
+ * formats iCalendar and vCards have.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_DateTimeParser {
+
+ /**
+ * Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
+ *
+ * Specifying a reference timezone is optional. It will only be used
+ * if the non-UTC format is used. The argument is used as a reference, the
+ * returned DateTime object will still be in the UTC timezone.
+ *
+ * @param string $dt
+ * @param DateTimeZone $tz
+ * @return DateTime
+ */
+ static public function parseDateTime($dt,DateTimeZone $tz = null) {
+
+ // Format is YYYYMMDD + "T" + hhmmss
+ $result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
+
+ if (!$result) {
+ throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar datetime value is incorrect: ' . $dt);
+ }
+
+ if ($matches[7]==='Z' || is_null($tz)) {
+ $tz = new DateTimeZone('UTC');
+ }
+ $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
+
+ // Still resetting the timezone, to normalize everything to UTC
+ $date->setTimeZone(new DateTimeZone('UTC'));
+ return $date;
+
+ }
+
+ /**
+ * Parses an iCalendar (rfc5545) formatted date and returns a DateTime object
+ *
+ * @param string $date
+ * @return DateTime
+ */
+ static public function parseDate($date) {
+
+ // Format is YYYYMMDD
+ $result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
+
+ if (!$result) {
+ throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar date value is incorrect: ' . $date);
+ }
+
+ $date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new DateTimeZone('UTC'));
+ return $date;
+
+ }
+
+ /**
+ * Parses an iCalendar (RFC5545) formatted duration value.
+ *
+ * This method will either return a DateTimeInterval object, or a string
+ * suitable for strtotime or DateTime::modify.
+ *
+ * @param string $duration
+ * @param bool $asString
+ * @return DateInterval|string
+ */
+ static public function parseDuration($duration, $asString = false) {
+
+ $result = preg_match('/^(?P<plusminus>\+|-)?P((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$/', $duration, $matches);
+ if (!$result) {
+ throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar duration value is incorrect: ' . $duration);
+ }
+
+ if (!$asString) {
+ $invert = false;
+ if ($matches['plusminus']==='-') {
+ $invert = true;
+ }
+
+
+ $parts = array(
+ 'week',
+ 'day',
+ 'hour',
+ 'minute',
+ 'second',
+ );
+ foreach($parts as $part) {
+ $matches[$part] = isset($matches[$part])&&$matches[$part]?(int)$matches[$part]:0;
+ }
+
+
+ // We need to re-construct the $duration string, because weeks and
+ // days are not supported by DateInterval in the same string.
+ $duration = 'P';
+ $days = $matches['day'];
+ if ($matches['week']) {
+ $days+=$matches['week']*7;
+ }
+ if ($days)
+ $duration.=$days . 'D';
+
+ if ($matches['minute'] || $matches['second'] || $matches['hour']) {
+ $duration.='T';
+
+ if ($matches['hour'])
+ $duration.=$matches['hour'].'H';
+
+ if ($matches['minute'])
+ $duration.=$matches['minute'].'M';
+
+ if ($matches['second'])
+ $duration.=$matches['second'].'S';
+
+ }
+
+ $iv = new DateInterval($duration);
+ if ($invert) $iv->invert = true;
+
+ return $iv;
+
+ }
+
+
+
+ $parts = array(
+ 'week',
+ 'day',
+ 'hour',
+ 'minute',
+ 'second',
+ );
+
+ $newDur = '';
+ foreach($parts as $part) {
+ if (isset($matches[$part]) && $matches[$part]) {
+ $newDur.=' '.$matches[$part] . ' ' . $part . 's';
+ }
+ }
+
+ $newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
+ return $newDur;
+
+ }
+
+ /**
+ * Parses either a Date or DateTime, or Duration value.
+ *
+ * @param string $date
+ * @param DateTimeZone|string $referenceTZ
+ * @return DateTime|DateInterval
+ */
+ static public function parse($date, $referenceTZ = null) {
+
+ if ($date[0]==='P' || ($date[0]==='-' && $date[1]==='P')) {
+ return self::parseDuration($date);
+ } elseif (strlen($date)===8) {
+ return self::parseDate($date);
+ } else {
+ return self::parseDateTime($date, $referenceTZ);
+ }
+
+ }
+
+
+}
diff --git a/3rdparty/Sabre/VObject/Element.php b/3rdparty/Sabre/VObject/Element.php
index 8d2b0aaacd1..e20ff0b353c 100644..100755
--- a/3rdparty/Sabre/VObject/Element.php
+++ b/3rdparty/Sabre/VObject/Element.php
@@ -2,14 +2,15 @@
/**
* Base class for all elements
- *
+ *
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_VObject_Element extends Sabre_VObject_Node {
+ public $parent = null;
}
diff --git a/3rdparty/Sabre/VObject/Element/DateTime.php b/3rdparty/Sabre/VObject/Element/DateTime.php
index 3350ec02c88..5e5eb7ab6f2 100644..100755
--- a/3rdparty/Sabre/VObject/Element/DateTime.php
+++ b/3rdparty/Sabre/VObject/Element/DateTime.php
@@ -1,25 +1,18 @@
<?php
/**
- * DateTime property
+ * DateTime property
*
- * This element is used for iCalendar properties such as the DTSTART property.
- * It basically provides a few helper functions that make it easier to deal
- * with these. It supports both DATE-TIME and DATE values.
+ * this class got renamed to Sabre_VObject_Property_DateTime
*
- * In order to use this correctly, you must call setDateTime and getDateTime to
- * retrieve and modify dates respectively.
- *
- * If you use the 'value' or properties directly, this object does not keep
- * reference and results might appear incorrectly.
- *
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ * @deprecated
*/
-class Sabre_VObject_Element_DateTime extends Sabre_VObject_Property {
+class Sabre_VObject_Element_DateTime extends Sabre_VObject_Property_DateTime {
/**
* Local 'floating' time
@@ -41,205 +34,4 @@ class Sabre_VObject_Element_DateTime extends Sabre_VObject_Property {
*/
const DATE = 4;
- /**
- * DateTime representation
- *
- * @var DateTime
- */
- protected $dateTime;
-
- /**
- * dateType
- *
- * @var int
- */
- protected $dateType;
-
- /**
- * Updates the Date and Time.
- *
- * @param DateTime $dt
- * @param int $dateType
- * @return void
- */
- public function setDateTime(DateTime $dt, $dateType = self::LOCALTZ) {
-
- switch($dateType) {
-
- case self::LOCAL :
- $this->setValue($dt->format('Ymd\\THis'));
- $this->offsetUnset('VALUE');
- $this->offsetUnset('TZID');
- $this->offsetSet('VALUE','DATE-TIME');
- break;
- case self::UTC :
- $dt->setTimeZone(new DateTimeZone('UTC'));
- $this->setValue($dt->format('Ymd\\THis\\Z'));
- $this->offsetUnset('VALUE');
- $this->offsetUnset('TZID');
- $this->offsetSet('VALUE','DATE-TIME');
- break;
- case self::LOCALTZ :
- $this->setValue($dt->format('Ymd\\THis'));
- $this->offsetUnset('VALUE');
- $this->offsetUnset('TZID');
- $this->offsetSet('VALUE','DATE-TIME');
- $this->offsetSet('TZID', $dt->getTimeZone()->getName());
- break;
- case self::DATE :
- $this->setValue($dt->format('Ymd'));
- $this->offsetUnset('VALUE');
- $this->offsetUnset('TZID');
- $this->offsetSet('VALUE','DATE');
- break;
- default :
- throw new InvalidArgumentException('You must pass a valid dateType constant');
-
- }
- $this->dateTime = $dt;
- $this->dateType = $dateType;
-
- }
-
- /**
- * Returns the current DateTime value.
- *
- * If no value was set, this method returns null.
- *
- * @return DateTime|null
- */
- public function getDateTime() {
-
- if ($this->dateTime)
- return $this->dateTime;
-
- list(
- $this->dateType,
- $this->dateTime
- ) = self::parseData($this->value, $this);
- return $this->dateTime;
-
- }
-
- /**
- * Returns the type of Date format.
- *
- * This method returns one of the format constants. If no date was set,
- * this method will return null.
- *
- * @return int|null
- */
- public function getDateType() {
-
- if ($this->dateType)
- return $this->dateType;
-
- list(
- $this->dateType,
- $this->dateTime,
- ) = self::parseData($this->value, $this);
- return $this->dateType;
-
- }
-
- /**
- * Parses the internal data structure to figure out what the current date
- * and time is.
- *
- * The returned array contains two elements:
- * 1. A 'DateType' constant (as defined on this class), or null.
- * 2. A DateTime object (or null)
- *
- * @param string|null $propertyValue The string to parse (yymmdd or
- * ymmddThhmmss, etc..)
- * @param Sabre_VObject_Property|null $property The instance of the
- * property we're parsing.
- * @return array
- */
- static public function parseData($propertyValue, Sabre_VObject_Property $property = null) {
-
- if (is_null($propertyValue)) {
- return array(null, null);
- }
-
- $date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
- $time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
- $regex = "/^$date(T$time(?P<isutc>Z)?)?$/";
-
- if (!preg_match($regex, $propertyValue, $matches)) {
- throw new InvalidArgumentException($propertyValue . ' is not a valid DateTime or Date string');
- }
-
- if (!isset($matches['hour'])) {
- // Date-only
- return array(
- self::DATE,
- new DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00'),
- );
- }
-
- $dateStr =
- $matches['year'] .'-' .
- $matches['month'] . '-' .
- $matches['date'] . ' ' .
- $matches['hour'] . ':' .
- $matches['minute'] . ':' .
- $matches['second'];
-
- if (isset($matches['isutc'])) {
- $dt = new DateTime($dateStr,new DateTimeZone('UTC'));
- $dt->setTimeZone(new DateTimeZone('UTC'));
- return array(
- self::UTC,
- $dt
- );
- }
-
- // Finding the timezone.
- $tzid = $property['TZID'];
- if (!$tzid) {
- return array(
- self::LOCAL,
- new DateTime($dateStr)
- );
- }
-
- try {
- $tz = new DateTimeZone($tzid->value);
- } catch (Exception $e) {
-
- // The id was invalid, we're going to try to find the information
- // through the VTIMEZONE object.
-
- // First we find the root object
- $root = $property;
- while($root->parent) {
- $root = $root->parent;
- }
-
- if (isset($root->VTIMEZONE)) {
- foreach($root->VTIMEZONE as $vtimezone) {
- if (((string)$vtimezone->TZID) == $tzid) {
- if (isset($vtimezone->{'X-LIC-LOCATION'})) {
- $tzid = (string)$vtimezone->{'X-LIC-LOCATION'};
- }
- }
- }
- }
-
- $tz = new DateTimeZone($tzid);
-
- }
- $dt = new DateTime($dateStr, $tz);
- $dt->setTimeZone($tz);
-
- return array(
- self::LOCALTZ,
- $dt
- );
-
- }
-
}
-
-?>
diff --git a/3rdparty/Sabre/VObject/Element/MultiDateTime.php b/3rdparty/Sabre/VObject/Element/MultiDateTime.php
index dc6ca5abb80..8a12ced94a8 100644..100755
--- a/3rdparty/Sabre/VObject/Element/MultiDateTime.php
+++ b/3rdparty/Sabre/VObject/Element/MultiDateTime.php
@@ -1,168 +1,17 @@
<?php
/**
- * Multi-DateTime property
+ * Multi-DateTime property
*
- * This element is used for iCalendar properties such as the EXDATE property.
- * It basically provides a few helper functions that make it easier to deal
- * with these. It supports both DATE-TIME and DATE values.
+ * This class got renamed to Sabre_VObject_Property_MultiDateTime
*
- * In order to use this correctly, you must call setDateTimes and getDateTimes
- * to retrieve and modify dates respectively.
- *
- * If you use the 'value' or properties directly, this object does not keep
- * reference and results might appear incorrectly.
- *
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ * @deprecated
*/
-class Sabre_VObject_Element_MultiDateTime extends Sabre_VObject_Property {
-
- /**
- * DateTime representation
- *
- * @var DateTime[]
- */
- protected $dateTimes;
-
- /**
- * dateType
- *
- * This is one of the Sabre_VObject_Element_DateTime constants.
- *
- * @var int
- */
- protected $dateType;
-
- /**
- * Updates the value
- *
- * @param array $dt Must be an array of DateTime objects.
- * @param int $dateType
- * @return void
- */
- public function setDateTimes(array $dt, $dateType = Sabre_VObject_Element_DateTime::LOCALTZ) {
-
- foreach($dt as $i)
- if (!$i instanceof DateTime)
- throw new InvalidArgumentException('You must pass an array of DateTime objects');
-
- $this->offsetUnset('VALUE');
- $this->offsetUnset('TZID');
- switch($dateType) {
-
- case Sabre_VObject_Element_DateTime::LOCAL :
- $val = array();
- foreach($dt as $i) {
- $val[] = $i->format('Ymd\\THis');
- }
- $this->setValue(implode(',',$val));
- $this->offsetSet('VALUE','DATE-TIME');
- break;
- case Sabre_VObject_Element_DateTime::UTC :
- $val = array();
- foreach($dt as $i) {
- $i->setTimeZone(new DateTimeZone('UTC'));
- $val[] = $i->format('Ymd\\THis\\Z');
- }
- $this->setValue(implode(',',$val));
- $this->offsetSet('VALUE','DATE-TIME');
- break;
- case Sabre_VObject_Element_DateTime::LOCALTZ :
- $val = array();
- foreach($dt as $i) {
- $val[] = $i->format('Ymd\\THis');
- }
- $this->setValue(implode(',',$val));
- $this->offsetSet('VALUE','DATE-TIME');
- $this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
- break;
- case Sabre_VObject_Element_DateTime::DATE :
- $val = array();
- foreach($dt as $i) {
- $val[] = $i->format('Ymd');
- }
- $this->setValue(implode(',',$val));
- $this->offsetSet('VALUE','DATE');
- break;
- default :
- throw new InvalidArgumentException('You must pass a valid dateType constant');
-
- }
- $this->dateTimes = $dt;
- $this->dateType = $dateType;
-
- }
-
- /**
- * Returns the current DateTime value.
- *
- * If no value was set, this method returns null.
- *
- * @return array|null
- */
- public function getDateTimes() {
-
- if ($this->dateTimes)
- return $this->dateTimes;
-
- $dts = array();
-
- if (!$this->value) {
- $this->dateTimes = null;
- $this->dateType = null;
- return null;
- }
-
- foreach(explode(',',$this->value) as $val) {
- list(
- $type,
- $dt
- ) = Sabre_VObject_Element_DateTime::parseData($val, $this);
- $dts[] = $dt;
- $this->dateType = $type;
- }
- $this->dateTimes = $dts;
- return $this->dateTimes;
-
- }
-
- /**
- * Returns the type of Date format.
- *
- * This method returns one of the format constants. If no date was set,
- * this method will return null.
- *
- * @return int|null
- */
- public function getDateType() {
-
- if ($this->dateType)
- return $this->dateType;
-
- if (!$this->value) {
- $this->dateTimes = null;
- $this->dateType = null;
- return null;
- }
-
- $dts = array();
- foreach(explode(',',$this->value) as $val) {
- list(
- $type,
- $dt
- ) = Sabre_VObject_Element_DateTime::parseData($val, $this);
- $dts[] = $dt;
- $this->dateType = $type;
- }
- $this->dateTimes = $dts;
- return $this->dateType;
-
- }
+class Sabre_VObject_Element_MultiDateTime extends Sabre_VObject_Property_MultiDateTime {
}
-
-?>
diff --git a/3rdparty/Sabre/VObject/ElementList.php b/3rdparty/Sabre/VObject/ElementList.php
index 9922cd587bc..7e508db20f0 100644..100755
--- a/3rdparty/Sabre/VObject/ElementList.php
+++ b/3rdparty/Sabre/VObject/ElementList.php
@@ -8,15 +8,15 @@
*
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
/**
- * Inner elements
- *
+ * Inner elements
+ *
* @var array
*/
protected $elements = array();
@@ -24,37 +24,37 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
/**
* Creates the element list.
*
- * @param array $elements
+ * @param array $elements
*/
public function __construct(array $elements) {
$this->elements = $elements;
- }
+ }
/* {{{ Iterator interface */
/**
- * Current position
- *
- * @var int
+ * Current position
+ *
+ * @var int
*/
private $key = 0;
/**
- * Returns current item in iteration
- *
- * @return Sabre_VObject_Element
+ * Returns current item in iteration
+ *
+ * @return Sabre_VObject_Element
*/
public function current() {
return $this->elements[$this->key];
}
-
+
/**
- * To the next item in the iterator
- *
+ * To the next item in the iterator
+ *
* @return void
*/
public function next() {
@@ -64,8 +64,8 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
}
/**
- * Returns the current iterator key
- *
+ * Returns the current iterator key
+ *
* @return int
*/
public function key() {
@@ -75,9 +75,9 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
}
/**
- * Returns true if the current position in the iterator is a valid one
- *
- * @return bool
+ * Returns true if the current position in the iterator is a valid one
+ *
+ * @return bool
*/
public function valid() {
@@ -86,9 +86,9 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
}
/**
- * Rewinds the iterator
- *
- * @return void
+ * Rewinds the iterator
+ *
+ * @return void
*/
public function rewind() {
@@ -101,9 +101,9 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
/* {{{ Countable interface */
/**
- * Returns the number of elements
- *
- * @return int
+ * Returns the number of elements
+ *
+ * @return int
*/
public function count() {
@@ -115,12 +115,12 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
/* {{{ ArrayAccess Interface */
-
+
/**
* Checks if an item exists through ArrayAccess.
*
- * @param int $offset
- * @return bool
+ * @param int $offset
+ * @return bool
*/
public function offsetExists($offset) {
@@ -131,8 +131,8 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
/**
* Gets an item through ArrayAccess.
*
- * @param int $offset
- * @return mixed
+ * @param int $offset
+ * @return mixed
*/
public function offsetGet($offset) {
@@ -143,8 +143,8 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
/**
* Sets an item through ArrayAccess.
*
- * @param int $offset
- * @param mixed $value
+ * @param int $offset
+ * @param mixed $value
* @return void
*/
public function offsetSet($offset,$value) {
@@ -158,7 +158,7 @@ class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
*
* This method just forwards the request to the inner iterator
*
- * @param int $offset
+ * @param int $offset
* @return void
*/
public function offsetUnset($offset) {
diff --git a/3rdparty/Sabre/VObject/FreeBusyGenerator.php b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
new file mode 100755
index 00000000000..1c96a64a004
--- /dev/null
+++ b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
@@ -0,0 +1,297 @@
+<?php
+
+/**
+ * This class helps with generating FREEBUSY reports based on existing sets of
+ * objects.
+ *
+ * It only looks at VEVENT and VFREEBUSY objects from the sourcedata, and
+ * generates a single VFREEBUSY object.
+ *
+ * VFREEBUSY components are described in RFC5545, The rules for what should
+ * go in a single freebusy report is taken from RFC4791, section 7.10.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_FreeBusyGenerator {
+
+ /**
+ * Input objects
+ *
+ * @var array
+ */
+ protected $objects;
+
+ /**
+ * Start of range
+ *
+ * @var DateTime|null
+ */
+ protected $start;
+
+ /**
+ * End of range
+ *
+ * @var DateTime|null
+ */
+ protected $end;
+
+ /**
+ * VCALENDAR object
+ *
+ * @var Sabre_VObject_Component
+ */
+ protected $baseObject;
+
+ /**
+ * Sets the VCALENDAR object.
+ *
+ * If this is set, it will not be generated for you. You are responsible
+ * for setting things like the METHOD, CALSCALE, VERSION, etc..
+ *
+ * The VFREEBUSY object will be automatically added though.
+ *
+ * @param Sabre_VObject_Component $vcalendar
+ * @return void
+ */
+ public function setBaseObject(Sabre_VObject_Component $vcalendar) {
+
+ $this->baseObject = $vcalendar;
+
+ }
+
+ /**
+ * Sets the input objects
+ *
+ * Every object must either be a string or a Sabre_VObject_Component.
+ *
+ * @param array $objects
+ * @return void
+ */
+ public function setObjects(array $objects) {
+
+ $this->objects = array();
+ foreach($objects as $object) {
+
+ if (is_string($object)) {
+ $this->objects[] = Sabre_VObject_Reader::read($object);
+ } elseif ($object instanceof Sabre_VObject_Component) {
+ $this->objects[] = $object;
+ } else {
+ throw new InvalidArgumentException('You can only pass strings or Sabre_VObject_Component arguments to setObjects');
+ }
+
+ }
+
+ }
+
+ /**
+ * Sets the time range
+ *
+ * Any freebusy object falling outside of this time range will be ignored.
+ *
+ * @param DateTime $start
+ * @param DateTime $end
+ * @return void
+ */
+ public function setTimeRange(DateTime $start = null, DateTime $end = null) {
+
+ $this->start = $start;
+ $this->end = $end;
+
+ }
+
+ /**
+ * Parses the input data and returns a correct VFREEBUSY object, wrapped in
+ * a VCALENDAR.
+ *
+ * @return Sabre_VObject_Component
+ */
+ public function getResult() {
+
+ $busyTimes = array();
+
+ foreach($this->objects as $object) {
+
+ foreach($object->getBaseComponents() as $component) {
+
+ switch($component->name) {
+
+ case 'VEVENT' :
+
+ $FBTYPE = 'BUSY';
+ if (isset($component->TRANSP) && (strtoupper($component->TRANSP) === 'TRANSPARENT')) {
+ break;
+ }
+ if (isset($component->STATUS)) {
+ $status = strtoupper($component->STATUS);
+ if ($status==='CANCELLED') {
+ break;
+ }
+ if ($status==='TENTATIVE') {
+ $FBTYPE = 'BUSY-TENTATIVE';
+ }
+ }
+
+ $times = array();
+
+ if ($component->RRULE) {
+
+ $iterator = new Sabre_VObject_RecurrenceIterator($object, (string)$component->uid);
+ if ($this->start) {
+ $iterator->fastForward($this->start);
+ }
+
+ $maxRecurrences = 200;
+
+ while($iterator->valid() && --$maxRecurrences) {
+
+ $startTime = $iterator->getDTStart();
+ if ($this->end && $startTime > $this->end) {
+ break;
+ }
+ $times[] = array(
+ $iterator->getDTStart(),
+ $iterator->getDTEnd(),
+ );
+
+ $iterator->next();
+
+ }
+
+ } else {
+
+ $startTime = $component->DTSTART->getDateTime();
+ if ($this->end && $startTime > $this->end) {
+ break;
+ }
+ $endTime = null;
+ if (isset($component->DTEND)) {
+ $endTime = $component->DTEND->getDateTime();
+ } elseif (isset($component->DURATION)) {
+ $duration = Sabre_VObject_DateTimeParser::parseDuration((string)$component->DURATION);
+ $endTime = clone $startTime;
+ $endTime->add($duration);
+ } elseif ($component->DTSTART->getDateType() === Sabre_VObject_Property_DateTime::DATE) {
+ $endTime = clone $startTime;
+ $endTime->modify('+1 day');
+ } else {
+ // The event had no duration (0 seconds)
+ break;
+ }
+
+ $times[] = array($startTime, $endTime);
+
+ }
+
+ foreach($times as $time) {
+
+ if ($this->end && $time[0] > $this->end) break;
+ if ($this->start && $time[1] < $this->start) break;
+
+ $busyTimes[] = array(
+ $time[0],
+ $time[1],
+ $FBTYPE,
+ );
+ }
+ break;
+
+ case 'VFREEBUSY' :
+ foreach($component->FREEBUSY as $freebusy) {
+
+ $fbType = isset($freebusy['FBTYPE'])?strtoupper($freebusy['FBTYPE']):'BUSY';
+
+ // Skipping intervals marked as 'free'
+ if ($fbType==='FREE')
+ continue;
+
+ $values = explode(',', $freebusy);
+ foreach($values as $value) {
+ list($startTime, $endTime) = explode('/', $value);
+ $startTime = Sabre_VObject_DateTimeParser::parseDateTime($startTime);
+
+ if (substr($endTime,0,1)==='P' || substr($endTime,0,2)==='-P') {
+ $duration = Sabre_VObject_DateTimeParser::parseDuration($endTime);
+ $endTime = clone $startTime;
+ $endTime->add($duration);
+ } else {
+ $endTime = Sabre_VObject_DateTimeParser::parseDateTime($endTime);
+ }
+
+ if($this->start && $this->start > $endTime) continue;
+ if($this->end && $this->end < $startTime) continue;
+ $busyTimes[] = array(
+ $startTime,
+ $endTime,
+ $fbType
+ );
+
+ }
+
+
+ }
+ break;
+
+
+
+ }
+
+
+ }
+
+ }
+
+ if ($this->baseObject) {
+ $calendar = $this->baseObject;
+ } else {
+ $calendar = new Sabre_VObject_Component('VCALENDAR');
+ $calendar->version = '2.0';
+ if (Sabre_DAV_Server::$exposeVersion) {
+ $calendar->prodid = '-//SabreDAV//Sabre VObject ' . Sabre_VObject_Version::VERSION . '//EN';
+ } else {
+ $calendar->prodid = '-//SabreDAV//Sabre VObject//EN';
+ }
+ $calendar->calscale = 'GREGORIAN';
+ }
+
+ $vfreebusy = new Sabre_VObject_Component('VFREEBUSY');
+ $calendar->add($vfreebusy);
+
+ if ($this->start) {
+ $dtstart = new Sabre_VObject_Property_DateTime('DTSTART');
+ $dtstart->setDateTime($this->start,Sabre_VObject_Property_DateTime::UTC);
+ $vfreebusy->add($dtstart);
+ }
+ if ($this->end) {
+ $dtend = new Sabre_VObject_Property_DateTime('DTEND');
+ $dtend->setDateTime($this->start,Sabre_VObject_Property_DateTime::UTC);
+ $vfreebusy->add($dtend);
+ }
+ $dtstamp = new Sabre_VObject_Property_DateTime('DTSTAMP');
+ $dtstamp->setDateTime(new DateTime('now'), Sabre_VObject_Property_DateTime::UTC);
+ $vfreebusy->add($dtstamp);
+
+ foreach($busyTimes as $busyTime) {
+
+ $busyTime[0]->setTimeZone(new DateTimeZone('UTC'));
+ $busyTime[1]->setTimeZone(new DateTimeZone('UTC'));
+
+ $prop = new Sabre_VObject_Property(
+ 'FREEBUSY',
+ $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')
+ );
+ $prop['FBTYPE'] = $busyTime[2];
+ $vfreebusy->add($prop);
+
+ }
+
+ return $calendar;
+
+ }
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Node.php b/3rdparty/Sabre/VObject/Node.php
index 7100b62f1cb..d89e01b56c6 100644..100755
--- a/3rdparty/Sabre/VObject/Node.php
+++ b/3rdparty/Sabre/VObject/Node.php
@@ -1,47 +1,47 @@
<?php
/**
- * Base class for all nodes
- *
+ * Base class for all nodes
+ *
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Countable {
/**
- * Turns the object back into a serialized blob.
- *
- * @return string
+ * Turns the object back into a serialized blob.
+ *
+ * @return string
*/
abstract function serialize();
/**
- * Iterator override
- *
- * @var Sabre_VObject_ElementList
+ * Iterator override
+ *
+ * @var Sabre_VObject_ElementList
*/
protected $iterator = null;
/**
* A link to the parent node
- *
- * @var Sabre_VObject_Node
+ *
+ * @var Sabre_VObject_Node
*/
- protected $parent = null;
+ public $parent = null;
/* {{{ IteratorAggregator interface */
/**
- * Returns the iterator for this object
- *
- * @return Sabre_VObject_ElementList
+ * Returns the iterator for this object
+ *
+ * @return Sabre_VObject_ElementList
*/
public function getIterator() {
- if (!is_null($this->iterator))
+ if (!is_null($this->iterator))
return $this->iterator;
return new Sabre_VObject_ElementList(array($this));
@@ -52,8 +52,8 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
* Sets the overridden iterator
*
* Note that this is not actually part of the iterator interface
- *
- * @param Sabre_VObject_ElementList $iterator
+ *
+ * @param Sabre_VObject_ElementList $iterator
* @return void
*/
public function setIterator(Sabre_VObject_ElementList $iterator) {
@@ -67,9 +67,9 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
/* {{{ Countable interface */
/**
- * Returns the number of elements
- *
- * @return int
+ * Returns the number of elements
+ *
+ * @return int
*/
public function count() {
@@ -82,14 +82,14 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
/* {{{ ArrayAccess Interface */
-
+
/**
* Checks if an item exists through ArrayAccess.
*
* This method just forwards the request to the inner iterator
- *
- * @param int $offset
- * @return bool
+ *
+ * @param int $offset
+ * @return bool
*/
public function offsetExists($offset) {
@@ -103,8 +103,8 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
*
* This method just forwards the request to the inner iterator
*
- * @param int $offset
- * @return mixed
+ * @param int $offset
+ * @return mixed
*/
public function offsetGet($offset) {
@@ -118,8 +118,8 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
*
* This method just forwards the request to the inner iterator
*
- * @param int $offset
- * @param mixed $value
+ * @param int $offset
+ * @param mixed $value
* @return void
*/
public function offsetSet($offset,$value) {
@@ -134,7 +134,7 @@ abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Cou
*
* This method just forwards the request to the inner iterator
*
- * @param int $offset
+ * @param int $offset
* @return void
*/
public function offsetUnset($offset) {
diff --git a/3rdparty/Sabre/VObject/Parameter.php b/3rdparty/Sabre/VObject/Parameter.php
index 9ebab6ec69b..2e39af5f78a 100644..100755
--- a/3rdparty/Sabre/VObject/Parameter.php
+++ b/3rdparty/Sabre/VObject/Parameter.php
@@ -5,51 +5,54 @@
*
* This class represents a parameter. A parameter is always tied to a property.
* In the case of:
- * DTSTART;VALUE=DATE:20101108
+ * DTSTART;VALUE=DATE:20101108
* VALUE=DATE would be the parameter name and value.
- *
+ *
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Parameter extends Sabre_VObject_Node {
/**
- * Parameter name
- *
- * @var string
+ * Parameter name
+ *
+ * @var string
*/
public $name;
/**
- * Parameter value
- *
- * @var string
+ * Parameter value
+ *
+ * @var string
*/
public $value;
/**
- * Sets up the object
- *
- * @param string $name
- * @param string $value
+ * Sets up the object
+ *
+ * @param string $name
+ * @param string $value
*/
public function __construct($name, $value = null) {
$this->name = strtoupper($name);
$this->value = $value;
- }
+ }
/**
- * Turns the object back into a serialized blob.
- *
- * @return string
+ * Turns the object back into a serialized blob.
+ *
+ * @return string
*/
public function serialize() {
+ if (is_null($this->value)) {
+ return $this->name;
+ }
$src = array(
'\\',
"\n",
@@ -68,9 +71,9 @@ class Sabre_VObject_Parameter extends Sabre_VObject_Node {
}
/**
- * Called when this object is being cast to a string
- *
- * @return string
+ * Called when this object is being cast to a string
+ *
+ * @return string
*/
public function __toString() {
diff --git a/3rdparty/Sabre/VObject/ParseException.php b/3rdparty/Sabre/VObject/ParseException.php
index ed4ef2e8592..1b5e95bf16e 100644..100755
--- a/3rdparty/Sabre/VObject/ParseException.php
+++ b/3rdparty/Sabre/VObject/ParseException.php
@@ -2,11 +2,11 @@
/**
* Exception thrown by Sabre_VObject_Reader if an invalid object was attempted to be parsed.
- *
+ *
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_ParseException extends Exception { }
diff --git a/3rdparty/Sabre/VObject/Property.php b/3rdparty/Sabre/VObject/Property.php
index 06058229043..ce74fe3865b 100644..100755
--- a/3rdparty/Sabre/VObject/Property.php
+++ b/3rdparty/Sabre/VObject/Property.php
@@ -4,58 +4,103 @@
* VObject Property
*
* A property in VObject is usually in the form PARAMNAME:paramValue.
- * An example is : SUMMARY:Weekly meeting
+ * An example is : SUMMARY:Weekly meeting
*
* Properties can also have parameters:
* SUMMARY;LANG=en:Weekly meeting.
*
- * Parameters can be accessed using the ArrayAccess interface.
+ * Parameters can be accessed using the ArrayAccess interface.
*
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Property extends Sabre_VObject_Element {
/**
- * Propertyname
- *
- * @var string
+ * Propertyname
+ *
+ * @var string
*/
public $name;
/**
* Group name
- *
+ *
* This may be something like 'HOME' for vcards.
*
- * @var string
+ * @var string
*/
public $group;
/**
- * Property parameters
- *
- * @var array
+ * Property parameters
+ *
+ * @var array
*/
public $parameters = array();
/**
- * Property value
- *
- * @var string
+ * Property value
+ *
+ * @var string
*/
public $value;
/**
+ * If properties are added to this map, they will be automatically mapped
+ * to their respective classes, if parsed by the reader or constructed with
+ * the 'create' method.
+ *
+ * @var array
+ */
+ static public $classMap = array(
+ 'COMPLETED' => 'Sabre_VObject_Property_DateTime',
+ 'CREATED' => 'Sabre_VObject_Property_DateTime',
+ 'DTEND' => 'Sabre_VObject_Property_DateTime',
+ 'DTSTAMP' => 'Sabre_VObject_Property_DateTime',
+ 'DTSTART' => 'Sabre_VObject_Property_DateTime',
+ 'DUE' => 'Sabre_VObject_Property_DateTime',
+ 'EXDATE' => 'Sabre_VObject_Property_MultiDateTime',
+ 'LAST-MODIFIED' => 'Sabre_VObject_Property_DateTime',
+ 'RECURRENCE-ID' => 'Sabre_VObject_Property_DateTime',
+ 'TRIGGER' => 'Sabre_VObject_Property_DateTime',
+ );
+
+ /**
+ * Creates the new property by name, but in addition will also see if
+ * there's a class mapped to the property name.
+ *
+ * @param string $name
+ * @param string $value
+ * @return void
+ */
+ static public function create($name, $value = null) {
+
+ $name = strtoupper($name);
+ $shortName = $name;
+ $group = null;
+ if (strpos($shortName,'.')!==false) {
+ list($group, $shortName) = explode('.', $shortName);
+ }
+
+ if (isset(self::$classMap[$shortName])) {
+ return new self::$classMap[$shortName]($name, $value);
+ } else {
+ return new self($name, $value);
+ }
+
+ }
+
+ /**
* Creates a new property object
- *
- * By default this object will iterate over its own children, but this can
+ *
+ * By default this object will iterate over its own children, but this can
* be overridden with the iterator argument
- *
- * @param string $name
+ *
+ * @param string $name
* @param string $value
* @param Sabre_VObject_ElementList $iterator
*/
@@ -73,10 +118,12 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
}
+
+
/**
- * Updates the internal value
- *
- * @param string $value
+ * Updates the internal value
+ *
+ * @param string $value
* @return void
*/
public function setValue($value) {
@@ -86,9 +133,9 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
}
/**
- * Turns the object back into a serialized blob.
- *
- * @return string
+ * Turns the object back into a serialized blob.
+ *
+ * @return string
*/
public function serialize() {
@@ -97,7 +144,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
if (count($this->parameters)) {
foreach($this->parameters as $param) {
-
+
$str.=';' . $param->serialize();
}
@@ -115,8 +162,8 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
$out = '';
while(strlen($str)>0) {
if (strlen($str)>75) {
- $out.= substr($str,0,75) . "\r\n";
- $str = ' ' . substr($str,75);
+ $out.= mb_strcut($str,0,75,'utf-8') . "\r\n";
+ $str = ' ' . mb_strcut($str,75,strlen($str),'utf-8');
} else {
$out.=$str . "\r\n";
$str='';
@@ -136,11 +183,11 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
* add(Sabre_VObject_Parameter $element)
* add(string $name, $value)
*
- * The first version adds an Parameter
- * The second adds a property as a string.
- *
- * @param mixed $item
- * @param mixed $itemValue
+ * The first version adds an Parameter
+ * The second adds a property as a string.
+ *
+ * @param mixed $item
+ * @param mixed $itemValue
* @return void
*/
public function add($item, $itemValue = null) {
@@ -153,7 +200,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
$this->parameters[] = $item;
} elseif(is_string($item)) {
- if (!is_scalar($itemValue)) {
+ if (!is_scalar($itemValue) && !is_null($itemValue)) {
throw new InvalidArgumentException('The second argument must be scalar');
}
$parameter = new Sabre_VObject_Parameter($item,$itemValue);
@@ -161,21 +208,20 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
$this->parameters[] = $parameter;
} else {
-
+
throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
}
}
-
/* ArrayAccess interface {{{ */
/**
* Checks if an array element exists
- *
- * @param mixed $name
- * @return bool
+ *
+ * @param mixed $name
+ * @return bool
*/
public function offsetExists($name) {
@@ -191,16 +237,16 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
}
/**
- * Returns a parameter, or parameter list.
- *
- * @param string $name
- * @return Sabre_VObject_Element
+ * Returns a parameter, or parameter list.
+ *
+ * @param string $name
+ * @return Sabre_VObject_Element
*/
public function offsetGet($name) {
if (is_int($name)) return parent::offsetGet($name);
$name = strtoupper($name);
-
+
$result = array();
foreach($this->parameters as $parameter) {
if ($parameter->name == $name)
@@ -219,8 +265,8 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
}
/**
- * Creates a new parameter
- *
+ * Creates a new parameter
+ *
* @param string $name
* @param mixed $value
* @return void
@@ -230,7 +276,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
if (is_int($name)) return parent::offsetSet($name, $value);
if (is_scalar($value)) {
- if (!is_string($name))
+ if (!is_string($name))
throw new InvalidArgumentException('A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.');
$this->offsetUnset($name);
@@ -242,7 +288,7 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
if (!is_null($name))
throw new InvalidArgumentException('Don\'t specify a parameter name if you\'re passing a Sabre_VObject_Parameter. Add using $array[]=$parameterObject.');
- $value->parent = $this;
+ $value->parent = $this;
$this->parameters[] = $value;
} else {
throw new InvalidArgumentException('You can only add parameters to the property object');
@@ -251,17 +297,16 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
}
/**
- * Removes one or more parameters with the specified name
- *
- * @param string $name
- * @return void
+ * Removes one or more parameters with the specified name
+ *
+ * @param string $name
+ * @return void
*/
public function offsetUnset($name) {
- if (is_int($name)) return parent::offsetUnset($name, $value);
+ if (is_int($name)) return parent::offsetUnset($name);
$name = strtoupper($name);
-
- $result = array();
+
foreach($this->parameters as $key=>$parameter) {
if ($parameter->name == $name) {
$parameter->parent = null;
@@ -275,15 +320,29 @@ class Sabre_VObject_Property extends Sabre_VObject_Element {
/* }}} */
/**
- * Called when this object is being cast to a string
- *
- * @return string
+ * Called when this object is being cast to a string
+ *
+ * @return string
*/
public function __toString() {
- return $this->value;
+ return (string)$this->value;
}
+ /**
+ * This method is automatically called when the object is cloned.
+ * Specifically, this will ensure all child elements are also cloned.
+ *
+ * @return void
+ */
+ public function __clone() {
+
+ foreach($this->parameters as $key=>$child) {
+ $this->parameters[$key] = clone $child;
+ $this->parameters[$key]->parent = $this;
+ }
+
+ }
}
diff --git a/3rdparty/Sabre/VObject/Property/DateTime.php b/3rdparty/Sabre/VObject/Property/DateTime.php
new file mode 100755
index 00000000000..fe2372caa81
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Property/DateTime.php
@@ -0,0 +1,260 @@
+<?php
+
+/**
+ * DateTime property
+ *
+ * This element is used for iCalendar properties such as the DTSTART property.
+ * It basically provides a few helper functions that make it easier to deal
+ * with these. It supports both DATE-TIME and DATE values.
+ *
+ * In order to use this correctly, you must call setDateTime and getDateTime to
+ * retrieve and modify dates respectively.
+ *
+ * If you use the 'value' or properties directly, this object does not keep
+ * reference and results might appear incorrectly.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
+
+ /**
+ * Local 'floating' time
+ */
+ const LOCAL = 1;
+
+ /**
+ * UTC-based time
+ */
+ const UTC = 2;
+
+ /**
+ * Local time plus timezone
+ */
+ const LOCALTZ = 3;
+
+ /**
+ * Only a date, time is ignored
+ */
+ const DATE = 4;
+
+ /**
+ * DateTime representation
+ *
+ * @var DateTime
+ */
+ protected $dateTime;
+
+ /**
+ * dateType
+ *
+ * @var int
+ */
+ protected $dateType;
+
+ /**
+ * Updates the Date and Time.
+ *
+ * @param DateTime $dt
+ * @param int $dateType
+ * @return void
+ */
+ public function setDateTime(DateTime $dt, $dateType = self::LOCALTZ) {
+
+ switch($dateType) {
+
+ case self::LOCAL :
+ $this->setValue($dt->format('Ymd\\THis'));
+ $this->offsetUnset('VALUE');
+ $this->offsetUnset('TZID');
+ $this->offsetSet('VALUE','DATE-TIME');
+ break;
+ case self::UTC :
+ $dt->setTimeZone(new DateTimeZone('UTC'));
+ $this->setValue($dt->format('Ymd\\THis\\Z'));
+ $this->offsetUnset('VALUE');
+ $this->offsetUnset('TZID');
+ $this->offsetSet('VALUE','DATE-TIME');
+ break;
+ case self::LOCALTZ :
+ $this->setValue($dt->format('Ymd\\THis'));
+ $this->offsetUnset('VALUE');
+ $this->offsetUnset('TZID');
+ $this->offsetSet('VALUE','DATE-TIME');
+ $this->offsetSet('TZID', $dt->getTimeZone()->getName());
+ break;
+ case self::DATE :
+ $this->setValue($dt->format('Ymd'));
+ $this->offsetUnset('VALUE');
+ $this->offsetUnset('TZID');
+ $this->offsetSet('VALUE','DATE');
+ break;
+ default :
+ throw new InvalidArgumentException('You must pass a valid dateType constant');
+
+ }
+ $this->dateTime = $dt;
+ $this->dateType = $dateType;
+
+ }
+
+ /**
+ * Returns the current DateTime value.
+ *
+ * If no value was set, this method returns null.
+ *
+ * @return DateTime|null
+ */
+ public function getDateTime() {
+
+ if ($this->dateTime)
+ return $this->dateTime;
+
+ list(
+ $this->dateType,
+ $this->dateTime
+ ) = self::parseData($this->value, $this);
+ return $this->dateTime;
+
+ }
+
+ /**
+ * Returns the type of Date format.
+ *
+ * This method returns one of the format constants. If no date was set,
+ * this method will return null.
+ *
+ * @return int|null
+ */
+ public function getDateType() {
+
+ if ($this->dateType)
+ return $this->dateType;
+
+ list(
+ $this->dateType,
+ $this->dateTime,
+ ) = self::parseData($this->value, $this);
+ return $this->dateType;
+
+ }
+
+ /**
+ * Parses the internal data structure to figure out what the current date
+ * and time is.
+ *
+ * The returned array contains two elements:
+ * 1. A 'DateType' constant (as defined on this class), or null.
+ * 2. A DateTime object (or null)
+ *
+ * @param string|null $propertyValue The string to parse (yymmdd or
+ * ymmddThhmmss, etc..)
+ * @param Sabre_VObject_Property|null $property The instance of the
+ * property we're parsing.
+ * @return array
+ */
+ static public function parseData($propertyValue, Sabre_VObject_Property $property = null) {
+
+ if (is_null($propertyValue)) {
+ return array(null, null);
+ }
+
+ $date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
+ $time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
+ $regex = "/^$date(T$time(?P<isutc>Z)?)?$/";
+
+ if (!preg_match($regex, $propertyValue, $matches)) {
+ throw new InvalidArgumentException($propertyValue . ' is not a valid DateTime or Date string');
+ }
+
+ if (!isset($matches['hour'])) {
+ // Date-only
+ return array(
+ self::DATE,
+ new DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00'),
+ );
+ }
+
+ $dateStr =
+ $matches['year'] .'-' .
+ $matches['month'] . '-' .
+ $matches['date'] . ' ' .
+ $matches['hour'] . ':' .
+ $matches['minute'] . ':' .
+ $matches['second'];
+
+ if (isset($matches['isutc'])) {
+ $dt = new DateTime($dateStr,new DateTimeZone('UTC'));
+ $dt->setTimeZone(new DateTimeZone('UTC'));
+ return array(
+ self::UTC,
+ $dt
+ );
+ }
+
+ // Finding the timezone.
+ $tzid = $property['TZID'];
+ if (!$tzid) {
+ return array(
+ self::LOCAL,
+ new DateTime($dateStr)
+ );
+ }
+
+ try {
+ // tzid an Olson identifier?
+ $tz = new DateTimeZone($tzid->value);
+ } catch (Exception $e) {
+
+ // Not an Olson id, we're going to try to find the information
+ // through the time zone name map.
+ $newtzid = Sabre_VObject_WindowsTimezoneMap::lookup($tzid->value);
+ if (is_null($newtzid)) {
+
+ // Not a well known time zone name either, we're going to try
+ // to find the information through the VTIMEZONE object.
+
+ // First we find the root object
+ $root = $property;
+ while($root->parent) {
+ $root = $root->parent;
+ }
+
+ if (isset($root->VTIMEZONE)) {
+ foreach($root->VTIMEZONE as $vtimezone) {
+ if (((string)$vtimezone->TZID) == $tzid) {
+ if (isset($vtimezone->{'X-LIC-LOCATION'})) {
+ $newtzid = (string)$vtimezone->{'X-LIC-LOCATION'};
+ } else {
+ // No libical location specified. As a last resort we could
+ // try matching $vtimezone's DST rules against all known
+ // time zones returned by DateTimeZone::list*
+
+ // TODO
+ }
+ }
+ }
+ }
+ }
+
+ try {
+ $tz = new DateTimeZone($newtzid);
+ } catch (Exception $e) {
+ // If all else fails, we use the default PHP timezone
+ $tz = new DateTimeZone(date_default_timezone_get());
+ }
+ }
+ $dt = new DateTime($dateStr, $tz);
+ $dt->setTimeZone($tz);
+
+ return array(
+ self::LOCALTZ,
+ $dt
+ );
+
+ }
+
+}
diff --git a/3rdparty/Sabre/VObject/Property/MultiDateTime.php b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
new file mode 100755
index 00000000000..ae53ab6a617
--- /dev/null
+++ b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
@@ -0,0 +1,166 @@
+<?php
+
+/**
+ * Multi-DateTime property
+ *
+ * This element is used for iCalendar properties such as the EXDATE property.
+ * It basically provides a few helper functions that make it easier to deal
+ * with these. It supports both DATE-TIME and DATE values.
+ *
+ * In order to use this correctly, you must call setDateTimes and getDateTimes
+ * to retrieve and modify dates respectively.
+ *
+ * If you use the 'value' or properties directly, this object does not keep
+ * reference and results might appear incorrectly.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
+
+ /**
+ * DateTime representation
+ *
+ * @var DateTime[]
+ */
+ protected $dateTimes;
+
+ /**
+ * dateType
+ *
+ * This is one of the Sabre_VObject_Property_DateTime constants.
+ *
+ * @var int
+ */
+ protected $dateType;
+
+ /**
+ * Updates the value
+ *
+ * @param array $dt Must be an array of DateTime objects.
+ * @param int $dateType
+ * @return void
+ */
+ public function setDateTimes(array $dt, $dateType = Sabre_VObject_Property_DateTime::LOCALTZ) {
+
+ foreach($dt as $i)
+ if (!$i instanceof DateTime)
+ throw new InvalidArgumentException('You must pass an array of DateTime objects');
+
+ $this->offsetUnset('VALUE');
+ $this->offsetUnset('TZID');
+ switch($dateType) {
+
+ case Sabre_VObject_Property_DateTime::LOCAL :
+ $val = array();
+ foreach($dt as $i) {
+ $val[] = $i->format('Ymd\\THis');
+ }
+ $this->setValue(implode(',',$val));
+ $this->offsetSet('VALUE','DATE-TIME');
+ break;
+ case Sabre_VObject_Property_DateTime::UTC :
+ $val = array();
+ foreach($dt as $i) {
+ $i->setTimeZone(new DateTimeZone('UTC'));
+ $val[] = $i->format('Ymd\\THis\\Z');
+ }
+ $this->setValue(implode(',',$val));
+ $this->offsetSet('VALUE','DATE-TIME');
+ break;
+ case Sabre_VObject_Property_DateTime::LOCALTZ :
+ $val = array();
+ foreach($dt as $i) {
+ $val[] = $i->format('Ymd\\THis');
+ }
+ $this->setValue(implode(',',$val));
+ $this->offsetSet('VALUE','DATE-TIME');
+ $this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
+ break;
+ case Sabre_VObject_Property_DateTime::DATE :
+ $val = array();
+ foreach($dt as $i) {
+ $val[] = $i->format('Ymd');
+ }
+ $this->setValue(implode(',',$val));
+ $this->offsetSet('VALUE','DATE');
+ break;
+ default :
+ throw new InvalidArgumentException('You must pass a valid dateType constant');
+
+ }
+ $this->dateTimes = $dt;
+ $this->dateType = $dateType;
+
+ }
+
+ /**
+ * Returns the current DateTime value.
+ *
+ * If no value was set, this method returns null.
+ *
+ * @return array|null
+ */
+ public function getDateTimes() {
+
+ if ($this->dateTimes)
+ return $this->dateTimes;
+
+ $dts = array();
+
+ if (!$this->value) {
+ $this->dateTimes = null;
+ $this->dateType = null;
+ return null;
+ }
+
+ foreach(explode(',',$this->value) as $val) {
+ list(
+ $type,
+ $dt
+ ) = Sabre_VObject_Property_DateTime::parseData($val, $this);
+ $dts[] = $dt;
+ $this->dateType = $type;
+ }
+ $this->dateTimes = $dts;
+ return $this->dateTimes;
+
+ }
+
+ /**
+ * Returns the type of Date format.
+ *
+ * This method returns one of the format constants. If no date was set,
+ * this method will return null.
+ *
+ * @return int|null
+ */
+ public function getDateType() {
+
+ if ($this->dateType)
+ return $this->dateType;
+
+ if (!$this->value) {
+ $this->dateTimes = null;
+ $this->dateType = null;
+ return null;
+ }
+
+ $dts = array();
+ foreach(explode(',',$this->value) as $val) {
+ list(
+ $type,
+ $dt
+ ) = Sabre_VObject_Property_DateTime::parseData($val, $this);
+ $dts[] = $dt;
+ $this->dateType = $type;
+ }
+ $this->dateTimes = $dts;
+ return $this->dateType;
+
+ }
+
+}
diff --git a/3rdparty/Sabre/VObject/Reader.php b/3rdparty/Sabre/VObject/Reader.php
index 7d1c282838e..eea73fa3dce 100644..100755
--- a/3rdparty/Sabre/VObject/Reader.php
+++ b/3rdparty/Sabre/VObject/Reader.php
@@ -5,40 +5,22 @@
*
* This class reads the vobject file, and returns a full element tree.
*
+ * TODO: this class currently completely works 'statically'. This is pointless,
+ * and defeats OOP principals. Needs refactoring in a future version.
*
- * TODO: this class currently completely works 'statically'. This is pointless,
- * and defeats OOP principals. Needs refaxtoring in a future version.
- *
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Reader {
/**
- * This array contains a list of Property names that are automatically
- * mapped to specific class names.
+ * Parses the file and returns the top component
*
- * Adding to this list allows you to specify custom property classes,
- * adding extra functionality.
- *
- * @var array
- */
- static public $elementMap = array(
- 'DTSTART' => 'Sabre_VObject_Element_DateTime',
- 'DTEND' => 'Sabre_VObject_Element_DateTime',
- 'COMPLETED' => 'Sabre_VObject_Element_DateTime',
- 'DUE' => 'Sabre_VObject_Element_DateTime',
- 'EXDATE' => 'Sabre_VObject_Element_MultiDateTime',
- );
-
- /**
- * Parses the file and returns the top component
- *
- * @param string $data
- * @return Sabre_VObject_Element
+ * @param string $data
+ * @return Sabre_VObject_Element
*/
static function read($data) {
@@ -63,11 +45,11 @@ class Sabre_VObject_Reader {
}
unset($lines);
-
+
reset($lines2);
return self::readLine($lines2);
-
+
}
/**
@@ -75,9 +57,9 @@ class Sabre_VObject_Reader {
*
* This method receives the full array of lines. The array pointer is used
* to traverse.
- *
- * @param array $lines
- * @return Sabre_VObject_Element
+ *
+ * @param array $lines
+ * @return Sabre_VObject_Element
*/
static private function readLine(&$lines) {
@@ -88,22 +70,23 @@ class Sabre_VObject_Reader {
// Components
if (stripos($line,"BEGIN:")===0) {
- // This is a component
- $obj = new Sabre_VObject_Component(strtoupper(substr($line,6)));
+ $componentName = strtoupper(substr($line,6));
+ $obj = Sabre_VObject_Component::create($componentName);
$nextLine = current($lines);
while(stripos($nextLine,"END:")!==0) {
$obj->add(self::readLine($lines));
+
$nextLine = current($lines);
- if ($nextLine===false)
+ if ($nextLine===false)
throw new Sabre_VObject_ParseException('Invalid VObject. Document ended prematurely.');
}
- // Checking component name of the 'END:' line.
+ // Checking component name of the 'END:' line.
if (substr($nextLine,4)!==$obj->name) {
throw new Sabre_VObject_ParseException('Invalid VObject, expected: "END:' . $obj->name . '" got: "' . $nextLine . '"');
}
@@ -117,7 +100,7 @@ class Sabre_VObject_Reader {
//$result = preg_match('/(?P<name>[A-Z0-9-]+)(?:;(?P<parameters>^(?<!:):))(.*)$/',$line,$matches);
- $token = '[A-Z0-9-\/\.]+';
+ $token = '[A-Z0-9-\.]+';
$parameters = "(?:;(?P<parameters>([^:^\"]|\"([^\"]*)\")*))?";
$regex = "/^(?P<name>$token)$parameters:(?P<value>.*)$/i";
@@ -128,22 +111,23 @@ class Sabre_VObject_Reader {
}
$propertyName = strtoupper($matches['name']);
- $propertyValue = stripcslashes($matches['value']);
-
- if (isset(self::$elementMap[$propertyName])) {
- $className = self::$elementMap[$propertyName];
- } else {
- $className = 'Sabre_VObject_Property';
- }
+ $propertyValue = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
+ if ($matches[2]==='n' || $matches[2]==='N') {
+ return "\n";
+ } else {
+ return $matches[2];
+ }
+ }, $matches['value']);
- $obj = new $className($propertyName, $propertyValue);
+ $obj = Sabre_VObject_Property::create($propertyName, $propertyValue);
if ($matches['parameters']) {
foreach(self::readParameters($matches['parameters']) as $param) {
$obj->add($param);
}
- }
+
+ }
return $obj;
@@ -151,12 +135,12 @@ class Sabre_VObject_Reader {
}
/**
- * Reads a parameter list from a property
+ * Reads a parameter list from a property
*
* This method returns an array of Sabre_VObject_Parameter
*
- * @param string $parameters
- * @return array
+ * @param string $parameters
+ * @return array
*/
static private function readParameters($parameters) {
@@ -179,7 +163,15 @@ class Sabre_VObject_Reader {
$value = '';
}
- $params[] = new Sabre_VObject_Parameter($match['paramName'], stripcslashes($value));
+ $value = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
+ if ($matches[2]==='n' || $matches[2]==='N') {
+ return "\n";
+ } else {
+ return $matches[2];
+ }
+ }, $value);
+
+ $params[] = new Sabre_VObject_Parameter($match['paramName'], $value);
}
diff --git a/3rdparty/Sabre/VObject/RecurrenceIterator.php b/3rdparty/Sabre/VObject/RecurrenceIterator.php
new file mode 100755
index 00000000000..833aa091ab7
--- /dev/null
+++ b/3rdparty/Sabre/VObject/RecurrenceIterator.php
@@ -0,0 +1,1009 @@
+<?php
+
+/**
+ * This class is used to determine new for a recurring event, when the next
+ * events occur.
+ *
+ * This iterator may loop infinitely in the future, therefore it is important
+ * that if you use this class, you set hard limits for the amount of iterations
+ * you want to handle.
+ *
+ * Note that currently there is not full support for the entire iCalendar
+ * specification, as it's very complex and contains a lot of permutations
+ * that's not yet used very often in software.
+ *
+ * For the focus has been on features as they actually appear in Calendaring
+ * software, but this may well get expanded as needed / on demand
+ *
+ * The following RRULE properties are supported
+ * * UNTIL
+ * * INTERVAL
+ * * COUNT
+ * * FREQ=DAILY
+ * * BYDAY
+ * * FREQ=WEEKLY
+ * * BYDAY
+ * * WKST
+ * * FREQ=MONTHLY
+ * * BYMONTHDAY
+ * * BYDAY
+ * * BYSETPOS
+ * * FREQ=YEARLY
+ * * BYMONTH
+ * * BYMONTHDAY (only if BYMONTH is also set)
+ * * BYDAY (only if BYMONTH is also set)
+ *
+ * Anything beyond this is 'undefined', which means that it may get ignored, or
+ * you may get unexpected results. The effect is that in some applications the
+ * specified recurrence may look incorrect, or is missing.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_RecurrenceIterator implements Iterator {
+
+ /**
+ * The initial event date
+ *
+ * @var DateTime
+ */
+ public $startDate;
+
+ /**
+ * The end-date of the initial event
+ *
+ * @var DateTime
+ */
+ public $endDate;
+
+ /**
+ * The 'current' recurrence.
+ *
+ * This will be increased for every iteration.
+ *
+ * @var DateTime
+ */
+ public $currentDate;
+
+
+ /**
+ * List of dates that are excluded from the rules.
+ *
+ * This list contains the items that have been overriden by the EXDATE
+ * property.
+ *
+ * @var array
+ */
+ public $exceptionDates = array();
+
+ /**
+ * Base event
+ *
+ * @var Sabre_VObject_Component_VEvent
+ */
+ public $baseEvent;
+
+ /**
+ * List of dates that are overridden by other events.
+ * Similar to $overriddenEvents, but this just contains the original dates.
+ *
+ * @var array
+ */
+ public $overriddenDates = array();
+
+ /**
+ * list of events that are 'overridden'.
+ *
+ * This is an array of Sabre_VObject_Component_VEvent objects.
+ *
+ * @var array
+ */
+ public $overriddenEvents = array();
+
+
+ /**
+ * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
+ * yearly.
+ *
+ * @var string
+ */
+ public $frequency;
+
+ /**
+ * The last instance of this recurrence, inclusively
+ *
+ * @var DateTime|null
+ */
+ public $until;
+
+ /**
+ * The number of recurrences, or 'null' if infinitely recurring.
+ *
+ * @var int
+ */
+ public $count;
+
+ /**
+ * The interval.
+ *
+ * If for example frequency is set to daily, interval = 2 would mean every
+ * 2 days.
+ *
+ * @var int
+ */
+ public $interval = 1;
+
+ /**
+ * Which seconds to recur.
+ *
+ * This is an array of integers (between 0 and 60)
+ *
+ * @var array
+ */
+ public $bySecond;
+
+ /**
+ * Which minutes to recur
+ *
+ * This is an array of integers (between 0 and 59)
+ *
+ * @var array
+ */
+ public $byMinute;
+
+ /**
+ * Which hours to recur
+ *
+ * This is an array of integers (between 0 and 23)
+ *
+ * @var array
+ */
+ public $byHour;
+
+ /**
+ * Which weekdays to recur.
+ *
+ * This is an array of weekdays
+ *
+ * This may also be preceeded by a positive or negative integer. If present,
+ * this indicates the nth occurrence of a specific day within the monthly or
+ * yearly rrule. For instance, -2TU indicates the second-last tuesday of
+ * the month, or year.
+ *
+ * @var array
+ */
+ public $byDay;
+
+ /**
+ * Which days of the month to recur
+ *
+ * This is an array of days of the months (1-31). The value can also be
+ * negative. -5 for instance means the 5th last day of the month.
+ *
+ * @var array
+ */
+ public $byMonthDay;
+
+ /**
+ * Which days of the year to recur.
+ *
+ * This is an array with days of the year (1 to 366). The values can also
+ * be negative. For instance, -1 will always represent the last day of the
+ * year. (December 31st).
+ *
+ * @var array
+ */
+ public $byYearDay;
+
+ /**
+ * Which week numbers to recur.
+ *
+ * This is an array of integers from 1 to 53. The values can also be
+ * negative. -1 will always refer to the last week of the year.
+ *
+ * @var array
+ */
+ public $byWeekNo;
+
+ /**
+ * Which months to recur
+ *
+ * This is an array of integers from 1 to 12.
+ *
+ * @var array
+ */
+ public $byMonth;
+
+ /**
+ * Which items in an existing st to recur.
+ *
+ * These numbers work together with an existing by* rule. It specifies
+ * exactly which items of the existing by-rule to filter.
+ *
+ * Valid values are 1 to 366 and -1 to -366. As an example, this can be
+ * used to recur the last workday of the month.
+ *
+ * This would be done by setting frequency to 'monthly', byDay to
+ * 'MO,TU,WE,TH,FR' and bySetPos to -1.
+ *
+ * @var array
+ */
+ public $bySetPos;
+
+ /**
+ * When a week starts
+ *
+ * @var string
+ */
+ public $weekStart = 'MO';
+
+ /**
+ * The current item in the list
+ *
+ * @var int
+ */
+ public $counter = 0;
+
+ /**
+ * Simple mapping from iCalendar day names to day numbers
+ *
+ * @var array
+ */
+ private $dayMap = array(
+ 'SU' => 0,
+ 'MO' => 1,
+ 'TU' => 2,
+ 'WE' => 3,
+ 'TH' => 4,
+ 'FR' => 5,
+ 'SA' => 6,
+ );
+
+ /**
+ * Mappings between the day number and english day name.
+ *
+ * @var array
+ */
+ private $dayNames = array(
+ 0 => 'Sunday',
+ 1 => 'Monday',
+ 2 => 'Tuesday',
+ 3 => 'Wednesday',
+ 4 => 'Thursday',
+ 5 => 'Friday',
+ 6 => 'Saturday',
+ );
+
+ /**
+ * If the current iteration of the event is an overriden event, this
+ * property will hold the VObject
+ *
+ * @var Sabre_Component_VObject
+ */
+ private $currentOverriddenEvent;
+
+ /**
+ * This property may contain the date of the next not-overridden event.
+ * This date is calculated sometimes a bit early, before overridden events
+ * are evaluated.
+ *
+ * @var DateTime
+ */
+ private $nextDate;
+
+ /**
+ * Creates the iterator
+ *
+ * You should pass a VCALENDAR component, as well as the UID of the event
+ * we're going to traverse.
+ *
+ * @param Sabre_VObject_Component $vcal
+ * @param string|null $uid
+ */
+ public function __construct(Sabre_VObject_Component $vcal, $uid=null) {
+
+ if (is_null($uid)) {
+ if ($vcal->name === 'VCALENDAR') {
+ throw new InvalidArgumentException('If you pass a VCALENDAR object, you must pass a uid argument as well');
+ }
+ $components = array($vcal);
+ $uid = (string)$vcal->uid;
+ } else {
+ $components = $vcal->select('VEVENT');
+ }
+ foreach($components as $component) {
+ if ((string)$component->uid == $uid) {
+ if (isset($component->{'RECURRENCE-ID'})) {
+ $this->overriddenEvents[$component->DTSTART->getDateTime()->getTimeStamp()] = $component;
+ $this->overriddenDates[] = $component->{'RECURRENCE-ID'}->getDateTime();
+ } else {
+ $this->baseEvent = $component;
+ }
+ }
+ }
+ if (!$this->baseEvent) {
+ throw new InvalidArgumentException('Could not find a base event with uid: ' . $uid);
+ }
+
+ $this->startDate = clone $this->baseEvent->DTSTART->getDateTime();
+
+ $this->endDate = null;
+ if (isset($this->baseEvent->DTEND)) {
+ $this->endDate = clone $this->baseEvent->DTEND->getDateTime();
+ } else {
+ $this->endDate = clone $this->startDate;
+ if (isset($this->baseEvent->DURATION)) {
+ $this->endDate->add(Sabre_VObject_DateTimeParser::parse($this->baseEvent->DURATION->value));
+ }
+ }
+ $this->currentDate = clone $this->startDate;
+
+ $rrule = (string)$this->baseEvent->RRULE;
+
+ $parts = explode(';', $rrule);
+
+ foreach($parts as $part) {
+
+ list($key, $value) = explode('=', $part, 2);
+
+ switch(strtoupper($key)) {
+
+ case 'FREQ' :
+ if (!in_array(
+ strtolower($value),
+ array('secondly','minutely','hourly','daily','weekly','monthly','yearly')
+ )) {
+ throw new InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
+
+ }
+ $this->frequency = strtolower($value);
+ break;
+
+ case 'UNTIL' :
+ $this->until = Sabre_VObject_DateTimeParser::parse($value);
+ break;
+
+ case 'COUNT' :
+ $this->count = (int)$value;
+ break;
+
+ case 'INTERVAL' :
+ $this->interval = (int)$value;
+ break;
+
+ case 'BYSECOND' :
+ $this->bySecond = explode(',', $value);
+ break;
+
+ case 'BYMINUTE' :
+ $this->byMinute = explode(',', $value);
+ break;
+
+ case 'BYHOUR' :
+ $this->byHour = explode(',', $value);
+ break;
+
+ case 'BYDAY' :
+ $this->byDay = explode(',', strtoupper($value));
+ break;
+
+ case 'BYMONTHDAY' :
+ $this->byMonthDay = explode(',', $value);
+ break;
+
+ case 'BYYEARDAY' :
+ $this->byYearDay = explode(',', $value);
+ break;
+
+ case 'BYWEEKNO' :
+ $this->byWeekNo = explode(',', $value);
+ break;
+
+ case 'BYMONTH' :
+ $this->byMonth = explode(',', $value);
+ break;
+
+ case 'BYSETPOS' :
+ $this->bySetPos = explode(',', $value);
+ break;
+
+ case 'WKST' :
+ $this->weekStart = strtoupper($value);
+ break;
+
+ }
+
+ }
+
+ // Parsing exception dates
+ if (isset($this->baseEvent->EXDATE)) {
+ foreach($this->baseEvent->EXDATE as $exDate) {
+
+ foreach(explode(',', (string)$exDate) as $exceptionDate) {
+
+ $this->exceptionDates[] =
+ Sabre_VObject_DateTimeParser::parse($exceptionDate, $this->startDate->getTimeZone());
+
+ }
+
+ }
+
+ }
+
+ }
+
+ /**
+ * Returns the current item in the list
+ *
+ * @return DateTime
+ */
+ public function current() {
+
+ if (!$this->valid()) return null;
+ return clone $this->currentDate;
+
+ }
+
+ /**
+ * This method returns the startdate for the current iteration of the
+ * event.
+ *
+ * @return DateTime
+ */
+ public function getDtStart() {
+
+ if (!$this->valid()) return null;
+ return clone $this->currentDate;
+
+ }
+
+ /**
+ * This method returns the enddate for the current iteration of the
+ * event.
+ *
+ * @return DateTime
+ */
+ public function getDtEnd() {
+
+ if (!$this->valid()) return null;
+ $dtEnd = clone $this->currentDate;
+ $dtEnd->add( $this->startDate->diff( $this->endDate ) );
+ return clone $dtEnd;
+
+ }
+
+ /**
+ * Returns a VEVENT object with the updated start and end date.
+ *
+ * Any recurrence information is removed, and this function may return an
+ * 'overridden' event instead.
+ *
+ * This method always returns a cloned instance.
+ *
+ * @return void
+ */
+ public function getEventObject() {
+
+ if ($this->currentOverriddenEvent) {
+ return clone $this->currentOverriddenEvent;
+ }
+ $event = clone $this->baseEvent;
+ unset($event->RRULE);
+ unset($event->EXDATE);
+ unset($event->RDATE);
+ unset($event->EXRULE);
+
+ $event->DTSTART->setDateTime($this->getDTStart(), $event->DTSTART->getDateType());
+ if (isset($event->DTEND)) {
+ $event->DTEND->setDateTime($this->getDtEnd(), $event->DTSTART->getDateType());
+ }
+ if ($this->counter > 0) {
+ $event->{'RECURRENCE-ID'} = (string)$event->DTSTART;
+ }
+
+ return $event;
+
+ }
+
+ /**
+ * Returns the current item number
+ *
+ * @return int
+ */
+ public function key() {
+
+ return $this->counter;
+
+ }
+
+ /**
+ * Whether or not there is a 'next item'
+ *
+ * @return bool
+ */
+ public function valid() {
+
+ if (!is_null($this->count)) {
+ return $this->counter < $this->count;
+ }
+ if (!is_null($this->until)) {
+ return $this->currentDate <= $this->until;
+ }
+ return true;
+
+ }
+
+ /**
+ * Resets the iterator
+ *
+ * @return void
+ */
+ public function rewind() {
+
+ $this->currentDate = clone $this->startDate;
+ $this->counter = 0;
+
+ }
+
+ /**
+ * This method allows you to quickly go to the next occurrence after the
+ * specified date.
+ *
+ * Note that this checks the current 'endDate', not the 'stardDate'. This
+ * means that if you forward to January 1st, the iterator will stop at the
+ * first event that ends *after* January 1st.
+ *
+ * @param DateTime $dt
+ * @return void
+ */
+ public function fastForward(DateTime $dt) {
+
+ while($this->valid() && $this->getDTEnd() < $dt) {
+ $this->next();
+ }
+
+ }
+
+ /**
+ * Goes on to the next iteration
+ *
+ * @return void
+ */
+ public function next() {
+
+ /*
+ if (!is_null($this->count) && $this->counter >= $this->count) {
+ $this->currentDate = null;
+ }*/
+
+
+ $previousStamp = $this->currentDate->getTimeStamp();
+
+ while(true) {
+
+ $this->currentOverriddenEvent = null;
+
+ // If we have a next date 'stored', we use that
+ if ($this->nextDate) {
+ $this->currentDate = $this->nextDate;
+ $currentStamp = $this->currentDate->getTimeStamp();
+ $this->nextDate = null;
+ } else {
+
+ // Otherwise, we calculate it
+ switch($this->frequency) {
+
+ case 'daily' :
+ $this->nextDaily();
+ break;
+
+ case 'weekly' :
+ $this->nextWeekly();
+ break;
+
+ case 'monthly' :
+ $this->nextMonthly();
+ break;
+
+ case 'yearly' :
+ $this->nextYearly();
+ break;
+
+ }
+ $currentStamp = $this->currentDate->getTimeStamp();
+
+ // Checking exception dates
+ foreach($this->exceptionDates as $exceptionDate) {
+ if ($this->currentDate == $exceptionDate) {
+ $this->counter++;
+ continue 2;
+ }
+ }
+ foreach($this->overriddenDates as $overriddenDate) {
+ if ($this->currentDate == $overriddenDate) {
+ continue 2;
+ }
+ }
+
+ }
+
+ // Checking overriden events
+ foreach($this->overriddenEvents as $index=>$event) {
+ if ($index > $previousStamp && $index <= $currentStamp) {
+
+ // We're moving the 'next date' aside, for later use.
+ $this->nextDate = clone $this->currentDate;
+
+ $this->currentDate = $event->DTSTART->getDateTime();
+ $this->currentOverriddenEvent = $event;
+
+ break;
+ }
+ }
+
+ break;
+
+ }
+
+ /*
+ if (!is_null($this->until)) {
+ if($this->currentDate > $this->until) {
+ $this->currentDate = null;
+ }
+ }*/
+
+ $this->counter++;
+
+ }
+
+ /**
+ * Does the processing for advancing the iterator for daily frequency.
+ *
+ * @return void
+ */
+ protected function nextDaily() {
+
+ if (!$this->byDay) {
+ $this->currentDate->modify('+' . $this->interval . ' days');
+ return;
+ }
+
+ $recurrenceDays = array();
+ foreach($this->byDay as $byDay) {
+
+ // The day may be preceeded with a positive (+n) or
+ // negative (-n) integer. However, this does not make
+ // sense in 'weekly' so we ignore it here.
+ $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
+
+ }
+
+ do {
+
+ $this->currentDate->modify('+' . $this->interval . ' days');
+
+ // Current day of the week
+ $currentDay = $this->currentDate->format('w');
+
+ } while (!in_array($currentDay, $recurrenceDays));
+
+ }
+
+ /**
+ * Does the processing for advancing the iterator for weekly frequency.
+ *
+ * @return void
+ */
+ protected function nextWeekly() {
+
+ if (!$this->byDay) {
+ $this->currentDate->modify('+' . $this->interval . ' weeks');
+ return;
+ }
+
+ $recurrenceDays = array();
+ foreach($this->byDay as $byDay) {
+
+ // The day may be preceeded with a positive (+n) or
+ // negative (-n) integer. However, this does not make
+ // sense in 'weekly' so we ignore it here.
+ $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
+
+ }
+
+ // Current day of the week
+ $currentDay = $this->currentDate->format('w');
+
+ // First day of the week:
+ $firstDay = $this->dayMap[$this->weekStart];
+
+ $time = array(
+ $this->currentDate->format('H'),
+ $this->currentDate->format('i'),
+ $this->currentDate->format('s')
+ );
+
+ // Increasing the 'current day' until we find our next
+ // occurrence.
+ while(true) {
+
+ $currentDay++;
+
+ if ($currentDay>6) {
+ $currentDay = 0;
+ }
+
+ // We need to roll over to the next week
+ if ($currentDay === $firstDay) {
+ $this->currentDate->modify('+' . $this->interval . ' weeks');
+
+ // We need to go to the first day of this week, but only if we
+ // are not already on this first day of this week.
+ if($this->currentDate->format('w') != $firstDay) {
+ $this->currentDate->modify('last ' . $this->dayNames[$this->dayMap[$this->weekStart]]);
+ $this->currentDate->setTime($time[0],$time[1],$time[2]);
+ }
+ }
+
+ // We have a match
+ if (in_array($currentDay ,$recurrenceDays)) {
+ $this->currentDate->modify($this->dayNames[$currentDay]);
+ $this->currentDate->setTime($time[0],$time[1],$time[2]);
+ break;
+ }
+
+ }
+
+ }
+
+ /**
+ * Does the processing for advancing the iterator for monthly frequency.
+ *
+ * @return void
+ */
+ protected function nextMonthly() {
+
+ $currentDayOfMonth = $this->currentDate->format('j');
+ if (!$this->byMonthDay && !$this->byDay) {
+
+ // If the current day is higher than the 28th, rollover can
+ // occur to the next month. We Must skip these invalid
+ // entries.
+ if ($currentDayOfMonth < 29) {
+ $this->currentDate->modify('+' . $this->interval . ' months');
+ } else {
+ $increase = 0;
+ do {
+ $increase++;
+ $tempDate = clone $this->currentDate;
+ $tempDate->modify('+ ' . ($this->interval*$increase) . ' months');
+ } while ($tempDate->format('j') != $currentDayOfMonth);
+ $this->currentDate = $tempDate;
+ }
+ return;
+ }
+
+ while(true) {
+
+ $occurrences = $this->getMonthlyOccurrences();
+
+ foreach($occurrences as $occurrence) {
+
+ // The first occurrence thats higher than the current
+ // day of the month wins.
+ if ($occurrence > $currentDayOfMonth) {
+ break 2;
+ }
+
+ }
+
+ // If we made it all the way here, it means there were no
+ // valid occurrences, and we need to advance to the next
+ // month.
+ $this->currentDate->modify('first day of this month');
+ $this->currentDate->modify('+ ' . $this->interval . ' months');
+
+ // This goes to 0 because we need to start counting at hte
+ // beginning.
+ $currentDayOfMonth = 0;
+
+ }
+
+ $this->currentDate->setDate($this->currentDate->format('Y'), $this->currentDate->format('n'), $occurrence);
+
+ }
+
+ /**
+ * Does the processing for advancing the iterator for yearly frequency.
+ *
+ * @return void
+ */
+ protected function nextYearly() {
+
+ if (!$this->byMonth) {
+ $this->currentDate->modify('+' . $this->interval . ' years');
+ return;
+ }
+
+ $currentMonth = $this->currentDate->format('n');
+ $currentYear = $this->currentDate->format('Y');
+ $currentDayOfMonth = $this->currentDate->format('j');
+
+ $advancedToNewMonth = false;
+
+ // If we got a byDay or getMonthDay filter, we must first expand
+ // further.
+ if ($this->byDay || $this->byMonthDay) {
+
+ while(true) {
+
+ $occurrences = $this->getMonthlyOccurrences();
+
+ foreach($occurrences as $occurrence) {
+
+ // The first occurrence that's higher than the current
+ // day of the month wins.
+ // If we advanced to the next month or year, the first
+ // occurence is always correct.
+ if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) {
+ break 2;
+ }
+
+ }
+
+ // If we made it here, it means we need to advance to
+ // the next month or year.
+ $currentDayOfMonth = 1;
+ $advancedToNewMonth = true;
+ do {
+
+ $currentMonth++;
+ if ($currentMonth>12) {
+ $currentYear+=$this->interval;
+ $currentMonth = 1;
+ }
+ } while (!in_array($currentMonth, $this->byMonth));
+
+ $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
+
+ }
+
+ // If we made it here, it means we got a valid occurrence
+ $this->currentDate->setDate($currentYear, $currentMonth, $occurrence);
+ return;
+
+ } else {
+
+ // no byDay or byMonthDay, so we can just loop through the
+ // months.
+ do {
+
+ $currentMonth++;
+ if ($currentMonth>12) {
+ $currentYear+=$this->interval;
+ $currentMonth = 1;
+ }
+ } while (!in_array($currentMonth, $this->byMonth));
+ $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
+ return;
+
+ }
+
+ }
+
+ /**
+ * Returns all the occurrences for a monthly frequency with a 'byDay' or
+ * 'byMonthDay' expansion for the current month.
+ *
+ * The returned list is an array of integers with the day of month (1-31).
+ *
+ * @return array
+ */
+ protected function getMonthlyOccurrences() {
+
+ $startDate = clone $this->currentDate;
+
+ $byDayResults = array();
+
+ // Our strategy is to simply go through the byDays, advance the date to
+ // that point and add it to the results.
+ if ($this->byDay) foreach($this->byDay as $day) {
+
+ $dayName = $this->dayNames[$this->dayMap[substr($day,-2)]];
+
+ // Dayname will be something like 'wednesday'. Now we need to find
+ // all wednesdays in this month.
+ $dayHits = array();
+
+ $checkDate = clone $startDate;
+ $checkDate->modify('first day of this month');
+ $checkDate->modify($dayName);
+
+ do {
+ $dayHits[] = $checkDate->format('j');
+ $checkDate->modify('next ' . $dayName);
+ } while ($checkDate->format('n') === $startDate->format('n'));
+
+ // So now we have 'all wednesdays' for month. It is however
+ // possible that the user only really wanted the 1st, 2nd or last
+ // wednesday.
+ if (strlen($day)>2) {
+ $offset = (int)substr($day,0,-2);
+
+ if ($offset>0) {
+ // It is possible that the day does not exist, such as a
+ // 5th or 6th wednesday of the month.
+ if (isset($dayHits[$offset-1])) {
+ $byDayResults[] = $dayHits[$offset-1];
+ }
+ } else {
+
+ // if it was negative we count from the end of the array
+ $byDayResults[] = $dayHits[count($dayHits) + $offset];
+ }
+ } else {
+ // There was no counter (first, second, last wednesdays), so we
+ // just need to add the all to the list).
+ $byDayResults = array_merge($byDayResults, $dayHits);
+
+ }
+
+ }
+
+ $byMonthDayResults = array();
+ if ($this->byMonthDay) foreach($this->byMonthDay as $monthDay) {
+
+ // Removing values that are out of range for this month
+ if ($monthDay > $startDate->format('t') ||
+ $monthDay < 0-$startDate->format('t')) {
+ continue;
+ }
+ if ($monthDay>0) {
+ $byMonthDayResults[] = $monthDay;
+ } else {
+ // Negative values
+ $byMonthDayResults[] = $startDate->format('t') + 1 + $monthDay;
+ }
+ }
+
+ // If there was just byDay or just byMonthDay, they just specify our
+ // (almost) final list. If both were provided, then byDay limits the
+ // list.
+ if ($this->byMonthDay && $this->byDay) {
+ $result = array_intersect($byMonthDayResults, $byDayResults);
+ } elseif ($this->byMonthDay) {
+ $result = $byMonthDayResults;
+ } else {
+ $result = $byDayResults;
+ }
+ $result = array_unique($result);
+ sort($result, SORT_NUMERIC);
+
+ // The last thing that needs checking is the BYSETPOS. If it's set, it
+ // means only certain items in the set survive the filter.
+ if (!$this->bySetPos) {
+ return $result;
+ }
+
+ $filteredResult = array();
+ foreach($this->bySetPos as $setPos) {
+
+ if ($setPos<0) {
+ $setPos = count($result)-($setPos+1);
+ }
+ if (isset($result[$setPos-1])) {
+ $filteredResult[] = $result[$setPos-1];
+ }
+ }
+
+ sort($filteredResult, SORT_NUMERIC);
+ return $filteredResult;
+
+ }
+
+
+}
+
diff --git a/3rdparty/Sabre/VObject/Version.php b/3rdparty/Sabre/VObject/Version.php
index 937c367e222..00110febc07 100644..100755
--- a/3rdparty/Sabre/VObject/Version.php
+++ b/3rdparty/Sabre/VObject/Version.php
@@ -2,10 +2,10 @@
/**
* This class contains the version number for the VObject package
- *
+ *
* @package Sabre
- * @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
@@ -14,7 +14,7 @@ class Sabre_VObject_Version {
/**
* Full version number
*/
- const VERSION = '1.2.4';
+ const VERSION = '1.3.2';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/VObject/WindowsTimezoneMap.php b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
new file mode 100755
index 00000000000..5e1cc5d479b
--- /dev/null
+++ b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
@@ -0,0 +1,128 @@
+<?php
+
+/**
+ * Time zone name translation
+ *
+ * This file translates well-known time zone names into "Olson database" time zone names.
+ *
+ * @package Sabre
+ * @subpackage VObject
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Frank Edelhaeuser (fedel@users.sourceforge.net)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_VObject_WindowsTimezoneMap {
+
+ protected static $map = array(
+
+ // from http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html
+ // snapshot taken on 2012/01/16
+
+ // windows
+ 'AUS Central Standard Time'=>'Australia/Darwin',
+ 'AUS Eastern Standard Time'=>'Australia/Sydney',
+ 'Afghanistan Standard Time'=>'Asia/Kabul',
+ 'Alaskan Standard Time'=>'America/Anchorage',
+ 'Arab Standard Time'=>'Asia/Riyadh',
+ 'Arabian Standard Time'=>'Asia/Dubai',
+ 'Arabic Standard Time'=>'Asia/Baghdad',
+ 'Argentina Standard Time'=>'America/Buenos_Aires',
+ 'Armenian Standard Time'=>'Asia/Yerevan',
+ 'Atlantic Standard Time'=>'America/Halifax',
+ 'Azerbaijan Standard Time'=>'Asia/Baku',
+ 'Azores Standard Time'=>'Atlantic/Azores',
+ 'Bangladesh Standard Time'=>'Asia/Dhaka',
+ 'Canada Central Standard Time'=>'America/Regina',
+ 'Cape Verde Standard Time'=>'Atlantic/Cape_Verde',
+ 'Caucasus Standard Time'=>'Asia/Yerevan',
+ 'Cen. Australia Standard Time'=>'Australia/Adelaide',
+ 'Central America Standard Time'=>'America/Guatemala',
+ 'Central Asia Standard Time'=>'Asia/Almaty',
+ 'Central Brazilian Standard Time'=>'America/Cuiaba',
+ 'Central Europe Standard Time'=>'Europe/Budapest',
+ 'Central European Standard Time'=>'Europe/Warsaw',
+ 'Central Pacific Standard Time'=>'Pacific/Guadalcanal',
+ 'Central Standard Time'=>'America/Chicago',
+ 'Central Standard Time (Mexico)'=>'America/Mexico_City',
+ 'China Standard Time'=>'Asia/Shanghai',
+ 'Dateline Standard Time'=>'Etc/GMT+12',
+ 'E. Africa Standard Time'=>'Africa/Nairobi',
+ 'E. Australia Standard Time'=>'Australia/Brisbane',
+ 'E. Europe Standard Time'=>'Europe/Minsk',
+ 'E. South America Standard Time'=>'America/Sao_Paulo',
+ 'Eastern Standard Time'=>'America/New_York',
+ 'Egypt Standard Time'=>'Africa/Cairo',
+ 'Ekaterinburg Standard Time'=>'Asia/Yekaterinburg',
+ 'FLE Standard Time'=>'Europe/Kiev',
+ 'Fiji Standard Time'=>'Pacific/Fiji',
+ 'GMT Standard Time'=>'Europe/London',
+ 'GTB Standard Time'=>'Europe/Istanbul',
+ 'Georgian Standard Time'=>'Asia/Tbilisi',
+ 'Greenland Standard Time'=>'America/Godthab',
+ 'Greenwich Standard Time'=>'Atlantic/Reykjavik',
+ 'Hawaiian Standard Time'=>'Pacific/Honolulu',
+ 'India Standard Time'=>'Asia/Calcutta',
+ 'Iran Standard Time'=>'Asia/Tehran',
+ 'Israel Standard Time'=>'Asia/Jerusalem',
+ 'Jordan Standard Time'=>'Asia/Amman',
+ 'Kamchatka Standard Time'=>'Asia/Kamchatka',
+ 'Korea Standard Time'=>'Asia/Seoul',
+ 'Magadan Standard Time'=>'Asia/Magadan',
+ 'Mauritius Standard Time'=>'Indian/Mauritius',
+ 'Mexico Standard Time'=>'America/Mexico_City',
+ 'Mexico Standard Time 2'=>'America/Chihuahua',
+ 'Mid-Atlantic Standard Time'=>'Etc/GMT+2',
+ 'Middle East Standard Time'=>'Asia/Beirut',
+ 'Montevideo Standard Time'=>'America/Montevideo',
+ 'Morocco Standard Time'=>'Africa/Casablanca',
+ 'Mountain Standard Time'=>'America/Denver',
+ 'Mountain Standard Time (Mexico)'=>'America/Chihuahua',
+ 'Myanmar Standard Time'=>'Asia/Rangoon',
+ 'N. Central Asia Standard Time'=>'Asia/Novosibirsk',
+ 'Namibia Standard Time'=>'Africa/Windhoek',
+ 'Nepal Standard Time'=>'Asia/Katmandu',
+ 'New Zealand Standard Time'=>'Pacific/Auckland',
+ 'Newfoundland Standard Time'=>'America/St_Johns',
+ 'North Asia East Standard Time'=>'Asia/Irkutsk',
+ 'North Asia Standard Time'=>'Asia/Krasnoyarsk',
+ 'Pacific SA Standard Time'=>'America/Santiago',
+ 'Pacific Standard Time'=>'America/Los_Angeles',
+ 'Pacific Standard Time (Mexico)'=>'America/Santa_Isabel',
+ 'Pakistan Standard Time'=>'Asia/Karachi',
+ 'Paraguay Standard Time'=>'America/Asuncion',
+ 'Romance Standard Time'=>'Europe/Paris',
+ 'Russian Standard Time'=>'Europe/Moscow',
+ 'SA Eastern Standard Time'=>'America/Cayenne',
+ 'SA Pacific Standard Time'=>'America/Bogota',
+ 'SA Western Standard Time'=>'America/La_Paz',
+ 'SE Asia Standard Time'=>'Asia/Bangkok',
+ 'Samoa Standard Time'=>'Pacific/Apia',
+ 'Singapore Standard Time'=>'Asia/Singapore',
+ 'South Africa Standard Time'=>'Africa/Johannesburg',
+ 'Sri Lanka Standard Time'=>'Asia/Colombo',
+ 'Syria Standard Time'=>'Asia/Damascus',
+ 'Taipei Standard Time'=>'Asia/Taipei',
+ 'Tasmania Standard Time'=>'Australia/Hobart',
+ 'Tokyo Standard Time'=>'Asia/Tokyo',
+ 'Tonga Standard Time'=>'Pacific/Tongatapu',
+ 'US Eastern Standard Time'=>'America/Indianapolis',
+ 'US Mountain Standard Time'=>'America/Phoenix',
+ 'UTC'=>'Etc/GMT',
+ 'UTC+12'=>'Etc/GMT-12',
+ 'UTC-02'=>'Etc/GMT+2',
+ 'UTC-11'=>'Etc/GMT+11',
+ 'Ulaanbaatar Standard Time'=>'Asia/Ulaanbaatar',
+ 'Venezuela Standard Time'=>'America/Caracas',
+ 'Vladivostok Standard Time'=>'Asia/Vladivostok',
+ 'W. Australia Standard Time'=>'Australia/Perth',
+ 'W. Central Africa Standard Time'=>'Africa/Lagos',
+ 'W. Europe Standard Time'=>'Europe/Berlin',
+ 'West Asia Standard Time'=>'Asia/Tashkent',
+ 'West Pacific Standard Time'=>'Pacific/Port_Moresby',
+ 'Yakutsk Standard Time'=>'Asia/Yakutsk',
+ );
+
+ static public function lookup($tzid) {
+ return isset(self::$map[$tzid]) ? self::$map[$tzid] : null;
+ }
+}
diff --git a/3rdparty/Sabre/VObject/includes.php b/3rdparty/Sabre/VObject/includes.php
index f21010fb275..0177a8f1ba6 100644..100755
--- a/3rdparty/Sabre/VObject/includes.php
+++ b/3rdparty/Sabre/VObject/includes.php
@@ -1,29 +1,41 @@
<?php
/**
- * VObject includes
+ * Sabre_VObject includes file
*
- * This file automatically includes all VObject classes
+ * Including this file will automatically include all files from the VObject
+ * package.
+ *
+ * This often allows faster loadtimes, as autoload-speed is often quite slow.
*
* @package Sabre
* @subpackage VObject
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
-
-include dirname(__FILE__) . '/ParseException.php';
-
-include dirname(__FILE__) . '/Node.php';
-include dirname(__FILE__) . '/Element.php';
-include dirname(__FILE__) . '/ElementList.php';
-include dirname(__FILE__) . '/Parameter.php';
-include dirname(__FILE__) . '/Property.php';
-include dirname(__FILE__) . '/Component.php';
-
-include dirname(__FILE__) . '/Element/DateTime.php';
-include dirname(__FILE__) . '/Element/MultiDateTime.php';
-
-include dirname(__FILE__) . '/Reader.php';
-include dirname(__FILE__) . '/Version.php';
+// Begin includes
+include __DIR__ . '/DateTimeParser.php';
+include __DIR__ . '/ElementList.php';
+include __DIR__ . '/FreeBusyGenerator.php';
+include __DIR__ . '/Node.php';
+include __DIR__ . '/Parameter.php';
+include __DIR__ . '/ParseException.php';
+include __DIR__ . '/Reader.php';
+include __DIR__ . '/RecurrenceIterator.php';
+include __DIR__ . '/Version.php';
+include __DIR__ . '/WindowsTimezoneMap.php';
+include __DIR__ . '/Element.php';
+include __DIR__ . '/Property.php';
+include __DIR__ . '/Component.php';
+include __DIR__ . '/Property/DateTime.php';
+include __DIR__ . '/Property/MultiDateTime.php';
+include __DIR__ . '/Component/VAlarm.php';
+include __DIR__ . '/Component/VCalendar.php';
+include __DIR__ . '/Component/VEvent.php';
+include __DIR__ . '/Component/VJournal.php';
+include __DIR__ . '/Component/VTodo.php';
+include __DIR__ . '/Element/DateTime.php';
+include __DIR__ . '/Element/MultiDateTime.php';
+// End includes
diff --git a/3rdparty/Sabre/autoload.php b/3rdparty/Sabre/autoload.php
index 0649df655b0..c7b537d83d3 100644..100755
--- a/3rdparty/Sabre/autoload.php
+++ b/3rdparty/Sabre/autoload.php
@@ -8,11 +8,15 @@
*
* @package Sabre
* @subpackage DAV
- * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
+/**
+ * @param string $className
+ * @return void
+ */
function Sabre_autoload($className) {
if(strpos($className,'Sabre_')===0) {
diff --git a/apps/calendar/ajax/event/edit.form.php b/apps/calendar/ajax/event/edit.form.php
index ec50b78be6f..e963da32958 100644
--- a/apps/calendar/ajax/event/edit.form.php
+++ b/apps/calendar/ajax/event/edit.form.php
@@ -27,15 +27,15 @@ $vevent = $object->VEVENT;
$dtstart = $vevent->DTSTART;
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
switch($dtstart->getDateType()) {
- case Sabre_VObject_Element_DateTime::LOCALTZ:
- case Sabre_VObject_Element_DateTime::LOCAL:
+ case Sabre_VObject_Property_DateTime::LOCALTZ:
+ case Sabre_VObject_Property_DateTime::LOCAL:
$startdate = $dtstart->getDateTime()->format('d-m-Y');
$starttime = $dtstart->getDateTime()->format('H:i');
$enddate = $dtend->getDateTime()->format('d-m-Y');
$endtime = $dtend->getDateTime()->format('H:i');
$allday = false;
break;
- case Sabre_VObject_Element_DateTime::DATE:
+ case Sabre_VObject_Property_DateTime::DATE:
$startdate = $dtstart->getDateTime()->format('d-m-Y');
$starttime = '';
$dtend->getDateTime()->modify('-1 day');
diff --git a/apps/calendar/ajax/event/move.php b/apps/calendar/ajax/event/move.php
index 0552c7bbc5b..75d174c13e1 100644
--- a/apps/calendar/ajax/event/move.php
+++ b/apps/calendar/ajax/event/move.php
@@ -27,19 +27,19 @@ $dtstart = $vevent->DTSTART;
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
$start_type = $dtstart->getDateType();
$end_type = $dtend->getDateType();
-if ($allday && $start_type != Sabre_VObject_Element_DateTime::DATE){
- $start_type = $end_type = Sabre_VObject_Element_DateTime::DATE;
+if ($allday && $start_type != Sabre_VObject_Property_DateTime::DATE){
+ $start_type = $end_type = Sabre_VObject_Property_DateTime::DATE;
$dtend->setDateTime($dtend->getDateTime()->modify('+1 day'), $end_type);
}
-if (!$allday && $start_type == Sabre_VObject_Element_DateTime::DATE){
- $start_type = $end_type = Sabre_VObject_Element_DateTime::LOCALTZ;
+if (!$allday && $start_type == Sabre_VObject_Property_DateTime::DATE){
+ $start_type = $end_type = Sabre_VObject_Property_DateTime::LOCALTZ;
}
$dtstart->setDateTime($dtstart->getDateTime()->add($delta), $start_type);
$dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type);
unset($vevent->DURATION);
-$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
-$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
$result = OC_Calendar_Object::edit($id, $vcalendar->serialize());
$lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
diff --git a/apps/calendar/ajax/event/resize.php b/apps/calendar/ajax/event/resize.php
index 593835d86c5..260b6914426 100644
--- a/apps/calendar/ajax/event/resize.php
+++ b/apps/calendar/ajax/event/resize.php
@@ -30,8 +30,8 @@ $end_type = $dtend->getDateType();
$dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type);
unset($vevent->DURATION);
-$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
-$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
OC_Calendar_Object::edit($id, $vcalendar->serialize());
$lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php
index 3aa487fd231..8adaa4c98f3 100755
--- a/apps/calendar/ajax/events.php
+++ b/apps/calendar/ajax/events.php
@@ -20,7 +20,6 @@ $events = OC_Calendar_App::getrequestedEvents($_GET['calendar_id'], $start, $end
$output = array();
foreach($events as $event){
$output[] = OC_Calendar_App::generateEventOutput($event, $start, $end);
-
}
OC_JSON::encodedPrint($output);
?>
diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php
index 825977c17c5..ae6fce3c842 100644
--- a/apps/calendar/lib/object.php
+++ b/apps/calendar/lib/object.php
@@ -590,7 +590,7 @@ class OC_Calendar_Object{
$vevent = new OC_VObject('VEVENT');
$vcalendar->add($vevent);
- $vevent->setDateTime('CREATED', 'now', Sabre_VObject_Element_DateTime::UTC);
+ $vevent->setDateTime('CREATED', 'now', Sabre_VObject_Property_DateTime::UTC);
$vevent->setUID();
return self::updateVCalendarFromRequest($request, $vcalendar);
@@ -751,22 +751,22 @@ class OC_Calendar_Object{
}
- $vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
- $vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+ $vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+ $vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
$vevent->setString('SUMMARY', $title);
if($allday){
$start = new DateTime($from);
$end = new DateTime($to.' +1 day');
- $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Element_DateTime::DATE);
- $vevent->setDateTime('DTEND', $end, Sabre_VObject_Element_DateTime::DATE);
+ $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Property_DateTime::DATE);
+ $vevent->setDateTime('DTEND', $end, Sabre_VObject_Property_DateTime::DATE);
}else{
$timezone = OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
$timezone = new DateTimeZone($timezone);
$start = new DateTime($from.' '.$fromtime, $timezone);
$end = new DateTime($to.' '.$totime, $timezone);
- $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Element_DateTime::LOCALTZ);
- $vevent->setDateTime('DTEND', $end, Sabre_VObject_Element_DateTime::LOCALTZ);
+ $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Property_DateTime::LOCALTZ);
+ $vevent->setDateTime('DTEND', $end, Sabre_VObject_Property_DateTime::LOCALTZ);
}
unset($vevent->DURATION);
diff --git a/apps/calendar/lib/search.php b/apps/calendar/lib/search.php
index da5fa35bc21..0e1a9032666 100644
--- a/apps/calendar/lib/search.php
+++ b/apps/calendar/lib/search.php
@@ -26,7 +26,7 @@ class OC_Search_Provider_Calendar extends OC_Search_Provider{
$start_dt->setTimezone(new DateTimeZone($user_timezone));
$end_dt = $dtend->getDateTime();
$end_dt->setTimezone(new DateTimeZone($user_timezone));
- if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){
+ if ($dtstart->getDateType() == Sabre_VObject_Property_DateTime::DATE){
$end_dt->modify('-1 sec');
if($start_dt->format('d.m.Y') != $end_dt->format('d.m.Y')){
$info = $l->t('Date') . ': ' . $start_dt->format('d.m.Y') . ' - ' . $end_dt->format('d.m.Y');
diff --git a/apps/contacts/ajax/uploadimport.php b/apps/contacts/ajax/uploadimport.php
index ab680c8823f..f44335a961e 100644
--- a/apps/contacts/ajax/uploadimport.php
+++ b/apps/contacts/ajax/uploadimport.php
@@ -34,17 +34,52 @@ function debug($msg) {
OC_Log::write('contacts','ajax/uploadimport.php: '.$msg, OC_Log::DEBUG);
}
+$view = OC_App::getStorage('contacts');
+$tmpfile = md5(rand());
+
// If it is a Drag'n'Drop transfer it's handled here.
$fn = (isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : false);
if($fn) {
- $view = OC_App::getStorage('contacts');
- $tmpfile = md5(rand());
if($view->file_put_contents('/'.$tmpfile, file_get_contents('php://input'))) {
debug($fn.' uploaded');
OC_JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+ exit();
} else {
bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
}
}
+// File input transfers are handled here
+if (!isset($_FILES['importfile'])) {
+ OC_Log::write('contacts','ajax/uploadphoto.php: No file was uploaded. Unknown error.', OC_Log::DEBUG);
+ OC_JSON::error(array('data' => array( 'message' => 'No file was uploaded. Unknown error' )));
+ exit();
+}
+$error = $_FILES['importfile']['error'];
+if($error !== UPLOAD_ERR_OK) {
+ $errors = array(
+ 0=>OC_Contacts_App::$l10n->t("There is no error, the file uploaded with success"),
+ 1=>OC_Contacts_App::$l10n->t("The uploaded file exceeds the upload_max_filesize directive in php.ini").ini_get('upload_max_filesize'),
+ 2=>OC_Contacts_App::$l10n->t("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"),
+ 3=>OC_Contacts_App::$l10n->t("The uploaded file was only partially uploaded"),
+ 4=>OC_Contacts_App::$l10n->t("No file was uploaded"),
+ 6=>OC_Contacts_App::$l10n->t("Missing a temporary folder")
+ );
+ bailOut($errors[$error]);
+}
+$file=$_FILES['importfile'];
+
+$tmpfname = tempnam("/tmp", "occOrig");
+if(file_exists($file['tmp_name'])) {
+ if($view->file_put_contents('/'.$tmpfile, file_get_contents($file['tmp_name']))) {
+ debug($fn.' uploaded');
+ OC_JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+ } else {
+ bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
+ }
+} else {
+ bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?');
+}
+
+
?>
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index 0bb9f975fc5..e3d2cfbdd66 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -100,4 +100,4 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.propertylist li > input[type="checkbox"],input[type="radio"] { float: left; clear: left; width: 20px; height: 20px; vertical-align: middle; }
.propertylist li > select { float: left; max-width: 8em; }
.typelist { float: left; max-width: 10em; } /* for multiselect */
-.addresslist { clear: both; } \ No newline at end of file
+.addresslist { clear: both; }
diff --git a/apps/contacts/import.php b/apps/contacts/import.php
index ca2c1e1605d..8e0a427399b 100644
--- a/apps/contacts/import.php
+++ b/apps/contacts/import.php
@@ -24,6 +24,11 @@ if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') {
} else {
$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);
}
+if(!$file) {
+ OC_JSON::error(array('message' => 'Import file was empty.'));
+ exit();
+}
+error_log('File: '.$file);
if(isset($_POST['method']) && $_POST['method'] == 'new'){
$id = OC_Contacts_Addressbook::add(OC_User::getUser(), $_POST['addressbookname']);
OC_Contacts_Addressbook::setActive($id, 1);
diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js
index 18edb40a3cb..7e0fe8b41cf 100644
--- a/apps/contacts/js/contacts.js
+++ b/apps/contacts/js/contacts.js
@@ -1287,6 +1287,7 @@ Contacts={
},
Addressbooks:{
droptarget:undefined,
+ droptext:t('contacts', 'Drop a VCF file to import contacts.'),
overview:function(){
if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
$('#chooseaddressbook_dialog').dialog('moveToTop');
@@ -1345,8 +1346,16 @@ Contacts={
}
},
loadImportHandlers:function() {
+ $('#import_upload_start').change(function(){
+ Contacts.UI.Addressbooks.uploadImport(this.files);
+ });
+ $('#importaddressbook_dialog').find('.upload').click(function() {
+ Contacts.UI.Addressbooks.droptarget.html(t('contacts', 'Uploading...'));
+ Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
+ $('#import_upload_start').trigger('click');
+ });
+ $('#importaddressbook_dialog').find('.upload').tipsy();
this.droptarget = $('#import_drop_target');
- console.log($('#import_drop_target').html());
$(this.droptarget).bind('dragover',function(event){
$(event.target).addClass('droppable');
event.stopPropagation();
@@ -1371,13 +1380,13 @@ Contacts={
console.log('size: '+file.size+', type: '+file.type);
if(file.size > $('#max_upload').val()){
OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts','Upload too large'));
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
return;
}
if(file.type.indexOf('text') != 0) {
OC.dialogs.alert(t('contacts','You have dropped a file type that cannot be imported: ') + file.type, t('contacts','Wrong file type'));
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
return;
}
@@ -1392,11 +1401,9 @@ Contacts={
response = $.parseJSON(xhr.responseText);
if(response.status == 'success') {
if(xhr.status == 200) {
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Importing...'));
- Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
Contacts.UI.Addressbooks.doImport(response.data.path, response.data.file);
} else {
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
OC.dialogs.alert(xhr.status + ': ' + xhr.responseText, t('contacts', 'Error'));
}
@@ -1405,7 +1412,7 @@ Contacts={
}
}
};
- xhr.open("POST", 'ajax/uploadimport.php?file='+encodeURIComponent(file.name), true);
+ xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name), true);
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name));
@@ -1414,12 +1421,39 @@ Contacts={
xhr.send(file);
}
},
+ uploadImport:function(filelist) {
+ if(!filelist) {
+ OC.dialogs.alert(t('contacts','No files selected for upload.'), t('contacts', 'Error'));
+ return;
+ }
+ //var file = filelist.item(0);
+ var file = filelist[0];
+ var target = $('#import_upload_target');
+ var form = $('#import_upload_form');
+ var totalSize=0;
+ if(file.size > $('#max_upload').val()){
+ OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts', 'Error'));
+ return;
+ } else {
+ target.load(function(){
+ var response=jQuery.parseJSON(target.contents().text());
+ if(response != undefined && response.status == 'success'){
+ Contacts.UI.Addressbooks.doImport(response.data.path, response.data.file);
+ }else{
+ OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
+ }
+ });
+ form.submit();
+ }
+ },
importAddressbook:function(object){
var tr = $(document.createElement('tr'))
.load(OC.filePath('contacts', 'ajax', 'importaddressbook.php'));
$(object).closest('tr').after(tr).hide();
},
doImport:function(path, file){
+ $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Importing...'));
+ Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
var id = $('#importaddressbook_dialog').find('#book').val();
console.log('Selected book: ' + id);
$.post(OC.filePath('contacts', '', 'import.php'), { id: id, path: path, file: file, fstype: 'OC_FilesystemView' },
@@ -1428,6 +1462,10 @@ Contacts={
Contacts.UI.Addressbooks.droptarget.html(t('contacts', 'Import done. Success/Failure: ')+jsondata.data.imported+'/'+jsondata.data.failed);
$('#chooseaddressbook_dialog').find('#close_button').val(t('contacts', 'OK'));
Contacts.UI.Contacts.update();
+ setTimeout(
+ function() {
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
+ }, 5000);
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
@@ -1590,7 +1628,7 @@ $(document).ready(function(){
* Profile picture upload handling
*/
// New profile picture selected
- $('#file_upload_start').live('change',function(){
+ $('#file_upload_start').change(function(){
Contacts.UI.Card.uploadPhoto(this.files);
});
$('#contacts_details_photo_wrapper').bind('dragover',function(event){
@@ -1662,7 +1700,7 @@ $(document).ready(function(){
};
// Start loading indicator.
//$('#contacts_details_photo_progress').show()();
- xhr.open("POST", OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&imagefile='+encodeURIComponent(file.name), true);
+ xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&imagefile='+encodeURIComponent(file.name), true);
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name));
@@ -1691,4 +1729,4 @@ $(document).ready(function(){
Contacts.UI.Card.addProperty(type);
$('#contacts_propertymenu').hide();
});
-}); \ No newline at end of file
+});
diff --git a/apps/contacts/templates/part.contact.php b/apps/contacts/templates/part.contact.php
index dec081a9b89..64a024c0926 100644
--- a/apps/contacts/templates/part.contact.php
+++ b/apps/contacts/templates/part.contact.php
@@ -24,7 +24,6 @@ $id = isset($_['id']) ? $_['id'] : '';
<div id="contact_photo" class="contactsection">
<form class="float" id="file_upload_form" action="ajax/uploadphoto.php" method="post" enctype="multipart/form-data" target="file_upload_target">
- <fieldset id="photo">
<div class="tip propertycontainer" id="contacts_details_photo_wrapper" title="<?php echo $l->t('Click or drop to upload picture'); ?> (max <?php echo $_['uploadMaxHumanFilesize']; ?>)" data-element="PHOTO">
<!-- img style="padding: 1em;" id="contacts_details_photo" alt="Profile picture" src="photo.php?id=<?php echo $_['id']; ?>" / -->
<progress id="contacts_details_photo_progress" style="display:none;" value="0" max="100">0 %</progress>
@@ -34,7 +33,6 @@ $id = isset($_['id']) ? $_['id'] : '';
<input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)">
<input id="file_upload_start" type="file" accept="image/*" name="imagefile" />
<iframe name="file_upload_target" id='file_upload_target' src=""></iframe>
- </fieldset>
</form>
</div> <!-- contact_photo -->
diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php
index 488f68e6b3c..a227dcc3ffc 100644
--- a/apps/files/ajax/scan.php
+++ b/apps/files/ajax/scan.php
@@ -3,6 +3,7 @@
set_time_limit(0);//scanning can take ages
$force=isset($_GET['force']) and $_GET['force']=='true';
+$dir=isset($_GET['dir'])?$_GET['dir']:'';
$checkOnly=isset($_GET['checkonly']) and $_GET['checkonly']=='true';
if(!$checkOnly){
@@ -14,7 +15,7 @@ if(!$checkOnly){
if($force or !OC_FileCache::inCache('')){
if(!$checkOnly){
OC_DB::beginTransaction();
- OC_FileCache::scan('',$eventSource);
+ OC_FileCache::scan($dir,$eventSource);
OC_FileCache::clean();
OC_DB::commit();
$eventSource->send('success',true);
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index 99623b6355e..a135f7ded5b 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -30,6 +30,8 @@
.file_upload_filename { position: relative; z-index:100; padding-left: 0.8em; padding-right: 0.8em; cursor:pointer; border-top-left-radius:0; border-bottom-left-radius:0; }
.file_upload_filename img { position: absolute; top: 0.4em; left: 0.4em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; }
+#upload { position:absolute; right:13.5em; top:0em; }
+#upload #uploadprogressbar { position:relative; display:inline-block; width:10em; height:1.5em; top:.4em; }
.file_upload_form, .file_upload_wrapper, .file_upload_start, .file_upload_filename, #file_upload_submit { cursor:pointer; }
@@ -41,7 +43,7 @@ tbody tr { background-color:#fff; height:2.5em; }
tbody tr:hover, tbody tr:active, tbody tr.selected { background-color:#f8f8f8; }
tbody tr.selected { background-color:#eee; }
tbody a { color:#000; }
-span.extension, td.date { color:#999; }
+span.extension, span.uploading, td.date { color:#999; }
span.extension { text-transform:lowercase; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70); opacity:.7; -webkit-transition:opacity 300ms; -moz-transition:opacity 300ms; -o-transition:opacity 300ms; transition:opacity 300ms; }
tr:hover span.extension { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; color:#777; }
div.crumb { float:left; display:block; background:no-repeat right 0; padding:.75em 1.5em 0 1em; height:2.9em; }
@@ -60,8 +62,10 @@ table td.filename a.name { display:block; height:1.5em; vertical-align:middle; m
table tr[data-type="dir"] td.filename a.name span.nametext {font-weight:bold; }
table td.filename a.name input, table td.filename a.name form { width:100%; cursor:text; }
table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:.2em .5em .5em 0; }
-table td.filename .nametext, .modified { float:left; padding:.3em 0; }
+table td.filename .nametext, .uploadtext, .modified { float:left; padding:.3em 0; }
+// TODO fix usability bug (accidental file/folder selection)
table td.filename .nametext { width:70%; overflow:hidden; }
+table td.filename .uploadtext { font-weight:normal; margin-left:.5em; }
table td.filename form { float:left; font-size:.85em; }
table thead.fixed tr{ position:fixed; top:6.5em; z-index:49; -moz-box-shadow:0 -3px 7px #ddd; -webkit-box-shadow:0 -3px 7px #ddd; box-shadow:0 -3px 7px #ddd; }
table thead.fixed { height:2em; }
diff --git a/apps/files/index.php b/apps/files/index.php
index 46b511d66eb..8464db30f01 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -26,6 +26,8 @@ OC_Util::checkLoggedIn();
// Load the files we need
OC_Util::addStyle( "files", "files" );
+OC_Util::addScript( "files", "jquery.iframe-transport" );
+OC_Util::addScript( "files", "jquery.fileupload" );
OC_Util::addScript( "files", "files" );
OC_Util::addScript( 'files', 'filelist' );
OC_Util::addScript( 'files', 'fileactions' );
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 481802e0d63..68268a7d3a9 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -140,7 +140,20 @@ $(document).ready(function(){
});
FileActions.register('all','Delete',function(){return OC.imagePath('core','actions/delete')},function(filename){
- FileList.do_delete(filename);
+ if(Files.cancelUpload(filename)) {
+ if(filename.substr){
+ filename=[filename];
+ }
+ $.each(filename,function(index,file){
+ var filename = $('tr').filterAttr('data-file',file);
+ filename.hide();
+ filename.find('input[type="checkbox"]').removeAttr('checked');
+ filename.removeClass('selected');
+ });
+ procesSelection();
+ }else{
+ FileList.do_delete(filename);
+ }
});
FileActions.register('all','Rename',function(){return OC.imagePath('core','actions/rename')},function(filename){
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 5bd85fc29ef..febdfc473b1 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -43,6 +43,7 @@ FileList={
td.append('<input type="checkbox" />');
var link_elem = $('<a></a>').attr({ "class": "name", "href": "index.php?dir="+ encodeURIComponent($('#dir').val()+'/'+name).replace(/%2F/g, '/') });
link_elem.append($('<span></span>').addClass('nametext').text(name));
+ link_elem.append($('<span></span>').attr({'class': 'uploadtext', 'currentUploads': 0}));
td.append(link_elem);
html.append(td);
if(size!='Pending'){
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 9d83e5e6d26..2dce00035e1 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -1,3 +1,32 @@
+var uploadingFiles = {};
+Files={
+ cancelUpload:function(filename) {
+ if(uploadingFiles[filename]) {
+ uploadingFiles[filename].abort();
+ delete uploadingFiles[filename];
+ return true;
+ }
+ return false;
+ },
+ cancelUploads:function() {
+ $.each(uploadingFiles,function(index,file) {
+ if(typeof file['abort'] === 'function') {
+ file.abort();
+ var filename = $('tr').filterAttr('data-file',index);
+ filename.hide();
+ filename.find('input[type="checkbox"]').removeAttr('checked');
+ filename.removeClass('selected');
+ } else {
+ $.each(file,function(i,f) {
+ f.abort();
+ delete file[i];
+ });
+ }
+ delete uploadingFiles[index];
+ });
+ procesSelection();
+ }
+}
$(document).ready(function() {
$('#fileList tr').each(function(){
//little hack to set unescape filenames in attribute
@@ -151,83 +180,205 @@ $(document).ready(function() {
return false;
});
- $('.file_upload_start').live('change',function(){
- var form=$(this).closest('form');
- var that=this;
- var uploadId=form.attr('data-upload-id');
- var files=this.files;
- var target=form.children('iframe');
- var totalSize=0;
- if(files){
- for(var i=0;i<files.length;i++){
- totalSize+=files[i].size;
- if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
- FileList.finishDelete(function(){
- $(that).change();
- });
- return;
- }
- }
- }
- if(totalSize>$('#max_upload').val()){
- $( "#uploadsize-message" ).dialog({
- modal: true,
- buttons: {
- Close: function() {
- $( this ).dialog( "close" );
+ // drag&drop support using jquery.fileupload
+ // TODO use OC.dialogs
+ $(document).bind('drop dragover', function (e) {
+ e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
+ });
+
+ $(function() {
+ $('.file_upload_start').fileupload({
+ dropZone: $('#content'), // restrict dropZone to content div
+ add: function(e, data) {
+ var files = data.files;
+ var totalSize=0;
+ if(files){
+ for(var i=0;i<files.length;i++){
+ totalSize+=files[i].size;
+ if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
+ FileList.finishDelete(function(){
+ $('.file_upload_start').change();
+ });
+ return;
+ }
}
}
- });
- }else{
- target.load(function(){
- var response=jQuery.parseJSON(target.contents().find('body').text());
- //set mimetype and if needed filesize
- if(response){
- if(response[0] != undefined && response[0].status == 'success'){
- for(var i=0;i<response.length;i++){
- var file=response[i];
+ if(totalSize>$('#max_upload').val()){
+ $( '#uploadsize-message' ).dialog({
+ modal: true,
+ buttons: {
+ Close: function() {
+ $( this ).dialog( 'close' );
+ }
+ }
+ });
+ }else{
+ if($.support.xhrFileUpload) {
+ for(var i=0;i<files.length;i++){
+ var fileName = files[i].name
+ var dropTarget = $(e.originalEvent.target).closest('tr');
+ if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
+ var dirName = dropTarget.attr('data-file')
+ var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i],
+ formData: function(form) {
+ var formArray = form.serializeArray();
+ formArray[1]['value'] = dirName;
+ return formArray;
+ }}).success(function(result, textStatus, jqXHR) {
+ var response;
+ response=jQuery.parseJSON(result);
+ if(response[0] == undefined || response[0].status != 'success') {
+ $('#notification').text(t('files', response.data.message));
+ $('#notification').fadeIn();
+ }
+ var file=response[0];
+ delete uploadingFiles[dirName][file.name];
+ var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+ currentUploads -= 1;
+ uploadtext.attr('currentUploads', currentUploads);
+ if(currentUploads === 0) {
+ var img = OC.imagePath('core', 'filetypes/folder.png');
+ var tr=$('tr').filterAttr('data-file',dirName);
+ tr.find('td.filename').attr('style','background-image:url('+img+')');
+ uploadtext.text('');
+ uploadtext.hide();
+ } else {
+ uploadtext.text(currentUploads + ' files uploading')
+ }
+ })
+ .error(function(jqXHR, textStatus, errorThrown) {
+ if(errorThrown === 'abort') {
+ var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+ currentUploads -= 1;
+ uploadtext.attr('currentUploads', currentUploads);
+ if(currentUploads === 0) {
+ var img = OC.imagePath('core', 'filetypes/folder.png');
+ var tr=$('tr').filterAttr('data-file',dirName);
+ tr.find('td.filename').attr('style','background-image:url('+img+')');
+ uploadtext.text('');
+ uploadtext.hide();
+ } else {
+ uploadtext.text(currentUploads + ' files uploading')
+ }
+ $('#notification').hide();
+ $('#notification').text(t('files', 'Upload cancelled.'));
+ $('#notification').fadeIn();
+ }
+ });
+ //TODO test with filenames containing slashes
+ if(uploadingFiles[dirName] === undefined) {
+ uploadingFiles[dirName] = {};
+ }
+ uploadingFiles[dirName][fileName] = jqXHR;
+ } else {
+ var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i]})
+ .success(function(result, textStatus, jqXHR) {
+ var response;
+ response=jQuery.parseJSON(result);
+ if(response[0] != undefined && response[0].status == 'success') {
+ var file=response[0];
+ delete uploadingFiles[file.name];
+ $('tr').filterAttr('data-file',file.name).data('mime',file.mime);
+ var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
+ if(size==t('files','Pending')){
+ $('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
+ }
+ FileList.loadingDone(file.name);
+ } else {
+ $('#notification').text(t('files', response.data.message));
+ $('#notification').fadeIn();
+ $('#fileList > tr').not('[data-mime]').fadeOut();
+ $('#fileList > tr').not('[data-mime]').remove();
+ }
+ })
+ .error(function(jqXHR, textStatus, errorThrown) {
+ if(errorThrown === 'abort') {
+ $('#notification').hide();
+ $('#notification').text(t('files', 'Upload cancelled.'));
+ $('#notification').fadeIn();
+ }
+ });
+ uploadingFiles[files[i].name] = jqXHR;
+ }
+ }
+ }else{
+ data.submit().success(function(data, status) {
+ response = jQuery.parseJSON(data[0].body.innerText);
+ if(response[0] != undefined && response[0].status == 'success') {
+ var file=response[0];
+ delete uploadingFiles[file.name];
$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
- if(size=='Pending'){
+ var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
+ if(size==t('files','Pending')){
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
}
FileList.loadingDone(file.name);
+ } else {
+ $('#notification').text(t('files', response.data.message));
+ $('#notification').fadeIn();
+ $('#fileList > tr').not('[data-mime]').fadeOut();
+ $('#fileList > tr').not('[data-mime]').remove();
}
- }
- else{
- $('#notification').text(t('files',response.data.message));
- $('#notification').fadeIn();
- $('#fileList > tr').not('[data-mime]').fadeOut();
- $('#fileList > tr').not('[data-mime]').remove();
- }
+ });
}
- });
- form.submit();
- var date=new Date();
- if(files){
- for(var i=0;i<files.length;i++){
- if(files[i].size>0){
- var size=files[i].size;
- }else{
- var size=t('files','Pending');
- }
+
+ var date=new Date();
if(files){
+ for(var i=0;i<files.length;i++){
+ if(files[i].size>0){
+ var size=files[i].size;
+ }else{
+ var size=t('files','Pending');
+ }
+ if(files && !dirName){
FileList.addFile(getUniqueName(files[i].name),size,date,true);
+ } else if(dirName) {
+ var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext')
+ var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+ currentUploads += 1;
+ uploadtext.attr('currentUploads', currentUploads);
+ if(currentUploads === 1) {
+ var img = OC.imagePath('core', 'loading.gif');
+ var tr=$('tr').filterAttr('data-file',dirName);
+ tr.find('td.filename').attr('style','background-image:url('+img+')');
+ uploadtext.text('1 file uploading');
+ uploadtext.show();
+ } else {
+ uploadtext.text(currentUploads + ' files uploading')
+ }
+ }
+ }
+ }else{
+ var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
+ FileList.addFile(getUniqueName(filename),'Pending',date,true);
}
}
- }else{
- var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
- FileList.addFile(getUniqueName(filename),'Pending',date,true);
+ },
+ fail: function(e, data) {
+ // TODO: cancel upload & display error notification
+ },
+ progress: function(e, data) {
+ // TODO: show nice progress bar in file row
+ },
+ progressall: function(e, data) {
+ var progress = (data.loaded/data.total)*100;
+ $('#uploadprogressbar').progressbar('value',progress);
+ },
+ start: function(e, data) {
+ $('#uploadprogressbar').progressbar({value:0});
+ $('#uploadprogressbar').fadeIn();
+ if(data.dataType != 'iframe ') {
+ $('#upload input.stop').show();
+ }
+ },
+ stop: function(e, data) {
+ if(data.dataType != 'iframe ') {
+ $('#upload input.stop').hide();
+ }
+ $('#uploadprogressbar').progressbar('value',100);
+ $('#uploadprogressbar').fadeOut();
}
-
- //clone the upload form and hide the new one to allow users to start a new upload while the old one is still uploading
- var clone=form.clone();
- uploadId++;
- clone.attr('data-upload-id',uploadId);
- clone.attr('target','file_upload_target_'+uploadId);
- clone.children('iframe').attr('name','file_upload_target_'+uploadId)
- clone.insertBefore(form);
- form.hide();
- }
+ })
});
//add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
@@ -370,12 +521,15 @@ $(document).ready(function() {
}, "json");
});
-function scanFiles(force){
+function scanFiles(force,dir){
+ if(!dir){
+ dir='';
+ }
force=!!force; //cast to bool
scanFiles.scanning=true;
$('#scanning-message').show();
$('#fileList').remove();
- var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force});
+ var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir});
scanFiles.cancel=scannerEventSource.close.bind(scannerEventSource);
scannerEventSource.listen('scanning',function(data){
$('#scan-count').text(data.count+' files scanned');
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php
index 3571950467e..fc385e1ed3a 100644
--- a/apps/files/templates/index.php
+++ b/apps/files/templates/index.php
@@ -22,6 +22,11 @@
<iframe name="file_upload_target_1" class='file_upload_target' src=""></iframe>
</form>
</div>
+ <div id="upload">
+ <div id="uploadprogressbar"></div>
+ <input type="button" class="stop" style="display:none" value="<?php echo $l->t('Cancel upload');?>" onclick="javascript:Files.cancelUploads();" />
+ </div>
+
</div>
<div id="file_action_panel"></div>
<?php else:?>
diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php
index 5a5941fc7ae..b2db4cbb8df 100644
--- a/apps/files/templates/part.list.php
+++ b/apps/files/templates/part.list.php
@@ -21,6 +21,10 @@
<?php echo htmlspecialchars($file['basename']);?><span class='extension'><?php echo $file['extension'];?></span>
<?php endif;?>
</span>
+ <?php if($file['type'] == 'dir'):?>
+ <span class="uploadtext" currentUploads="0">
+ </span>
+ <?php endif;?>
</a>
</td>
<td class="filesize" title="<?php echo human_file_size($file['size']); ?>" style="color:rgb(<?php echo $simple_size_color.','.$simple_size_color.','.$simple_size_color ?>)"><?php echo $simple_file_size; ?></td>
diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php
index 21fa38e4b59..07a2e523a42 100644
--- a/apps/files_encryption/lib/cryptstream.php
+++ b/apps/files_encryption/lib/cryptstream.php
@@ -33,6 +33,7 @@ class OC_CryptStream{
private $path;
private $readBuffer;//for streams that dont support seeking
private $meta=array();//header/meta for source stream
+ private $count;
public function stream_open($path, $mode, $options, &$opened_path){
$path=str_replace('crypt://','',$path);
@@ -92,16 +93,6 @@ class OC_CryptStream{
$data=substr($block,0,$currentPos%8192).$data;
}
while(strlen($data)>0){
- if(strlen($data)<8192){
- //fetch the current data in that block and append it to the input so we always write entire blocks
- $oldPos=ftell($this->source);
- $encryptedBlock=fread($this->source,8192);
- fseek($this->source,$oldPos);
- if($encryptedBlock){
- $block=OC_Crypt::decrypt($encryptedBlock);
- $data.=substr($block,strlen($data));
- }
- }
$encrypted=OC_Crypt::encrypt(substr($data,0,8192));
fwrite($this->source,$encrypted);
$data=substr($data,8192);
@@ -139,7 +130,9 @@ class OC_CryptStream{
}
public function stream_close(){
- OC_FileCache::put($this->path,array('encrypted'=>true));
+ if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){
+ OC_FileCache::put($this->path,array('encrypted'=>true));
+ }
return fclose($this->source);
}
} \ No newline at end of file
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index e3a106d0d04..d65bcba8bfa 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -27,7 +27,6 @@
class OC_FileProxy_Encryption extends OC_FileProxy{
private static $blackList=null; //mimetypes blacklisted from encryption
- private static $metaData=array(); //metadata cache
private static $enableEncryption=null;
/**
@@ -60,13 +59,8 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
* @return bool
*/
private static function isEncrypted($path){
- if(isset(self::$metaData[$path])){
- $metadata=self::$metaData[$path];
- }else{
- $metadata=OC_FileCache::getCached($path);
- self::$metaData[$path]=$metadata;
- }
- return (bool)$metadata['encrypted'];
+ $metadata=OC_FileCache::getCached($path);
+ return isset($metadata['encrypted']) and (bool)$metadata['encrypted'];
}
public function preFile_put_contents($path,&$data){
@@ -98,12 +92,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
//first encrypt the target file so we don't end up with a half encrypted file
OC_Log::write('files_encryption','Decrypting '.$path.' before writing',OC_Log::DEBUG);
$tmp=fopen('php://temp');
- while(!feof($result)){
- $chunk=fread($result,8192);
- if($chunk){
- fwrite($tmp,$chunk);
- }
- }
+ OC_Helper::streamCopy($result,$tmp);
fclose($result);
OC_Filesystem::file_put_contents($path,$tmp);
fclose($tmp);
diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php
index e53eb1ff3b6..a987d17d799 100644
--- a/apps/files_external/lib/swift.php
+++ b/apps/files_external/lib/swift.php
@@ -28,6 +28,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
private $rootContainer;
private static $tempFiles=array();
+ private $objects=array();
+ private $containers=array();
const SUBCONTAINER_FILE='.subcontainers';
@@ -38,7 +40,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
*/
private function getContainerName($path){
$path=trim($this->root.$path,'/');
- return md5($path);
+ return str_replace('/','\\',$path);
}
/**
@@ -50,8 +52,12 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
if($path=='' or $path=='/'){
return $this->rootContainer;
}
+ if(isset($this->containers[$path])){
+ return $this->containers[$path];
+ }
try{
$container=$this->conn->get_container($this->getContainerName($path));
+ $this->containers[$path]=$container;
return $container;
}catch(NoSuchContainerException $e){
return null;
@@ -87,12 +93,16 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
* @return CF_Object
*/
private function getObject($path){
+ if(isset($this->objects[$path])){
+ return $this->objects[$path];
+ }
$container=$this->getContainer(dirname($path));
if(is_null($container)){
return null;
}else{
try{
$obj=$container->get_object(basename($path));
+ $this->objects[$path]=$obj;
return $obj;
}catch(NoSuchObjectException $e){
return null;
@@ -295,6 +305,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
}
$this->conn->delete_container($this->getContainerName($path));
+ unset($this->containers[$path]);
return true;
}
}
@@ -309,12 +320,14 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
if($sub){
$this->emptyContainer($path.'/'.$sub);
$this->conn->delete_container($this->getContainerName($path.'/'.$sub));
+ unset($this->containers[$path.'/'.$sub]);
}
}
$objects=$this->getObjects($container);
foreach($objects as $object){
$container->delete_object($object);
+ unset($this->objects[$path.'/'.$object]);
}
}
@@ -381,6 +394,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
if($this->objectExists($path)){
$container=$this->getContainer(dirname($path));
$container->delete_object(basename($path));
+ unset($this->objects[$path]);
}else{
return false;
}
@@ -447,6 +461,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
$sourceContainer=$this->getContainer(dirname($path1));
$targetContainer=$this->getContainer(dirname($path2));
$result=$sourceContainer->move_object_to(basename($path1),$targetContainer,basename($path2));
+ unset($this->objects[$path1]);
if($result){
$targetObj=$this->getObject($path2);
$this->resetMTime($targetObj);
diff --git a/apps/files_sharing/ajax/email.php b/apps/files_sharing/ajax/email.php
new file mode 100644
index 00000000000..d6d53c49bff
--- /dev/null
+++ b/apps/files_sharing/ajax/email.php
@@ -0,0 +1,15 @@
+<?php
+
+require_once('../../../lib/base.php');
+
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('files_sharing');
+$user = OC_User::getUser();
+// TODO translations
+$subject = $user + ' ' + 'shared a file with you';
+$link = $_POST['link'] + '&f=' + $_POST['f'];
+$text = $user + ' ' + 'shared the file' + ' ' + $_POST['f'] + ' ' + 'with you.' + ' ' + 'It is available for download here:' + ' ' + $link;
+$fromaddress = OC_Preferences::getValue($user, 'settings', 'email', 'owncloud.org');
+OC_Mail::send($_POST['toaddress'], $_POST['toaddress'], $subject, $text, $fromaddress, $user);
+
+?> \ No newline at end of file
diff --git a/apps/files_sharing/ajax/toggleresharing.php b/apps/files_sharing/ajax/toggleresharing.php
new file mode 100644
index 00000000000..72af1eedec1
--- /dev/null
+++ b/apps/files_sharing/ajax/toggleresharing.php
@@ -0,0 +1,13 @@
+<?php
+
+require_once('../../../lib/base.php');
+
+OC_JSON::checkAppEnabled('files_sharing');
+OC_JSON::checkAdminUser();
+if ($_POST['resharing'] == true) {
+ OC_Appconfig::setValue('files_sharing', 'resharing', 'yes');
+} else {
+ OC_Appconfig::setValue('files_sharing', 'resharing', 'no');
+}
+
+?>
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 8049e9b0ae3..645f4f5e4f2 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -3,10 +3,17 @@
require_once('apps/files_sharing/sharedstorage.php');
OC::$CLASSPATH['OC_Share'] = "apps/files_sharing/lib_share.php";
+OC_APP::registerAdmin('files_sharing', 'settings');
OC_Hook::connect("OC_Filesystem", "post_delete", "OC_Share", "deleteItem");
OC_Hook::connect("OC_Filesystem", "post_rename", "OC_Share", "renameItem");
OC_Hook::connect("OC_Filesystem", "post_write", "OC_Share", "updateItem");
-OC_Util::addScript("files_sharing", "share");
+OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_Share', 'removeUser');
+OC_Hook::connect('OC_User', 'post_addToGroup', 'OC_Share', 'addToGroupShare');
+OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC_Share', 'removeFromGroupShare');
+$dir = isset($_GET['dir']) ? $_GET['dir'] : '/';
+if ($dir != '/Shared' || OC_Appconfig::getValue('files_sharing', 'resharing', 'yes') == 'yes') {
+ OC_Util::addScript("files_sharing", "share");
+}
OC_Util::addScript("3rdparty", "chosen/chosen.jquery.min");
OC_Util::addStyle( 'files_sharing', 'sharing' );
OC_Util::addStyle("3rdparty", "chosen/chosen");
diff --git a/apps/files_sharing/js/settings.js b/apps/files_sharing/js/settings.js
new file mode 100644
index 00000000000..bb7d79fecbb
--- /dev/null
+++ b/apps/files_sharing/js/settings.js
@@ -0,0 +1,9 @@
+$(document).ready(function() {
+ $('#allowResharing').bind('change', function() {
+ var checked = 1;
+ if (!this.checked) {
+ checked = 0;
+ }
+ $.post(OC.filePath('files_sharing','ajax','toggleresharing.php'), 'resharing='+checked);
+ });
+}); \ No newline at end of file
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 54d749d833e..4125fd14d25 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -163,6 +163,9 @@ $(document).ready(function() {
data: data,
success: function(){
$('#link').hide('blind');
+ $('#emailBreak').remove();
+ $('#email').hide('blind');
+ $('#emailButton').hide('blind');
}
});
}
@@ -172,6 +175,14 @@ $(document).ready(function() {
$(this).focus();
$(this).select();
});
+
+ $('#emailButton').live('click', function() {
+ $('#email').css('font-weight', 'bold');
+ $('#email').animate({ fontWeight: 'normal' }, 2000, function() {
+ $(this).val('');
+ }).val('Email sent');
+ $.post(OC.filePath('files_sharing','ajax','email.php'), 'toaddress='+$('#email').val()+'&link='+$('#link').val());
+ });
});
function createDropdown(filename, files) {
@@ -183,10 +194,12 @@ function createDropdown(filename, files) {
html += '<ul id="shared_list"></ul>';
html += '</div>';
html += '<div id="public">';
- html += '<input type="checkbox" name="makelink" id="makelink" value="1" /><label for="makelink">make public</label>';
+ html += '<input type="checkbox" name="makelink" id="makelink" value="1" /><label for="makelink">Share with private link</label>';
//html += '<input type="checkbox" name="public_link_write" id="public_link_write" value="1" /><label for="public_link_write">allow upload</label>';
html += '<br />';
html += '<input id="link" style="display:none; width:90%;" />';
+ html += '<input id="email" style="display:none; width:65%;" value="" placeholder="Email link to person" />';
+ html += '<input id="emailButton" style="display:none;" type="submit" value="Send" />';
html += '</div>';
if (filename) {
$('tr').filterAttr('data-file',filename).addClass('mouseOver');
@@ -241,5 +254,9 @@ function showPublicLink(token, file) {
$('#makelink').attr('checked', true);
$('#link').data('token', token);
$('#link').val(parent.location.protocol+'//'+location.host+OC.linkTo('files_sharing','get.php')+'?token='+token+'&f='+file);
- $('#link').show('blind');
+ $('#link').show('blind', function() {
+ $('#link').after('<br id="emailBreak" />');
+ $('#email').show('blind');
+ $('#emailButton').show('blind');
+ });
}
diff --git a/apps/files_sharing/lib_share.php b/apps/files_sharing/lib_share.php
index 673984f393b..62ac05a5952 100644
--- a/apps/files_sharing/lib_share.php
+++ b/apps/files_sharing/lib_share.php
@@ -436,6 +436,34 @@ class OC_Share {
}
}
+ public static function removeUser($arguments) {
+ $query = OC_DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_owner = ? OR uid_shared_with '.self::getUsersAndGroups($arguments['uid']));
+ $query->execute(array($arguments['uid']));
+ }
+
+ public static function addToGroupShare($arguments) {
+ $length = -strlen($arguments['gid']) - 1;
+ $query = OC_DB::prepare('SELECT uid_owner, source, permissions FROM *PREFIX*sharing WHERE SUBSTR(uid_shared_with, '.$length.') = ?');
+ $gid = '@'.$arguments['gid'];
+ $result = $query->execute(array($gid))->fetchAll();
+ if (count($result) > 0) {
+ $query = OC_DB::prepare('INSERT INTO *PREFIX*sharing VALUES(?,?,?,?,?)');
+ $sharedFolder = '/'.$arguments['uid'].'/files/Shared/';
+ $lastSource = '';
+ for ($i = 0; $i < count($result) - 1; $i++) {
+ if ($result[$i]['source'] != $lastSource) {
+ $query->execute(array($result[$i]['uid_owner'], $arguments['uid'].'@'.$arguments['gid'], $result[$i]['source'], $sharedFolder.basename($result[$i]['source']), $result[$i]['permissions']));
+ $lastSource = $result[$i]['source'];
+ }
+ }
+ }
+ }
+
+ public static function removeFromGroupShare($arguments) {
+ $query = OC_DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_shared_with = ?');
+ $query->execute(array($arguments['uid'].'@'.$arguments['gid']));
+ }
+
}
?>
diff --git a/apps/files_sharing/settings.php b/apps/files_sharing/settings.php
new file mode 100644
index 00000000000..b30c4f45cde
--- /dev/null
+++ b/apps/files_sharing/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+OC_Util::checkAdminUser();
+OC_Util::addScript('files_sharing', 'settings');
+$tmpl = new OC_Template('files_sharing', 'settings');
+$tmpl->assign('allowResharing', OC_Appconfig::getValue('files_sharing', 'resharing', 'yes'));
+return $tmpl->fetchPage();
+
+?> \ No newline at end of file
diff --git a/apps/files_sharing/templates/settings.php b/apps/files_sharing/templates/settings.php
new file mode 100644
index 00000000000..5b6ba5f33ee
--- /dev/null
+++ b/apps/files_sharing/templates/settings.php
@@ -0,0 +1,6 @@
+<form id="resharing">
+ <fieldset class="personalblock">
+ <input type="checkbox" name="allowResharing" id="allowResharing" value="1" <?php if ($_['allowResharing'] == 'yes') echo ' checked="checked"'; ?> /> <label for="allowResharing"><?php echo $l->t('Enable Resharing'); ?></label> <br/>
+ <em><?php echo $l->t('Allow users to reshare files they don\'t own');?></em>
+ </fieldset>
+</form> \ No newline at end of file
diff --git a/apps/files_versions/appinfo/app.php b/apps/files_versions/appinfo/app.php
index 6e7a803252e..32e4c0ce81b 100644
--- a/apps/files_versions/appinfo/app.php
+++ b/apps/files_versions/appinfo/app.php
@@ -9,6 +9,7 @@ OC_App::register( array(
'name' => 'Versioning' ));
OC_APP::registerAdmin('files_versions', 'settings');
+OC_UTIL::addScript('files_versions', 'versions');
// Listen to write signals
OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, "OCA_Versions\Storage", "write_hook");
diff --git a/apps/files_versions/css/versions.css b/apps/files_versions/css/versions.css
index 139597f9cb0..b2279e9b05a 100644
--- a/apps/files_versions/css/versions.css
+++ b/apps/files_versions/css/versions.css
@@ -1,2 +1,3 @@
-
-
+#history {
+ margin: 2em 2em 0;
+} \ No newline at end of file
diff --git a/apps/files_versions/history.php b/apps/files_versions/history.php
index 6c7626ca4ed..b0aa8fdc982 100644
--- a/apps/files_versions/history.php
+++ b/apps/files_versions/history.php
@@ -20,40 +20,41 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
-require_once('../../lib/base.php');
+require_once( '../../lib/base.php' );
-OC_Util::checkLoggedIn();
+OC_Util::checkLoggedIn( );
+OC_Util::addStyle('files_versions','versions');
-if (isset($_GET['path'])) {
+if ( isset( $_GET['path'] ) ) {
$path = $_GET['path'];
- $path = strip_tags($path);
+ $path = strip_tags( $path);
// roll back to old version if button clicked
- if(isset($_GET['revert'])) {
- \OCA_Versions\Storage::rollback($path,$_GET['revert']);
+ if( isset( $_GET['revert'] ) ) {
+ \OCA_Versions\Storage::rollback( $path, $_GET['revert'] );
}
// show the history only if there is something to show
- if(OCA_Versions\Storage::isversioned($path)) {
+ if( OCA_Versions\Storage::isversioned( $path ) ) {
$count=5; //show the newest revisions
- $versions=OCA_Versions\Storage::getversions($path,$count);
+ $versions=OCA_Versions\Storage::getversions( $path, $count);
- $tmpl = new OC_Template('files_versions', 'history', 'user');
- $tmpl->assign('path', $path);
- $tmpl->assign('versions', array_reverse($versions));
- $tmpl->printPage();
+ $tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+ $tmpl->assign( 'path', $path);
+ $tmpl->assign( 'versions', array_reverse( $versions) );
+ $tmpl->printPage( );
}else{
- $tmpl = new OC_Template('files_versions', 'history', 'user');
- $tmpl->assign('path', $path);
- $tmpl->assign('message', 'No old versions available');
- $tmpl->printPage();
+ $tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+ $tmpl->assign( 'path', $path);
+ $tmpl->assign( 'message', 'No old versions available' );
+ $tmpl->printPage( );
}
}else{
- $tmpl = new OC_Template('files_versions', 'history', 'user');
- $tmpl->assign('message', 'No path specified');
- $tmpl->printPage();
+ $tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+ $tmpl->assign( 'message', 'No path specified' );
+ $tmpl->printPage( );
}
diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js
index 139597f9cb0..325ef823a9c 100644
--- a/apps/files_versions/js/versions.js
+++ b/apps/files_versions/js/versions.js
@@ -1,2 +1,67 @@
+$(document).ready(function(){
+
+ // Add history button to files/index.php
+ FileActions.register('file','History',function(){return OC.imagePath('core','actions/history')},function(filename){
+
+ if (scanFiles.scanning){return;}//workaround to prevent additional http request block scanning feedback
+
+ var file = $('#dir').val()+'/'+filename;
+
+ createVersionsDropdown(filename, file)
+ //window.location='../apps/files_versions/history.php?path='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
+
+ });
+
+});
+
+function createVersionsDropdown(filename, files) {
+ var historyUrl = '../apps/files_versions/history.php?path='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
+ //alert( historyUrl );
+ var html = '<div id="dropdown" class="drop" data-file="'+files+'">';
+ html += '<div id="private">';
+ html += '<select data-placeholder="File Version" id="share_with" class="chzen-select">';
+ html += '<option value=""></option>';
+ html += '</select>';
+ html += '<ul id="shared_list"></ul>';
+ html += '</div>';
+ html += '<div id="public">';
+ html += '<input type="button" name="makelink" id="makelink" value="Revert file" />';
+ html += '<input type="button" onclick="window.location=\''+historyUrl+'\'" name="makelink" id="makelink" value="More..." />';
+ html += '<br />';
+ html += '<input id="link" style="display:none; width:90%;" />';
+ html += '</div>';
+
+ if (filename) {
+ $('tr').filterAttr('data-file',filename).addClass('mouseOver');
+ $(html).appendTo($('tr').filterAttr('data-file',filename).find('td.filename'));
+ } else {
+ $(html).appendTo($('thead .share'));
+ }
+// $.getJSON(OC.linkTo('files_sharing', 'ajax/userautocomplete.php'), function(users) {
+// if (users) {
+// $.each(users, function(index, row) {
+// $(row).appendTo('#share_with');
+// });
+// $('#share_with').trigger('liszt:updated');
+// }
+// });
+// $.getJSON(OC.linkTo('files_sharing', 'ajax/getitem.php'), { source: files }, function(users) {
+// if (users) {
+// $.each(users, function(index, row) {
+// if (row.uid_shared_with == 'public') {
+// showPublicLink(row.token, '/'+filename);
+// } else if (isNaN(index)) {
+// addUser(row.uid_shared_with, row.permissions, index.substr(0, index.lastIndexOf('-')));
+// } else {
+// addUser(row.uid_shared_with, row.permissions, false);
+// }
+// });
+// }
+// });
+
+ $('#dropdown').show('blind');
+ $('#share_with').chosen();
+
+} \ No newline at end of file
diff --git a/apps/files_versions/templates/history.php b/apps/files_versions/templates/history.php
index 1b3de9ce77c..d33d2b0f68b 100644
--- a/apps/files_versions/templates/history.php
+++ b/apps/files_versions/templates/history.php
@@ -1,3 +1,4 @@
+<div id="history">
<?php
if(isset($_['message'])){
@@ -10,9 +11,10 @@
echo('<strong>Versions of '.$_['path']).'</strong><br>';
echo('<p><em>You can click on the revert button to revert to the specific verson.</em></p><br />');
foreach ($_['versions'] as $v){
- echo(' '.OC_Util::formatDate($v).' <a href="history.php?path='.urlencode($_['path']).'&revert='.$v.'" class="button">revert</a><br /><br />');
+ echo(' '.OC_Util::formatDate($v).' <a href="history.php?path='.urlencode($_['path']).'&revert='.$v.'" class="button">Revert</a><br /><br />');
}
}
?>
+</div>
diff --git a/apps/files_versions/versions.php b/apps/files_versions/versions.php
index 156a4f59c73..167c64a4345 100644
--- a/apps/files_versions/versions.php
+++ b/apps/files_versions/versions.php
@@ -36,7 +36,7 @@ class Storage {
const DEFAULTFOLDER='versions';
const DEFAULTBLACKLIST='avi mp3 mpg mp4';
const DEFAULTMAXFILESIZE=1048576; // 10MB
- const DEFAULTMININTERVAL=300; // 5 min
+ const DEFAULTMININTERVAL=1; // 5 min
const DEFAULTMAXVERSIONS=50;
/**
diff --git a/apps/user_ldap/appinfo/database.xml b/apps/user_ldap/appinfo/database.xml
new file mode 100644
index 00000000000..74c56fcf743
--- /dev/null
+++ b/apps/user_ldap/appinfo/database.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<database>
+
+ <name>*dbname*</name>
+ <create>true</create>
+ <overwrite>false</overwrite>
+ <charset>utf8</charset>
+
+ <table>
+
+ <name>*dbprefix*ldap_user_mapping</name>
+
+ <declaration>
+
+ <field>
+ <name>ldap_dn</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <field>
+ <name>owncloud_name</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <index>
+ <name>ldap_dn</name>
+ <unique>true</unique>
+ <field>
+ <name>ldap_dn</name>
+ </field>
+ </index>
+
+ <index>
+ <name>owncloud_name</name>
+ <unique>true</unique>
+ <field>
+ <name>owncloud_name</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+
+ </declaration>
+
+ </table>
+
+ <table>
+
+ <name>*dbprefix*ldap_group_mapping</name>
+
+ <declaration>
+
+ <field>
+ <name>ldap_dn</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <field>
+ <name>owncloud_name</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <index>
+ <name>ldap_dn</name>
+ <unique>true</unique>
+ <field>
+ <name>ldap_dn</name>
+ </field>
+ </index>
+
+ <index>
+ <name>owncloud_name</name>
+ <unique>true</unique>
+ <field>
+ <name>owncloud_name</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+
+ </declaration>
+
+ </table>
+
+</database> \ No newline at end of file
diff --git a/apps/user_ldap/appinfo/version b/apps/user_ldap/appinfo/version
index ceab6e11ece..a0d78bd347e 100644
--- a/apps/user_ldap/appinfo/version
+++ b/apps/user_ldap/appinfo/version
@@ -1 +1 @@
-0.1 \ No newline at end of file
+0.1.90 \ No newline at end of file
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index fe0789cdeb7..7773968e208 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -24,13 +24,9 @@
class OC_GROUP_LDAP extends OC_Group_Backend {
// //group specific settings
protected $ldapGroupFilter;
- protected $ldapGroupDisplayName;
- protected $ldapGroupMemberAttr;
public function __construct() {
$this->ldapGroupFilter = OC_Appconfig::getValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)');
- $this->ldapGroupDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_group_display_name', 'cn');
- $this->ldapGroupMemberAttr = OC_Appconfig::getValue('user_ldap', 'ldap_group_member_attr', 'memberUid');
}
/**
@@ -42,18 +38,17 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Checks whether the user is member of a group or not.
*/
public function inGroup($uid, $gid) {
- $filter = OC_LDAP::combineFilterWithAnd(array(
- $this->ldapGroupFilter,
- LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$uid,
- $this->ldapGroupDisplayName.'='.$gid
- ));
- $groups = $this->retrieveList($filter, $this->ldapGroupDisplayName);
-
- if(count($groups) > 0) {
- return true;
- } else {
+ $dn_user = OC_LDAP::username2dn($uid);
+ $dn_group = OC_LDAP::groupname2dn($gid);
+// if($dn_group == 'c') {echo('#sdfsdgfds');die($gid);}
+ // just in case
+ if(!$dn_group || !$dn_user) {
return false;
}
+// var_dump($dn_group);
+ $members = OC_LDAP::readAttribute($dn_group, LDAP_GROUP_MEMBER_ASSOC_ATTR);
+
+ return in_array($dn_user, $members);
}
/**
@@ -65,12 +60,19 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* if the user exists at all.
*/
public function getUserGroups($uid) {
+ $userDN = OC_LDAP::username2dn($uid);
+ if(!$userDN) {
+ return array();
+ }
+
$filter = OC_LDAP::combineFilterWithAnd(array(
$this->ldapGroupFilter,
- LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$uid
+ LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$userDN
));
+ $groups = $this->retrieveList($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn'));
+ $userGroups = OC_LDAP::ownCloudGroupNames($groups);
- return $this->retrieveList($filter, $this->ldapGroupDisplayName);
+ return array_unique($userGroups, SORT_LOCALE_STRING);
}
/**
@@ -78,12 +80,16 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* @returns array with user ids
*/
public function usersInGroup($gid) {
- $filter = OC_LDAP::combineFilterWithAnd(array(
- $this->ldapGroupFilter,
- $this->ldapGroupDisplayName.'='.$gid
- ));
-
- return $this->retrieveList($filter, $this->ldapGroupMemberAttr, false);
+ $groupDN = OC_LDAP::groupname2dn($gid);
+ if(!$groupDN) {
+ return array();
+ }
+ $members = OC_LDAP::readAttribute($groupDN, LDAP_GROUP_MEMBER_ASSOC_ATTR);
+ $result = array();
+ foreach($members as $member) {
+ $result[] = OC_LDAP::dn2username($member);
+ }
+ return array_unique($result, SORT_LOCALE_STRING);
}
/**
@@ -93,7 +99,9 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Returns a list with all groups
*/
public function getGroups() {
- return $this->retrieveList($this->ldapGroupFilter, $this->ldapGroupDisplayName);
+ $ldap_groups = $this->retrieveList($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
+ $groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
+ return $groups;
}
/**
@@ -112,13 +120,18 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
$list = OC_LDAP::searchUsers($filter, $attr);
}
-
if(is_array($list)) {
- return array_unique($list, SORT_LOCALE_STRING);
+ if(count($attr) > 1){
+ return $list;
+ } else {
+ return array_unique($list, SORT_LOCALE_STRING);
+ }
}
//error cause actually, maybe throw an exception in future.
return array();
}
+
+
} \ No newline at end of file
diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js
new file mode 100644
index 00000000000..cae9655e3df
--- /dev/null
+++ b/apps/user_ldap/js/settings.js
@@ -0,0 +1,3 @@
+$(document).ready(function() {
+ $('#ldapSettings').tabs();
+}); \ No newline at end of file
diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php
index 752ac4f2289..4efcf0c5a0d 100644
--- a/apps/user_ldap/lib_ldap.php
+++ b/apps/user_ldap/lib_ldap.php
@@ -21,7 +21,8 @@
*
*/
-define('LDAP_GROUP_MEMBER_ASSOC_ATTR','memberUid');
+define('LDAP_GROUP_MEMBER_ASSOC_ATTR','uniqueMember');
+define('LDAP_GROUP_DISPLAY_NAME_ATTR','cn');
//needed to unbind, because we use OC_LDAP only statically
class OC_LDAP_DESTRUCTOR {
@@ -45,7 +46,9 @@ class OC_LDAP {
static protected $ldapTLS;
static protected $ldapNoCase;
// user and group settings, that are needed in both backends
- static public $ldapUserDisplayName;
+ static protected $ldapUserDisplayName;
+ static protected $ldapUserFilter;
+ static protected $ldapGroupDisplayName;
static public function init() {
self::readConfiguration();
@@ -56,14 +59,345 @@ class OC_LDAP {
@ldap_unbind(self::$ldapConnectionRes);
}
+ /**
+ * @brief returns a read-only configuration value
+ * @param $key the name of the configuration value
+ * @returns the value on success, otherwise null
+ *
+ * returns a read-only configuration values
+ *
+ * we cannot work with getters, because it is a static class
+ */
static public function conf($key) {
+ if(!self::$configured) {
+ self::init();
+ }
+
$availableProperties = array(
'ldapUserDisplayName',
+ 'ldapGroupDisplayName',
);
if(in_array($key, $availableProperties)) {
return self::$$key;
}
+
+ return null;
+ }
+
+ /**
+ * gives back the database table for the query
+ */
+ static private function getMapTable($isUser) {
+ if($isUser) {
+ return '*PREFIX*ldap_user_mapping';
+ } else {
+ return '*PREFIX*ldap_group_mapping';
+ }
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name of the group
+ * @param $name the ownCloud name in question
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name of the group
+ */
+ static public function groupname2dn($name) {
+ return self::ocname2dn($name, false);
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name of the user
+ * @param $name the ownCloud name in question
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name of the user
+ */
+ static public function username2dn($name) {
+ $dn = self::ocname2dn($name, true);
+ if($dn) {
+ return $dn;
+ } else {
+ //fallback: user is not mapped
+ $filter = self::combineFilterWithAnd(array(
+ self::$ldapUserFilter,
+ self::$ldapUserDisplayName . '=' . $name,
+ ));
+ $result = self::searchUsers($filter, 'dn');
+ if(isset($result[0]['dn'])) {
+ self::mapUser($result[0], $name);
+ return $result[0];
+ }
+ }
+
+ return false;
+ }
+
+ static private function ocname2dn($name, $isUser) {
+ $table = self::getMapTable($isUser);
+
+ $query = OC_DB::prepare('
+ SELECT ldap_dn
+ FROM '.$table.'
+ WHERE owncloud_name = ?
+ ');
+
+ $record = $query->execute(array($name))->fetchOne();
+ return $record;
+ if($name=='Coyotes') {
+ echo("adsfasdf ");
+ var_dump($record);
+ die();
+ }
+ if(isset($record['ldap_dn'])) {
+ return $record['ldap_dn'];
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief returns the internal ownCloud name for the given LDAP DN of the group
+ * @param $dn the dn of the group object
+ * @param $ldapname optional, the display name of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the group
+ */
+ static public function dn2groupname($dn, $ldapname = null) {
+ return self::dn2ocname($dn, $ldapname, false);
+ }
+
+ /**
+ * @brief returns the internal ownCloud name for the given LDAP DN of the user
+ * @param $dn the dn of the user object
+ * @param $ldapname optional, the display name of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the user
+ */
+ static public function dn2username($dn, $ldapname = null) {
+ return self::dn2ocname($dn, $ldapname, true);
+ }
+
+ static public function dn2ocname($dn, $ldapname = null, $isUser = true) {
+ $table = self::getMapTable($isUser);
+ if($isUser) {
+ $nameAttribute = self::conf('ldapUserDisplayName');
+ } else {
+ $nameAttribute = self::conf('ldapGroupDisplayName');
+ }
+
+ $query = OC_DB::prepare('
+ SELECT owncloud_name
+ FROM '.$table.'
+ WHERE ldap_dn = ?
+ ');
+
+ $component = $query->execute(array($dn))->fetchOne();
+ if($component) {
+ return $component;
+ }
+
+ if(is_null($ldapname)) {
+ $ldapname = self::readAttribute($dn, $nameAttribute);
+ $ldapname = $ldapname[0];
+ }
+
+ //a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot.
+ if(self::mapComponent($dn, $ldapname, $isUser)) {
+ return $ldapname;
+ }
+
+ //doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located.
+ $oc_name = self::alternateOwnCloudName($ldapname, $dn);
+ if(self::mapComponent($dn, $oc_name, $isUser)) {
+ return $oc_name;
+ }
+
+ //and this of course should never been thrown :)
+ throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+ }
+
+ /**
+ * @brief gives back the user names as they are used ownClod internally
+ * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... )
+ * @returns an array with the user names to use in ownCloud
+ *
+ * gives back the user names as they are used ownClod internally
+ */
+ static public function ownCloudUserNames($ldapUsers) {
+ return self::ldap2ownCloudNames($ldapUsers, true);
+ }
+
+ /**
+ * @brief gives back the group names as they are used ownClod internally
+ * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... )
+ * @returns an array with the group names to use in ownCloud
+ *
+ * gives back the group names as they are used ownClod internally
+ */
+ static public function ownCloudGroupNames($ldapGroups) {
+ return self::ldap2ownCloudNames($ldapGroups, false);
+ }
+
+ static private function ldap2ownCloudNames($ldapObjects, $isUsers) {
+ if($isUsers) {
+ $knownObjects = self::mappedUsers();
+ $nameAttribute = self::conf('ldapUserDisplayName');
+ } else {
+ $knownObjects = self::mappedGroups();
+ $nameAttribute = self::conf('ldapGroupDisplayName');
+ }
+ $ownCloudNames = array();
+
+ foreach($ldapObjects as $ldapObject) {
+ $key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']);
+
+ //everything is fine when we know the group
+ if($key) {
+ $ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
+ continue;
+ }
+
+ //a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict
+ if(self::mapComponent($ldapObject['dn'], $ldapObject[$nameAttribute], $isUsers)) {
+ $ownCloudNames[] = $ldapObject[$nameAttribute];
+ continue;
+ }
+
+ //doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
+ $oc_name = self::alternateOwnCloudName($ldapObject[$nameAttribute], $ldapObject['dn']);
+ if(self::mapComponent($ldapObject['dn'], $oc_name, $isUsers)) {
+ $ownCloudNames[] = $oc_name;
+ continue;
+ }
+
+ //and this of course should never been thrown :)
+ throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+ }
+ return $ownCloudNames;
+ }
+
+ /**
+ * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+ * @param $name the display name of the object
+ * @param $dn the dn of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+ */
+ static private function alternateOwnCloudName($name, $dn) {
+ $ufn = ldap_dn2ufn($dn);
+ return $name . ' (' . trim(substr_replace($ufn, '', 0, strpos($ufn, ','))) . ')';
+ }
+
+ /**
+ * @brief retrieves all known groups from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known groups from the mappings table
+ */
+ static private function mappedGroups() {
+ return self::mappedComponents(false);
+ }
+
+ /**
+ * @brief retrieves all known users from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known users from the mappings table
+ */
+ static private function mappedUsers() {
+ return self::mappedComponents(true);
+ }
+
+ static private function mappedComponents($isUsers) {
+ $table = self::getMapTable($isUsers);
+
+ $query = OC_DB::prepare('
+ SELECT ldap_dn, owncloud_name
+ FROM '. $table
+ );
+
+ return $query->execute()->fetchAll();
+ }
+
+ /**
+ * @brief inserts a new group into the mappings table
+ * @param $dn the record in question
+ * @param $ocname the name to use in ownCloud
+ * @returns true on success, false otherwise
+ *
+ * inserts a new group into the mappings table
+ */
+ static private function mapGroup($dn, $ocname) {
+ return self::mapComponent($dn, $ocname, false);
+ }
+
+ /**
+ * @brief inserts a new user into the mappings table
+ * @param $dn the record in question
+ * @param $ocname the name to use in ownCloud
+ * @returns true on success, false otherwise
+ *
+ * inserts a new user into the mappings table
+ */
+ static private function mapUser($dn, $ocname) {
+ return self::mapComponent($dn, $ocname, true);
+ }
+
+ /**
+ * @brief inserts a new user or group into the mappings table
+ * @param $dn the record in question
+ * @param $ocname the name to use in ownCloud
+ * @param $isUser is it a user or a group?
+ * @returns true on success, false otherwise
+ *
+ * inserts a new user or group into the mappings table
+ */
+ static private function mapComponent($dn, $ocname, $isUser = true) {
+ $table = self::getMapTable($isUser);
+
+ $insert = OC_DB::prepare('
+ INSERT IGNORE INTO '.$table.'
+ (ldap_dn, owncloud_name)
+ VALUES (?,?)
+ ');
+
+ $res = $insert->execute(array($dn, $ocname));
+
+ return !OC_DB::isError($res);
+ }
+
+ /**
+ * @brief reads a given attribute for an LDAP record identified by a DN
+ * @param $dn the record in question
+ * @param $attr the attribute that shall be retrieved
+ * @returns the values in an array on success, false otherwise
+ *
+ * Reads an attribute from an LDAP entry
+ */
+ static public function readAttribute($dn, $attr) {
+ $cr = self::getConnectionResource();
+// echo("<pre>");var_dump($dn);
+ $rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
+ if(!$rr) {
+ echo('<pre>###RA ');var_dump($dn);var_dump(debug_backtrace());die();
+ }
+ $er = ldap_first_entry($cr, $rr);
+ $result = ldap_get_attributes($cr, $er);
+
+// if($dn == 'cn=Coyotes,cn=groups,dc=blizzz-oc,dc=bzoc') die((var_dump($result)));
+ if($result[$attr]['count'] > 0){
+ $values = array();
+ for($i=0;$i<$result[$attr]['count'];$i++) {
+ $values[] = $result[$attr][$i];
+ }
+ return $values;
+ }
+ return false;
}
/**
@@ -100,15 +434,38 @@ class OC_LDAP {
* Executes an LDAP search
*/
static private function search($filter, $base, $attr = null) {
- $sr = ldap_search(self::getConnectionResource(), $base, $filter, array($attr));
+ if(!is_null($attr) && !is_array($attr)) {
+ $attr = array(strtolower($attr));
+ }
+ $sr = ldap_search(self::getConnectionResource(), $base, $filter, $attr);
$findings = ldap_get_entries(self::getConnectionResource(), $sr );
if(!is_null($attr)) {
$selection = array();
+ $multiarray = false;
+ if(count($attr) > 1) {
+ $multiarray = true;
+ $i = 0;
+ }
foreach($findings as $item) {
- if(isset($item[strtolower($attr)])) {
- $selection[] = $item[strtolower($attr)][0];
+ if($multiarray) {
+ foreach($attr as $key) {
+ if(isset($item[$key])) {
+ if($key != 'dn'){
+ $selection[$i][$key] = $item[$key][0];
+ } else {
+ $selection[$i][$key] = $item[$key];
+ }
+ }
+
+ }
+ $i++;
+ } else {
+ if(isset($item[$attr[0]])) {
+ $selection[] = $item[$attr[0]];
+ }
}
+
}
return $selection;
}
@@ -173,16 +530,18 @@ class OC_LDAP {
*/
static private function readConfiguration() {
if(!self::$configured) {
- self::$ldapHost = OC_Appconfig::getValue('user_ldap', 'ldap_host', '');
- self::$ldapPort = OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT);
- self::$ldapAgentName = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
- self::$ldapAgentPassword = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
- self::$ldapBase = OC_Appconfig::getValue('user_ldap', 'ldap_base', '');
- self::$ldapBaseUsers = OC_Appconfig::getValue('user_ldap', 'ldap_base_users',self::$ldapBase);
- self::$ldapBaseGroups = OC_Appconfig::getValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
- self::$ldapTLS = OC_Appconfig::getValue('user_ldap', 'ldap_tls',0);
- self::$ldapNoCase = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
- self::$ldapUserDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
+ self::$ldapHost = OC_Appconfig::getValue('user_ldap', 'ldap_host', '');
+ self::$ldapPort = OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT);
+ self::$ldapAgentName = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
+ self::$ldapAgentPassword = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
+ self::$ldapBase = OC_Appconfig::getValue('user_ldap', 'ldap_base', '');
+ self::$ldapBaseUsers = OC_Appconfig::getValue('user_ldap', 'ldap_base_users',self::$ldapBase);
+ self::$ldapBaseGroups = OC_Appconfig::getValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
+ self::$ldapTLS = OC_Appconfig::getValue('user_ldap', 'ldap_tls',0);
+ self::$ldapNoCase = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
+ self::$ldapUserDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
+ self::$ldapUserFilter = OC_Appconfig::getValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
+ self::$ldapGroupDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR);
if(
!empty(self::$ldapHost)
@@ -226,5 +585,23 @@ class OC_LDAP {
}
}
+ /**
+ * taken from http://www.php.net/manual/en/function.array-search.php#97645
+ * TODO: move somewhere, where its better placed since it is not LDAP specific. OC_Helper maybe?
+ */
+ static public function recursiveArraySearch($haystack, $needle, $index = null) {
+ $aIt = new RecursiveArrayIterator($haystack);
+ $it = new RecursiveIteratorIterator($aIt);
+
+ while($it->valid()) {
+ if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
+ return $aIt->key();
+ }
+
+ $it->next();
+ }
+
+ return false;
+ }
} \ No newline at end of file
diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php
index ad44fe95f9e..2226c74609d 100644
--- a/apps/user_ldap/settings.php
+++ b/apps/user_ldap/settings.php
@@ -20,7 +20,10 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
-$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'. 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr');
+$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_base_users', 'ldap_base_groups', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'. 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr');
+
+OC_Util::addScript('user_ldap', 'settings');
+OC_Util::addStyle('user_ldap', 'settings');
if ($_POST) {
foreach($params as $param){
@@ -45,10 +48,8 @@ foreach($params as $param){
$tmpl->assign($param, $value);
}
-// ldap_port has a default value
+// settings with default values
$tmpl->assign( 'ldap_port', OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT));
-
-// ldap_display_name has a default value
$tmpl->assign( 'ldap_display_name', OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME));
return $tmpl->fetchPage();
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index 828c72cba97..7e327bb0701 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -1,21 +1,30 @@
<form id="ldap" action="#" method="post">
- <fieldset class="personalblock">
- <legend><strong>LDAP</strong></legend>
- <p><label for="ldap_host"><?php echo $l->t('Host');?><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>"></label>
- <label for="ldap_port"><?php echo $l->t('Port');?></label><input type="text" id="ldap_port" name="ldap_port" value="<?php echo $_['ldap_port']; ?>" /></p>
+ <div id="ldapSettings" class="personalblock">
+ <ul>
+ <li><a href="#ldapSettings-1">LDAP Basic</a></li>
+ <li><a href="#ldapSettings-2">Advanced</a></li>
+ </ul>
+ <fieldset id="ldapSettings-1">
+ <p><label for="ldap_host"><?php echo $l->t('Host');?><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>"></label> <label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p>
<p><label for="ldap_dn"><?php echo $l->t('Name');?></label><input type="text" id="ldap_dn" name="ldap_dn" value="<?php echo $_['ldap_dn']; ?>" />
<label for="ldap_password"><?php echo $l->t('Password');?></label><input type="password" id="ldap_password" name="ldap_password" value="<?php echo $_['ldap_password']; ?>" />
<small><?php echo $l->t('Leave both empty for anonymous bind for search, then bind with users credentials.');?></small></p>
- <p><label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p>
<p><label for="ldap_login_filter"><?php echo $l->t('User Login Filter');?></label><input type="text" id="ldap_login_filter" name="ldap_login_filter" value="<?php echo $_['ldap_login_filter']; ?>" /><small><?php echo $l->t('use %%uid placeholder, e.g. uid=%%uid');?></small></p>
- <p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?> </p>
- <p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" />
- <small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p>
+ <p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?></small></p>
+ </fieldset>
+ <fieldset id="ldapSettings-2">
+ <p><label for="ldap_port"><?php echo $l->t('Port');?></label><input type="text" id="ldap_port" name="ldap_port" value="<?php echo $_['ldap_port']; ?>" /></p>
+ <p><label for="ldap_base_users"><?php echo $l->t('Base User Tree');?></label><input type="text" id="ldap_base_users" name="ldap_base_users" value="<?php echo $_['ldap_base_users']; ?>" /></p>
+ <p><label for="ldap_base_groups"><?php echo $l->t('Base Group Tree');?></label><input type="text" id="ldap_base_groups" name="ldap_base_groups" value="<?php echo $_['ldap_base_groups']; ?>" /></p>
<p><input type="checkbox" id="ldap_tls" name="ldap_tls" value="1"<?php if ($_['ldap_tls']) echo ' checked'; ?>><label for="ldap_tls"><?php echo $l->t('Use TLS');?></label></p>
<p><input type="checkbox" id="ldap_nocase" name="ldap_nocase" value="1"<?php if ($_['ldap_nocase']) echo ' checked'; ?>><label for="ldap_nocase"><?php echo $l->t('Case insensitve LDAP server (Windows)');?></label></p>
+ <p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" />
+ <small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p>
<p><label for="ldap_quota_attr">Quota Attribute</label><input type="text" id="ldap_quota_attr" name="ldap_quota_attr" value="<?php echo $_['ldap_quota_attr']; ?>" />
- <label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php echo $_['ldap_quota_def']; ?>" />bytes</p>
- <p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
- <input type="submit" value="Save" />
+ <label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php echo $_['ldap_quota_def']; ?>" />bytes</p>
+ <p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
</fieldset>
+ <input type="submit" value="Save" />
+ </div>
+
</form>
diff --git a/core/img/actions/history.png b/core/img/actions/history.png
new file mode 100644
index 00000000000..b1e743651f8
--- /dev/null
+++ b/core/img/actions/history.png
Binary files differ
diff --git a/core/img/actions/history.svg b/core/img/actions/history.svg
new file mode 100644
index 00000000000..9c2838d565b
--- /dev/null
+++ b/core/img/actions/history.svg
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="17"
+ height="17"
+ id="svg3972"
+ version="1.1"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="backup.svg"
+ inkscape:export-filename="/home/ronny/persoenliches/Programme/JBackpack/jbackpack/src/ch/fhnw/jbackpack/icons/16x16/icon.png"
+ inkscape:export-xdpi="2.8099999"
+ inkscape:export-ydpi="2.8099999">
+ <defs
+ id="defs3974">
+ <linearGradient
+ id="linearGradient3820">
+ <stop
+ style="stop-color:#7399ab;stop-opacity:1;"
+ offset="0"
+ id="stop3822" />
+ <stop
+ style="stop-color:#fffeff;stop-opacity:1;"
+ offset="1"
+ id="stop3824" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5144">
+ <stop
+ style="stop-color:#ab7392;stop-opacity:1;"
+ offset="0"
+ id="stop5146" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.02909091"
+ offset="1"
+ id="stop5148" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5130">
+ <stop
+ id="stop5140"
+ offset="0"
+ style="stop-color:#a08f82;stop-opacity:0.74901961;" />
+ <stop
+ id="stop5138"
+ offset="0.5"
+ style="stop-color:#ab7392;stop-opacity:0.49803922;" />
+ <stop
+ style="stop-color:#ab7392;stop-opacity:0;"
+ offset="1"
+ id="stop5134" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4519"
+ osb:paint="gradient">
+ <stop
+ style="stop-color:#5d879d;stop-opacity:1;"
+ offset="0"
+ id="stop4521" />
+ <stop
+ style="stop-color:#5d879d;stop-opacity:0;"
+ offset="1"
+ id="stop4523" />
+ </linearGradient>
+ <filter
+ id="filter4697"
+ inkscape:label="Drop shadow"
+ width="1.5"
+ height="1.5"
+ x="-0.25"
+ y="-0.25"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ id="feGaussianBlur4699"
+ in="SourceAlpha"
+ stdDeviation="2"
+ result="blur" />
+ <feColorMatrix
+ id="feColorMatrix4701"
+ result="bluralpha"
+ type="matrix"
+ values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0 " />
+ <feOffset
+ id="feOffset4703"
+ in="bluralpha"
+ dx="4"
+ dy="4"
+ result="offsetBlur" />
+ <feMerge
+ id="feMerge4705">
+ <feMergeNode
+ id="feMergeNode4707"
+ in="offsetBlur" />
+ <feMergeNode
+ id="feMergeNode4709"
+ in="SourceGraphic" />
+ </feMerge>
+ </filter>
+ <filter
+ id="filter5086"
+ inkscape:label="Drop shadow"
+ width="1.5"
+ height="1.5"
+ x="-0.25"
+ y="-0.25"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ id="feGaussianBlur5088"
+ in="SourceAlpha"
+ stdDeviation="5"
+ result="blur" />
+ <feColorMatrix
+ id="feColorMatrix5090"
+ result="bluralpha"
+ type="matrix"
+ values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.5 0 " />
+ <feOffset
+ id="feOffset5092"
+ in="bluralpha"
+ dx="10"
+ dy="10"
+ result="offsetBlur" />
+ <feMerge
+ id="feMerge5094">
+ <feMergeNode
+ id="feMergeNode5096"
+ in="offsetBlur" />
+ <feMergeNode
+ id="feMergeNode5098"
+ in="SourceGraphic" />
+ </feMerge>
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5130"
+ id="linearGradient5136"
+ x1="119.76609"
+ y1="431.36642"
+ x2="631.76611"
+ y2="431.36642"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5144"
+ id="radialGradient5150"
+ cx="294.02567"
+ cy="300.53604"
+ fx="294.02567"
+ fy="300.53604"
+ r="183.84033"
+ gradientTransform="matrix(0.66691196,0.43225768,-0.44145763,0.68110633,230.61036,-24.143353)"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter4381"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="2.5"
+ id="feGaussianBlur4383" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3820"
+ id="linearGradient3575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.06875313,0,0,0.06875313,2.829762,444.82336)"
+ x1="339.43503"
+ y1="370.08636"
+ x2="66.978798"
+ y2="135.09288" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254834"
+ inkscape:cx="12.081283"
+ inkscape:cy="8.5032287"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1033"
+ inkscape:window-x="-3"
+ inkscape:window-y="-3"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4447"
+ empspacing="5"
+ visible="true"
+ enabled="true"
+ snapvisiblegridlinesonly="true" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata3977">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(93.42207,-466.65551)">
+ <path
+ style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ d="m -83.896989,468.73997 c -3.950245,0 -6.534942,3.44694 -6.364259,6.72133 l -2.160822,0 3.904021,3.91738 4.081269,-3.87222 -2.148938,0 c -0.237051,-1.70092 1.163456,-3.1145 2.688727,-3.0921 1.596496,0.0235 2.800571,1.22922 2.800571,2.73336 0.08961,1.59378 -1.629405,3.4279 -3.965431,2.53172 -8.3e-5,1.22806 0.0027,2.54389 0,3.76397 4.189434,0.82896 7.639781,-2.50953 7.639781,-6.25087 0,-3.56212 -2.9188,-6.45252 -6.474921,-6.45252 z"
+ id="path4438"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccscccccc"
+ inkscape:export-filename="/home/samtuke/owncloud/git/owncloud/core/img/actions/history.png"
+ inkscape:export-xdpi="89.929733"
+ inkscape:export-ydpi="89.929733" />
+ </g>
+</svg>
diff --git a/files/js/jquery.fileupload.js b/files/js/jquery.fileupload.js
new file mode 100644
index 00000000000..a89e9dc2c44
--- /dev/null
+++ b/files/js/jquery.fileupload.js
@@ -0,0 +1,866 @@
+/*
+ * jQuery File Upload Plugin 5.9
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/*jslint nomen: true, unparam: true, regexp: true */
+/*global define, window, document, Blob, FormData, location */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ 'jquery.ui.widget'
+ ], factory);
+ } else {
+ // Browser globals:
+ factory(window.jQuery);
+ }
+}(function ($) {
+ 'use strict';
+
+ // The FileReader API is not actually used, but works as feature detection,
+ // as e.g. Safari supports XHR file uploads via the FormData API,
+ // but not non-multipart XHR file uploads:
+ $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
+ $.support.xhrFormDataFileUpload = !!window.FormData;
+
+ // The fileupload widget listens for change events on file input fields defined
+ // via fileInput setting and paste or drop events of the given dropZone.
+ // In addition to the default jQuery Widget methods, the fileupload widget
+ // exposes the "add" and "send" methods, to add or directly send files using
+ // the fileupload API.
+ // By default, files added via file input selection, paste, drag & drop or
+ // "add" method are uploaded immediately, but it is possible to override
+ // the "add" callback option to queue file uploads.
+ $.widget('blueimp.fileupload', {
+
+ options: {
+ // The namespace used for event handler binding on the dropZone and
+ // fileInput collections.
+ // If not set, the name of the widget ("fileupload") is used.
+ namespace: undefined,
+ // The drop target collection, by the default the complete document.
+ // Set to null or an empty collection to disable drag & drop support:
+ dropZone: $(document),
+ // The file input field collection, that is listened for change events.
+ // If undefined, it is set to the file input fields inside
+ // of the widget element on plugin initialization.
+ // Set to null or an empty collection to disable the change listener.
+ fileInput: undefined,
+ // By default, the file input field is replaced with a clone after
+ // each input field change event. This is required for iframe transport
+ // queues and allows change events to be fired for the same file
+ // selection, but can be disabled by setting the following option to false:
+ replaceFileInput: true,
+ // The parameter name for the file form data (the request argument name).
+ // If undefined or empty, the name property of the file input field is
+ // used, or "files[]" if the file input name property is also empty:
+ paramName: undefined,
+ // By default, each file of a selection is uploaded using an individual
+ // request for XHR type uploads. Set to false to upload file
+ // selections in one request each:
+ singleFileUploads: true,
+ // To limit the number of files uploaded with one XHR request,
+ // set the following option to an integer greater than 0:
+ limitMultiFileUploads: undefined,
+ // Set the following option to true to issue all file upload requests
+ // in a sequential order:
+ sequentialUploads: false,
+ // To limit the number of concurrent uploads,
+ // set the following option to an integer greater than 0:
+ limitConcurrentUploads: undefined,
+ // Set the following option to true to force iframe transport uploads:
+ forceIframeTransport: false,
+ // Set the following option to the location of a redirect url on the
+ // origin server, for cross-domain iframe transport uploads:
+ redirect: undefined,
+ // The parameter name for the redirect url, sent as part of the form
+ // data and set to 'redirect' if this option is empty:
+ redirectParamName: undefined,
+ // Set the following option to the location of a postMessage window,
+ // to enable postMessage transport uploads:
+ postMessage: undefined,
+ // By default, XHR file uploads are sent as multipart/form-data.
+ // The iframe transport is always using multipart/form-data.
+ // Set to false to enable non-multipart XHR uploads:
+ multipart: true,
+ // To upload large files in smaller chunks, set the following option
+ // to a preferred maximum chunk size. If set to 0, null or undefined,
+ // or the browser does not support the required Blob API, files will
+ // be uploaded as a whole.
+ maxChunkSize: undefined,
+ // When a non-multipart upload or a chunked multipart upload has been
+ // aborted, this option can be used to resume the upload by setting
+ // it to the size of the already uploaded bytes. This option is most
+ // useful when modifying the options object inside of the "add" or
+ // "send" callbacks, as the options are cloned for each file upload.
+ uploadedBytes: undefined,
+ // By default, failed (abort or error) file uploads are removed from the
+ // global progress calculation. Set the following option to false to
+ // prevent recalculating the global progress data:
+ recalculateProgress: true,
+
+ // Additional form data to be sent along with the file uploads can be set
+ // using this option, which accepts an array of objects with name and
+ // value properties, a function returning such an array, a FormData
+ // object (for XHR file uploads), or a simple object.
+ // The form of the first fileInput is given as parameter to the function:
+ formData: function (form) {
+ return form.serializeArray();
+ },
+
+ // The add callback is invoked as soon as files are added to the fileupload
+ // widget (via file input selection, drag & drop, paste or add API call).
+ // If the singleFileUploads option is enabled, this callback will be
+ // called once for each file in the selection for XHR file uplaods, else
+ // once for each file selection.
+ // The upload starts when the submit method is invoked on the data parameter.
+ // The data object contains a files property holding the added files
+ // and allows to override plugin options as well as define ajax settings.
+ // Listeners for this callback can also be bound the following way:
+ // .bind('fileuploadadd', func);
+ // data.submit() returns a Promise object and allows to attach additional
+ // handlers using jQuery's Deferred callbacks:
+ // data.submit().done(func).fail(func).always(func);
+ add: function (e, data) {
+ data.submit();
+ },
+
+ // Other callbacks:
+ // Callback for the submit event of each file upload:
+ // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
+ // Callback for the start of each file upload request:
+ // send: function (e, data) {}, // .bind('fileuploadsend', func);
+ // Callback for successful uploads:
+ // done: function (e, data) {}, // .bind('fileuploaddone', func);
+ // Callback for failed (abort or error) uploads:
+ // fail: function (e, data) {}, // .bind('fileuploadfail', func);
+ // Callback for completed (success, abort or error) requests:
+ // always: function (e, data) {}, // .bind('fileuploadalways', func);
+ // Callback for upload progress events:
+ // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
+ // Callback for global upload progress events:
+ // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
+ // Callback for uploads start, equivalent to the global ajaxStart event:
+ // start: function (e) {}, // .bind('fileuploadstart', func);
+ // Callback for uploads stop, equivalent to the global ajaxStop event:
+ // stop: function (e) {}, // .bind('fileuploadstop', func);
+ // Callback for change events of the fileInput collection:
+ // change: function (e, data) {}, // .bind('fileuploadchange', func);
+ // Callback for paste events to the dropZone collection:
+ // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
+ // Callback for drop events of the dropZone collection:
+ // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
+ // Callback for dragover events of the dropZone collection:
+ // dragover: function (e) {}, // .bind('fileuploaddragover', func);
+
+ // The plugin options are used as settings object for the ajax calls.
+ // The following are jQuery ajax settings required for the file uploads:
+ processData: false,
+ contentType: false,
+ cache: false
+ },
+
+ // A list of options that require a refresh after assigning a new value:
+ _refreshOptionsList: [
+ 'namespace',
+ 'dropZone',
+ 'fileInput',
+ 'multipart',
+ 'forceIframeTransport'
+ ],
+
+ _isXHRUpload: function (options) {
+ return !options.forceIframeTransport &&
+ ((!options.multipart && $.support.xhrFileUpload) ||
+ $.support.xhrFormDataFileUpload);
+ },
+
+ _getFormData: function (options) {
+ var formData;
+ if (typeof options.formData === 'function') {
+ return options.formData(options.form);
+ } else if ($.isArray(options.formData)) {
+ return options.formData;
+ } else if (options.formData) {
+ formData = [];
+ $.each(options.formData, function (name, value) {
+ formData.push({name: name, value: value});
+ });
+ return formData;
+ }
+ return [];
+ },
+
+ _getTotal: function (files) {
+ var total = 0;
+ $.each(files, function (index, file) {
+ total += file.size || 1;
+ });
+ return total;
+ },
+
+ _onProgress: function (e, data) {
+ if (e.lengthComputable) {
+ var total = data.total || this._getTotal(data.files),
+ loaded = parseInt(
+ e.loaded / e.total * (data.chunkSize || total),
+ 10
+ ) + (data.uploadedBytes || 0);
+ this._loaded += loaded - (data.loaded || data.uploadedBytes || 0);
+ data.lengthComputable = true;
+ data.loaded = loaded;
+ data.total = total;
+ // Trigger a custom progress event with a total data property set
+ // to the file size(s) of the current upload and a loaded data
+ // property calculated accordingly:
+ this._trigger('progress', e, data);
+ // Trigger a global progress event for all current file uploads,
+ // including ajax calls queued for sequential file uploads:
+ this._trigger('progressall', e, {
+ lengthComputable: true,
+ loaded: this._loaded,
+ total: this._total
+ });
+ }
+ },
+
+ _initProgressListener: function (options) {
+ var that = this,
+ xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
+ // Accesss to the native XHR object is required to add event listeners
+ // for the upload progress event:
+ if (xhr.upload) {
+ $(xhr.upload).bind('progress', function (e) {
+ var oe = e.originalEvent;
+ // Make sure the progress event properties get copied over:
+ e.lengthComputable = oe.lengthComputable;
+ e.loaded = oe.loaded;
+ e.total = oe.total;
+ that._onProgress(e, options);
+ });
+ options.xhr = function () {
+ return xhr;
+ };
+ }
+ },
+
+ _initXHRData: function (options) {
+ var formData,
+ file = options.files[0],
+ // Ignore non-multipart setting if not supported:
+ multipart = options.multipart || !$.support.xhrFileUpload;
+ if (!multipart || options.blob) {
+ // For non-multipart uploads and chunked uploads,
+ // file meta data is not part of the request body,
+ // so we transmit this data as part of the HTTP headers.
+ // For cross domain requests, these headers must be allowed
+ // via Access-Control-Allow-Headers or removed using
+ // the beforeSend callback:
+ options.headers = $.extend(options.headers, {
+ 'X-File-Name': file.name,
+ 'X-File-Type': file.type,
+ 'X-File-Size': file.size
+ });
+ if (!options.blob) {
+ // Non-chunked non-multipart upload:
+ options.contentType = file.type;
+ options.data = file;
+ } else if (!multipart) {
+ // Chunked non-multipart upload:
+ options.contentType = 'application/octet-stream';
+ options.data = options.blob;
+ }
+ }
+ if (multipart && $.support.xhrFormDataFileUpload) {
+ if (options.postMessage) {
+ // window.postMessage does not allow sending FormData
+ // objects, so we just add the File/Blob objects to
+ // the formData array and let the postMessage window
+ // create the FormData object out of this array:
+ formData = this._getFormData(options);
+ if (options.blob) {
+ formData.push({
+ name: options.paramName,
+ value: options.blob
+ });
+ } else {
+ $.each(options.files, function (index, file) {
+ formData.push({
+ name: options.paramName,
+ value: file
+ });
+ });
+ }
+ } else {
+ if (options.formData instanceof FormData) {
+ formData = options.formData;
+ } else {
+ formData = new FormData();
+ $.each(this._getFormData(options), function (index, field) {
+ formData.append(field.name, field.value);
+ });
+ }
+ if (options.blob) {
+ formData.append(options.paramName, options.blob, file.name);
+ } else {
+ $.each(options.files, function (index, file) {
+ // File objects are also Blob instances.
+ // This check allows the tests to run with
+ // dummy objects:
+ if (file instanceof Blob) {
+ formData.append(options.paramName, file, file.name);
+ }
+ });
+ }
+ }
+ options.data = formData;
+ }
+ // Blob reference is not needed anymore, free memory:
+ options.blob = null;
+ },
+
+ _initIframeSettings: function (options) {
+ // Setting the dataType to iframe enables the iframe transport:
+ options.dataType = 'iframe ' + (options.dataType || '');
+ // The iframe transport accepts a serialized array as form data:
+ options.formData = this._getFormData(options);
+ // Add redirect url to form data on cross-domain uploads:
+ if (options.redirect && $('<a></a>').prop('href', options.url)
+ .prop('host') !== location.host) {
+ options.formData.push({
+ name: options.redirectParamName || 'redirect',
+ value: options.redirect
+ });
+ }
+ },
+
+ _initDataSettings: function (options) {
+ if (this._isXHRUpload(options)) {
+ if (!this._chunkedUpload(options, true)) {
+ if (!options.data) {
+ this._initXHRData(options);
+ }
+ this._initProgressListener(options);
+ }
+ if (options.postMessage) {
+ // Setting the dataType to postmessage enables the
+ // postMessage transport:
+ options.dataType = 'postmessage ' + (options.dataType || '');
+ }
+ } else {
+ this._initIframeSettings(options, 'iframe');
+ }
+ },
+
+ _initFormSettings: function (options) {
+ // Retrieve missing options from the input field and the
+ // associated form, if available:
+ if (!options.form || !options.form.length) {
+ options.form = $(options.fileInput.prop('form'));
+ }
+ if (!options.paramName) {
+ options.paramName = options.fileInput.prop('name') ||
+ 'files[]';
+ }
+ if (!options.url) {
+ options.url = options.form.prop('action') || location.href;
+ }
+ // The HTTP request method must be "POST" or "PUT":
+ options.type = (options.type || options.form.prop('method') || '')
+ .toUpperCase();
+ if (options.type !== 'POST' && options.type !== 'PUT') {
+ options.type = 'POST';
+ }
+ },
+
+ _getAJAXSettings: function (data) {
+ var options = $.extend({}, this.options, data);
+ this._initFormSettings(options);
+ this._initDataSettings(options);
+ return options;
+ },
+
+ // Maps jqXHR callbacks to the equivalent
+ // methods of the given Promise object:
+ _enhancePromise: function (promise) {
+ promise.success = promise.done;
+ promise.error = promise.fail;
+ promise.complete = promise.always;
+ return promise;
+ },
+
+ // Creates and returns a Promise object enhanced with
+ // the jqXHR methods abort, success, error and complete:
+ _getXHRPromise: function (resolveOrReject, context, args) {
+ var dfd = $.Deferred(),
+ promise = dfd.promise();
+ context = context || this.options.context || promise;
+ if (resolveOrReject === true) {
+ dfd.resolveWith(context, args);
+ } else if (resolveOrReject === false) {
+ dfd.rejectWith(context, args);
+ }
+ promise.abort = dfd.promise;
+ return this._enhancePromise(promise);
+ },
+
+ // Uploads a file in multiple, sequential requests
+ // by splitting the file up in multiple blob chunks.
+ // If the second parameter is true, only tests if the file
+ // should be uploaded in chunks, but does not invoke any
+ // upload requests:
+ _chunkedUpload: function (options, testOnly) {
+ var that = this,
+ file = options.files[0],
+ fs = file.size,
+ ub = options.uploadedBytes = options.uploadedBytes || 0,
+ mcs = options.maxChunkSize || fs,
+ // Use the Blob methods with the slice implementation
+ // according to the W3C Blob API specification:
+ slice = file.webkitSlice || file.mozSlice || file.slice,
+ upload,
+ n,
+ jqXHR,
+ pipe;
+ if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
+ options.data) {
+ return false;
+ }
+ if (testOnly) {
+ return true;
+ }
+ if (ub >= fs) {
+ file.error = 'uploadedBytes';
+ return this._getXHRPromise(
+ false,
+ options.context,
+ [null, 'error', file.error]
+ );
+ }
+ // n is the number of blobs to upload,
+ // calculated via filesize, uploaded bytes and max chunk size:
+ n = Math.ceil((fs - ub) / mcs);
+ // The chunk upload method accepting the chunk number as parameter:
+ upload = function (i) {
+ if (!i) {
+ return that._getXHRPromise(true, options.context);
+ }
+ // Upload the blobs in sequential order:
+ return upload(i -= 1).pipe(function () {
+ // Clone the options object for each chunk upload:
+ var o = $.extend({}, options);
+ o.blob = slice.call(
+ file,
+ ub + i * mcs,
+ ub + (i + 1) * mcs
+ );
+ // Store the current chunk size, as the blob itself
+ // will be dereferenced after data processing:
+ o.chunkSize = o.blob.size;
+ // Process the upload data (the blob and potential form data):
+ that._initXHRData(o);
+ // Add progress listeners for this chunk upload:
+ that._initProgressListener(o);
+ jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context))
+ .done(function () {
+ // Create a progress event if upload is done and
+ // no progress event has been invoked for this chunk:
+ if (!o.loaded) {
+ that._onProgress($.Event('progress', {
+ lengthComputable: true,
+ loaded: o.chunkSize,
+ total: o.chunkSize
+ }), o);
+ }
+ options.uploadedBytes = o.uploadedBytes +=
+ o.chunkSize;
+ });
+ return jqXHR;
+ });
+ };
+ // Return the piped Promise object, enhanced with an abort method,
+ // which is delegated to the jqXHR object of the current upload,
+ // and jqXHR callbacks mapped to the equivalent Promise methods:
+ pipe = upload(n);
+ pipe.abort = function () {
+ return jqXHR.abort();
+ };
+ return this._enhancePromise(pipe);
+ },
+
+ _beforeSend: function (e, data) {
+ if (this._active === 0) {
+ // the start callback is triggered when an upload starts
+ // and no other uploads are currently running,
+ // equivalent to the global ajaxStart event:
+ this._trigger('start');
+ }
+ this._active += 1;
+ // Initialize the global progress values:
+ this._loaded += data.uploadedBytes || 0;
+ this._total += this._getTotal(data.files);
+ },
+
+ _onDone: function (result, textStatus, jqXHR, options) {
+ if (!this._isXHRUpload(options)) {
+ // Create a progress event for each iframe load:
+ this._onProgress($.Event('progress', {
+ lengthComputable: true,
+ loaded: 1,
+ total: 1
+ }), options);
+ }
+ options.result = result;
+ options.textStatus = textStatus;
+ options.jqXHR = jqXHR;
+ this._trigger('done', null, options);
+ },
+
+ _onFail: function (jqXHR, textStatus, errorThrown, options) {
+ options.jqXHR = jqXHR;
+ options.textStatus = textStatus;
+ options.errorThrown = errorThrown;
+ this._trigger('fail', null, options);
+ if (options.recalculateProgress) {
+ // Remove the failed (error or abort) file upload from
+ // the global progress calculation:
+ this._loaded -= options.loaded || options.uploadedBytes || 0;
+ this._total -= options.total || this._getTotal(options.files);
+ }
+ },
+
+ _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
+ this._active -= 1;
+ options.textStatus = textStatus;
+ if (jqXHRorError && jqXHRorError.always) {
+ options.jqXHR = jqXHRorError;
+ options.result = jqXHRorResult;
+ } else {
+ options.jqXHR = jqXHRorResult;
+ options.errorThrown = jqXHRorError;
+ }
+ this._trigger('always', null, options);
+ if (this._active === 0) {
+ // The stop callback is triggered when all uploads have
+ // been completed, equivalent to the global ajaxStop event:
+ this._trigger('stop');
+ // Reset the global progress values:
+ this._loaded = this._total = 0;
+ }
+ },
+
+ _onSend: function (e, data) {
+ var that = this,
+ jqXHR,
+ slot,
+ pipe,
+ options = that._getAJAXSettings(data),
+ send = function (resolve, args) {
+ that._sending += 1;
+ jqXHR = jqXHR || (
+ (resolve !== false &&
+ that._trigger('send', e, options) !== false &&
+ (that._chunkedUpload(options) || $.ajax(options))) ||
+ that._getXHRPromise(false, options.context, args)
+ ).done(function (result, textStatus, jqXHR) {
+ that._onDone(result, textStatus, jqXHR, options);
+ }).fail(function (jqXHR, textStatus, errorThrown) {
+ that._onFail(jqXHR, textStatus, errorThrown, options);
+ }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
+ that._sending -= 1;
+ that._onAlways(
+ jqXHRorResult,
+ textStatus,
+ jqXHRorError,
+ options
+ );
+ if (options.limitConcurrentUploads &&
+ options.limitConcurrentUploads > that._sending) {
+ // Start the next queued upload,
+ // that has not been aborted:
+ var nextSlot = that._slots.shift();
+ while (nextSlot) {
+ if (!nextSlot.isRejected()) {
+ nextSlot.resolve();
+ break;
+ }
+ nextSlot = that._slots.shift();
+ }
+ }
+ });
+ return jqXHR;
+ };
+ this._beforeSend(e, options);
+ if (this.options.sequentialUploads ||
+ (this.options.limitConcurrentUploads &&
+ this.options.limitConcurrentUploads <= this._sending)) {
+ if (this.options.limitConcurrentUploads > 1) {
+ slot = $.Deferred();
+ this._slots.push(slot);
+ pipe = slot.pipe(send);
+ } else {
+ pipe = (this._sequence = this._sequence.pipe(send, send));
+ }
+ // Return the piped Promise object, enhanced with an abort method,
+ // which is delegated to the jqXHR object of the current upload,
+ // and jqXHR callbacks mapped to the equivalent Promise methods:
+ pipe.abort = function () {
+ var args = [undefined, 'abort', 'abort'];
+ if (!jqXHR) {
+ if (slot) {
+ slot.rejectWith(args);
+ }
+ return send(false, args);
+ }
+ return jqXHR.abort();
+ };
+ return this._enhancePromise(pipe);
+ }
+ return send();
+ },
+
+ _onAdd: function (e, data) {
+ var that = this,
+ result = true,
+ options = $.extend({}, this.options, data),
+ limit = options.limitMultiFileUploads,
+ fileSet,
+ i;
+ if (!(options.singleFileUploads || limit) ||
+ !this._isXHRUpload(options)) {
+ fileSet = [data.files];
+ } else if (!options.singleFileUploads && limit) {
+ fileSet = [];
+ for (i = 0; i < data.files.length; i += limit) {
+ fileSet.push(data.files.slice(i, i + limit));
+ }
+ }
+ data.originalFiles = data.files;
+ $.each(fileSet || data.files, function (index, element) {
+ var files = fileSet ? element : [element],
+ newData = $.extend({}, data, {files: files});
+ newData.submit = function () {
+ newData.jqXHR = this.jqXHR =
+ (that._trigger('submit', e, this) !== false) &&
+ that._onSend(e, this);
+ return this.jqXHR;
+ };
+ return (result = that._trigger('add', e, newData));
+ });
+ return result;
+ },
+
+ // File Normalization for Gecko 1.9.1 (Firefox 3.5) support:
+ _normalizeFile: function (index, file) {
+ if (file.name === undefined && file.size === undefined) {
+ file.name = file.fileName;
+ file.size = file.fileSize;
+ }
+ },
+
+ _replaceFileInput: function (input) {
+ var inputClone = input.clone(true);
+ $('<form></form>').append(inputClone)[0].reset();
+ // Detaching allows to insert the fileInput on another form
+ // without loosing the file input value:
+ input.after(inputClone).detach();
+ // Avoid memory leaks with the detached file input:
+ $.cleanData(input.unbind('remove'));
+ // Replace the original file input element in the fileInput
+ // collection with the clone, which has been copied including
+ // event handlers:
+ this.options.fileInput = this.options.fileInput.map(function (i, el) {
+ if (el === input[0]) {
+ return inputClone[0];
+ }
+ return el;
+ });
+ // If the widget has been initialized on the file input itself,
+ // override this.element with the file input clone:
+ if (input[0] === this.element[0]) {
+ this.element = inputClone;
+ }
+ },
+
+ _onChange: function (e) {
+ var that = e.data.fileupload,
+ data = {
+ files: $.each($.makeArray(e.target.files), that._normalizeFile),
+ fileInput: $(e.target),
+ form: $(e.target.form)
+ };
+ if (!data.files.length) {
+ // If the files property is not available, the browser does not
+ // support the File API and we add a pseudo File object with
+ // the input value as name with path information removed:
+ data.files = [{name: e.target.value.replace(/^.*\\/, '')}];
+ }
+ if (that.options.replaceFileInput) {
+ that._replaceFileInput(data.fileInput);
+ }
+ if (that._trigger('change', e, data) === false ||
+ that._onAdd(e, data) === false) {
+ return false;
+ }
+ },
+
+ _onPaste: function (e) {
+ var that = e.data.fileupload,
+ cbd = e.originalEvent.clipboardData,
+ items = (cbd && cbd.items) || [],
+ data = {files: []};
+ $.each(items, function (index, item) {
+ var file = item.getAsFile && item.getAsFile();
+ if (file) {
+ data.files.push(file);
+ }
+ });
+ if (that._trigger('paste', e, data) === false ||
+ that._onAdd(e, data) === false) {
+ return false;
+ }
+ },
+
+ _onDrop: function (e) {
+ var that = e.data.fileupload,
+ dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
+ data = {
+ files: $.each(
+ $.makeArray(dataTransfer && dataTransfer.files),
+ that._normalizeFile
+ )
+ };
+ if (that._trigger('drop', e, data) === false ||
+ that._onAdd(e, data) === false) {
+ return false;
+ }
+ e.preventDefault();
+ },
+
+ _onDragOver: function (e) {
+ var that = e.data.fileupload,
+ dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
+ if (that._trigger('dragover', e) === false) {
+ return false;
+ }
+ if (dataTransfer) {
+ dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
+ }
+ e.preventDefault();
+ },
+
+ _initEventHandlers: function () {
+ var ns = this.options.namespace;
+ if (this._isXHRUpload(this.options)) {
+ this.options.dropZone
+ .bind('dragover.' + ns, {fileupload: this}, this._onDragOver)
+ .bind('drop.' + ns, {fileupload: this}, this._onDrop)
+ .bind('paste.' + ns, {fileupload: this}, this._onPaste);
+ }
+ this.options.fileInput
+ .bind('change.' + ns, {fileupload: this}, this._onChange);
+ },
+
+ _destroyEventHandlers: function () {
+ var ns = this.options.namespace;
+ this.options.dropZone
+ .unbind('dragover.' + ns, this._onDragOver)
+ .unbind('drop.' + ns, this._onDrop)
+ .unbind('paste.' + ns, this._onPaste);
+ this.options.fileInput
+ .unbind('change.' + ns, this._onChange);
+ },
+
+ _setOption: function (key, value) {
+ var refresh = $.inArray(key, this._refreshOptionsList) !== -1;
+ if (refresh) {
+ this._destroyEventHandlers();
+ }
+ $.Widget.prototype._setOption.call(this, key, value);
+ if (refresh) {
+ this._initSpecialOptions();
+ this._initEventHandlers();
+ }
+ },
+
+ _initSpecialOptions: function () {
+ var options = this.options;
+ if (options.fileInput === undefined) {
+ options.fileInput = this.element.is('input:file') ?
+ this.element : this.element.find('input:file');
+ } else if (!(options.fileInput instanceof $)) {
+ options.fileInput = $(options.fileInput);
+ }
+ if (!(options.dropZone instanceof $)) {
+ options.dropZone = $(options.dropZone);
+ }
+ },
+
+ _create: function () {
+ var options = this.options,
+ dataOpts = $.extend({}, this.element.data());
+ dataOpts[this.widgetName] = undefined;
+ $.extend(options, dataOpts);
+ options.namespace = options.namespace || this.widgetName;
+ this._initSpecialOptions();
+ this._slots = [];
+ this._sequence = this._getXHRPromise(true);
+ this._sending = this._active = this._loaded = this._total = 0;
+ this._initEventHandlers();
+ },
+
+ destroy: function () {
+ this._destroyEventHandlers();
+ $.Widget.prototype.destroy.call(this);
+ },
+
+ enable: function () {
+ $.Widget.prototype.enable.call(this);
+ this._initEventHandlers();
+ },
+
+ disable: function () {
+ this._destroyEventHandlers();
+ $.Widget.prototype.disable.call(this);
+ },
+
+ // This method is exposed to the widget API and allows adding files
+ // using the fileupload API. The data parameter accepts an object which
+ // must have a files property and can contain additional options:
+ // .fileupload('add', {files: filesList});
+ add: function (data) {
+ if (!data || this.options.disabled) {
+ return;
+ }
+ data.files = $.each($.makeArray(data.files), this._normalizeFile);
+ this._onAdd(null, data);
+ },
+
+ // This method is exposed to the widget API and allows sending files
+ // using the fileupload API. The data parameter accepts an object which
+ // must have a files property and can contain additional options:
+ // .fileupload('send', {files: filesList});
+ // The method returns a Promise object for the file upload call.
+ send: function (data) {
+ if (data && !this.options.disabled) {
+ data.files = $.each($.makeArray(data.files), this._normalizeFile);
+ if (data.files.length) {
+ return this._onSend(null, data);
+ }
+ }
+ return this._getXHRPromise(false, data && data.context);
+ }
+
+ });
+
+}));
diff --git a/files/js/jquery.iframe-transport.js b/files/js/jquery.iframe-transport.js
new file mode 100644
index 00000000000..d85c0c11297
--- /dev/null
+++ b/files/js/jquery.iframe-transport.js
@@ -0,0 +1,165 @@
+/*
+ * jQuery Iframe Transport Plugin 1.3
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2011, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/*jslint unparam: true, nomen: true */
+/*global define, window, document */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define(['jquery'], factory);
+ } else {
+ // Browser globals:
+ factory(window.jQuery);
+ }
+}(function ($) {
+ 'use strict';
+
+ // Helper variable to create unique names for the transport iframes:
+ var counter = 0;
+
+ // The iframe transport accepts three additional options:
+ // options.fileInput: a jQuery collection of file input fields
+ // options.paramName: the parameter name for the file form data,
+ // overrides the name property of the file input field(s)
+ // options.formData: an array of objects with name and value properties,
+ // equivalent to the return data of .serializeArray(), e.g.:
+ // [{name: 'a', value: 1}, {name: 'b', value: 2}]
+ $.ajaxTransport('iframe', function (options) {
+ if (options.async && (options.type === 'POST' || options.type === 'GET')) {
+ var form,
+ iframe;
+ return {
+ send: function (_, completeCallback) {
+ form = $('<form style="display:none;"></form>');
+ // javascript:false as initial iframe src
+ // prevents warning popups on HTTPS in IE6.
+ // IE versions below IE8 cannot set the name property of
+ // elements that have already been added to the DOM,
+ // so we set the name along with the iframe HTML markup:
+ iframe = $(
+ '<iframe src="javascript:false;" name="iframe-transport-' +
+ (counter += 1) + '"></iframe>'
+ ).bind('load', function () {
+ var fileInputClones;
+ iframe
+ .unbind('load')
+ .bind('load', function () {
+ var response;
+ // Wrap in a try/catch block to catch exceptions thrown
+ // when trying to access cross-domain iframe contents:
+ try {
+ response = iframe.contents();
+ // Google Chrome and Firefox do not throw an
+ // exception when calling iframe.contents() on
+ // cross-domain requests, so we unify the response:
+ if (!response.length || !response[0].firstChild) {
+ throw new Error();
+ }
+ } catch (e) {
+ response = undefined;
+ }
+ // The complete callback returns the
+ // iframe content document as response object:
+ completeCallback(
+ 200,
+ 'success',
+ {'iframe': response}
+ );
+ // Fix for IE endless progress bar activity bug
+ // (happens on form submits to iframe targets):
+ $('<iframe src="javascript:false;"></iframe>')
+ .appendTo(form);
+ form.remove();
+ });
+ form
+ .prop('target', iframe.prop('name'))
+ .prop('action', options.url)
+ .prop('method', options.type);
+ if (options.formData) {
+ $.each(options.formData, function (index, field) {
+ $('<input type="hidden"/>')
+ .prop('name', field.name)
+ .val(field.value)
+ .appendTo(form);
+ });
+ }
+ if (options.fileInput && options.fileInput.length &&
+ options.type === 'POST') {
+ fileInputClones = options.fileInput.clone();
+ // Insert a clone for each file input field:
+ options.fileInput.after(function (index) {
+ return fileInputClones[index];
+ });
+ if (options.paramName) {
+ options.fileInput.each(function () {
+ $(this).prop('name', options.paramName);
+ });
+ }
+ // Appending the file input fields to the hidden form
+ // removes them from their original location:
+ form
+ .append(options.fileInput)
+ .prop('enctype', 'multipart/form-data')
+ // enctype must be set as encoding for IE:
+ .prop('encoding', 'multipart/form-data');
+ }
+ form.submit();
+ // Insert the file input fields at their original location
+ // by replacing the clones with the originals:
+ if (fileInputClones && fileInputClones.length) {
+ options.fileInput.each(function (index, input) {
+ var clone = $(fileInputClones[index]);
+ $(input).prop('name', clone.prop('name'));
+ clone.replaceWith(input);
+ });
+ }
+ });
+ form.append(iframe).appendTo(document.body);
+ },
+ abort: function () {
+ if (iframe) {
+ // javascript:false as iframe src aborts the request
+ // and prevents warning popups on HTTPS in IE6.
+ // concat is used to avoid the "Script URL" JSLint error:
+ iframe
+ .unbind('load')
+ .prop('src', 'javascript'.concat(':false;'));
+ }
+ if (form) {
+ form.remove();
+ }
+ }
+ };
+ }
+ });
+
+ // The iframe transport returns the iframe content document as response.
+ // The following adds converters from iframe to text, json, html, and script:
+ $.ajaxSetup({
+ converters: {
+ 'iframe text': function (iframe) {
+ return $(iframe[0].body).text();
+ },
+ 'iframe json': function (iframe) {
+ return $.parseJSON($(iframe[0].body).text());
+ },
+ 'iframe html': function (iframe) {
+ return $(iframe[0].body).html();
+ },
+ 'iframe script': function (iframe) {
+ return $.globalEval($(iframe[0].body).text());
+ }
+ }
+ });
+
+}));
diff --git a/lib/base.php b/lib/base.php
index 74693641f6e..fa4c9850a3b 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -428,7 +428,7 @@ class OC{
$parent = OC::$APPSROOT . '/' . self::$REQUESTEDAPP;
if(!OC_Helper::issubdirectory($subdir, $parent)){
self::$REQUESTEDFILE = null;
- //header('HTTP/1.0 404 Not Found');
+ header('HTTP/1.0 404 Not Found');
exit;
}
}
diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php
index cc37bf22d5d..912c8cd439a 100644
--- a/lib/connector/sabre/directory.php
+++ b/lib/connector/sabre/directory.php
@@ -50,7 +50,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
$path = $this->path . '/' . $name;
- if (!OC_Filesystem::file_exists($path)) throw new Sabre_DAV_Exception_FileNotFound('File with name ' . $path . ' could not be located');
+ if (!OC_Filesystem::file_exists($path)) throw new Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
if (OC_Filesystem::is_dir($path)) {
diff --git a/lib/connector/sabre/principal.php b/lib/connector/sabre/principal.php
index 28a36438e87..d1456f7c642 100644
--- a/lib/connector/sabre/principal.php
+++ b/lib/connector/sabre/principal.php
@@ -46,7 +46,7 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend {
* @return array
*/
public function getPrincipalByPath($path) {
- list($prefix,$name) = Sabre_DAV_URLUtil::splitPath($path);
+ list($prefix,$name) = explode('/', $path);
if ($prefix == 'principals' && OC_User::userExists($name)) {
return array(
@@ -115,4 +115,6 @@ class OC_Connector_Sabre_Principal implements Sabre_DAVACL_IPrincipalBackend {
public function setGroupMemberSet($principal, array $members) {
throw new Sabre_DAV_Exception('Setting members of the group is not supported yet');
}
+ function updatePrincipal($path, $mutations){return 0;}
+ function searchPrincipals($prefixPath, array $searchProperties){return 0;}
}
diff --git a/lib/filecache.php b/lib/filecache.php
index 19286ff746b..28a9eb247a6 100644
--- a/lib/filecache.php
+++ b/lib/filecache.php
@@ -64,7 +64,7 @@ class OC_FileCache{
if(is_array($result)){
return $result;
}else{
- OC_Log::write('get(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
+ OC_Log::write('files','get(): file not found in cache ('.$path.')',OC_Log::DEBUG);
return false;
}
}
@@ -257,7 +257,7 @@ class OC_FileCache{
if(is_array($result)){
return $result;
}else{
- OC_Log::write('getFolderContent(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
+ OC_Log::write('files','getFolderContent(): file not found in cache ('.$path.')',OC_Log::DEBUG);
return false;
}
}
@@ -300,7 +300,7 @@ class OC_FileCache{
if(is_array($result)){
return $result['id'];
}else{
- OC_Log::write('getFileId(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
+ OC_Log::write('files','getFileId(): file not found in cache ('.$path.')',OC_Log::DEBUG);
return -1;
}
}
@@ -414,8 +414,12 @@ class OC_FileCache{
}
return $result;
}else{
- OC_Log::write('get(): file not found in cache ('.$path.')','core',OC_Log::DEBUG);
- return false;
+ OC_Log::write('files','getChached(): file not found in cache ('.$path.')',OC_Log::DEBUG);
+ if(isset(self::$savedData[$path])){
+ return self::$savedData[$path];
+ }else{
+ return array();
+ }
}
}
@@ -553,6 +557,7 @@ class OC_FileCache{
$view=new OC_FilesystemView(($root=='/')?'':$root);
}
if(!$view->is_readable($path)) return; //cant read, nothing we can do
+ clearstatcache();
$stat=$view->stat($path);
$mimetype=$view->getMimeType($path);
$writable=$view->is_writable($path);
diff --git a/lib/filesystem.php b/lib/filesystem.php
index dc678fba74c..1b91eabc7c1 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -196,10 +196,58 @@ class OC_Filesystem{
return false;
}
self::$defaultInstance=new OC_FilesystemView($root);
+
+ //load custom mount config
+ if(is_file(OC::$SERVERROOT.'/config/mount.php')){
+ $mountConfig=include(OC::$SERVERROOT.'/config/mount.php');
+ if(isset($mountConfig['global'])){
+ foreach($mountConfig['global'] as $mountPoint=>$options){
+ self::mount($options['class'],$options['options'],$mountPoint);
+ }
+ }
+
+ if(isset($mountConfig['group'])){
+ foreach($mountConfig['group'] as $group=>$mounts){
+ if(OC_Group::inGroup(OC_User::getUser(),$group)){
+ foreach($mounts as $mountPoint=>$options){
+ $mountPoint=self::setUserVars($mountPoint);
+ foreach($options as &$option){
+ $option=self::setUserVars($option);
+ }
+ self::mount($options['class'],$options['options'],$mountPoint);
+ }
+ }
+ }
+ }
+
+ if(isset($mountConfig['user'])){
+ foreach($mountConfig['user'] as $user=>$mounts){
+ if($user==='all' or strtolower($user)===strtolower(OC_User::getUser())){
+ foreach($mounts as $mountPoint=>$options){
+ $mountPoint=self::setUserVars($mountPoint);
+ foreach($options as &$option){
+ $option=self::setUserVars($option);
+ }
+ self::mount($options['class'],$options['options'],$mountPoint);
+ }
+ }
+ }
+ }
+ }
+
self::$loaded=true;
}
/**
+ * fill in the correct values for $user, and $password placeholders
+ * @param string intput
+ * @return string
+ */
+ private static function setUserVars($input){
+ return str_replace('$user',OC_User::getUser(),$input);
+ }
+
+ /**
* get the default filesystem view
* @return OC_FilesystemView
*/
diff --git a/lib/filesystemview.php b/lib/filesystemview.php
index 95873bd87cf..ac5a0a3bff5 100644
--- a/lib/filesystemview.php
+++ b/lib/filesystemview.php
@@ -136,15 +136,16 @@ class OC_FilesystemView {
return $this->basicOperation('filesize',$path);
}
public function readfile($path){
+ @ob_end_clean();
$handle=$this->fopen($path,'r');
if ($handle) {
- $chunkSize = 1024*1024;// 1 MB chunks
+ $chunkSize = 8*1024;// 1 MB chunks
while (!feof($handle)) {
echo fread($handle, $chunkSize);
- @ob_flush();
flush();
}
- return $this->filesize($path);
+ $size=$this->filesize($path);
+ return $size;
}
return false;
}
@@ -174,11 +175,23 @@ class OC_FilesystemView {
}
public function file_put_contents($path,$data){
if(is_resource($data)){//not having to deal with streams in file_put_contents makes life easier
+ $exists=$this->file_exists($path);
+ $run=true;
+ if(!$exists){
+ OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
+ }
+ OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
+ if(!$run){
+ return false;
+ }
$target=$this->fopen($path,'w');
if($target){
$count=OC_Helper::streamCopy($data,$target);
fclose($target);
fclose($data);
+ if(!$exists){
+ OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path));
+ }
OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path));
return $count>0;
}else{
diff --git a/lib/helper.php b/lib/helper.php
index 1d9862bf8b1..c5af76dbe52 100755
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -569,14 +569,22 @@ class OC_Helper {
return false;
}
if($realpath_sub && $realpath_sub != '' && $realpath_parent && $realpath_parent != ''){
- if(substr($sub, 0, strlen($parent)) == $parent){
+ if(substr($realpath_sub, 0, strlen($realpath_parent)) == $realpath_parent){
return true;
}
}else{
- if(substr($realpath_sub, 0, strlen($realpath_parent)) == $realpath_parent){
+ if(substr($sub, 0, strlen($parent)) == $parent){
return true;
}
}
+ /*
+ echo 'SUB: ' . $sub . "\n";
+ echo 'PAR: ' . $parent . "\n";
+ echo 'REALSUB: ' . $realpath_sub . "\n";
+ echo 'REALPAR: ' . $realpath_parent . "\n";
+ echo substr($realpath_sub, 0, strlen($realpath_parent));
+ exit;
+ */
return false;
}
}
diff --git a/lib/vobject.php b/lib/vobject.php
index e3479fc6d36..ec80e1d605a 100644
--- a/lib/vobject.php
+++ b/lib/vobject.php
@@ -41,7 +41,7 @@ class OC_VObject{
*/
public static function parse($data){
try {
- Sabre_VObject_Reader::$elementMap['LAST-MODIFIED'] = 'Sabre_VObject_Element_DateTime';
+ Sabre_VObject_Property::$classMap['LAST-MODIFIED'] = 'Sabre_VObject_Property_DateTime';
$vobject = Sabre_VObject_Reader::read($data);
if ($vobject instanceof Sabre_VObject_Component){
$vobject = new OC_VObject($vobject);
@@ -150,12 +150,12 @@ class OC_VObject{
* @param int $dateType
* @return void
*/
- public function setDateTime($name, $datetime, $dateType=Sabre_VObject_Element_DateTime::LOCALTZ){
+ public function setDateTime($name, $datetime, $dateType=Sabre_VObject_Property_DateTime::LOCALTZ){
if ($datetime == 'now'){
$datetime = new DateTime();
}
if ($datetime instanceof DateTime){
- $datetime_element = new Sabre_VObject_Element_DateTime($name);
+ $datetime_element = new Sabre_VObject_Property_DateTime($name);
$datetime_element->setDateTime($datetime, $dateType);
$this->vobject->__set($name, $datetime_element);
}else{
diff --git a/settings/templates/help.php b/settings/templates/help.php
index df640d97469..f9eb8615972 100644
--- a/settings/templates/help.php
+++ b/settings/templates/help.php
@@ -6,6 +6,7 @@
<div id="controls">
<a class="button newquestion" href="http://owncloud.org/support" target="_blank"><?php echo $l->t( 'Documentation' ); ?></a>
+ <a class="button newquestion" href="http://owncloud.org/support/big-files" target="_blank"><?php echo $l->t( 'Managing Big Files' ); ?></a>
<a class="button newquestion" href="http://apps.owncloud.com/knowledgebase/editquestion.php?action=new" target="_blank"><?php echo $l->t( 'Ask a question' ); ?></a>
<?php
$url=OC_Helper::linkTo( "settings", "help.php" ).'?page=';