From f6cc00ee5e13ecf8c859b7a6ca186f352ff2f473 Mon Sep 17 00:00:00 2001 From: Sebastian Krupinski Date: Tue, 14 Jul 2026 18:45:10 -0400 Subject: [PATCH] Remove committed vendor dependencies --- lib/vendor/autoload.php | 22 - lib/vendor/bin/generate_vcards | 120 -- lib/vendor/bin/generate_vcards.bat | 5 - lib/vendor/bin/naturalselection | 37 - lib/vendor/bin/naturalselection.bat | 5 - lib/vendor/bin/sabredav | 37 - lib/vendor/bin/sabredav.bat | 5 - lib/vendor/bin/vobject | 120 -- lib/vendor/bin/vobject.bat | 5 - lib/vendor/composer/ClassLoader.php | 579 ------ lib/vendor/composer/InstalledVersions.php | 380 ---- lib/vendor/composer/LICENSE | 19 - lib/vendor/composer/autoload_classmap.php | 370 ---- lib/vendor/composer/autoload_files.php | 16 - lib/vendor/composer/autoload_namespaces.php | 9 - lib/vendor/composer/autoload_psr4.php | 16 - lib/vendor/composer/autoload_real.php | 50 - lib/vendor/composer/autoload_static.php | 439 ----- lib/vendor/composer/installed.json | 522 ----- lib/vendor/composer/installed.php | 86 - lib/vendor/composer/platform_check.php | 26 - lib/vendor/psr/log/LICENSE | 19 - lib/vendor/psr/log/README.md | 58 - lib/vendor/psr/log/composer.json | 26 - lib/vendor/psr/log/src/AbstractLogger.php | 15 - .../psr/log/src/InvalidArgumentException.php | 7 - lib/vendor/psr/log/src/LogLevel.php | 18 - .../psr/log/src/LoggerAwareInterface.php | 14 - lib/vendor/psr/log/src/LoggerAwareTrait.php | 22 - lib/vendor/psr/log/src/LoggerInterface.php | 98 - lib/vendor/psr/log/src/LoggerTrait.php | 98 - lib/vendor/psr/log/src/NullLogger.php | 26 - lib/vendor/sabre/dav/LICENSE | 27 - lib/vendor/sabre/dav/README.md | 39 - lib/vendor/sabre/dav/bin/build.php | 169 -- lib/vendor/sabre/dav/bin/migrateto20.php | 414 ---- lib/vendor/sabre/dav/bin/migrateto21.php | 166 -- lib/vendor/sabre/dav/bin/migrateto30.php | 161 -- lib/vendor/sabre/dav/bin/migrateto32.php | 258 --- lib/vendor/sabre/dav/bin/naturalselection | 140 -- lib/vendor/sabre/dav/bin/sabredav | 2 - lib/vendor/sabre/dav/bin/sabredav.php | 51 - lib/vendor/sabre/dav/composer.json | 81 - .../lib/CalDAV/Backend/AbstractBackend.php | 216 --- .../lib/CalDAV/Backend/BackendInterface.php | 273 --- .../CalDAV/Backend/NotificationSupport.php | 62 - .../sabre/dav/lib/CalDAV/Backend/PDO.php | 1487 --------------- .../lib/CalDAV/Backend/SchedulingSupport.php | 66 - .../dav/lib/CalDAV/Backend/SharingSupport.php | 60 - .../dav/lib/CalDAV/Backend/SimplePDO.php | 289 --- .../CalDAV/Backend/SubscriptionSupport.php | 89 - .../dav/lib/CalDAV/Backend/SyncSupport.php | 83 - lib/vendor/sabre/dav/lib/CalDAV/Calendar.php | 460 ----- .../sabre/dav/lib/CalDAV/CalendarHome.php | 356 ---- .../sabre/dav/lib/CalDAV/CalendarObject.php | 223 --- .../dav/lib/CalDAV/CalendarQueryValidator.php | 354 ---- .../sabre/dav/lib/CalDAV/CalendarRoot.php | 75 - .../CalDAV/Exception/InvalidComponentType.php | 31 - .../sabre/dav/lib/CalDAV/ICSExportPlugin.php | 377 ---- lib/vendor/sabre/dav/lib/CalDAV/ICalendar.php | 20 - .../sabre/dav/lib/CalDAV/ICalendarObject.php | 23 - .../lib/CalDAV/ICalendarObjectContainer.php | 39 - .../sabre/dav/lib/CalDAV/ISharedCalendar.php | 27 - .../lib/CalDAV/Notifications/Collection.php | 96 - .../lib/CalDAV/Notifications/ICollection.php | 25 - .../dav/lib/CalDAV/Notifications/INode.php | 41 - .../dav/lib/CalDAV/Notifications/Node.php | 112 -- .../dav/lib/CalDAV/Notifications/Plugin.php | 161 -- lib/vendor/sabre/dav/lib/CalDAV/Plugin.php | 1011 ---------- .../dav/lib/CalDAV/Principal/Collection.php | 32 - .../dav/lib/CalDAV/Principal/IProxyRead.php | 21 - .../dav/lib/CalDAV/Principal/IProxyWrite.php | 21 - .../dav/lib/CalDAV/Principal/ProxyRead.php | 161 -- .../dav/lib/CalDAV/Principal/ProxyWrite.php | 161 -- .../sabre/dav/lib/CalDAV/Principal/User.php | 136 -- .../sabre/dav/lib/CalDAV/Schedule/IInbox.php | 17 - .../dav/lib/CalDAV/Schedule/IMipPlugin.php | 178 -- .../sabre/dav/lib/CalDAV/Schedule/IOutbox.php | 17 - .../lib/CalDAV/Schedule/ISchedulingObject.php | 15 - .../sabre/dav/lib/CalDAV/Schedule/Inbox.php | 198 -- .../sabre/dav/lib/CalDAV/Schedule/Outbox.php | 119 -- .../sabre/dav/lib/CalDAV/Schedule/Plugin.php | 1006 ---------- .../lib/CalDAV/Schedule/SchedulingObject.php | 130 -- .../sabre/dav/lib/CalDAV/SharedCalendar.php | 219 --- .../sabre/dav/lib/CalDAV/SharingPlugin.php | 346 ---- .../CalDAV/Subscriptions/ISubscription.php | 41 - .../dav/lib/CalDAV/Subscriptions/Plugin.php | 108 -- .../lib/CalDAV/Subscriptions/Subscription.php | 204 -- .../lib/CalDAV/Xml/Filter/CalendarData.php | 80 - .../dav/lib/CalDAV/Xml/Filter/CompFilter.php | 94 - .../dav/lib/CalDAV/Xml/Filter/ParamFilter.php | 79 - .../dav/lib/CalDAV/Xml/Filter/PropFilter.php | 95 - .../lib/CalDAV/Xml/Notification/Invite.php | 290 --- .../CalDAV/Xml/Notification/InviteReply.php | 199 -- .../Notification/NotificationInterface.php | 43 - .../CalDAV/Xml/Notification/SystemStatus.php | 171 -- .../Xml/Property/AllowedSharingModes.php | 81 - .../CalDAV/Xml/Property/EmailAddressSet.php | 71 - .../dav/lib/CalDAV/Xml/Property/Invite.php | 120 -- .../Xml/Property/ScheduleCalendarTransp.php | 124 -- .../SupportedCalendarComponentSet.php | 118 -- .../Xml/Property/SupportedCalendarData.php | 57 - .../Xml/Property/SupportedCollationSet.php | 54 - .../Xml/Request/CalendarMultiGetReport.php | 119 -- .../Xml/Request/CalendarQueryReport.php | 137 -- .../Xml/Request/FreeBusyQueryReport.php | 90 - .../lib/CalDAV/Xml/Request/InviteReply.php | 145 -- .../dav/lib/CalDAV/Xml/Request/MkCalendar.php | 77 - .../dav/lib/CalDAV/Xml/Request/Share.php | 107 -- .../sabre/dav/lib/CardDAV/AddressBook.php | 335 ---- .../sabre/dav/lib/CardDAV/AddressBookHome.php | 178 -- .../sabre/dav/lib/CardDAV/AddressBookRoot.php | 75 - .../lib/CardDAV/Backend/AbstractBackend.php | 38 - .../lib/CardDAV/Backend/BackendInterface.php | 194 -- .../sabre/dav/lib/CardDAV/Backend/PDO.php | 539 ------ .../dav/lib/CardDAV/Backend/SyncSupport.php | 83 - lib/vendor/sabre/dav/lib/CardDAV/Card.php | 202 -- .../sabre/dav/lib/CardDAV/IAddressBook.php | 20 - lib/vendor/sabre/dav/lib/CardDAV/ICard.php | 21 - .../sabre/dav/lib/CardDAV/IDirectory.php | 22 - lib/vendor/sabre/dav/lib/CardDAV/Plugin.php | 886 --------- .../sabre/dav/lib/CardDAV/VCFExportPlugin.php | 165 -- .../lib/CardDAV/Xml/Filter/AddressData.php | 66 - .../lib/CardDAV/Xml/Filter/ParamFilter.php | 86 - .../dav/lib/CardDAV/Xml/Filter/PropFilter.php | 95 - .../Xml/Property/SupportedAddressData.php | 77 - .../Xml/Property/SupportedCollationSet.php | 44 - .../Xml/Request/AddressBookMultiGetReport.php | 116 -- .../Xml/Request/AddressBookQueryReport.php | 193 -- .../lib/DAV/Auth/Backend/AbstractBasic.php | 136 -- .../lib/DAV/Auth/Backend/AbstractBearer.php | 130 -- .../lib/DAV/Auth/Backend/AbstractDigest.php | 160 -- .../sabre/dav/lib/DAV/Auth/Backend/Apache.php | 93 - .../lib/DAV/Auth/Backend/BackendInterface.php | 65 - .../lib/DAV/Auth/Backend/BasicCallBack.php | 56 - .../sabre/dav/lib/DAV/Auth/Backend/File.php | 74 - .../sabre/dav/lib/DAV/Auth/Backend/IMAP.php | 82 - .../sabre/dav/lib/DAV/Auth/Backend/PDO.php | 55 - .../dav/lib/DAV/Auth/Backend/PDOBasicAuth.php | 114 -- lib/vendor/sabre/dav/lib/DAV/Auth/Plugin.php | 255 --- .../dav/lib/DAV/Browser/GuessContentType.php | 93 - .../sabre/dav/lib/DAV/Browser/HtmlOutput.php | 34 - .../dav/lib/DAV/Browser/HtmlOutputHelper.php | 118 -- .../dav/lib/DAV/Browser/MapGetToPropFind.php | 58 - .../sabre/dav/lib/DAV/Browser/Plugin.php | 789 -------- .../sabre/dav/lib/DAV/Browser/PropFindAll.php | 128 -- .../dav/lib/DAV/Browser/assets/favicon.ico | Bin 4286 -> 0 bytes .../Browser/assets/openiconic/ICON-LICENSE | 21 - .../Browser/assets/openiconic/open-iconic.css | 510 ----- .../Browser/assets/openiconic/open-iconic.eot | Bin 23144 -> 0 bytes .../Browser/assets/openiconic/open-iconic.otf | Bin 21048 -> 0 bytes .../Browser/assets/openiconic/open-iconic.svg | 543 ------ .../Browser/assets/openiconic/open-iconic.ttf | Bin 25568 -> 0 bytes .../assets/openiconic/open-iconic.woff | Bin 12404 -> 0 bytes .../dav/lib/DAV/Browser/assets/sabredav.css | 228 --- .../dav/lib/DAV/Browser/assets/sabredav.png | Bin 2825 -> 0 bytes lib/vendor/sabre/dav/lib/DAV/Client.php | 485 ----- lib/vendor/sabre/dav/lib/DAV/Collection.php | 106 -- lib/vendor/sabre/dav/lib/DAV/CorePlugin.php | 907 --------- lib/vendor/sabre/dav/lib/DAV/Exception.php | 50 - .../dav/lib/DAV/Exception/BadRequest.php | 30 - .../sabre/dav/lib/DAV/Exception/Conflict.php | 30 - .../dav/lib/DAV/Exception/ConflictingLock.php | 32 - .../sabre/dav/lib/DAV/Exception/Forbidden.php | 29 - .../lib/DAV/Exception/InsufficientStorage.php | 29 - .../lib/DAV/Exception/InvalidResourceType.php | 29 - .../lib/DAV/Exception/InvalidSyncToken.php | 34 - .../dav/lib/DAV/Exception/LengthRequired.php | 30 - .../Exception/LockTokenMatchesRequestUri.php | 36 - .../sabre/dav/lib/DAV/Exception/Locked.php | 68 - .../lib/DAV/Exception/MethodNotAllowed.php | 46 - .../lib/DAV/Exception/NotAuthenticated.php | 30 - .../sabre/dav/lib/DAV/Exception/NotFound.php | 29 - .../dav/lib/DAV/Exception/NotImplemented.php | 29 - .../dav/lib/DAV/Exception/PaymentRequired.php | 30 - .../lib/DAV/Exception/PreconditionFailed.php | 65 - .../lib/DAV/Exception/ReportNotSupported.php | 28 - .../RequestedRangeNotSatisfiable.php | 30 - .../lib/DAV/Exception/ServiceUnavailable.php | 30 - .../dav/lib/DAV/Exception/TooManyMatches.php | 34 - .../DAV/Exception/UnsupportedMediaType.php | 30 - lib/vendor/sabre/dav/lib/DAV/FS/Directory.php | 147 -- lib/vendor/sabre/dav/lib/DAV/FS/File.php | 87 - lib/vendor/sabre/dav/lib/DAV/FS/Node.php | 96 - .../sabre/dav/lib/DAV/FSExt/Directory.php | 212 --- lib/vendor/sabre/dav/lib/DAV/FSExt/File.php | 153 -- lib/vendor/sabre/dav/lib/DAV/File.php | 93 - lib/vendor/sabre/dav/lib/DAV/ICollection.php | 79 - lib/vendor/sabre/dav/lib/DAV/ICopyTarget.php | 38 - .../sabre/dav/lib/DAV/IExtendedCollection.php | 43 - lib/vendor/sabre/dav/lib/DAV/IFile.php | 83 - lib/vendor/sabre/dav/lib/DAV/IMoveTarget.php | 46 - lib/vendor/sabre/dav/lib/DAV/IMultiGet.php | 38 - lib/vendor/sabre/dav/lib/DAV/INode.php | 44 - lib/vendor/sabre/dav/lib/DAV/INodeByPath.php | 36 - lib/vendor/sabre/dav/lib/DAV/IProperties.php | 46 - lib/vendor/sabre/dav/lib/DAV/IQuota.php | 27 - .../lib/DAV/Locks/Backend/AbstractBackend.php | 20 - .../DAV/Locks/Backend/BackendInterface.php | 52 - .../sabre/dav/lib/DAV/Locks/Backend/File.php | 182 -- .../sabre/dav/lib/DAV/Locks/Backend/PDO.php | 172 -- .../sabre/dav/lib/DAV/Locks/LockInfo.php | 82 - lib/vendor/sabre/dav/lib/DAV/Locks/Plugin.php | 550 ------ lib/vendor/sabre/dav/lib/DAV/MkCol.php | 71 - lib/vendor/sabre/dav/lib/DAV/Mount/Plugin.php | 78 - lib/vendor/sabre/dav/lib/DAV/Node.php | 51 - .../lib/DAV/PartialUpdate/IPatchSupport.php | 49 - .../dav/lib/DAV/PartialUpdate/Plugin.php | 212 --- lib/vendor/sabre/dav/lib/DAV/PropFind.php | 335 ---- lib/vendor/sabre/dav/lib/DAV/PropPatch.php | 337 ---- .../Backend/BackendInterface.php | 75 - .../lib/DAV/PropertyStorage/Backend/PDO.php | 224 --- .../dav/lib/DAV/PropertyStorage/Plugin.php | 176 -- lib/vendor/sabre/dav/lib/DAV/Server.php | 1682 ----------------- lib/vendor/sabre/dav/lib/DAV/ServerPlugin.php | 105 - .../sabre/dav/lib/DAV/Sharing/ISharedNode.php | 69 - .../sabre/dav/lib/DAV/Sharing/Plugin.php | 312 --- .../sabre/dav/lib/DAV/SimpleCollection.php | 109 -- lib/vendor/sabre/dav/lib/DAV/SimpleFile.php | 118 -- lib/vendor/sabre/dav/lib/DAV/StringUtil.php | 86 - .../dav/lib/DAV/Sync/ISyncCollection.php | 90 - lib/vendor/sabre/dav/lib/DAV/Sync/Plugin.php | 249 --- .../dav/lib/DAV/TemporaryFileFilterPlugin.php | 298 --- lib/vendor/sabre/dav/lib/DAV/Tree.php | 342 ---- lib/vendor/sabre/dav/lib/DAV/UUIDUtil.php | 66 - lib/vendor/sabre/dav/lib/DAV/Version.php | 20 - .../sabre/dav/lib/DAV/Xml/Element/Prop.php | 110 -- .../dav/lib/DAV/Xml/Element/Response.php | 267 --- .../sabre/dav/lib/DAV/Xml/Element/Sharee.php | 189 -- .../dav/lib/DAV/Xml/Property/Complex.php | 87 - .../lib/DAV/Xml/Property/GetLastModified.php | 103 - .../sabre/dav/lib/DAV/Xml/Property/Href.php | 166 -- .../sabre/dav/lib/DAV/Xml/Property/Invite.php | 66 - .../dav/lib/DAV/Xml/Property/LocalHref.php | 48 - .../lib/DAV/Xml/Property/LockDiscovery.php | 105 - .../dav/lib/DAV/Xml/Property/ResourceType.php | 120 -- .../dav/lib/DAV/Xml/Property/ShareAccess.php | 135 -- .../lib/DAV/Xml/Property/SupportedLock.php | 52 - .../DAV/Xml/Property/SupportedMethodSet.php | 114 -- .../DAV/Xml/Property/SupportedReportSet.php | 144 -- .../sabre/dav/lib/DAV/Xml/Request/Lock.php | 84 - .../sabre/dav/lib/DAV/Xml/Request/MkCol.php | 80 - .../dav/lib/DAV/Xml/Request/PropFind.php | 79 - .../dav/lib/DAV/Xml/Request/PropPatch.php | 109 -- .../dav/lib/DAV/Xml/Request/ShareResource.php | 80 - .../DAV/Xml/Request/SyncCollectionReport.php | 118 -- .../dav/lib/DAV/Xml/Response/MultiStatus.php | 136 -- lib/vendor/sabre/dav/lib/DAV/Xml/Service.php | 47 - lib/vendor/sabre/dav/lib/DAVACL/ACLTrait.php | 94 - .../DAVACL/AbstractPrincipalCollection.php | 178 -- .../dav/lib/DAVACL/Exception/AceConflict.php | 31 - .../lib/DAVACL/Exception/NeedPrivileges.php | 73 - .../dav/lib/DAVACL/Exception/NoAbstract.php | 31 - .../Exception/NotRecognizedPrincipal.php | 31 - .../Exception/NotSupportedPrivilege.php | 31 - .../sabre/dav/lib/DAVACL/FS/Collection.php | 109 -- lib/vendor/sabre/dav/lib/DAVACL/FS/File.php | 78 - .../dav/lib/DAVACL/FS/HomeCollection.php | 123 -- lib/vendor/sabre/dav/lib/DAVACL/IACL.php | 72 - .../sabre/dav/lib/DAVACL/IPrincipal.php | 75 - .../dav/lib/DAVACL/IPrincipalCollection.php | 64 - lib/vendor/sabre/dav/lib/DAVACL/Plugin.php | 1545 --------------- lib/vendor/sabre/dav/lib/DAVACL/Principal.php | 199 -- .../PrincipalBackend/AbstractBackend.php | 54 - .../PrincipalBackend/BackendInterface.php | 143 -- .../CreatePrincipalSupport.php | 29 - .../dav/lib/DAVACL/PrincipalBackend/PDO.php | 443 ----- .../dav/lib/DAVACL/PrincipalCollection.php | 96 - .../sabre/dav/lib/DAVACL/Xml/Property/Acl.php | 257 --- .../DAVACL/Xml/Property/AclRestrictions.php | 42 - .../Xml/Property/CurrentUserPrivilegeSet.php | 145 -- .../dav/lib/DAVACL/Xml/Property/Principal.php | 186 -- .../Xml/Property/SupportedPrivilegeSet.php | 146 -- .../Xml/Request/AclPrincipalPropSetReport.php | 66 - .../Xml/Request/ExpandPropertyReport.php | 100 - .../Xml/Request/PrincipalMatchReport.php | 106 -- .../Request/PrincipalPropertySearchReport.php | 122 -- .../PrincipalSearchPropertySetReport.php | 58 - lib/vendor/sabre/event/.php-cs-fixer.dist.php | 18 - lib/vendor/sabre/event/LICENSE | 27 - lib/vendor/sabre/event/composer.json | 69 - lib/vendor/sabre/event/lib/Emitter.php | 19 - .../sabre/event/lib/EmitterInterface.php | 78 - lib/vendor/sabre/event/lib/EmitterTrait.php | 178 -- lib/vendor/sabre/event/lib/EventEmitter.php | 20 - lib/vendor/sabre/event/lib/Loop/Loop.php | 343 ---- lib/vendor/sabre/event/lib/Loop/functions.php | 143 -- lib/vendor/sabre/event/lib/Promise.php | 253 --- .../sabre/event/lib/Promise/functions.php | 125 -- .../lib/PromiseAlreadyResolvedException.php | 17 - lib/vendor/sabre/event/lib/Version.php | 20 - .../sabre/event/lib/WildcardEmitter.php | 36 - .../sabre/event/lib/WildcardEmitterTrait.php | 233 --- lib/vendor/sabre/event/lib/coroutine.php | 122 -- .../sabre/http/.github/workflows/ci.yml | 68 - lib/vendor/sabre/http/.gitignore | 9 - lib/vendor/sabre/http/.php-cs-fixer.dist.php | 17 - lib/vendor/sabre/http/.php_cs.dist | 12 - lib/vendor/sabre/http/CHANGELOG.md | 403 ---- lib/vendor/sabre/http/LICENSE | 27 - lib/vendor/sabre/http/README.md | 747 -------- lib/vendor/sabre/http/bin/.empty | 0 lib/vendor/sabre/http/composer.json | 64 - .../sabre/http/examples/asyncclient.php | 62 - lib/vendor/sabre/http/examples/basicauth.php | 50 - lib/vendor/sabre/http/examples/client.php | 37 - lib/vendor/sabre/http/examples/digestauth.php | 51 - .../sabre/http/examples/reverseproxy.php | 48 - lib/vendor/sabre/http/examples/stringify.php | 50 - lib/vendor/sabre/http/lib/Auth/AWS.php | 220 --- .../sabre/http/lib/Auth/AbstractAuth.php | 65 - lib/vendor/sabre/http/lib/Auth/Basic.php | 60 - lib/vendor/sabre/http/lib/Auth/Bearer.php | 53 - lib/vendor/sabre/http/lib/Auth/Digest.php | 208 -- lib/vendor/sabre/http/lib/Client.php | 620 ------ lib/vendor/sabre/http/lib/ClientException.php | 17 - .../sabre/http/lib/ClientHttpException.php | 50 - lib/vendor/sabre/http/lib/HttpException.php | 31 - lib/vendor/sabre/http/lib/Message.php | 291 --- .../sabre/http/lib/MessageDecoratorTrait.php | 206 -- .../sabre/http/lib/MessageInterface.php | 151 -- lib/vendor/sabre/http/lib/Request.php | 273 --- .../sabre/http/lib/RequestDecorator.php | 179 -- .../sabre/http/lib/RequestInterface.php | 114 -- lib/vendor/sabre/http/lib/Response.php | 187 -- .../sabre/http/lib/ResponseDecorator.php | 72 - .../sabre/http/lib/ResponseInterface.php | 42 - lib/vendor/sabre/http/lib/Sapi.php | 240 --- lib/vendor/sabre/http/lib/Version.php | 20 - lib/vendor/sabre/http/lib/functions.php | 410 ---- lib/vendor/sabre/http/phpstan.neon | 2 - .../sabre/http/tests/HTTP/Auth/AWSTest.php | 236 --- .../sabre/http/tests/HTTP/Auth/BasicTest.php | 67 - .../sabre/http/tests/HTTP/Auth/BearerTest.php | 55 - .../sabre/http/tests/HTTP/Auth/DigestTest.php | 185 -- .../sabre/http/tests/HTTP/ClientTest.php | 605 ------ .../sabre/http/tests/HTTP/FunctionsTest.php | 212 --- .../http/tests/HTTP/MessageDecoratorTest.php | 91 - .../sabre/http/tests/HTTP/MessageTest.php | 281 --- .../sabre/http/tests/HTTP/NegotiateTest.php | 135 -- .../http/tests/HTTP/RequestDecoratorTest.php | 103 - .../sabre/http/tests/HTTP/RequestTest.php | 151 -- .../http/tests/HTTP/ResponseDecoratorTest.php | 35 - .../sabre/http/tests/HTTP/ResponseTest.php | 41 - lib/vendor/sabre/http/tests/HTTP/SapiTest.php | 326 ---- .../sabre/http/tests/HTTP/URLUtilTest.php | 114 -- lib/vendor/sabre/http/tests/bootstrap.php | 17 - lib/vendor/sabre/http/tests/phpunit.xml | 27 - lib/vendor/sabre/http/tests/www/bar.php | 5 - .../http/tests/www/connection_aborted.php | 69 - lib/vendor/sabre/http/tests/www/foo | 1 - lib/vendor/sabre/http/tests/www/large.php | 7 - lib/vendor/sabre/uri/.php-cs-fixer.dist.php | 17 - lib/vendor/sabre/uri/LICENSE | 27 - lib/vendor/sabre/uri/composer.json | 68 - .../sabre/uri/lib/InvalidUriException.php | 19 - lib/vendor/sabre/uri/lib/Version.php | 20 - lib/vendor/sabre/uri/lib/functions.php | 412 ---- lib/vendor/sabre/vobject/LICENSE | 27 - lib/vendor/sabre/vobject/README.md | 55 - lib/vendor/sabre/vobject/bin/bench.php | 12 - .../vobject/bin/bench_freebusygenerator.php | 53 - .../vobject/bin/bench_manipulatevcard.php | 64 - .../sabre/vobject/bin/fetch_windows_zones.php | 48 - lib/vendor/sabre/vobject/bin/generate_vcards | 241 --- .../vobject/bin/generateicalendardata.php | 87 - .../sabre/vobject/bin/mergeduplicates.php | 160 -- lib/vendor/sabre/vobject/bin/rrulebench.php | 32 - lib/vendor/sabre/vobject/bin/vobject | 27 - lib/vendor/sabre/vobject/composer.json | 107 -- .../vobject/lib/BirthdayCalendarGenerator.php | 172 -- lib/vendor/sabre/vobject/lib/Cli.php | 705 ------- lib/vendor/sabre/vobject/lib/Component.php | 672 ------- .../sabre/vobject/lib/Component/Available.php | 123 -- .../sabre/vobject/lib/Component/VAlarm.php | 138 -- .../vobject/lib/Component/VAvailability.php | 149 -- .../sabre/vobject/lib/Component/VCalendar.php | 528 ------ .../sabre/vobject/lib/Component/VCard.php | 541 ------ .../sabre/vobject/lib/Component/VEvent.php | 140 -- .../sabre/vobject/lib/Component/VFreeBusy.php | 93 - .../sabre/vobject/lib/Component/VJournal.php | 101 - .../sabre/vobject/lib/Component/VTimeZone.php | 63 - .../sabre/vobject/lib/Component/VTodo.php | 181 -- .../sabre/vobject/lib/DateTimeParser.php | 560 ------ lib/vendor/sabre/vobject/lib/Document.php | 269 --- lib/vendor/sabre/vobject/lib/ElementList.php | 52 - lib/vendor/sabre/vobject/lib/EofException.php | 15 - lib/vendor/sabre/vobject/lib/FreeBusyData.php | 185 -- .../sabre/vobject/lib/FreeBusyGenerator.php | 549 ------ lib/vendor/sabre/vobject/lib/ITip/Broker.php | 1003 ---------- .../sabre/vobject/lib/ITip/ITipException.php | 16 - lib/vendor/sabre/vobject/lib/ITip/Message.php | 136 -- ...SameOrganizerForAllComponentsException.php | 18 - .../vobject/lib/InvalidDataException.php | 15 - lib/vendor/sabre/vobject/lib/Node.php | 256 --- .../sabre/vobject/lib/PHPUnitAssertions.php | 75 - lib/vendor/sabre/vobject/lib/Parameter.php | 368 ---- .../sabre/vobject/lib/ParseException.php | 14 - lib/vendor/sabre/vobject/lib/Parser/Json.php | 190 -- .../sabre/vobject/lib/Parser/MimeDir.php | 710 ------- .../sabre/vobject/lib/Parser/Parser.php | 75 - lib/vendor/sabre/vobject/lib/Parser/XML.php | 377 ---- .../lib/Parser/XML/Element/KeyValue.php | 63 - lib/vendor/sabre/vobject/lib/Property.php | 646 ------- .../sabre/vobject/lib/Property/Binary.php | 109 -- .../sabre/vobject/lib/Property/Boolean.php | 72 - .../sabre/vobject/lib/Property/FlatText.php | 46 - .../sabre/vobject/lib/Property/FloatValue.php | 124 -- .../lib/Property/ICalendar/CalAddress.php | 63 - .../vobject/lib/Property/ICalendar/Date.php | 18 - .../lib/Property/ICalendar/DateTime.php | 366 ---- .../lib/Property/ICalendar/Duration.php | 79 - .../vobject/lib/Property/ICalendar/Period.php | 135 -- .../vobject/lib/Property/ICalendar/Recur.php | 344 ---- .../vobject/lib/Property/IntegerValue.php | 76 - .../sabre/vobject/lib/Property/Text.php | 392 ---- .../sabre/vobject/lib/Property/Time.php | 131 -- .../sabre/vobject/lib/Property/Unknown.php | 41 - lib/vendor/sabre/vobject/lib/Property/Uri.php | 116 -- .../sabre/vobject/lib/Property/UtcOffset.php | 70 - .../sabre/vobject/lib/Property/VCard/Date.php | 36 - .../lib/Property/VCard/DateAndOrTime.php | 367 ---- .../vobject/lib/Property/VCard/DateTime.php | 28 - .../lib/Property/VCard/LanguageTag.php | 53 - .../lib/Property/VCard/PhoneNumber.php | 30 - .../vobject/lib/Property/VCard/TimeStamp.php | 81 - lib/vendor/sabre/vobject/lib/Reader.php | 95 - .../sabre/vobject/lib/Recur/EventIterator.php | 501 ----- .../Recur/MaxInstancesExceededException.php | 17 - .../lib/Recur/NoInstancesException.php | 18 - .../sabre/vobject/lib/Recur/RDateIterator.php | 175 -- .../sabre/vobject/lib/Recur/RRuleIterator.php | 1079 ----------- lib/vendor/sabre/vobject/lib/Settings.php | 55 - .../sabre/vobject/lib/Splitter/ICalendar.php | 106 -- .../lib/Splitter/SplitterInterface.php | 38 - .../sabre/vobject/lib/Splitter/VCard.php | 74 - lib/vendor/sabre/vobject/lib/StringUtil.php | 50 - lib/vendor/sabre/vobject/lib/TimeZoneUtil.php | 272 --- .../lib/TimezoneGuesser/FindFromOffset.php | 31 - .../FindFromTimezoneIdentifier.php | 71 - .../TimezoneGuesser/FindFromTimezoneMap.php | 78 - .../lib/TimezoneGuesser/GuessFromLicEntry.php | 33 - .../lib/TimezoneGuesser/GuessFromMsTzId.php | 119 -- .../lib/TimezoneGuesser/TimezoneFinder.php | 10 - .../lib/TimezoneGuesser/TimezoneGuesser.php | 11 - lib/vendor/sabre/vobject/lib/UUIDUtil.php | 66 - .../sabre/vobject/lib/VCardConverter.php | 421 ----- lib/vendor/sabre/vobject/lib/Version.php | 18 - lib/vendor/sabre/vobject/lib/Writer.php | 68 - .../lib/timezonedata/exchangezones.php | 95 - .../vobject/lib/timezonedata/lotuszones.php | 101 - .../sabre/vobject/lib/timezonedata/php-bc.php | 152 -- .../lib/timezonedata/php-workaround.php | 46 - .../vobject/lib/timezonedata/windowszones.php | 152 -- .../sabre/vobject/resources/schema/xcal.rng | 1192 ------------ .../sabre/vobject/resources/schema/xcard.rng | 388 ---- lib/vendor/sabre/xml/.github/workflows/ci.yml | 69 - lib/vendor/sabre/xml/.php-cs-fixer.dist.php | 17 - lib/vendor/sabre/xml/LICENSE | 27 - lib/vendor/sabre/xml/README.md | 25 - lib/vendor/sabre/xml/bin/.empty | 0 lib/vendor/sabre/xml/composer.json | 67 - .../sabre/xml/lib/ContextStackTrait.php | 118 -- .../sabre/xml/lib/Deserializer/functions.php | 360 ---- lib/vendor/sabre/xml/lib/Element.php | 22 - lib/vendor/sabre/xml/lib/Element/Base.php | 80 - lib/vendor/sabre/xml/lib/Element/Cdata.php | 59 - lib/vendor/sabre/xml/lib/Element/Elements.php | 98 - lib/vendor/sabre/xml/lib/Element/KeyValue.php | 98 - lib/vendor/sabre/xml/lib/Element/Uri.php | 97 - .../sabre/xml/lib/Element/XmlFragment.php | 146 -- lib/vendor/sabre/xml/lib/LibXMLException.php | 47 - lib/vendor/sabre/xml/lib/ParseException.php | 18 - lib/vendor/sabre/xml/lib/Reader.php | 307 --- .../sabre/xml/lib/Serializer/functions.php | 207 -- lib/vendor/sabre/xml/lib/Service.php | 326 ---- lib/vendor/sabre/xml/lib/Version.php | 20 - lib/vendor/sabre/xml/lib/Writer.php | 255 --- .../sabre/xml/lib/XmlDeserializable.php | 36 - lib/vendor/sabre/xml/lib/XmlSerializable.php | 34 - 480 files changed, 71549 deletions(-) delete mode 100644 lib/vendor/autoload.php delete mode 100755 lib/vendor/bin/generate_vcards delete mode 100755 lib/vendor/bin/generate_vcards.bat delete mode 100755 lib/vendor/bin/naturalselection delete mode 100755 lib/vendor/bin/naturalselection.bat delete mode 100755 lib/vendor/bin/sabredav delete mode 100755 lib/vendor/bin/sabredav.bat delete mode 100755 lib/vendor/bin/vobject delete mode 100755 lib/vendor/bin/vobject.bat delete mode 100644 lib/vendor/composer/ClassLoader.php delete mode 100644 lib/vendor/composer/InstalledVersions.php delete mode 100644 lib/vendor/composer/LICENSE delete mode 100644 lib/vendor/composer/autoload_classmap.php delete mode 100644 lib/vendor/composer/autoload_files.php delete mode 100644 lib/vendor/composer/autoload_namespaces.php delete mode 100644 lib/vendor/composer/autoload_psr4.php delete mode 100644 lib/vendor/composer/autoload_real.php delete mode 100644 lib/vendor/composer/autoload_static.php delete mode 100644 lib/vendor/composer/installed.json delete mode 100644 lib/vendor/composer/installed.php delete mode 100644 lib/vendor/composer/platform_check.php delete mode 100644 lib/vendor/psr/log/LICENSE delete mode 100644 lib/vendor/psr/log/README.md delete mode 100644 lib/vendor/psr/log/composer.json delete mode 100644 lib/vendor/psr/log/src/AbstractLogger.php delete mode 100644 lib/vendor/psr/log/src/InvalidArgumentException.php delete mode 100644 lib/vendor/psr/log/src/LogLevel.php delete mode 100644 lib/vendor/psr/log/src/LoggerAwareInterface.php delete mode 100644 lib/vendor/psr/log/src/LoggerAwareTrait.php delete mode 100644 lib/vendor/psr/log/src/LoggerInterface.php delete mode 100644 lib/vendor/psr/log/src/LoggerTrait.php delete mode 100644 lib/vendor/psr/log/src/NullLogger.php delete mode 100644 lib/vendor/sabre/dav/LICENSE delete mode 100644 lib/vendor/sabre/dav/README.md delete mode 100755 lib/vendor/sabre/dav/bin/build.php delete mode 100755 lib/vendor/sabre/dav/bin/migrateto20.php delete mode 100755 lib/vendor/sabre/dav/bin/migrateto21.php delete mode 100755 lib/vendor/sabre/dav/bin/migrateto30.php delete mode 100755 lib/vendor/sabre/dav/bin/migrateto32.php delete mode 100755 lib/vendor/sabre/dav/bin/naturalselection delete mode 100755 lib/vendor/sabre/dav/bin/sabredav delete mode 100755 lib/vendor/sabre/dav/bin/sabredav.php delete mode 100644 lib/vendor/sabre/dav/composer.json delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Backend/SyncSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Calendar.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/CalendarHome.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/CalendarObject.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/ICalendar.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/ICalendarObject.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Notifications/ICollection.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Notifications/INode.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Principal/Collection.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Principal/IProxyRead.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Principal/IProxyWrite.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Principal/ProxyRead.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Principal/User.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/IInbox.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/IOutbox.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/ISchedulingObject.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php delete mode 100644 lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/AddressBook.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Backend/SyncSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Card.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/IAddressBook.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/ICard.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/IDirectory.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php delete mode 100644 lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/IMAP.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDOBasicAuth.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Auth/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/HtmlOutput.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/HtmlOutputHelper.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/favicon.ico delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/ICON-LICENSE delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.css delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.eot delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.otf delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.svg delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.ttf delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.woff delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/sabredav.css delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Browser/assets/sabredav.png delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Client.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Collection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/CorePlugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/BadRequest.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/Conflict.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/ConflictingLock.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/Forbidden.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/InsufficientStorage.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/InvalidResourceType.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/LengthRequired.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/LockTokenMatchesRequestUri.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/Locked.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/NotAuthenticated.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/NotFound.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/NotImplemented.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/PaymentRequired.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/PreconditionFailed.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/ReportNotSupported.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/ServiceUnavailable.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/TooManyMatches.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/FS/Directory.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/FS/File.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/FS/Node.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/FSExt/Directory.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/FSExt/File.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/File.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/ICollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/ICopyTarget.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/IExtendedCollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/IFile.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/IMoveTarget.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/IMultiGet.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/INode.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/INodeByPath.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/IProperties.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/IQuota.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Locks/Backend/AbstractBackend.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Locks/Backend/BackendInterface.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Locks/Backend/File.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Locks/LockInfo.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Locks/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/MkCol.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Mount/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Node.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/PartialUpdate/IPatchSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/PartialUpdate/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/PropFind.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/PropPatch.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Server.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/ServerPlugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/SimpleCollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/SimpleFile.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/StringUtil.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Sync/ISyncCollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Sync/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Tree.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/UUIDUtil.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Version.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Element/Prop.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/LockDiscovery.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php delete mode 100644 lib/vendor/sabre/dav/lib/DAV/Xml/Service.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/ACLTrait.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Exception/AceConflict.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Exception/NoAbstract.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/FS/Collection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/FS/File.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/IACL.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/IPrincipal.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/IPrincipalCollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Plugin.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Principal.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/CreatePrincipalSupport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php delete mode 100644 lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php delete mode 100644 lib/vendor/sabre/event/.php-cs-fixer.dist.php delete mode 100644 lib/vendor/sabre/event/LICENSE delete mode 100644 lib/vendor/sabre/event/composer.json delete mode 100644 lib/vendor/sabre/event/lib/Emitter.php delete mode 100644 lib/vendor/sabre/event/lib/EmitterInterface.php delete mode 100644 lib/vendor/sabre/event/lib/EmitterTrait.php delete mode 100644 lib/vendor/sabre/event/lib/EventEmitter.php delete mode 100644 lib/vendor/sabre/event/lib/Loop/Loop.php delete mode 100644 lib/vendor/sabre/event/lib/Loop/functions.php delete mode 100644 lib/vendor/sabre/event/lib/Promise.php delete mode 100644 lib/vendor/sabre/event/lib/Promise/functions.php delete mode 100644 lib/vendor/sabre/event/lib/PromiseAlreadyResolvedException.php delete mode 100644 lib/vendor/sabre/event/lib/Version.php delete mode 100644 lib/vendor/sabre/event/lib/WildcardEmitter.php delete mode 100644 lib/vendor/sabre/event/lib/WildcardEmitterTrait.php delete mode 100644 lib/vendor/sabre/event/lib/coroutine.php delete mode 100644 lib/vendor/sabre/http/.github/workflows/ci.yml delete mode 100644 lib/vendor/sabre/http/.gitignore delete mode 100644 lib/vendor/sabre/http/.php-cs-fixer.dist.php delete mode 100644 lib/vendor/sabre/http/.php_cs.dist delete mode 100644 lib/vendor/sabre/http/CHANGELOG.md delete mode 100644 lib/vendor/sabre/http/LICENSE delete mode 100644 lib/vendor/sabre/http/README.md delete mode 100644 lib/vendor/sabre/http/bin/.empty delete mode 100644 lib/vendor/sabre/http/composer.json delete mode 100644 lib/vendor/sabre/http/examples/asyncclient.php delete mode 100644 lib/vendor/sabre/http/examples/basicauth.php delete mode 100644 lib/vendor/sabre/http/examples/client.php delete mode 100644 lib/vendor/sabre/http/examples/digestauth.php delete mode 100644 lib/vendor/sabre/http/examples/reverseproxy.php delete mode 100644 lib/vendor/sabre/http/examples/stringify.php delete mode 100644 lib/vendor/sabre/http/lib/Auth/AWS.php delete mode 100644 lib/vendor/sabre/http/lib/Auth/AbstractAuth.php delete mode 100644 lib/vendor/sabre/http/lib/Auth/Basic.php delete mode 100644 lib/vendor/sabre/http/lib/Auth/Bearer.php delete mode 100644 lib/vendor/sabre/http/lib/Auth/Digest.php delete mode 100644 lib/vendor/sabre/http/lib/Client.php delete mode 100644 lib/vendor/sabre/http/lib/ClientException.php delete mode 100644 lib/vendor/sabre/http/lib/ClientHttpException.php delete mode 100644 lib/vendor/sabre/http/lib/HttpException.php delete mode 100644 lib/vendor/sabre/http/lib/Message.php delete mode 100644 lib/vendor/sabre/http/lib/MessageDecoratorTrait.php delete mode 100644 lib/vendor/sabre/http/lib/MessageInterface.php delete mode 100644 lib/vendor/sabre/http/lib/Request.php delete mode 100644 lib/vendor/sabre/http/lib/RequestDecorator.php delete mode 100644 lib/vendor/sabre/http/lib/RequestInterface.php delete mode 100644 lib/vendor/sabre/http/lib/Response.php delete mode 100644 lib/vendor/sabre/http/lib/ResponseDecorator.php delete mode 100644 lib/vendor/sabre/http/lib/ResponseInterface.php delete mode 100644 lib/vendor/sabre/http/lib/Sapi.php delete mode 100644 lib/vendor/sabre/http/lib/Version.php delete mode 100644 lib/vendor/sabre/http/lib/functions.php delete mode 100644 lib/vendor/sabre/http/phpstan.neon delete mode 100644 lib/vendor/sabre/http/tests/HTTP/Auth/AWSTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/Auth/BasicTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/Auth/BearerTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/Auth/DigestTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/ClientTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/FunctionsTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/MessageDecoratorTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/MessageTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/NegotiateTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/RequestDecoratorTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/RequestTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/ResponseDecoratorTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/ResponseTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/SapiTest.php delete mode 100644 lib/vendor/sabre/http/tests/HTTP/URLUtilTest.php delete mode 100644 lib/vendor/sabre/http/tests/bootstrap.php delete mode 100644 lib/vendor/sabre/http/tests/phpunit.xml delete mode 100644 lib/vendor/sabre/http/tests/www/bar.php delete mode 100644 lib/vendor/sabre/http/tests/www/connection_aborted.php delete mode 100644 lib/vendor/sabre/http/tests/www/foo delete mode 100644 lib/vendor/sabre/http/tests/www/large.php delete mode 100644 lib/vendor/sabre/uri/.php-cs-fixer.dist.php delete mode 100644 lib/vendor/sabre/uri/LICENSE delete mode 100644 lib/vendor/sabre/uri/composer.json delete mode 100644 lib/vendor/sabre/uri/lib/InvalidUriException.php delete mode 100644 lib/vendor/sabre/uri/lib/Version.php delete mode 100644 lib/vendor/sabre/uri/lib/functions.php delete mode 100644 lib/vendor/sabre/vobject/LICENSE delete mode 100644 lib/vendor/sabre/vobject/README.md delete mode 100755 lib/vendor/sabre/vobject/bin/bench.php delete mode 100644 lib/vendor/sabre/vobject/bin/bench_freebusygenerator.php delete mode 100644 lib/vendor/sabre/vobject/bin/bench_manipulatevcard.php delete mode 100755 lib/vendor/sabre/vobject/bin/fetch_windows_zones.php delete mode 100755 lib/vendor/sabre/vobject/bin/generate_vcards delete mode 100755 lib/vendor/sabre/vobject/bin/generateicalendardata.php delete mode 100755 lib/vendor/sabre/vobject/bin/mergeduplicates.php delete mode 100644 lib/vendor/sabre/vobject/bin/rrulebench.php delete mode 100755 lib/vendor/sabre/vobject/bin/vobject delete mode 100644 lib/vendor/sabre/vobject/composer.json delete mode 100644 lib/vendor/sabre/vobject/lib/BirthdayCalendarGenerator.php delete mode 100644 lib/vendor/sabre/vobject/lib/Cli.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/Available.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VAlarm.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VAvailability.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VCalendar.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VCard.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VEvent.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VFreeBusy.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VJournal.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VTimeZone.php delete mode 100644 lib/vendor/sabre/vobject/lib/Component/VTodo.php delete mode 100644 lib/vendor/sabre/vobject/lib/DateTimeParser.php delete mode 100644 lib/vendor/sabre/vobject/lib/Document.php delete mode 100644 lib/vendor/sabre/vobject/lib/ElementList.php delete mode 100644 lib/vendor/sabre/vobject/lib/EofException.php delete mode 100644 lib/vendor/sabre/vobject/lib/FreeBusyData.php delete mode 100644 lib/vendor/sabre/vobject/lib/FreeBusyGenerator.php delete mode 100644 lib/vendor/sabre/vobject/lib/ITip/Broker.php delete mode 100644 lib/vendor/sabre/vobject/lib/ITip/ITipException.php delete mode 100644 lib/vendor/sabre/vobject/lib/ITip/Message.php delete mode 100644 lib/vendor/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php delete mode 100644 lib/vendor/sabre/vobject/lib/InvalidDataException.php delete mode 100644 lib/vendor/sabre/vobject/lib/Node.php delete mode 100644 lib/vendor/sabre/vobject/lib/PHPUnitAssertions.php delete mode 100644 lib/vendor/sabre/vobject/lib/Parameter.php delete mode 100644 lib/vendor/sabre/vobject/lib/ParseException.php delete mode 100644 lib/vendor/sabre/vobject/lib/Parser/Json.php delete mode 100644 lib/vendor/sabre/vobject/lib/Parser/MimeDir.php delete mode 100644 lib/vendor/sabre/vobject/lib/Parser/Parser.php delete mode 100644 lib/vendor/sabre/vobject/lib/Parser/XML.php delete mode 100644 lib/vendor/sabre/vobject/lib/Parser/XML/Element/KeyValue.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/Binary.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/Boolean.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/FlatText.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/FloatValue.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/ICalendar/Date.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/ICalendar/Duration.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/ICalendar/Period.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/ICalendar/Recur.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/IntegerValue.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/Text.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/Time.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/Unknown.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/Uri.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/UtcOffset.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/VCard/Date.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/VCard/DateAndOrTime.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/VCard/DateTime.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/VCard/LanguageTag.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/VCard/PhoneNumber.php delete mode 100644 lib/vendor/sabre/vobject/lib/Property/VCard/TimeStamp.php delete mode 100644 lib/vendor/sabre/vobject/lib/Reader.php delete mode 100644 lib/vendor/sabre/vobject/lib/Recur/EventIterator.php delete mode 100644 lib/vendor/sabre/vobject/lib/Recur/MaxInstancesExceededException.php delete mode 100644 lib/vendor/sabre/vobject/lib/Recur/NoInstancesException.php delete mode 100644 lib/vendor/sabre/vobject/lib/Recur/RDateIterator.php delete mode 100644 lib/vendor/sabre/vobject/lib/Recur/RRuleIterator.php delete mode 100644 lib/vendor/sabre/vobject/lib/Settings.php delete mode 100644 lib/vendor/sabre/vobject/lib/Splitter/ICalendar.php delete mode 100644 lib/vendor/sabre/vobject/lib/Splitter/SplitterInterface.php delete mode 100644 lib/vendor/sabre/vobject/lib/Splitter/VCard.php delete mode 100644 lib/vendor/sabre/vobject/lib/StringUtil.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimeZoneUtil.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromOffset.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneMap.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromLicEntry.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromMsTzId.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimezoneGuesser/TimezoneFinder.php delete mode 100644 lib/vendor/sabre/vobject/lib/TimezoneGuesser/TimezoneGuesser.php delete mode 100644 lib/vendor/sabre/vobject/lib/UUIDUtil.php delete mode 100644 lib/vendor/sabre/vobject/lib/VCardConverter.php delete mode 100644 lib/vendor/sabre/vobject/lib/Version.php delete mode 100644 lib/vendor/sabre/vobject/lib/Writer.php delete mode 100644 lib/vendor/sabre/vobject/lib/timezonedata/exchangezones.php delete mode 100644 lib/vendor/sabre/vobject/lib/timezonedata/lotuszones.php delete mode 100644 lib/vendor/sabre/vobject/lib/timezonedata/php-bc.php delete mode 100644 lib/vendor/sabre/vobject/lib/timezonedata/php-workaround.php delete mode 100644 lib/vendor/sabre/vobject/lib/timezonedata/windowszones.php delete mode 100644 lib/vendor/sabre/vobject/resources/schema/xcal.rng delete mode 100644 lib/vendor/sabre/vobject/resources/schema/xcard.rng delete mode 100644 lib/vendor/sabre/xml/.github/workflows/ci.yml delete mode 100644 lib/vendor/sabre/xml/.php-cs-fixer.dist.php delete mode 100644 lib/vendor/sabre/xml/LICENSE delete mode 100644 lib/vendor/sabre/xml/README.md delete mode 100644 lib/vendor/sabre/xml/bin/.empty delete mode 100644 lib/vendor/sabre/xml/composer.json delete mode 100644 lib/vendor/sabre/xml/lib/ContextStackTrait.php delete mode 100644 lib/vendor/sabre/xml/lib/Deserializer/functions.php delete mode 100644 lib/vendor/sabre/xml/lib/Element.php delete mode 100644 lib/vendor/sabre/xml/lib/Element/Base.php delete mode 100644 lib/vendor/sabre/xml/lib/Element/Cdata.php delete mode 100644 lib/vendor/sabre/xml/lib/Element/Elements.php delete mode 100644 lib/vendor/sabre/xml/lib/Element/KeyValue.php delete mode 100644 lib/vendor/sabre/xml/lib/Element/Uri.php delete mode 100644 lib/vendor/sabre/xml/lib/Element/XmlFragment.php delete mode 100644 lib/vendor/sabre/xml/lib/LibXMLException.php delete mode 100644 lib/vendor/sabre/xml/lib/ParseException.php delete mode 100644 lib/vendor/sabre/xml/lib/Reader.php delete mode 100644 lib/vendor/sabre/xml/lib/Serializer/functions.php delete mode 100644 lib/vendor/sabre/xml/lib/Service.php delete mode 100644 lib/vendor/sabre/xml/lib/Version.php delete mode 100644 lib/vendor/sabre/xml/lib/Writer.php delete mode 100644 lib/vendor/sabre/xml/lib/XmlDeserializable.php delete mode 100644 lib/vendor/sabre/xml/lib/XmlSerializable.php diff --git a/lib/vendor/autoload.php b/lib/vendor/autoload.php deleted file mode 100644 index 0b8a598..0000000 --- a/lib/vendor/autoload.php +++ /dev/null @@ -1,22 +0,0 @@ -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if ( - (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) - || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) - ) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/sabre/vobject/bin/generate_vcards'); - exit(0); - } -} - -include __DIR__ . '/..'.'/sabre/vobject/bin/generate_vcards'; diff --git a/lib/vendor/bin/generate_vcards.bat b/lib/vendor/bin/generate_vcards.bat deleted file mode 100755 index cae5cbc..0000000 --- a/lib/vendor/bin/generate_vcards.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/generate_vcards -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/vendor/bin/naturalselection b/lib/vendor/bin/naturalselection deleted file mode 100755 index d13c00b..0000000 --- a/lib/vendor/bin/naturalselection +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env sh - -# Support bash to support `source` with fallback on $0 if this does not run with bash -# https://stackoverflow.com/a/35006505/6512 -selfArg="$BASH_SOURCE" -if [ -z "$selfArg" ]; then - selfArg="$0" -fi - -self=$(realpath $selfArg 2> /dev/null) -if [ -z "$self" ]; then - self="$selfArg" -fi - -dir=$(cd "${self%[/\\]*}" > /dev/null; cd '../sabre/dav/bin' && pwd) - -if [ -d /proc/cygdrive ]; then - case $(which php) in - $(readlink -n /proc/cygdrive)/*) - # We are in Cygwin using Windows php, so the path must be translated - dir=$(cygpath -m "$dir"); - ;; - esac -fi - -export COMPOSER_RUNTIME_BIN_DIR="$(cd "${self%[/\\]*}" > /dev/null; pwd)" - -# If bash is sourcing this file, we have to source the target as well -bashSource="$BASH_SOURCE" -if [ -n "$bashSource" ]; then - if [ "$bashSource" != "$0" ]; then - source "${dir}/naturalselection" "$@" - return - fi -fi - -"${dir}/naturalselection" "$@" diff --git a/lib/vendor/bin/naturalselection.bat b/lib/vendor/bin/naturalselection.bat deleted file mode 100755 index 1979ed1..0000000 --- a/lib/vendor/bin/naturalselection.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/../sabre/dav/bin/naturalselection -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -python "%BIN_TARGET%" %* diff --git a/lib/vendor/bin/sabredav b/lib/vendor/bin/sabredav deleted file mode 100755 index 6e915f6..0000000 --- a/lib/vendor/bin/sabredav +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env sh - -# Support bash to support `source` with fallback on $0 if this does not run with bash -# https://stackoverflow.com/a/35006505/6512 -selfArg="$BASH_SOURCE" -if [ -z "$selfArg" ]; then - selfArg="$0" -fi - -self=$(realpath $selfArg 2> /dev/null) -if [ -z "$self" ]; then - self="$selfArg" -fi - -dir=$(cd "${self%[/\\]*}" > /dev/null; cd '../sabre/dav/bin' && pwd) - -if [ -d /proc/cygdrive ]; then - case $(which php) in - $(readlink -n /proc/cygdrive)/*) - # We are in Cygwin using Windows php, so the path must be translated - dir=$(cygpath -m "$dir"); - ;; - esac -fi - -export COMPOSER_RUNTIME_BIN_DIR="$(cd "${self%[/\\]*}" > /dev/null; pwd)" - -# If bash is sourcing this file, we have to source the target as well -bashSource="$BASH_SOURCE" -if [ -n "$bashSource" ]; then - if [ "$bashSource" != "$0" ]; then - source "${dir}/sabredav" "$@" - return - fi -fi - -"${dir}/sabredav" "$@" diff --git a/lib/vendor/bin/sabredav.bat b/lib/vendor/bin/sabredav.bat deleted file mode 100755 index ab3bbe6..0000000 --- a/lib/vendor/bin/sabredav.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/../sabre/dav/bin/sabredav -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -sh "%BIN_TARGET%" %* diff --git a/lib/vendor/bin/vobject b/lib/vendor/bin/vobject deleted file mode 100755 index 0a78d49..0000000 --- a/lib/vendor/bin/vobject +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if ( - (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) - || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) - ) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/sabre/vobject/bin/vobject'); - exit(0); - } -} - -include __DIR__ . '/..'.'/sabre/vobject/bin/vobject'; diff --git a/lib/vendor/bin/vobject.bat b/lib/vendor/bin/vobject.bat deleted file mode 100755 index c43b741..0000000 --- a/lib/vendor/bin/vobject.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/vobject -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/vendor/composer/ClassLoader.php b/lib/vendor/composer/ClassLoader.php deleted file mode 100644 index 7824d8f..0000000 --- a/lib/vendor/composer/ClassLoader.php +++ /dev/null @@ -1,579 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - /** @var \Closure(string):void */ - private static $includeFile; - - /** @var string|null */ - private $vendorDir; - - // PSR-4 - /** - * @var array> - */ - private $prefixLengthsPsr4 = array(); - /** - * @var array> - */ - private $prefixDirsPsr4 = array(); - /** - * @var list - */ - private $fallbackDirsPsr4 = array(); - - // PSR-0 - /** - * List of PSR-0 prefixes - * - * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) - * - * @var array>> - */ - private $prefixesPsr0 = array(); - /** - * @var list - */ - private $fallbackDirsPsr0 = array(); - - /** @var bool */ - private $useIncludePath = false; - - /** - * @var array - */ - private $classMap = array(); - - /** @var bool */ - private $classMapAuthoritative = false; - - /** - * @var array - */ - private $missingClasses = array(); - - /** @var string|null */ - private $apcuPrefix; - - /** - * @var array - */ - private static $registeredLoaders = array(); - - /** - * @param string|null $vendorDir - */ - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - self::initializeIncludeClosure(); - } - - /** - * @return array> - */ - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - /** - * @return array> - */ - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - /** - * @return list - */ - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - /** - * @return list - */ - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - /** - * @return array Array of classname => path - */ - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - * - * @return void - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - * - * @return void - */ - public function add($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 base directories - * - * @return void - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - * - * @return void - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - * - * @return void - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - * - * @return void - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - * - * @return void - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } - } - - /** - * Unregisters this instance as an autoloader. - * - * @return void - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return true|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - $includeFile = self::$includeFile; - $includeFile($file); - - return true; - } - - return null; - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - /** - * Returns the currently registered loaders keyed by their corresponding vendor directories. - * - * @return array - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - /** - * @param string $class - * @param string $ext - * @return string|false - */ - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } - - /** - * @return void - */ - private static function initializeIncludeClosure() - { - if (self::$includeFile !== null) { - return; - } - - /** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - */ - self::$includeFile = \Closure::bind(static function($file) { - include $file; - }, null, null); - } -} diff --git a/lib/vendor/composer/InstalledVersions.php b/lib/vendor/composer/InstalledVersions.php deleted file mode 100644 index 87766a2..0000000 --- a/lib/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,380 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer; - -use Composer\Autoload\ClassLoader; -use Composer\Semver\VersionParser; - -/** - * This class is copied in every Composer installed project and available to all - * - * See also https://getcomposer.org/doc/07-runtime.md#installed-versions - * - * To require its presence, you can require `composer-runtime-api ^2.0` - * - * @final - */ -class InstalledVersions -{ - /** - * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to - * @internal - */ - private static $selfDir = null; - - /** - * @var mixed[]|null - * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null - */ - private static $installed; - - /** - * @var bool|null - */ - private static $canGetVendors; - - /** - * @var array[] - * @psalm-var array}> - */ - private static $installedByVendor = array(); - - /** - * Returns a list of all package names which are present, either by being installed, replaced or provided - * - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackages() - { - $packages = array(); - foreach (self::getInstalled() as $installed) { - $packages[] = array_keys($installed['versions']); - } - - if (1 === \count($packages)) { - return $packages[0]; - } - - return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); - } - - /** - * Returns a list of all package names with a specific type e.g. 'library' - * - * @param string $type - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackagesByType($type) - { - $packagesByType = array(); - - foreach (self::getInstalled() as $installed) { - foreach ($installed['versions'] as $name => $package) { - if (isset($package['type']) && $package['type'] === $type) { - $packagesByType[] = $name; - } - } - } - - return $packagesByType; - } - - /** - * Checks whether the given package is installed - * - * This also returns true if the package name is provided or replaced by another package - * - * @param string $packageName - * @param bool $includeDevRequirements - * @return bool - */ - public static function isInstalled($packageName, $includeDevRequirements = true) - { - foreach (self::getInstalled() as $installed) { - if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; - } - } - - return false; - } - - /** - * Checks whether the given package satisfies a version constraint - * - * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: - * - * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') - * - * @param VersionParser $parser Install composer/semver to have access to this class and functionality - * @param string $packageName - * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package - * @return bool - */ - public static function satisfies(VersionParser $parser, $packageName, $constraint) - { - $constraint = $parser->parseConstraints((string) $constraint); - $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - - return $provided->matches($constraint); - } - - /** - * Returns a version constraint representing all the range(s) which are installed for a given package - * - * It is easier to use this via isInstalled() with the $constraint argument if you need to check - * whether a given version of a package is installed, and not just whether it exists - * - * @param string $packageName - * @return string Version constraint usable with composer/semver - */ - public static function getVersionRanges($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - $ranges = array(); - if (isset($installed['versions'][$packageName]['pretty_version'])) { - $ranges[] = $installed['versions'][$packageName]['pretty_version']; - } - if (array_key_exists('aliases', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); - } - if (array_key_exists('replaced', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); - } - if (array_key_exists('provided', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); - } - - return implode(' || ', $ranges); - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['version'])) { - return null; - } - - return $installed['versions'][$packageName]['version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getPrettyVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['pretty_version'])) { - return null; - } - - return $installed['versions'][$packageName]['pretty_version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference - */ - public static function getReference($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['reference'])) { - return null; - } - - return $installed['versions'][$packageName]['reference']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. - */ - public static function getInstallPath($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @return array - * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} - */ - public static function getRootPackage() - { - $installed = self::getInstalled(); - - return $installed[0]['root']; - } - - /** - * Returns the raw installed.php data for custom implementations - * - * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. - * @return array[] - * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} - */ - public static function getRawData() - { - @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = include __DIR__ . '/installed.php'; - } else { - self::$installed = array(); - } - } - - return self::$installed; - } - - /** - * Returns the raw data of all installed.php which are currently loaded for custom implementations - * - * @return array[] - * @psalm-return list}> - */ - public static function getAllRawData() - { - return self::getInstalled(); - } - - /** - * Lets you reload the static array from another file - * - * This is only useful for complex integrations in which a project needs to use - * this class but then also needs to execute another project's autoloader in process, - * and wants to ensure both projects have access to their version of installed.php. - * - * A typical case would be PHPUnit, where it would need to make sure it reads all - * the data it needs from this class, then call reload() with - * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure - * the project in which it runs can then also use this class safely, without - * interference between PHPUnit's dependencies and the project's dependencies. - * - * @param array[] $data A vendor/composer/installed.php data set - * @return void - * - * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data - */ - public static function reload($data) - { - self::$installed = $data; - self::$installedByVendor = array(); - } - - /** - * @return string - */ - private static function getSelfDir() - { - if (self::$selfDir === null) { - self::$selfDir = strtr(__DIR__, '\\', '/'); - } - - return self::$selfDir; - } - - /** - * @return array[] - * @psalm-return list}> - */ - private static function getInstalled() - { - if (null === self::$canGetVendors) { - self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); - } - - $installed = array(); - $copiedLocalDir = false; - - if (self::$canGetVendors) { - foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { - if (isset(self::$installedByVendor[$vendorDir])) { - $installed[] = self::$installedByVendor[$vendorDir]; - } elseif (is_file($vendorDir.'/composer/installed.php')) { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require $vendorDir.'/composer/installed.php'; - self::$installedByVendor[$vendorDir] = $required; - $installed[] = $required; - if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $required; - $copiedLocalDir = true; - } - } - } - } - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require __DIR__ . '/installed.php'; - self::$installed = $required; - } else { - self::$installed = array(); - } - } - - if (self::$installed !== array() && !$copiedLocalDir) { - $installed[] = self::$installed; - } - - return $installed; - } -} diff --git a/lib/vendor/composer/LICENSE b/lib/vendor/composer/LICENSE deleted file mode 100644 index 62ecfd8..0000000 --- a/lib/vendor/composer/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/lib/vendor/composer/autoload_classmap.php b/lib/vendor/composer/autoload_classmap.php deleted file mode 100644 index 6e01649..0000000 --- a/lib/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,370 +0,0 @@ - $vendorDir . '/composer/InstalledVersions.php', - 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/src/AbstractLogger.php', - 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/src/InvalidArgumentException.php', - 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/src/LogLevel.php', - 'Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/src/LoggerAwareInterface.php', - 'Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/src/LoggerAwareTrait.php', - 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/src/LoggerInterface.php', - 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/src/LoggerTrait.php', - 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/src/NullLogger.php', - 'Sabre\\CalDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php', - 'Sabre\\CalDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/BackendInterface.php', - 'Sabre\\CalDAV\\Backend\\NotificationSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php', - 'Sabre\\CalDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/PDO.php', - 'Sabre\\CalDAV\\Backend\\SchedulingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php', - 'Sabre\\CalDAV\\Backend\\SharingSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SharingSupport.php', - 'Sabre\\CalDAV\\Backend\\SimplePDO' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SimplePDO.php', - 'Sabre\\CalDAV\\Backend\\SubscriptionSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php', - 'Sabre\\CalDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CalDAV/Backend/SyncSupport.php', - 'Sabre\\CalDAV\\Calendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Calendar.php', - 'Sabre\\CalDAV\\CalendarHome' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarHome.php', - 'Sabre\\CalDAV\\CalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarObject.php', - 'Sabre\\CalDAV\\CalendarQueryValidator' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarQueryValidator.php', - 'Sabre\\CalDAV\\CalendarRoot' => $vendorDir . '/sabre/dav/lib/CalDAV/CalendarRoot.php', - 'Sabre\\CalDAV\\Exception\\InvalidComponentType' => $vendorDir . '/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php', - 'Sabre\\CalDAV\\ICSExportPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/ICSExportPlugin.php', - 'Sabre\\CalDAV\\ICalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendar.php', - 'Sabre\\CalDAV\\ICalendarObject' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObject.php', - 'Sabre\\CalDAV\\ICalendarObjectContainer' => $vendorDir . '/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php', - 'Sabre\\CalDAV\\ISharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/ISharedCalendar.php', - 'Sabre\\CalDAV\\Notifications\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Collection.php', - 'Sabre\\CalDAV\\Notifications\\ICollection' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/ICollection.php', - 'Sabre\\CalDAV\\Notifications\\INode' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/INode.php', - 'Sabre\\CalDAV\\Notifications\\Node' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Node.php', - 'Sabre\\CalDAV\\Notifications\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Notifications/Plugin.php', - 'Sabre\\CalDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Plugin.php', - 'Sabre\\CalDAV\\Principal\\Collection' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/Collection.php', - 'Sabre\\CalDAV\\Principal\\IProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyRead.php', - 'Sabre\\CalDAV\\Principal\\IProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/IProxyWrite.php', - 'Sabre\\CalDAV\\Principal\\ProxyRead' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyRead.php', - 'Sabre\\CalDAV\\Principal\\ProxyWrite' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php', - 'Sabre\\CalDAV\\Principal\\User' => $vendorDir . '/sabre/dav/lib/CalDAV/Principal/User.php', - 'Sabre\\CalDAV\\Schedule\\IInbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IInbox.php', - 'Sabre\\CalDAV\\Schedule\\IMipPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php', - 'Sabre\\CalDAV\\Schedule\\IOutbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/IOutbox.php', - 'Sabre\\CalDAV\\Schedule\\ISchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/ISchedulingObject.php', - 'Sabre\\CalDAV\\Schedule\\Inbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Inbox.php', - 'Sabre\\CalDAV\\Schedule\\Outbox' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Outbox.php', - 'Sabre\\CalDAV\\Schedule\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/Plugin.php', - 'Sabre\\CalDAV\\Schedule\\SchedulingObject' => $vendorDir . '/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php', - 'Sabre\\CalDAV\\SharedCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/SharedCalendar.php', - 'Sabre\\CalDAV\\SharingPlugin' => $vendorDir . '/sabre/dav/lib/CalDAV/SharingPlugin.php', - 'Sabre\\CalDAV\\Subscriptions\\ISubscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php', - 'Sabre\\CalDAV\\Subscriptions\\Plugin' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php', - 'Sabre\\CalDAV\\Subscriptions\\Subscription' => $vendorDir . '/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php', - 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php', - 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php', - 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php', - 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php', - 'Sabre\\CalDAV\\Xml\\Notification\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php', - 'Sabre\\CalDAV\\Xml\\Notification\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php', - 'Sabre\\CalDAV\\Xml\\Notification\\NotificationInterface' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php', - 'Sabre\\CalDAV\\Xml\\Notification\\SystemStatus' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php', - 'Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php', - 'Sabre\\CalDAV\\Xml\\Property\\EmailAddressSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php', - 'Sabre\\CalDAV\\Xml\\Property\\Invite' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/Invite.php', - 'Sabre\\CalDAV\\Xml\\Property\\ScheduleCalendarTransp' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php', - 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php', - 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarData' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php', - 'Sabre\\CalDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php', - 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php', - 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php', - 'Sabre\\CalDAV\\Xml\\Request\\FreeBusyQueryReport' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php', - 'Sabre\\CalDAV\\Xml\\Request\\InviteReply' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php', - 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php', - 'Sabre\\CalDAV\\Xml\\Request\\Share' => $vendorDir . '/sabre/dav/lib/CalDAV/Xml/Request/Share.php', - 'Sabre\\CardDAV\\AddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBook.php', - 'Sabre\\CardDAV\\AddressBookHome' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookHome.php', - 'Sabre\\CardDAV\\AddressBookRoot' => $vendorDir . '/sabre/dav/lib/CardDAV/AddressBookRoot.php', - 'Sabre\\CardDAV\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php', - 'Sabre\\CardDAV\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/BackendInterface.php', - 'Sabre\\CardDAV\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/PDO.php', - 'Sabre\\CardDAV\\Backend\\SyncSupport' => $vendorDir . '/sabre/dav/lib/CardDAV/Backend/SyncSupport.php', - 'Sabre\\CardDAV\\Card' => $vendorDir . '/sabre/dav/lib/CardDAV/Card.php', - 'Sabre\\CardDAV\\IAddressBook' => $vendorDir . '/sabre/dav/lib/CardDAV/IAddressBook.php', - 'Sabre\\CardDAV\\ICard' => $vendorDir . '/sabre/dav/lib/CardDAV/ICard.php', - 'Sabre\\CardDAV\\IDirectory' => $vendorDir . '/sabre/dav/lib/CardDAV/IDirectory.php', - 'Sabre\\CardDAV\\Plugin' => $vendorDir . '/sabre/dav/lib/CardDAV/Plugin.php', - 'Sabre\\CardDAV\\VCFExportPlugin' => $vendorDir . '/sabre/dav/lib/CardDAV/VCFExportPlugin.php', - 'Sabre\\CardDAV\\Xml\\Filter\\AddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php', - 'Sabre\\CardDAV\\Xml\\Filter\\ParamFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php', - 'Sabre\\CardDAV\\Xml\\Filter\\PropFilter' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php', - 'Sabre\\CardDAV\\Xml\\Property\\SupportedAddressData' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php', - 'Sabre\\CardDAV\\Xml\\Property\\SupportedCollationSet' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php', - 'Sabre\\CardDAV\\Xml\\Request\\AddressBookMultiGetReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php', - 'Sabre\\CardDAV\\Xml\\Request\\AddressBookQueryReport' => $vendorDir . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php', - 'Sabre\\DAVACL\\ACLTrait' => $vendorDir . '/sabre/dav/lib/DAVACL/ACLTrait.php', - 'Sabre\\DAVACL\\AbstractPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php', - 'Sabre\\DAVACL\\Exception\\AceConflict' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/AceConflict.php', - 'Sabre\\DAVACL\\Exception\\NeedPrivileges' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php', - 'Sabre\\DAVACL\\Exception\\NoAbstract' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NoAbstract.php', - 'Sabre\\DAVACL\\Exception\\NotRecognizedPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php', - 'Sabre\\DAVACL\\Exception\\NotSupportedPrivilege' => $vendorDir . '/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php', - 'Sabre\\DAVACL\\FS\\Collection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/Collection.php', - 'Sabre\\DAVACL\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/File.php', - 'Sabre\\DAVACL\\FS\\HomeCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/FS/HomeCollection.php', - 'Sabre\\DAVACL\\IACL' => $vendorDir . '/sabre/dav/lib/DAVACL/IACL.php', - 'Sabre\\DAVACL\\IPrincipal' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipal.php', - 'Sabre\\DAVACL\\IPrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/IPrincipalCollection.php', - 'Sabre\\DAVACL\\Plugin' => $vendorDir . '/sabre/dav/lib/DAVACL/Plugin.php', - 'Sabre\\DAVACL\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Principal.php', - 'Sabre\\DAVACL\\PrincipalBackend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php', - 'Sabre\\DAVACL\\PrincipalBackend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php', - 'Sabre\\DAVACL\\PrincipalBackend\\CreatePrincipalSupport' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/CreatePrincipalSupport.php', - 'Sabre\\DAVACL\\PrincipalBackend\\PDO' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php', - 'Sabre\\DAVACL\\PrincipalCollection' => $vendorDir . '/sabre/dav/lib/DAVACL/PrincipalCollection.php', - 'Sabre\\DAVACL\\Xml\\Property\\Acl' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Acl.php', - 'Sabre\\DAVACL\\Xml\\Property\\AclRestrictions' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php', - 'Sabre\\DAVACL\\Xml\\Property\\CurrentUserPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php', - 'Sabre\\DAVACL\\Xml\\Property\\Principal' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/Principal.php', - 'Sabre\\DAVACL\\Xml\\Property\\SupportedPrivilegeSet' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php', - 'Sabre\\DAVACL\\Xml\\Request\\AclPrincipalPropSetReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\PrincipalMatchReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport' => $vendorDir . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php', - 'Sabre\\DAV\\Auth\\Backend\\AbstractBasic' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php', - 'Sabre\\DAV\\Auth\\Backend\\AbstractBearer' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php', - 'Sabre\\DAV\\Auth\\Backend\\AbstractDigest' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php', - 'Sabre\\DAV\\Auth\\Backend\\Apache' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/Apache.php', - 'Sabre\\DAV\\Auth\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php', - 'Sabre\\DAV\\Auth\\Backend\\BasicCallBack' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php', - 'Sabre\\DAV\\Auth\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/File.php', - 'Sabre\\DAV\\Auth\\Backend\\IMAP' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/IMAP.php', - 'Sabre\\DAV\\Auth\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/PDO.php', - 'Sabre\\DAV\\Auth\\Backend\\PDOBasicAuth' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Backend/PDOBasicAuth.php', - 'Sabre\\DAV\\Auth\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Auth/Plugin.php', - 'Sabre\\DAV\\Browser\\GuessContentType' => $vendorDir . '/sabre/dav/lib/DAV/Browser/GuessContentType.php', - 'Sabre\\DAV\\Browser\\HtmlOutput' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutput.php', - 'Sabre\\DAV\\Browser\\HtmlOutputHelper' => $vendorDir . '/sabre/dav/lib/DAV/Browser/HtmlOutputHelper.php', - 'Sabre\\DAV\\Browser\\MapGetToPropFind' => $vendorDir . '/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php', - 'Sabre\\DAV\\Browser\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Browser/Plugin.php', - 'Sabre\\DAV\\Browser\\PropFindAll' => $vendorDir . '/sabre/dav/lib/DAV/Browser/PropFindAll.php', - 'Sabre\\DAV\\Client' => $vendorDir . '/sabre/dav/lib/DAV/Client.php', - 'Sabre\\DAV\\Collection' => $vendorDir . '/sabre/dav/lib/DAV/Collection.php', - 'Sabre\\DAV\\CorePlugin' => $vendorDir . '/sabre/dav/lib/DAV/CorePlugin.php', - 'Sabre\\DAV\\Exception' => $vendorDir . '/sabre/dav/lib/DAV/Exception.php', - 'Sabre\\DAV\\Exception\\BadRequest' => $vendorDir . '/sabre/dav/lib/DAV/Exception/BadRequest.php', - 'Sabre\\DAV\\Exception\\Conflict' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Conflict.php', - 'Sabre\\DAV\\Exception\\ConflictingLock' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ConflictingLock.php', - 'Sabre\\DAV\\Exception\\Forbidden' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Forbidden.php', - 'Sabre\\DAV\\Exception\\InsufficientStorage' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InsufficientStorage.php', - 'Sabre\\DAV\\Exception\\InvalidResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidResourceType.php', - 'Sabre\\DAV\\Exception\\InvalidSyncToken' => $vendorDir . '/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php', - 'Sabre\\DAV\\Exception\\LengthRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LengthRequired.php', - 'Sabre\\DAV\\Exception\\LockTokenMatchesRequestUri' => $vendorDir . '/sabre/dav/lib/DAV/Exception/LockTokenMatchesRequestUri.php', - 'Sabre\\DAV\\Exception\\Locked' => $vendorDir . '/sabre/dav/lib/DAV/Exception/Locked.php', - 'Sabre\\DAV\\Exception\\MethodNotAllowed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php', - 'Sabre\\DAV\\Exception\\NotAuthenticated' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotAuthenticated.php', - 'Sabre\\DAV\\Exception\\NotFound' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotFound.php', - 'Sabre\\DAV\\Exception\\NotImplemented' => $vendorDir . '/sabre/dav/lib/DAV/Exception/NotImplemented.php', - 'Sabre\\DAV\\Exception\\PaymentRequired' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PaymentRequired.php', - 'Sabre\\DAV\\Exception\\PreconditionFailed' => $vendorDir . '/sabre/dav/lib/DAV/Exception/PreconditionFailed.php', - 'Sabre\\DAV\\Exception\\ReportNotSupported' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ReportNotSupported.php', - 'Sabre\\DAV\\Exception\\RequestedRangeNotSatisfiable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php', - 'Sabre\\DAV\\Exception\\ServiceUnavailable' => $vendorDir . '/sabre/dav/lib/DAV/Exception/ServiceUnavailable.php', - 'Sabre\\DAV\\Exception\\TooManyMatches' => $vendorDir . '/sabre/dav/lib/DAV/Exception/TooManyMatches.php', - 'Sabre\\DAV\\Exception\\UnsupportedMediaType' => $vendorDir . '/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php', - 'Sabre\\DAV\\FSExt\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/Directory.php', - 'Sabre\\DAV\\FSExt\\File' => $vendorDir . '/sabre/dav/lib/DAV/FSExt/File.php', - 'Sabre\\DAV\\FS\\Directory' => $vendorDir . '/sabre/dav/lib/DAV/FS/Directory.php', - 'Sabre\\DAV\\FS\\File' => $vendorDir . '/sabre/dav/lib/DAV/FS/File.php', - 'Sabre\\DAV\\FS\\Node' => $vendorDir . '/sabre/dav/lib/DAV/FS/Node.php', - 'Sabre\\DAV\\File' => $vendorDir . '/sabre/dav/lib/DAV/File.php', - 'Sabre\\DAV\\ICollection' => $vendorDir . '/sabre/dav/lib/DAV/ICollection.php', - 'Sabre\\DAV\\ICopyTarget' => $vendorDir . '/sabre/dav/lib/DAV/ICopyTarget.php', - 'Sabre\\DAV\\IExtendedCollection' => $vendorDir . '/sabre/dav/lib/DAV/IExtendedCollection.php', - 'Sabre\\DAV\\IFile' => $vendorDir . '/sabre/dav/lib/DAV/IFile.php', - 'Sabre\\DAV\\IMoveTarget' => $vendorDir . '/sabre/dav/lib/DAV/IMoveTarget.php', - 'Sabre\\DAV\\IMultiGet' => $vendorDir . '/sabre/dav/lib/DAV/IMultiGet.php', - 'Sabre\\DAV\\INode' => $vendorDir . '/sabre/dav/lib/DAV/INode.php', - 'Sabre\\DAV\\INodeByPath' => $vendorDir . '/sabre/dav/lib/DAV/INodeByPath.php', - 'Sabre\\DAV\\IProperties' => $vendorDir . '/sabre/dav/lib/DAV/IProperties.php', - 'Sabre\\DAV\\IQuota' => $vendorDir . '/sabre/dav/lib/DAV/IQuota.php', - 'Sabre\\DAV\\Locks\\Backend\\AbstractBackend' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/AbstractBackend.php', - 'Sabre\\DAV\\Locks\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/BackendInterface.php', - 'Sabre\\DAV\\Locks\\Backend\\File' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/File.php', - 'Sabre\\DAV\\Locks\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Backend/PDO.php', - 'Sabre\\DAV\\Locks\\LockInfo' => $vendorDir . '/sabre/dav/lib/DAV/Locks/LockInfo.php', - 'Sabre\\DAV\\Locks\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Locks/Plugin.php', - 'Sabre\\DAV\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/MkCol.php', - 'Sabre\\DAV\\Mount\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Mount/Plugin.php', - 'Sabre\\DAV\\Node' => $vendorDir . '/sabre/dav/lib/DAV/Node.php', - 'Sabre\\DAV\\PartialUpdate\\IPatchSupport' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/IPatchSupport.php', - 'Sabre\\DAV\\PartialUpdate\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PartialUpdate/Plugin.php', - 'Sabre\\DAV\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/PropFind.php', - 'Sabre\\DAV\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/PropPatch.php', - 'Sabre\\DAV\\PropertyStorage\\Backend\\BackendInterface' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php', - 'Sabre\\DAV\\PropertyStorage\\Backend\\PDO' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php', - 'Sabre\\DAV\\PropertyStorage\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/PropertyStorage/Plugin.php', - 'Sabre\\DAV\\Server' => $vendorDir . '/sabre/dav/lib/DAV/Server.php', - 'Sabre\\DAV\\ServerPlugin' => $vendorDir . '/sabre/dav/lib/DAV/ServerPlugin.php', - 'Sabre\\DAV\\Sharing\\ISharedNode' => $vendorDir . '/sabre/dav/lib/DAV/Sharing/ISharedNode.php', - 'Sabre\\DAV\\Sharing\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Sharing/Plugin.php', - 'Sabre\\DAV\\SimpleCollection' => $vendorDir . '/sabre/dav/lib/DAV/SimpleCollection.php', - 'Sabre\\DAV\\SimpleFile' => $vendorDir . '/sabre/dav/lib/DAV/SimpleFile.php', - 'Sabre\\DAV\\StringUtil' => $vendorDir . '/sabre/dav/lib/DAV/StringUtil.php', - 'Sabre\\DAV\\Sync\\ISyncCollection' => $vendorDir . '/sabre/dav/lib/DAV/Sync/ISyncCollection.php', - 'Sabre\\DAV\\Sync\\Plugin' => $vendorDir . '/sabre/dav/lib/DAV/Sync/Plugin.php', - 'Sabre\\DAV\\TemporaryFileFilterPlugin' => $vendorDir . '/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php', - 'Sabre\\DAV\\Tree' => $vendorDir . '/sabre/dav/lib/DAV/Tree.php', - 'Sabre\\DAV\\UUIDUtil' => $vendorDir . '/sabre/dav/lib/DAV/UUIDUtil.php', - 'Sabre\\DAV\\Version' => $vendorDir . '/sabre/dav/lib/DAV/Version.php', - 'Sabre\\DAV\\Xml\\Element\\Prop' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Prop.php', - 'Sabre\\DAV\\Xml\\Element\\Response' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Response.php', - 'Sabre\\DAV\\Xml\\Element\\Sharee' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Element/Sharee.php', - 'Sabre\\DAV\\Xml\\Property\\Complex' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Complex.php', - 'Sabre\\DAV\\Xml\\Property\\GetLastModified' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php', - 'Sabre\\DAV\\Xml\\Property\\Href' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Href.php', - 'Sabre\\DAV\\Xml\\Property\\Invite' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/Invite.php', - 'Sabre\\DAV\\Xml\\Property\\LocalHref' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/LocalHref.php', - 'Sabre\\DAV\\Xml\\Property\\LockDiscovery' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/LockDiscovery.php', - 'Sabre\\DAV\\Xml\\Property\\ResourceType' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/ResourceType.php', - 'Sabre\\DAV\\Xml\\Property\\ShareAccess' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php', - 'Sabre\\DAV\\Xml\\Property\\SupportedLock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php', - 'Sabre\\DAV\\Xml\\Property\\SupportedMethodSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php', - 'Sabre\\DAV\\Xml\\Property\\SupportedReportSet' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php', - 'Sabre\\DAV\\Xml\\Request\\Lock' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/Lock.php', - 'Sabre\\DAV\\Xml\\Request\\MkCol' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/MkCol.php', - 'Sabre\\DAV\\Xml\\Request\\PropFind' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropFind.php', - 'Sabre\\DAV\\Xml\\Request\\PropPatch' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/PropPatch.php', - 'Sabre\\DAV\\Xml\\Request\\ShareResource' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/ShareResource.php', - 'Sabre\\DAV\\Xml\\Request\\SyncCollectionReport' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php', - 'Sabre\\DAV\\Xml\\Response\\MultiStatus' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php', - 'Sabre\\DAV\\Xml\\Service' => $vendorDir . '/sabre/dav/lib/DAV/Xml/Service.php', - 'Sabre\\Event\\Emitter' => $vendorDir . '/sabre/event/lib/Emitter.php', - 'Sabre\\Event\\EmitterInterface' => $vendorDir . '/sabre/event/lib/EmitterInterface.php', - 'Sabre\\Event\\EmitterTrait' => $vendorDir . '/sabre/event/lib/EmitterTrait.php', - 'Sabre\\Event\\EventEmitter' => $vendorDir . '/sabre/event/lib/EventEmitter.php', - 'Sabre\\Event\\Loop\\Loop' => $vendorDir . '/sabre/event/lib/Loop/Loop.php', - 'Sabre\\Event\\Promise' => $vendorDir . '/sabre/event/lib/Promise.php', - 'Sabre\\Event\\PromiseAlreadyResolvedException' => $vendorDir . '/sabre/event/lib/PromiseAlreadyResolvedException.php', - 'Sabre\\Event\\Version' => $vendorDir . '/sabre/event/lib/Version.php', - 'Sabre\\Event\\WildcardEmitter' => $vendorDir . '/sabre/event/lib/WildcardEmitter.php', - 'Sabre\\Event\\WildcardEmitterTrait' => $vendorDir . '/sabre/event/lib/WildcardEmitterTrait.php', - 'Sabre\\HTTP\\Auth\\AWS' => $vendorDir . '/sabre/http/lib/Auth/AWS.php', - 'Sabre\\HTTP\\Auth\\AbstractAuth' => $vendorDir . '/sabre/http/lib/Auth/AbstractAuth.php', - 'Sabre\\HTTP\\Auth\\Basic' => $vendorDir . '/sabre/http/lib/Auth/Basic.php', - 'Sabre\\HTTP\\Auth\\Bearer' => $vendorDir . '/sabre/http/lib/Auth/Bearer.php', - 'Sabre\\HTTP\\Auth\\Digest' => $vendorDir . '/sabre/http/lib/Auth/Digest.php', - 'Sabre\\HTTP\\Client' => $vendorDir . '/sabre/http/lib/Client.php', - 'Sabre\\HTTP\\ClientException' => $vendorDir . '/sabre/http/lib/ClientException.php', - 'Sabre\\HTTP\\ClientHttpException' => $vendorDir . '/sabre/http/lib/ClientHttpException.php', - 'Sabre\\HTTP\\HttpException' => $vendorDir . '/sabre/http/lib/HttpException.php', - 'Sabre\\HTTP\\Message' => $vendorDir . '/sabre/http/lib/Message.php', - 'Sabre\\HTTP\\MessageDecoratorTrait' => $vendorDir . '/sabre/http/lib/MessageDecoratorTrait.php', - 'Sabre\\HTTP\\MessageInterface' => $vendorDir . '/sabre/http/lib/MessageInterface.php', - 'Sabre\\HTTP\\Request' => $vendorDir . '/sabre/http/lib/Request.php', - 'Sabre\\HTTP\\RequestDecorator' => $vendorDir . '/sabre/http/lib/RequestDecorator.php', - 'Sabre\\HTTP\\RequestInterface' => $vendorDir . '/sabre/http/lib/RequestInterface.php', - 'Sabre\\HTTP\\Response' => $vendorDir . '/sabre/http/lib/Response.php', - 'Sabre\\HTTP\\ResponseDecorator' => $vendorDir . '/sabre/http/lib/ResponseDecorator.php', - 'Sabre\\HTTP\\ResponseInterface' => $vendorDir . '/sabre/http/lib/ResponseInterface.php', - 'Sabre\\HTTP\\Sapi' => $vendorDir . '/sabre/http/lib/Sapi.php', - 'Sabre\\HTTP\\Version' => $vendorDir . '/sabre/http/lib/Version.php', - 'Sabre\\Uri\\InvalidUriException' => $vendorDir . '/sabre/uri/lib/InvalidUriException.php', - 'Sabre\\Uri\\Version' => $vendorDir . '/sabre/uri/lib/Version.php', - 'Sabre\\VObject\\BirthdayCalendarGenerator' => $vendorDir . '/sabre/vobject/lib/BirthdayCalendarGenerator.php', - 'Sabre\\VObject\\Cli' => $vendorDir . '/sabre/vobject/lib/Cli.php', - 'Sabre\\VObject\\Component' => $vendorDir . '/sabre/vobject/lib/Component.php', - 'Sabre\\VObject\\Component\\Available' => $vendorDir . '/sabre/vobject/lib/Component/Available.php', - 'Sabre\\VObject\\Component\\VAlarm' => $vendorDir . '/sabre/vobject/lib/Component/VAlarm.php', - 'Sabre\\VObject\\Component\\VAvailability' => $vendorDir . '/sabre/vobject/lib/Component/VAvailability.php', - 'Sabre\\VObject\\Component\\VCalendar' => $vendorDir . '/sabre/vobject/lib/Component/VCalendar.php', - 'Sabre\\VObject\\Component\\VCard' => $vendorDir . '/sabre/vobject/lib/Component/VCard.php', - 'Sabre\\VObject\\Component\\VEvent' => $vendorDir . '/sabre/vobject/lib/Component/VEvent.php', - 'Sabre\\VObject\\Component\\VFreeBusy' => $vendorDir . '/sabre/vobject/lib/Component/VFreeBusy.php', - 'Sabre\\VObject\\Component\\VJournal' => $vendorDir . '/sabre/vobject/lib/Component/VJournal.php', - 'Sabre\\VObject\\Component\\VTimeZone' => $vendorDir . '/sabre/vobject/lib/Component/VTimeZone.php', - 'Sabre\\VObject\\Component\\VTodo' => $vendorDir . '/sabre/vobject/lib/Component/VTodo.php', - 'Sabre\\VObject\\DateTimeParser' => $vendorDir . '/sabre/vobject/lib/DateTimeParser.php', - 'Sabre\\VObject\\Document' => $vendorDir . '/sabre/vobject/lib/Document.php', - 'Sabre\\VObject\\ElementList' => $vendorDir . '/sabre/vobject/lib/ElementList.php', - 'Sabre\\VObject\\EofException' => $vendorDir . '/sabre/vobject/lib/EofException.php', - 'Sabre\\VObject\\FreeBusyData' => $vendorDir . '/sabre/vobject/lib/FreeBusyData.php', - 'Sabre\\VObject\\FreeBusyGenerator' => $vendorDir . '/sabre/vobject/lib/FreeBusyGenerator.php', - 'Sabre\\VObject\\ITip\\Broker' => $vendorDir . '/sabre/vobject/lib/ITip/Broker.php', - 'Sabre\\VObject\\ITip\\ITipException' => $vendorDir . '/sabre/vobject/lib/ITip/ITipException.php', - 'Sabre\\VObject\\ITip\\Message' => $vendorDir . '/sabre/vobject/lib/ITip/Message.php', - 'Sabre\\VObject\\ITip\\SameOrganizerForAllComponentsException' => $vendorDir . '/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php', - 'Sabre\\VObject\\InvalidDataException' => $vendorDir . '/sabre/vobject/lib/InvalidDataException.php', - 'Sabre\\VObject\\Node' => $vendorDir . '/sabre/vobject/lib/Node.php', - 'Sabre\\VObject\\PHPUnitAssertions' => $vendorDir . '/sabre/vobject/lib/PHPUnitAssertions.php', - 'Sabre\\VObject\\Parameter' => $vendorDir . '/sabre/vobject/lib/Parameter.php', - 'Sabre\\VObject\\ParseException' => $vendorDir . '/sabre/vobject/lib/ParseException.php', - 'Sabre\\VObject\\Parser\\Json' => $vendorDir . '/sabre/vobject/lib/Parser/Json.php', - 'Sabre\\VObject\\Parser\\MimeDir' => $vendorDir . '/sabre/vobject/lib/Parser/MimeDir.php', - 'Sabre\\VObject\\Parser\\Parser' => $vendorDir . '/sabre/vobject/lib/Parser/Parser.php', - 'Sabre\\VObject\\Parser\\XML' => $vendorDir . '/sabre/vobject/lib/Parser/XML.php', - 'Sabre\\VObject\\Parser\\XML\\Element\\KeyValue' => $vendorDir . '/sabre/vobject/lib/Parser/XML/Element/KeyValue.php', - 'Sabre\\VObject\\Property' => $vendorDir . '/sabre/vobject/lib/Property.php', - 'Sabre\\VObject\\Property\\Binary' => $vendorDir . '/sabre/vobject/lib/Property/Binary.php', - 'Sabre\\VObject\\Property\\Boolean' => $vendorDir . '/sabre/vobject/lib/Property/Boolean.php', - 'Sabre\\VObject\\Property\\FlatText' => $vendorDir . '/sabre/vobject/lib/Property/FlatText.php', - 'Sabre\\VObject\\Property\\FloatValue' => $vendorDir . '/sabre/vobject/lib/Property/FloatValue.php', - 'Sabre\\VObject\\Property\\ICalendar\\CalAddress' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/CalAddress.php', - 'Sabre\\VObject\\Property\\ICalendar\\Date' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Date.php', - 'Sabre\\VObject\\Property\\ICalendar\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/DateTime.php', - 'Sabre\\VObject\\Property\\ICalendar\\Duration' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Duration.php', - 'Sabre\\VObject\\Property\\ICalendar\\Period' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Period.php', - 'Sabre\\VObject\\Property\\ICalendar\\Recur' => $vendorDir . '/sabre/vobject/lib/Property/ICalendar/Recur.php', - 'Sabre\\VObject\\Property\\IntegerValue' => $vendorDir . '/sabre/vobject/lib/Property/IntegerValue.php', - 'Sabre\\VObject\\Property\\Text' => $vendorDir . '/sabre/vobject/lib/Property/Text.php', - 'Sabre\\VObject\\Property\\Time' => $vendorDir . '/sabre/vobject/lib/Property/Time.php', - 'Sabre\\VObject\\Property\\Unknown' => $vendorDir . '/sabre/vobject/lib/Property/Unknown.php', - 'Sabre\\VObject\\Property\\Uri' => $vendorDir . '/sabre/vobject/lib/Property/Uri.php', - 'Sabre\\VObject\\Property\\UtcOffset' => $vendorDir . '/sabre/vobject/lib/Property/UtcOffset.php', - 'Sabre\\VObject\\Property\\VCard\\Date' => $vendorDir . '/sabre/vobject/lib/Property/VCard/Date.php', - 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateAndOrTime.php', - 'Sabre\\VObject\\Property\\VCard\\DateTime' => $vendorDir . '/sabre/vobject/lib/Property/VCard/DateTime.php', - 'Sabre\\VObject\\Property\\VCard\\LanguageTag' => $vendorDir . '/sabre/vobject/lib/Property/VCard/LanguageTag.php', - 'Sabre\\VObject\\Property\\VCard\\PhoneNumber' => $vendorDir . '/sabre/vobject/lib/Property/VCard/PhoneNumber.php', - 'Sabre\\VObject\\Property\\VCard\\TimeStamp' => $vendorDir . '/sabre/vobject/lib/Property/VCard/TimeStamp.php', - 'Sabre\\VObject\\Reader' => $vendorDir . '/sabre/vobject/lib/Reader.php', - 'Sabre\\VObject\\Recur\\EventIterator' => $vendorDir . '/sabre/vobject/lib/Recur/EventIterator.php', - 'Sabre\\VObject\\Recur\\MaxInstancesExceededException' => $vendorDir . '/sabre/vobject/lib/Recur/MaxInstancesExceededException.php', - 'Sabre\\VObject\\Recur\\NoInstancesException' => $vendorDir . '/sabre/vobject/lib/Recur/NoInstancesException.php', - 'Sabre\\VObject\\Recur\\RDateIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RDateIterator.php', - 'Sabre\\VObject\\Recur\\RRuleIterator' => $vendorDir . '/sabre/vobject/lib/Recur/RRuleIterator.php', - 'Sabre\\VObject\\Settings' => $vendorDir . '/sabre/vobject/lib/Settings.php', - 'Sabre\\VObject\\Splitter\\ICalendar' => $vendorDir . '/sabre/vobject/lib/Splitter/ICalendar.php', - 'Sabre\\VObject\\Splitter\\SplitterInterface' => $vendorDir . '/sabre/vobject/lib/Splitter/SplitterInterface.php', - 'Sabre\\VObject\\Splitter\\VCard' => $vendorDir . '/sabre/vobject/lib/Splitter/VCard.php', - 'Sabre\\VObject\\StringUtil' => $vendorDir . '/sabre/vobject/lib/StringUtil.php', - 'Sabre\\VObject\\TimeZoneUtil' => $vendorDir . '/sabre/vobject/lib/TimeZoneUtil.php', - 'Sabre\\VObject\\TimezoneGuesser\\FindFromOffset' => $vendorDir . '/sabre/vobject/lib/TimezoneGuesser/FindFromOffset.php', - 'Sabre\\VObject\\TimezoneGuesser\\FindFromTimezoneIdentifier' => $vendorDir . '/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php', - 'Sabre\\VObject\\TimezoneGuesser\\FindFromTimezoneMap' => $vendorDir . '/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneMap.php', - 'Sabre\\VObject\\TimezoneGuesser\\GuessFromLicEntry' => $vendorDir . '/sabre/vobject/lib/TimezoneGuesser/GuessFromLicEntry.php', - 'Sabre\\VObject\\TimezoneGuesser\\GuessFromMsTzId' => $vendorDir . '/sabre/vobject/lib/TimezoneGuesser/GuessFromMsTzId.php', - 'Sabre\\VObject\\TimezoneGuesser\\TimezoneFinder' => $vendorDir . '/sabre/vobject/lib/TimezoneGuesser/TimezoneFinder.php', - 'Sabre\\VObject\\TimezoneGuesser\\TimezoneGuesser' => $vendorDir . '/sabre/vobject/lib/TimezoneGuesser/TimezoneGuesser.php', - 'Sabre\\VObject\\UUIDUtil' => $vendorDir . '/sabre/vobject/lib/UUIDUtil.php', - 'Sabre\\VObject\\VCardConverter' => $vendorDir . '/sabre/vobject/lib/VCardConverter.php', - 'Sabre\\VObject\\Version' => $vendorDir . '/sabre/vobject/lib/Version.php', - 'Sabre\\VObject\\Writer' => $vendorDir . '/sabre/vobject/lib/Writer.php', - 'Sabre\\Xml\\ContextStackTrait' => $vendorDir . '/sabre/xml/lib/ContextStackTrait.php', - 'Sabre\\Xml\\Element' => $vendorDir . '/sabre/xml/lib/Element.php', - 'Sabre\\Xml\\Element\\Base' => $vendorDir . '/sabre/xml/lib/Element/Base.php', - 'Sabre\\Xml\\Element\\Cdata' => $vendorDir . '/sabre/xml/lib/Element/Cdata.php', - 'Sabre\\Xml\\Element\\Elements' => $vendorDir . '/sabre/xml/lib/Element/Elements.php', - 'Sabre\\Xml\\Element\\KeyValue' => $vendorDir . '/sabre/xml/lib/Element/KeyValue.php', - 'Sabre\\Xml\\Element\\Uri' => $vendorDir . '/sabre/xml/lib/Element/Uri.php', - 'Sabre\\Xml\\Element\\XmlFragment' => $vendorDir . '/sabre/xml/lib/Element/XmlFragment.php', - 'Sabre\\Xml\\LibXMLException' => $vendorDir . '/sabre/xml/lib/LibXMLException.php', - 'Sabre\\Xml\\ParseException' => $vendorDir . '/sabre/xml/lib/ParseException.php', - 'Sabre\\Xml\\Reader' => $vendorDir . '/sabre/xml/lib/Reader.php', - 'Sabre\\Xml\\Service' => $vendorDir . '/sabre/xml/lib/Service.php', - 'Sabre\\Xml\\Version' => $vendorDir . '/sabre/xml/lib/Version.php', - 'Sabre\\Xml\\Writer' => $vendorDir . '/sabre/xml/lib/Writer.php', - 'Sabre\\Xml\\XmlDeserializable' => $vendorDir . '/sabre/xml/lib/XmlDeserializable.php', - 'Sabre\\Xml\\XmlSerializable' => $vendorDir . '/sabre/xml/lib/XmlSerializable.php', -); diff --git a/lib/vendor/composer/autoload_files.php b/lib/vendor/composer/autoload_files.php deleted file mode 100644 index 674815f..0000000 --- a/lib/vendor/composer/autoload_files.php +++ /dev/null @@ -1,16 +0,0 @@ - $vendorDir . '/sabre/uri/lib/functions.php', - '2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php', - 'd81bab31d3feb45bfe2f283ea3c8fdf7' => $vendorDir . '/sabre/event/lib/Loop/functions.php', - 'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php', - '3569eecfeed3bcf0bad3c998a494ecb8' => $vendorDir . '/sabre/xml/lib/Deserializer/functions.php', - '93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php', - 'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php', -); diff --git a/lib/vendor/composer/autoload_namespaces.php b/lib/vendor/composer/autoload_namespaces.php deleted file mode 100644 index f1ae7a0..0000000 --- a/lib/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,9 +0,0 @@ - array($vendorDir . '/sabre/xml/lib'), - 'Sabre\\VObject\\' => array($vendorDir . '/sabre/vobject/lib'), - 'Sabre\\Uri\\' => array($vendorDir . '/sabre/uri/lib'), - 'Sabre\\HTTP\\' => array($vendorDir . '/sabre/http/lib'), - 'Sabre\\Event\\' => array($vendorDir . '/sabre/event/lib'), - 'Sabre\\' => array($vendorDir . '/sabre/dav/lib'), - 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), -); diff --git a/lib/vendor/composer/autoload_real.php b/lib/vendor/composer/autoload_real.php deleted file mode 100644 index 6286096..0000000 --- a/lib/vendor/composer/autoload_real.php +++ /dev/null @@ -1,50 +0,0 @@ -register(true); - - $filesToLoad = \Composer\Autoload\ComposerStaticInita07591154e0386cfc9ad0f9217878d04::$files; - $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - - require $file; - } - }, null, null); - foreach ($filesToLoad as $fileIdentifier => $file) { - $requireFile($fileIdentifier, $file); - } - - return $loader; - } -} diff --git a/lib/vendor/composer/autoload_static.php b/lib/vendor/composer/autoload_static.php deleted file mode 100644 index 307e983..0000000 --- a/lib/vendor/composer/autoload_static.php +++ /dev/null @@ -1,439 +0,0 @@ - __DIR__ . '/..' . '/sabre/uri/lib/functions.php', - '2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php', - 'd81bab31d3feb45bfe2f283ea3c8fdf7' => __DIR__ . '/..' . '/sabre/event/lib/Loop/functions.php', - 'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php', - '3569eecfeed3bcf0bad3c998a494ecb8' => __DIR__ . '/..' . '/sabre/xml/lib/Deserializer/functions.php', - '93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php', - 'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'S' => - array ( - 'Sabre\\Xml\\' => 10, - 'Sabre\\VObject\\' => 14, - 'Sabre\\Uri\\' => 10, - 'Sabre\\HTTP\\' => 11, - 'Sabre\\Event\\' => 12, - 'Sabre\\' => 6, - ), - 'P' => - array ( - 'Psr\\Log\\' => 8, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'Sabre\\Xml\\' => - array ( - 0 => __DIR__ . '/..' . '/sabre/xml/lib', - ), - 'Sabre\\VObject\\' => - array ( - 0 => __DIR__ . '/..' . '/sabre/vobject/lib', - ), - 'Sabre\\Uri\\' => - array ( - 0 => __DIR__ . '/..' . '/sabre/uri/lib', - ), - 'Sabre\\HTTP\\' => - array ( - 0 => __DIR__ . '/..' . '/sabre/http/lib', - ), - 'Sabre\\Event\\' => - array ( - 0 => __DIR__ . '/..' . '/sabre/event/lib', - ), - 'Sabre\\' => - array ( - 0 => __DIR__ . '/..' . '/sabre/dav/lib', - ), - 'Psr\\Log\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/log/src', - ), - ); - - public static $classMap = array ( - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - 'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/src/AbstractLogger.php', - 'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/src/InvalidArgumentException.php', - 'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/src/LogLevel.php', - 'Psr\\Log\\LoggerAwareInterface' => __DIR__ . '/..' . '/psr/log/src/LoggerAwareInterface.php', - 'Psr\\Log\\LoggerAwareTrait' => __DIR__ . '/..' . '/psr/log/src/LoggerAwareTrait.php', - 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/src/LoggerInterface.php', - 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/src/LoggerTrait.php', - 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/src/NullLogger.php', - 'Sabre\\CalDAV\\Backend\\AbstractBackend' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php', - 'Sabre\\CalDAV\\Backend\\BackendInterface' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/BackendInterface.php', - 'Sabre\\CalDAV\\Backend\\NotificationSupport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php', - 'Sabre\\CalDAV\\Backend\\PDO' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/PDO.php', - 'Sabre\\CalDAV\\Backend\\SchedulingSupport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php', - 'Sabre\\CalDAV\\Backend\\SharingSupport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/SharingSupport.php', - 'Sabre\\CalDAV\\Backend\\SimplePDO' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/SimplePDO.php', - 'Sabre\\CalDAV\\Backend\\SubscriptionSupport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php', - 'Sabre\\CalDAV\\Backend\\SyncSupport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Backend/SyncSupport.php', - 'Sabre\\CalDAV\\Calendar' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Calendar.php', - 'Sabre\\CalDAV\\CalendarHome' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/CalendarHome.php', - 'Sabre\\CalDAV\\CalendarObject' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/CalendarObject.php', - 'Sabre\\CalDAV\\CalendarQueryValidator' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/CalendarQueryValidator.php', - 'Sabre\\CalDAV\\CalendarRoot' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/CalendarRoot.php', - 'Sabre\\CalDAV\\Exception\\InvalidComponentType' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php', - 'Sabre\\CalDAV\\ICSExportPlugin' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/ICSExportPlugin.php', - 'Sabre\\CalDAV\\ICalendar' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/ICalendar.php', - 'Sabre\\CalDAV\\ICalendarObject' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/ICalendarObject.php', - 'Sabre\\CalDAV\\ICalendarObjectContainer' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/ICalendarObjectContainer.php', - 'Sabre\\CalDAV\\ISharedCalendar' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/ISharedCalendar.php', - 'Sabre\\CalDAV\\Notifications\\Collection' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Notifications/Collection.php', - 'Sabre\\CalDAV\\Notifications\\ICollection' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Notifications/ICollection.php', - 'Sabre\\CalDAV\\Notifications\\INode' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Notifications/INode.php', - 'Sabre\\CalDAV\\Notifications\\Node' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Notifications/Node.php', - 'Sabre\\CalDAV\\Notifications\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Notifications/Plugin.php', - 'Sabre\\CalDAV\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Plugin.php', - 'Sabre\\CalDAV\\Principal\\Collection' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Principal/Collection.php', - 'Sabre\\CalDAV\\Principal\\IProxyRead' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Principal/IProxyRead.php', - 'Sabre\\CalDAV\\Principal\\IProxyWrite' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Principal/IProxyWrite.php', - 'Sabre\\CalDAV\\Principal\\ProxyRead' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Principal/ProxyRead.php', - 'Sabre\\CalDAV\\Principal\\ProxyWrite' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php', - 'Sabre\\CalDAV\\Principal\\User' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Principal/User.php', - 'Sabre\\CalDAV\\Schedule\\IInbox' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/IInbox.php', - 'Sabre\\CalDAV\\Schedule\\IMipPlugin' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/IMipPlugin.php', - 'Sabre\\CalDAV\\Schedule\\IOutbox' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/IOutbox.php', - 'Sabre\\CalDAV\\Schedule\\ISchedulingObject' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/ISchedulingObject.php', - 'Sabre\\CalDAV\\Schedule\\Inbox' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/Inbox.php', - 'Sabre\\CalDAV\\Schedule\\Outbox' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/Outbox.php', - 'Sabre\\CalDAV\\Schedule\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/Plugin.php', - 'Sabre\\CalDAV\\Schedule\\SchedulingObject' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php', - 'Sabre\\CalDAV\\SharedCalendar' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/SharedCalendar.php', - 'Sabre\\CalDAV\\SharingPlugin' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/SharingPlugin.php', - 'Sabre\\CalDAV\\Subscriptions\\ISubscription' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php', - 'Sabre\\CalDAV\\Subscriptions\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Subscriptions/Plugin.php', - 'Sabre\\CalDAV\\Subscriptions\\Subscription' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php', - 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php', - 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php', - 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php', - 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php', - 'Sabre\\CalDAV\\Xml\\Notification\\Invite' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php', - 'Sabre\\CalDAV\\Xml\\Notification\\InviteReply' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php', - 'Sabre\\CalDAV\\Xml\\Notification\\NotificationInterface' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php', - 'Sabre\\CalDAV\\Xml\\Notification\\SystemStatus' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Notification/SystemStatus.php', - 'Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php', - 'Sabre\\CalDAV\\Xml\\Property\\EmailAddressSet' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php', - 'Sabre\\CalDAV\\Xml\\Property\\Invite' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Property/Invite.php', - 'Sabre\\CalDAV\\Xml\\Property\\ScheduleCalendarTransp' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php', - 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php', - 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarData' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php', - 'Sabre\\CalDAV\\Xml\\Property\\SupportedCollationSet' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php', - 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php', - 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php', - 'Sabre\\CalDAV\\Xml\\Request\\FreeBusyQueryReport' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php', - 'Sabre\\CalDAV\\Xml\\Request\\InviteReply' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php', - 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php', - 'Sabre\\CalDAV\\Xml\\Request\\Share' => __DIR__ . '/..' . '/sabre/dav/lib/CalDAV/Xml/Request/Share.php', - 'Sabre\\CardDAV\\AddressBook' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/AddressBook.php', - 'Sabre\\CardDAV\\AddressBookHome' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/AddressBookHome.php', - 'Sabre\\CardDAV\\AddressBookRoot' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/AddressBookRoot.php', - 'Sabre\\CardDAV\\Backend\\AbstractBackend' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php', - 'Sabre\\CardDAV\\Backend\\BackendInterface' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Backend/BackendInterface.php', - 'Sabre\\CardDAV\\Backend\\PDO' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Backend/PDO.php', - 'Sabre\\CardDAV\\Backend\\SyncSupport' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Backend/SyncSupport.php', - 'Sabre\\CardDAV\\Card' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Card.php', - 'Sabre\\CardDAV\\IAddressBook' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/IAddressBook.php', - 'Sabre\\CardDAV\\ICard' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/ICard.php', - 'Sabre\\CardDAV\\IDirectory' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/IDirectory.php', - 'Sabre\\CardDAV\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Plugin.php', - 'Sabre\\CardDAV\\VCFExportPlugin' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/VCFExportPlugin.php', - 'Sabre\\CardDAV\\Xml\\Filter\\AddressData' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php', - 'Sabre\\CardDAV\\Xml\\Filter\\ParamFilter' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php', - 'Sabre\\CardDAV\\Xml\\Filter\\PropFilter' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php', - 'Sabre\\CardDAV\\Xml\\Property\\SupportedAddressData' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php', - 'Sabre\\CardDAV\\Xml\\Property\\SupportedCollationSet' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php', - 'Sabre\\CardDAV\\Xml\\Request\\AddressBookMultiGetReport' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php', - 'Sabre\\CardDAV\\Xml\\Request\\AddressBookQueryReport' => __DIR__ . '/..' . '/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php', - 'Sabre\\DAVACL\\ACLTrait' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/ACLTrait.php', - 'Sabre\\DAVACL\\AbstractPrincipalCollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php', - 'Sabre\\DAVACL\\Exception\\AceConflict' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Exception/AceConflict.php', - 'Sabre\\DAVACL\\Exception\\NeedPrivileges' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php', - 'Sabre\\DAVACL\\Exception\\NoAbstract' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Exception/NoAbstract.php', - 'Sabre\\DAVACL\\Exception\\NotRecognizedPrincipal' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php', - 'Sabre\\DAVACL\\Exception\\NotSupportedPrivilege' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php', - 'Sabre\\DAVACL\\FS\\Collection' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/FS/Collection.php', - 'Sabre\\DAVACL\\FS\\File' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/FS/File.php', - 'Sabre\\DAVACL\\FS\\HomeCollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/FS/HomeCollection.php', - 'Sabre\\DAVACL\\IACL' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/IACL.php', - 'Sabre\\DAVACL\\IPrincipal' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/IPrincipal.php', - 'Sabre\\DAVACL\\IPrincipalCollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/IPrincipalCollection.php', - 'Sabre\\DAVACL\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Plugin.php', - 'Sabre\\DAVACL\\Principal' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Principal.php', - 'Sabre\\DAVACL\\PrincipalBackend\\AbstractBackend' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php', - 'Sabre\\DAVACL\\PrincipalBackend\\BackendInterface' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php', - 'Sabre\\DAVACL\\PrincipalBackend\\CreatePrincipalSupport' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/PrincipalBackend/CreatePrincipalSupport.php', - 'Sabre\\DAVACL\\PrincipalBackend\\PDO' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php', - 'Sabre\\DAVACL\\PrincipalCollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/PrincipalCollection.php', - 'Sabre\\DAVACL\\Xml\\Property\\Acl' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Property/Acl.php', - 'Sabre\\DAVACL\\Xml\\Property\\AclRestrictions' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php', - 'Sabre\\DAVACL\\Xml\\Property\\CurrentUserPrivilegeSet' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php', - 'Sabre\\DAVACL\\Xml\\Property\\Principal' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Property/Principal.php', - 'Sabre\\DAVACL\\Xml\\Property\\SupportedPrivilegeSet' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php', - 'Sabre\\DAVACL\\Xml\\Request\\AclPrincipalPropSetReport' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\PrincipalMatchReport' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php', - 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport' => __DIR__ . '/..' . '/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php', - 'Sabre\\DAV\\Auth\\Backend\\AbstractBasic' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php', - 'Sabre\\DAV\\Auth\\Backend\\AbstractBearer' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php', - 'Sabre\\DAV\\Auth\\Backend\\AbstractDigest' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php', - 'Sabre\\DAV\\Auth\\Backend\\Apache' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/Apache.php', - 'Sabre\\DAV\\Auth\\Backend\\BackendInterface' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php', - 'Sabre\\DAV\\Auth\\Backend\\BasicCallBack' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php', - 'Sabre\\DAV\\Auth\\Backend\\File' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/File.php', - 'Sabre\\DAV\\Auth\\Backend\\IMAP' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/IMAP.php', - 'Sabre\\DAV\\Auth\\Backend\\PDO' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/PDO.php', - 'Sabre\\DAV\\Auth\\Backend\\PDOBasicAuth' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Backend/PDOBasicAuth.php', - 'Sabre\\DAV\\Auth\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Auth/Plugin.php', - 'Sabre\\DAV\\Browser\\GuessContentType' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Browser/GuessContentType.php', - 'Sabre\\DAV\\Browser\\HtmlOutput' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Browser/HtmlOutput.php', - 'Sabre\\DAV\\Browser\\HtmlOutputHelper' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Browser/HtmlOutputHelper.php', - 'Sabre\\DAV\\Browser\\MapGetToPropFind' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php', - 'Sabre\\DAV\\Browser\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Browser/Plugin.php', - 'Sabre\\DAV\\Browser\\PropFindAll' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Browser/PropFindAll.php', - 'Sabre\\DAV\\Client' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Client.php', - 'Sabre\\DAV\\Collection' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Collection.php', - 'Sabre\\DAV\\CorePlugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/CorePlugin.php', - 'Sabre\\DAV\\Exception' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception.php', - 'Sabre\\DAV\\Exception\\BadRequest' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/BadRequest.php', - 'Sabre\\DAV\\Exception\\Conflict' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/Conflict.php', - 'Sabre\\DAV\\Exception\\ConflictingLock' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/ConflictingLock.php', - 'Sabre\\DAV\\Exception\\Forbidden' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/Forbidden.php', - 'Sabre\\DAV\\Exception\\InsufficientStorage' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/InsufficientStorage.php', - 'Sabre\\DAV\\Exception\\InvalidResourceType' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/InvalidResourceType.php', - 'Sabre\\DAV\\Exception\\InvalidSyncToken' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php', - 'Sabre\\DAV\\Exception\\LengthRequired' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/LengthRequired.php', - 'Sabre\\DAV\\Exception\\LockTokenMatchesRequestUri' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/LockTokenMatchesRequestUri.php', - 'Sabre\\DAV\\Exception\\Locked' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/Locked.php', - 'Sabre\\DAV\\Exception\\MethodNotAllowed' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php', - 'Sabre\\DAV\\Exception\\NotAuthenticated' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/NotAuthenticated.php', - 'Sabre\\DAV\\Exception\\NotFound' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/NotFound.php', - 'Sabre\\DAV\\Exception\\NotImplemented' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/NotImplemented.php', - 'Sabre\\DAV\\Exception\\PaymentRequired' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/PaymentRequired.php', - 'Sabre\\DAV\\Exception\\PreconditionFailed' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/PreconditionFailed.php', - 'Sabre\\DAV\\Exception\\ReportNotSupported' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/ReportNotSupported.php', - 'Sabre\\DAV\\Exception\\RequestedRangeNotSatisfiable' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php', - 'Sabre\\DAV\\Exception\\ServiceUnavailable' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/ServiceUnavailable.php', - 'Sabre\\DAV\\Exception\\TooManyMatches' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/TooManyMatches.php', - 'Sabre\\DAV\\Exception\\UnsupportedMediaType' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php', - 'Sabre\\DAV\\FSExt\\Directory' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/FSExt/Directory.php', - 'Sabre\\DAV\\FSExt\\File' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/FSExt/File.php', - 'Sabre\\DAV\\FS\\Directory' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/FS/Directory.php', - 'Sabre\\DAV\\FS\\File' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/FS/File.php', - 'Sabre\\DAV\\FS\\Node' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/FS/Node.php', - 'Sabre\\DAV\\File' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/File.php', - 'Sabre\\DAV\\ICollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/ICollection.php', - 'Sabre\\DAV\\ICopyTarget' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/ICopyTarget.php', - 'Sabre\\DAV\\IExtendedCollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/IExtendedCollection.php', - 'Sabre\\DAV\\IFile' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/IFile.php', - 'Sabre\\DAV\\IMoveTarget' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/IMoveTarget.php', - 'Sabre\\DAV\\IMultiGet' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/IMultiGet.php', - 'Sabre\\DAV\\INode' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/INode.php', - 'Sabre\\DAV\\INodeByPath' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/INodeByPath.php', - 'Sabre\\DAV\\IProperties' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/IProperties.php', - 'Sabre\\DAV\\IQuota' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/IQuota.php', - 'Sabre\\DAV\\Locks\\Backend\\AbstractBackend' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Locks/Backend/AbstractBackend.php', - 'Sabre\\DAV\\Locks\\Backend\\BackendInterface' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Locks/Backend/BackendInterface.php', - 'Sabre\\DAV\\Locks\\Backend\\File' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Locks/Backend/File.php', - 'Sabre\\DAV\\Locks\\Backend\\PDO' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Locks/Backend/PDO.php', - 'Sabre\\DAV\\Locks\\LockInfo' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Locks/LockInfo.php', - 'Sabre\\DAV\\Locks\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Locks/Plugin.php', - 'Sabre\\DAV\\MkCol' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/MkCol.php', - 'Sabre\\DAV\\Mount\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Mount/Plugin.php', - 'Sabre\\DAV\\Node' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Node.php', - 'Sabre\\DAV\\PartialUpdate\\IPatchSupport' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/PartialUpdate/IPatchSupport.php', - 'Sabre\\DAV\\PartialUpdate\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/PartialUpdate/Plugin.php', - 'Sabre\\DAV\\PropFind' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/PropFind.php', - 'Sabre\\DAV\\PropPatch' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/PropPatch.php', - 'Sabre\\DAV\\PropertyStorage\\Backend\\BackendInterface' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php', - 'Sabre\\DAV\\PropertyStorage\\Backend\\PDO' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php', - 'Sabre\\DAV\\PropertyStorage\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/PropertyStorage/Plugin.php', - 'Sabre\\DAV\\Server' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Server.php', - 'Sabre\\DAV\\ServerPlugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/ServerPlugin.php', - 'Sabre\\DAV\\Sharing\\ISharedNode' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Sharing/ISharedNode.php', - 'Sabre\\DAV\\Sharing\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Sharing/Plugin.php', - 'Sabre\\DAV\\SimpleCollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/SimpleCollection.php', - 'Sabre\\DAV\\SimpleFile' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/SimpleFile.php', - 'Sabre\\DAV\\StringUtil' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/StringUtil.php', - 'Sabre\\DAV\\Sync\\ISyncCollection' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Sync/ISyncCollection.php', - 'Sabre\\DAV\\Sync\\Plugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Sync/Plugin.php', - 'Sabre\\DAV\\TemporaryFileFilterPlugin' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php', - 'Sabre\\DAV\\Tree' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Tree.php', - 'Sabre\\DAV\\UUIDUtil' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/UUIDUtil.php', - 'Sabre\\DAV\\Version' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Version.php', - 'Sabre\\DAV\\Xml\\Element\\Prop' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Element/Prop.php', - 'Sabre\\DAV\\Xml\\Element\\Response' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Element/Response.php', - 'Sabre\\DAV\\Xml\\Element\\Sharee' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Element/Sharee.php', - 'Sabre\\DAV\\Xml\\Property\\Complex' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/Complex.php', - 'Sabre\\DAV\\Xml\\Property\\GetLastModified' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php', - 'Sabre\\DAV\\Xml\\Property\\Href' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/Href.php', - 'Sabre\\DAV\\Xml\\Property\\Invite' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/Invite.php', - 'Sabre\\DAV\\Xml\\Property\\LocalHref' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/LocalHref.php', - 'Sabre\\DAV\\Xml\\Property\\LockDiscovery' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/LockDiscovery.php', - 'Sabre\\DAV\\Xml\\Property\\ResourceType' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/ResourceType.php', - 'Sabre\\DAV\\Xml\\Property\\ShareAccess' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php', - 'Sabre\\DAV\\Xml\\Property\\SupportedLock' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php', - 'Sabre\\DAV\\Xml\\Property\\SupportedMethodSet' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php', - 'Sabre\\DAV\\Xml\\Property\\SupportedReportSet' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php', - 'Sabre\\DAV\\Xml\\Request\\Lock' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Request/Lock.php', - 'Sabre\\DAV\\Xml\\Request\\MkCol' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Request/MkCol.php', - 'Sabre\\DAV\\Xml\\Request\\PropFind' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Request/PropFind.php', - 'Sabre\\DAV\\Xml\\Request\\PropPatch' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Request/PropPatch.php', - 'Sabre\\DAV\\Xml\\Request\\ShareResource' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Request/ShareResource.php', - 'Sabre\\DAV\\Xml\\Request\\SyncCollectionReport' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php', - 'Sabre\\DAV\\Xml\\Response\\MultiStatus' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php', - 'Sabre\\DAV\\Xml\\Service' => __DIR__ . '/..' . '/sabre/dav/lib/DAV/Xml/Service.php', - 'Sabre\\Event\\Emitter' => __DIR__ . '/..' . '/sabre/event/lib/Emitter.php', - 'Sabre\\Event\\EmitterInterface' => __DIR__ . '/..' . '/sabre/event/lib/EmitterInterface.php', - 'Sabre\\Event\\EmitterTrait' => __DIR__ . '/..' . '/sabre/event/lib/EmitterTrait.php', - 'Sabre\\Event\\EventEmitter' => __DIR__ . '/..' . '/sabre/event/lib/EventEmitter.php', - 'Sabre\\Event\\Loop\\Loop' => __DIR__ . '/..' . '/sabre/event/lib/Loop/Loop.php', - 'Sabre\\Event\\Promise' => __DIR__ . '/..' . '/sabre/event/lib/Promise.php', - 'Sabre\\Event\\PromiseAlreadyResolvedException' => __DIR__ . '/..' . '/sabre/event/lib/PromiseAlreadyResolvedException.php', - 'Sabre\\Event\\Version' => __DIR__ . '/..' . '/sabre/event/lib/Version.php', - 'Sabre\\Event\\WildcardEmitter' => __DIR__ . '/..' . '/sabre/event/lib/WildcardEmitter.php', - 'Sabre\\Event\\WildcardEmitterTrait' => __DIR__ . '/..' . '/sabre/event/lib/WildcardEmitterTrait.php', - 'Sabre\\HTTP\\Auth\\AWS' => __DIR__ . '/..' . '/sabre/http/lib/Auth/AWS.php', - 'Sabre\\HTTP\\Auth\\AbstractAuth' => __DIR__ . '/..' . '/sabre/http/lib/Auth/AbstractAuth.php', - 'Sabre\\HTTP\\Auth\\Basic' => __DIR__ . '/..' . '/sabre/http/lib/Auth/Basic.php', - 'Sabre\\HTTP\\Auth\\Bearer' => __DIR__ . '/..' . '/sabre/http/lib/Auth/Bearer.php', - 'Sabre\\HTTP\\Auth\\Digest' => __DIR__ . '/..' . '/sabre/http/lib/Auth/Digest.php', - 'Sabre\\HTTP\\Client' => __DIR__ . '/..' . '/sabre/http/lib/Client.php', - 'Sabre\\HTTP\\ClientException' => __DIR__ . '/..' . '/sabre/http/lib/ClientException.php', - 'Sabre\\HTTP\\ClientHttpException' => __DIR__ . '/..' . '/sabre/http/lib/ClientHttpException.php', - 'Sabre\\HTTP\\HttpException' => __DIR__ . '/..' . '/sabre/http/lib/HttpException.php', - 'Sabre\\HTTP\\Message' => __DIR__ . '/..' . '/sabre/http/lib/Message.php', - 'Sabre\\HTTP\\MessageDecoratorTrait' => __DIR__ . '/..' . '/sabre/http/lib/MessageDecoratorTrait.php', - 'Sabre\\HTTP\\MessageInterface' => __DIR__ . '/..' . '/sabre/http/lib/MessageInterface.php', - 'Sabre\\HTTP\\Request' => __DIR__ . '/..' . '/sabre/http/lib/Request.php', - 'Sabre\\HTTP\\RequestDecorator' => __DIR__ . '/..' . '/sabre/http/lib/RequestDecorator.php', - 'Sabre\\HTTP\\RequestInterface' => __DIR__ . '/..' . '/sabre/http/lib/RequestInterface.php', - 'Sabre\\HTTP\\Response' => __DIR__ . '/..' . '/sabre/http/lib/Response.php', - 'Sabre\\HTTP\\ResponseDecorator' => __DIR__ . '/..' . '/sabre/http/lib/ResponseDecorator.php', - 'Sabre\\HTTP\\ResponseInterface' => __DIR__ . '/..' . '/sabre/http/lib/ResponseInterface.php', - 'Sabre\\HTTP\\Sapi' => __DIR__ . '/..' . '/sabre/http/lib/Sapi.php', - 'Sabre\\HTTP\\Version' => __DIR__ . '/..' . '/sabre/http/lib/Version.php', - 'Sabre\\Uri\\InvalidUriException' => __DIR__ . '/..' . '/sabre/uri/lib/InvalidUriException.php', - 'Sabre\\Uri\\Version' => __DIR__ . '/..' . '/sabre/uri/lib/Version.php', - 'Sabre\\VObject\\BirthdayCalendarGenerator' => __DIR__ . '/..' . '/sabre/vobject/lib/BirthdayCalendarGenerator.php', - 'Sabre\\VObject\\Cli' => __DIR__ . '/..' . '/sabre/vobject/lib/Cli.php', - 'Sabre\\VObject\\Component' => __DIR__ . '/..' . '/sabre/vobject/lib/Component.php', - 'Sabre\\VObject\\Component\\Available' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/Available.php', - 'Sabre\\VObject\\Component\\VAlarm' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VAlarm.php', - 'Sabre\\VObject\\Component\\VAvailability' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VAvailability.php', - 'Sabre\\VObject\\Component\\VCalendar' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VCalendar.php', - 'Sabre\\VObject\\Component\\VCard' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VCard.php', - 'Sabre\\VObject\\Component\\VEvent' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VEvent.php', - 'Sabre\\VObject\\Component\\VFreeBusy' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VFreeBusy.php', - 'Sabre\\VObject\\Component\\VJournal' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VJournal.php', - 'Sabre\\VObject\\Component\\VTimeZone' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VTimeZone.php', - 'Sabre\\VObject\\Component\\VTodo' => __DIR__ . '/..' . '/sabre/vobject/lib/Component/VTodo.php', - 'Sabre\\VObject\\DateTimeParser' => __DIR__ . '/..' . '/sabre/vobject/lib/DateTimeParser.php', - 'Sabre\\VObject\\Document' => __DIR__ . '/..' . '/sabre/vobject/lib/Document.php', - 'Sabre\\VObject\\ElementList' => __DIR__ . '/..' . '/sabre/vobject/lib/ElementList.php', - 'Sabre\\VObject\\EofException' => __DIR__ . '/..' . '/sabre/vobject/lib/EofException.php', - 'Sabre\\VObject\\FreeBusyData' => __DIR__ . '/..' . '/sabre/vobject/lib/FreeBusyData.php', - 'Sabre\\VObject\\FreeBusyGenerator' => __DIR__ . '/..' . '/sabre/vobject/lib/FreeBusyGenerator.php', - 'Sabre\\VObject\\ITip\\Broker' => __DIR__ . '/..' . '/sabre/vobject/lib/ITip/Broker.php', - 'Sabre\\VObject\\ITip\\ITipException' => __DIR__ . '/..' . '/sabre/vobject/lib/ITip/ITipException.php', - 'Sabre\\VObject\\ITip\\Message' => __DIR__ . '/..' . '/sabre/vobject/lib/ITip/Message.php', - 'Sabre\\VObject\\ITip\\SameOrganizerForAllComponentsException' => __DIR__ . '/..' . '/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php', - 'Sabre\\VObject\\InvalidDataException' => __DIR__ . '/..' . '/sabre/vobject/lib/InvalidDataException.php', - 'Sabre\\VObject\\Node' => __DIR__ . '/..' . '/sabre/vobject/lib/Node.php', - 'Sabre\\VObject\\PHPUnitAssertions' => __DIR__ . '/..' . '/sabre/vobject/lib/PHPUnitAssertions.php', - 'Sabre\\VObject\\Parameter' => __DIR__ . '/..' . '/sabre/vobject/lib/Parameter.php', - 'Sabre\\VObject\\ParseException' => __DIR__ . '/..' . '/sabre/vobject/lib/ParseException.php', - 'Sabre\\VObject\\Parser\\Json' => __DIR__ . '/..' . '/sabre/vobject/lib/Parser/Json.php', - 'Sabre\\VObject\\Parser\\MimeDir' => __DIR__ . '/..' . '/sabre/vobject/lib/Parser/MimeDir.php', - 'Sabre\\VObject\\Parser\\Parser' => __DIR__ . '/..' . '/sabre/vobject/lib/Parser/Parser.php', - 'Sabre\\VObject\\Parser\\XML' => __DIR__ . '/..' . '/sabre/vobject/lib/Parser/XML.php', - 'Sabre\\VObject\\Parser\\XML\\Element\\KeyValue' => __DIR__ . '/..' . '/sabre/vobject/lib/Parser/XML/Element/KeyValue.php', - 'Sabre\\VObject\\Property' => __DIR__ . '/..' . '/sabre/vobject/lib/Property.php', - 'Sabre\\VObject\\Property\\Binary' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/Binary.php', - 'Sabre\\VObject\\Property\\Boolean' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/Boolean.php', - 'Sabre\\VObject\\Property\\FlatText' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/FlatText.php', - 'Sabre\\VObject\\Property\\FloatValue' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/FloatValue.php', - 'Sabre\\VObject\\Property\\ICalendar\\CalAddress' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/ICalendar/CalAddress.php', - 'Sabre\\VObject\\Property\\ICalendar\\Date' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/ICalendar/Date.php', - 'Sabre\\VObject\\Property\\ICalendar\\DateTime' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/ICalendar/DateTime.php', - 'Sabre\\VObject\\Property\\ICalendar\\Duration' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/ICalendar/Duration.php', - 'Sabre\\VObject\\Property\\ICalendar\\Period' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/ICalendar/Period.php', - 'Sabre\\VObject\\Property\\ICalendar\\Recur' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/ICalendar/Recur.php', - 'Sabre\\VObject\\Property\\IntegerValue' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/IntegerValue.php', - 'Sabre\\VObject\\Property\\Text' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/Text.php', - 'Sabre\\VObject\\Property\\Time' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/Time.php', - 'Sabre\\VObject\\Property\\Unknown' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/Unknown.php', - 'Sabre\\VObject\\Property\\Uri' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/Uri.php', - 'Sabre\\VObject\\Property\\UtcOffset' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/UtcOffset.php', - 'Sabre\\VObject\\Property\\VCard\\Date' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/VCard/Date.php', - 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/VCard/DateAndOrTime.php', - 'Sabre\\VObject\\Property\\VCard\\DateTime' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/VCard/DateTime.php', - 'Sabre\\VObject\\Property\\VCard\\LanguageTag' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/VCard/LanguageTag.php', - 'Sabre\\VObject\\Property\\VCard\\PhoneNumber' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/VCard/PhoneNumber.php', - 'Sabre\\VObject\\Property\\VCard\\TimeStamp' => __DIR__ . '/..' . '/sabre/vobject/lib/Property/VCard/TimeStamp.php', - 'Sabre\\VObject\\Reader' => __DIR__ . '/..' . '/sabre/vobject/lib/Reader.php', - 'Sabre\\VObject\\Recur\\EventIterator' => __DIR__ . '/..' . '/sabre/vobject/lib/Recur/EventIterator.php', - 'Sabre\\VObject\\Recur\\MaxInstancesExceededException' => __DIR__ . '/..' . '/sabre/vobject/lib/Recur/MaxInstancesExceededException.php', - 'Sabre\\VObject\\Recur\\NoInstancesException' => __DIR__ . '/..' . '/sabre/vobject/lib/Recur/NoInstancesException.php', - 'Sabre\\VObject\\Recur\\RDateIterator' => __DIR__ . '/..' . '/sabre/vobject/lib/Recur/RDateIterator.php', - 'Sabre\\VObject\\Recur\\RRuleIterator' => __DIR__ . '/..' . '/sabre/vobject/lib/Recur/RRuleIterator.php', - 'Sabre\\VObject\\Settings' => __DIR__ . '/..' . '/sabre/vobject/lib/Settings.php', - 'Sabre\\VObject\\Splitter\\ICalendar' => __DIR__ . '/..' . '/sabre/vobject/lib/Splitter/ICalendar.php', - 'Sabre\\VObject\\Splitter\\SplitterInterface' => __DIR__ . '/..' . '/sabre/vobject/lib/Splitter/SplitterInterface.php', - 'Sabre\\VObject\\Splitter\\VCard' => __DIR__ . '/..' . '/sabre/vobject/lib/Splitter/VCard.php', - 'Sabre\\VObject\\StringUtil' => __DIR__ . '/..' . '/sabre/vobject/lib/StringUtil.php', - 'Sabre\\VObject\\TimeZoneUtil' => __DIR__ . '/..' . '/sabre/vobject/lib/TimeZoneUtil.php', - 'Sabre\\VObject\\TimezoneGuesser\\FindFromOffset' => __DIR__ . '/..' . '/sabre/vobject/lib/TimezoneGuesser/FindFromOffset.php', - 'Sabre\\VObject\\TimezoneGuesser\\FindFromTimezoneIdentifier' => __DIR__ . '/..' . '/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneIdentifier.php', - 'Sabre\\VObject\\TimezoneGuesser\\FindFromTimezoneMap' => __DIR__ . '/..' . '/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneMap.php', - 'Sabre\\VObject\\TimezoneGuesser\\GuessFromLicEntry' => __DIR__ . '/..' . '/sabre/vobject/lib/TimezoneGuesser/GuessFromLicEntry.php', - 'Sabre\\VObject\\TimezoneGuesser\\GuessFromMsTzId' => __DIR__ . '/..' . '/sabre/vobject/lib/TimezoneGuesser/GuessFromMsTzId.php', - 'Sabre\\VObject\\TimezoneGuesser\\TimezoneFinder' => __DIR__ . '/..' . '/sabre/vobject/lib/TimezoneGuesser/TimezoneFinder.php', - 'Sabre\\VObject\\TimezoneGuesser\\TimezoneGuesser' => __DIR__ . '/..' . '/sabre/vobject/lib/TimezoneGuesser/TimezoneGuesser.php', - 'Sabre\\VObject\\UUIDUtil' => __DIR__ . '/..' . '/sabre/vobject/lib/UUIDUtil.php', - 'Sabre\\VObject\\VCardConverter' => __DIR__ . '/..' . '/sabre/vobject/lib/VCardConverter.php', - 'Sabre\\VObject\\Version' => __DIR__ . '/..' . '/sabre/vobject/lib/Version.php', - 'Sabre\\VObject\\Writer' => __DIR__ . '/..' . '/sabre/vobject/lib/Writer.php', - 'Sabre\\Xml\\ContextStackTrait' => __DIR__ . '/..' . '/sabre/xml/lib/ContextStackTrait.php', - 'Sabre\\Xml\\Element' => __DIR__ . '/..' . '/sabre/xml/lib/Element.php', - 'Sabre\\Xml\\Element\\Base' => __DIR__ . '/..' . '/sabre/xml/lib/Element/Base.php', - 'Sabre\\Xml\\Element\\Cdata' => __DIR__ . '/..' . '/sabre/xml/lib/Element/Cdata.php', - 'Sabre\\Xml\\Element\\Elements' => __DIR__ . '/..' . '/sabre/xml/lib/Element/Elements.php', - 'Sabre\\Xml\\Element\\KeyValue' => __DIR__ . '/..' . '/sabre/xml/lib/Element/KeyValue.php', - 'Sabre\\Xml\\Element\\Uri' => __DIR__ . '/..' . '/sabre/xml/lib/Element/Uri.php', - 'Sabre\\Xml\\Element\\XmlFragment' => __DIR__ . '/..' . '/sabre/xml/lib/Element/XmlFragment.php', - 'Sabre\\Xml\\LibXMLException' => __DIR__ . '/..' . '/sabre/xml/lib/LibXMLException.php', - 'Sabre\\Xml\\ParseException' => __DIR__ . '/..' . '/sabre/xml/lib/ParseException.php', - 'Sabre\\Xml\\Reader' => __DIR__ . '/..' . '/sabre/xml/lib/Reader.php', - 'Sabre\\Xml\\Service' => __DIR__ . '/..' . '/sabre/xml/lib/Service.php', - 'Sabre\\Xml\\Version' => __DIR__ . '/..' . '/sabre/xml/lib/Version.php', - 'Sabre\\Xml\\Writer' => __DIR__ . '/..' . '/sabre/xml/lib/Writer.php', - 'Sabre\\Xml\\XmlDeserializable' => __DIR__ . '/..' . '/sabre/xml/lib/XmlDeserializable.php', - 'Sabre\\Xml\\XmlSerializable' => __DIR__ . '/..' . '/sabre/xml/lib/XmlSerializable.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInita07591154e0386cfc9ad0f9217878d04::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInita07591154e0386cfc9ad0f9217878d04::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInita07591154e0386cfc9ad0f9217878d04::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/lib/vendor/composer/installed.json b/lib/vendor/composer/installed.json deleted file mode 100644 index 145cc32..0000000 --- a/lib/vendor/composer/installed.json +++ /dev/null @@ -1,522 +0,0 @@ -{ - "packages": [ - { - "name": "psr/log", - "version": "3.0.2", - "version_normalized": "3.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "time": "2024-09-11T13:17:53+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" - }, - "install-path": "../psr/log" - }, - { - "name": "sabre/dav", - "version": "4.7.0", - "version_normalized": "4.7.0.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/dav.git", - "reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/dav/zipball/074373bcd689a30bcf5aaa6bbb20a3395964ce7a", - "reference": "074373bcd689a30bcf5aaa6bbb20a3395964ce7a", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-date": "*", - "ext-dom": "*", - "ext-iconv": "*", - "ext-json": "*", - "ext-mbstring": "*", - "ext-pcre": "*", - "ext-simplexml": "*", - "ext-spl": "*", - "lib-libxml": ">=2.7.0", - "php": "^7.1.0 || ^8.0", - "psr/log": "^1.0 || ^2.0 || ^3.0", - "sabre/event": "^5.0", - "sabre/http": "^5.0.5", - "sabre/uri": "^2.0", - "sabre/vobject": "^4.2.1", - "sabre/xml": "^2.0.1" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.19", - "monolog/monolog": "^1.27 || ^2.0", - "phpstan/phpstan": "^0.12 || ^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" - }, - "suggest": { - "ext-curl": "*", - "ext-imap": "*", - "ext-pdo": "*" - }, - "time": "2024-10-29T11:46:02+00:00", - "bin": [ - "bin/sabredav", - "bin/naturalselection" - ], - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sabre\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "description": "WebDAV Framework for PHP", - "homepage": "http://sabre.io/", - "keywords": [ - "CalDAV", - "CardDAV", - "WebDAV", - "framework", - "iCalendar" - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "issues": "https://github.com/sabre-io/dav/issues", - "source": "https://github.com/fruux/sabre-dav" - }, - "install-path": "../sabre/dav" - }, - { - "name": "sabre/event", - "version": "5.1.7", - "version_normalized": "5.1.7.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/event.git", - "reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/event/zipball/86d57e305c272898ba3c28e9bd3d65d5464587c2", - "reference": "86d57e305c272898ba3c28e9bd3d65d5464587c2", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1||^3.63", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" - }, - "time": "2024-08-27T11:23:05+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "lib/coroutine.php", - "lib/Loop/functions.php", - "lib/Promise/functions.php" - ], - "psr-4": { - "Sabre\\Event\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "description": "sabre/event is a library for lightweight event-based programming", - "homepage": "http://sabre.io/event/", - "keywords": [ - "EventEmitter", - "async", - "coroutine", - "eventloop", - "events", - "hooks", - "plugin", - "promise", - "reactor", - "signal" - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "issues": "https://github.com/sabre-io/event/issues", - "source": "https://github.com/fruux/sabre-event" - }, - "install-path": "../sabre/event" - }, - { - "name": "sabre/http", - "version": "5.1.13", - "version_normalized": "5.1.13.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/http.git", - "reference": "7c2a14097d1a0de2347dcbdc91a02f38e338f4db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/http/zipball/7c2a14097d1a0de2347dcbdc91a02f38e338f4db", - "reference": "7c2a14097d1a0de2347dcbdc91a02f38e338f4db", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-curl": "*", - "ext-mbstring": "*", - "php": "^7.1 || ^8.0", - "sabre/event": ">=4.0 <6.0", - "sabre/uri": "^2.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" - }, - "suggest": { - "ext-curl": " to make http requests with the Client class" - }, - "time": "2025-09-09T10:21:47+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "lib/functions.php" - ], - "psr-4": { - "Sabre\\HTTP\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "description": "The sabre/http library provides utilities for dealing with http requests and responses. ", - "homepage": "https://github.com/fruux/sabre-http", - "keywords": [ - "http" - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "issues": "https://github.com/sabre-io/http/issues", - "source": "https://github.com/fruux/sabre-http" - }, - "install-path": "../sabre/http" - }, - { - "name": "sabre/uri", - "version": "2.3.4", - "version_normalized": "2.3.4.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/uri.git", - "reference": "b76524c22de90d80ca73143680a8e77b1266c291" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/uri/zipball/b76524c22de90d80ca73143680a8e77b1266c291", - "reference": "b76524c22de90d80ca73143680a8e77b1266c291", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.63", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^1.12", - "phpstan/phpstan-phpunit": "^1.4", - "phpstan/phpstan-strict-rules": "^1.6", - "phpunit/phpunit": "^9.6" - }, - "time": "2024-08-27T12:18:16+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "lib/functions.php" - ], - "psr-4": { - "Sabre\\Uri\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "description": "Functions for making sense out of URIs.", - "homepage": "http://sabre.io/uri/", - "keywords": [ - "rfc3986", - "uri", - "url" - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "issues": "https://github.com/sabre-io/uri/issues", - "source": "https://github.com/fruux/sabre-uri" - }, - "install-path": "../sabre/uri" - }, - { - "name": "sabre/vobject", - "version": "4.5.8", - "version_normalized": "4.5.8.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/vobject.git", - "reference": "d554eb24d64232922e1eab5896cc2f84b3b9ffb1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/vobject/zipball/d554eb24d64232922e1eab5896cc2f84b3b9ffb1", - "reference": "d554eb24d64232922e1eab5896cc2f84b3b9ffb1", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^7.1 || ^8.0", - "sabre/xml": "^2.1 || ^3.0 || ^4.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1", - "phpstan/phpstan": "^0.12 || ^1.12 || ^2.0", - "phpunit/php-invoker": "^2.0 || ^3.1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" - }, - "suggest": { - "hoa/bench": "If you would like to run the benchmark scripts" - }, - "time": "2026-01-12T10:45:19+00:00", - "bin": [ - "bin/vobject", - "bin/generate_vcards" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sabre\\VObject\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - }, - { - "name": "Dominik Tobschall", - "email": "dominik@fruux.com", - "homepage": "http://tobschall.de/", - "role": "Developer" - }, - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net", - "homepage": "http://mnt.io/", - "role": "Developer" - } - ], - "description": "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", - "homepage": "http://sabre.io/vobject/", - "keywords": [ - "availability", - "freebusy", - "iCalendar", - "ical", - "ics", - "jCal", - "jCard", - "recurrence", - "rfc2425", - "rfc2426", - "rfc2739", - "rfc4770", - "rfc5545", - "rfc5546", - "rfc6321", - "rfc6350", - "rfc6351", - "rfc6474", - "rfc6638", - "rfc6715", - "rfc6868", - "vCalendar", - "vCard", - "vcf", - "xCal", - "xCard" - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "issues": "https://github.com/sabre-io/vobject/issues", - "source": "https://github.com/fruux/sabre-vobject" - }, - "install-path": "../sabre/vobject" - }, - { - "name": "sabre/xml", - "version": "2.2.11", - "version_normalized": "2.2.11.0", - "source": { - "type": "git", - "url": "https://github.com/sabre-io/xml.git", - "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", - "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlreader": "*", - "ext-xmlwriter": "*", - "lib-libxml": ">=2.6.20", - "php": "^7.1 || ^8.0", - "sabre/uri": ">=1.0,<3.0.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" - }, - "time": "2024-09-06T07:37:46+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "lib/Deserializer/functions.php", - "lib/Serializer/functions.php" - ], - "psr-4": { - "Sabre\\Xml\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - }, - { - "name": "Markus Staab", - "email": "markus.staab@redaxo.de", - "role": "Developer" - } - ], - "description": "sabre/xml is an XML library that you may not hate.", - "homepage": "https://sabre.io/xml/", - "keywords": [ - "XMLReader", - "XMLWriter", - "dom", - "xml" - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "issues": "https://github.com/sabre-io/xml/issues", - "source": "https://github.com/fruux/sabre-xml" - }, - "install-path": "../sabre/xml" - } - ], - "dev": true, - "dev-package-names": [] -} diff --git a/lib/vendor/composer/installed.php b/lib/vendor/composer/installed.php deleted file mode 100644 index b97014f..0000000 --- a/lib/vendor/composer/installed.php +++ /dev/null @@ -1,86 +0,0 @@ - array( - 'name' => 'ktrix/service-dav', - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => null, - 'type' => 'library', - 'install_path' => __DIR__ . '/../../../', - 'aliases' => array(), - 'dev' => true, - ), - 'versions' => array( - 'ktrix/service-dav' => array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => null, - 'type' => 'library', - 'install_path' => __DIR__ . '/../../../', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'psr/log' => array( - 'pretty_version' => '3.0.2', - 'version' => '3.0.2.0', - 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', - 'type' => 'library', - 'install_path' => __DIR__ . '/../psr/log', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sabre/dav' => array( - 'pretty_version' => '4.7.0', - 'version' => '4.7.0.0', - 'reference' => '074373bcd689a30bcf5aaa6bbb20a3395964ce7a', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sabre/dav', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sabre/event' => array( - 'pretty_version' => '5.1.7', - 'version' => '5.1.7.0', - 'reference' => '86d57e305c272898ba3c28e9bd3d65d5464587c2', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sabre/event', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sabre/http' => array( - 'pretty_version' => '5.1.13', - 'version' => '5.1.13.0', - 'reference' => '7c2a14097d1a0de2347dcbdc91a02f38e338f4db', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sabre/http', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sabre/uri' => array( - 'pretty_version' => '2.3.4', - 'version' => '2.3.4.0', - 'reference' => 'b76524c22de90d80ca73143680a8e77b1266c291', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sabre/uri', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sabre/vobject' => array( - 'pretty_version' => '4.5.8', - 'version' => '4.5.8.0', - 'reference' => 'd554eb24d64232922e1eab5896cc2f84b3b9ffb1', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sabre/vobject', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sabre/xml' => array( - 'pretty_version' => '2.2.11', - 'version' => '2.2.11.0', - 'reference' => '01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sabre/xml', - 'aliases' => array(), - 'dev_requirement' => false, - ), - ), -); diff --git a/lib/vendor/composer/platform_check.php b/lib/vendor/composer/platform_check.php deleted file mode 100644 index 4c3a5d6..0000000 --- a/lib/vendor/composer/platform_check.php +++ /dev/null @@ -1,26 +0,0 @@ -= 80100)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; -} - -if ($issues) { - if (!headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - if (!ini_get('display_errors')) { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); - } elseif (!headers_sent()) { - echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; - } - } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR - ); -} diff --git a/lib/vendor/psr/log/LICENSE b/lib/vendor/psr/log/LICENSE deleted file mode 100644 index 474c952..0000000 --- a/lib/vendor/psr/log/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 PHP Framework Interoperability Group - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/lib/vendor/psr/log/README.md b/lib/vendor/psr/log/README.md deleted file mode 100644 index a9f20c4..0000000 --- a/lib/vendor/psr/log/README.md +++ /dev/null @@ -1,58 +0,0 @@ -PSR Log -======= - -This repository holds all interfaces/classes/traits related to -[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). - -Note that this is not a logger of its own. It is merely an interface that -describes a logger. See the specification for more details. - -Installation ------------- - -```bash -composer require psr/log -``` - -Usage ------ - -If you need a logger, you can use the interface like this: - -```php -logger = $logger; - } - - public function doSomething() - { - if ($this->logger) { - $this->logger->info('Doing work'); - } - - try { - $this->doSomethingElse(); - } catch (Exception $exception) { - $this->logger->error('Oh no!', array('exception' => $exception)); - } - - // do something useful - } -} -``` - -You can then pick one of the implementations of the interface to get a logger. - -If you want to implement the interface, you can require this package and -implement `Psr\Log\LoggerInterface` in your code. Please read the -[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) -for details. diff --git a/lib/vendor/psr/log/composer.json b/lib/vendor/psr/log/composer.json deleted file mode 100644 index 879fc6f..0000000 --- a/lib/vendor/psr/log/composer.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "psr/log", - "description": "Common interface for logging libraries", - "keywords": ["psr", "psr-3", "log"], - "homepage": "https://github.com/php-fig/log", - "license": "MIT", - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "require": { - "php": ">=8.0.0" - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - } -} diff --git a/lib/vendor/psr/log/src/AbstractLogger.php b/lib/vendor/psr/log/src/AbstractLogger.php deleted file mode 100644 index d60a091..0000000 --- a/lib/vendor/psr/log/src/AbstractLogger.php +++ /dev/null @@ -1,15 +0,0 @@ -logger = $logger; - } -} diff --git a/lib/vendor/psr/log/src/LoggerInterface.php b/lib/vendor/psr/log/src/LoggerInterface.php deleted file mode 100644 index cb4cf64..0000000 --- a/lib/vendor/psr/log/src/LoggerInterface.php +++ /dev/null @@ -1,98 +0,0 @@ -log(LogLevel::EMERGENCY, $message, $context); - } - - /** - * Action must be taken immediately. - * - * Example: Entire website down, database unavailable, etc. This should - * trigger the SMS alerts and wake you up. - */ - public function alert(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::ALERT, $message, $context); - } - - /** - * Critical conditions. - * - * Example: Application component unavailable, unexpected exception. - */ - public function critical(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::CRITICAL, $message, $context); - } - - /** - * Runtime errors that do not require immediate action but should typically - * be logged and monitored. - */ - public function error(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::ERROR, $message, $context); - } - - /** - * Exceptional occurrences that are not errors. - * - * Example: Use of deprecated APIs, poor use of an API, undesirable things - * that are not necessarily wrong. - */ - public function warning(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::WARNING, $message, $context); - } - - /** - * Normal but significant events. - */ - public function notice(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::NOTICE, $message, $context); - } - - /** - * Interesting events. - * - * Example: User logs in, SQL logs. - */ - public function info(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::INFO, $message, $context); - } - - /** - * Detailed debug information. - */ - public function debug(string|\Stringable $message, array $context = []): void - { - $this->log(LogLevel::DEBUG, $message, $context); - } - - /** - * Logs with an arbitrary level. - * - * @param mixed $level - * - * @throws \Psr\Log\InvalidArgumentException - */ - abstract public function log($level, string|\Stringable $message, array $context = []): void; -} diff --git a/lib/vendor/psr/log/src/NullLogger.php b/lib/vendor/psr/log/src/NullLogger.php deleted file mode 100644 index de0561e..0000000 --- a/lib/vendor/psr/log/src/NullLogger.php +++ /dev/null @@ -1,26 +0,0 @@ -logger) { }` - * blocks. - */ -class NullLogger extends AbstractLogger -{ - /** - * Logs with an arbitrary level. - * - * @param mixed[] $context - * - * @throws \Psr\Log\InvalidArgumentException - */ - public function log($level, string|\Stringable $message, array $context = []): void - { - // noop - } -} diff --git a/lib/vendor/sabre/dav/LICENSE b/lib/vendor/sabre/dav/LICENSE deleted file mode 100644 index fd3539e..0000000 --- a/lib/vendor/sabre/dav/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (C) 2007-2016 fruux GmbH (https://fruux.com/). - -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 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/lib/vendor/sabre/dav/README.md b/lib/vendor/sabre/dav/README.md deleted file mode 100644 index 32ca1c3..0000000 --- a/lib/vendor/sabre/dav/README.md +++ /dev/null @@ -1,39 +0,0 @@ -![sabre's logo](http://sabre.io/img/logo.png) sabre/dav -======================================================= - -Introduction ------------- - -sabre/dav is the most popular WebDAV framework for PHP. Use it to create WebDAV, CalDAV and CardDAV servers. - -Full documentation can be found on the website: - -http://sabre.io/ - - -Build status ------------- - -| branch | status | PHP version | -|------------|---------------------------------------------------------------------------|--------------------| -| master 4.* | ![CI](https://github.com/sabre-io/dav/actions/workflows/ci.yml/badge.svg) | PHP 7.1 up, 8.0 up | -| 3.2 | unmaintained | PHP 5.5 to 7.1 | -| 3.1 | unmaintained | PHP 5.5 | -| 3.0 | unmaintained | PHP 5.4 | -| 2.1 | unmaintained | PHP 5.4 | -| 2.0 | unmaintained | PHP 5.4 | -| 1.8 | unmaintained | PHP 5.3 | -| 1.7 | unmaintained | PHP 5.3 | -| 1.6 | unmaintained | PHP 5.3 | - -Documentation -------------- - -* [Introduction](http://sabre.io/dav/). -* [Installation](http://sabre.io/dav/install/). - - -Made at fruux -------------- - -SabreDAV is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support. diff --git a/lib/vendor/sabre/dav/bin/build.php b/lib/vendor/sabre/dav/bin/build.php deleted file mode 100755 index 4dd25d9..0000000 --- a/lib/vendor/sabre/dav/bin/build.php +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env php - [ - 'init', 'test', 'clean', - ], - 'markrelease' => [ - 'init', 'test', 'clean', - ], - 'clean' => [], - 'test' => [ - 'composerupdate', - ], - 'init' => [], - 'composerupdate' => [], - ]; - -$default = 'buildzip'; - -$baseDir = __DIR__.'/../'; -chdir($baseDir); - -$currentTask = $default; -if ($argc > 1) { - $currentTask = $argv[1]; -} -$version = null; -if ($argc > 2) { - $version = $argv[2]; -} - -if (!isset($tasks[$currentTask])) { - echo 'Task not found: ', $currentTask, "\n"; - exit(1); -} - -// Creating the dependency graph -$newTaskList = []; -$oldTaskList = [$currentTask => true]; - -while (count($oldTaskList) > 0) { - foreach ($oldTaskList as $task => $foo) { - if (!isset($tasks[$task])) { - echo 'Dependency not found: '.$task, "\n"; - exit(1); - } - $dependencies = $tasks[$task]; - - $fullFilled = true; - foreach ($dependencies as $dependency) { - if (isset($newTaskList[$dependency])) { - // Already in the fulfilled task list. - continue; - } else { - $oldTaskList[$dependency] = true; - $fullFilled = false; - } - } - if ($fullFilled) { - unset($oldTaskList[$task]); - $newTaskList[$task] = 1; - } - } -} - -foreach (array_keys($newTaskList) as $task) { - echo 'task: '.$task, "\n"; - call_user_func($task); - echo "\n"; -} - -function init() -{ - global $version; - if (!$version) { - include __DIR__.'/../vendor/autoload.php'; - $version = Sabre\DAV\Version::VERSION; - } - - echo ' Building sabre/dav '.$version, "\n"; -} - -function clean() -{ - global $baseDir; - echo " Removing build files\n"; - $outputDir = $baseDir.'/build/SabreDAV'; - if (is_dir($outputDir)) { - system('rm -r '.$baseDir.'/build/SabreDAV'); - } -} - -function composerupdate() -{ - global $baseDir; - echo " Updating composer packages to latest version\n\n"; - system('cd '.$baseDir.'; composer update'); -} - -function test() -{ - global $baseDir; - - echo " Running all unittests.\n"; - echo " This may take a while.\n\n"; - system(__DIR__.'/phpunit --configuration '.$baseDir.'/tests/phpunit.xml.dist --stop-on-failure', $code); - if (0 != $code) { - echo "PHPUnit reported error code $code\n"; - exit(1); - } -} - -function buildzip() -{ - global $baseDir, $version; - echo " Generating composer.json\n"; - - $input = json_decode(file_get_contents(__DIR__.'/../composer.json'), true); - $newComposer = [ - 'require' => $input['require'], - 'config' => [ - 'bin-dir' => './bin', - ], - 'prefer-stable' => true, - 'minimum-stability' => 'alpha', - ]; - unset( - $newComposer['require']['sabre/vobject'], - $newComposer['require']['sabre/http'], - $newComposer['require']['sabre/uri'], - $newComposer['require']['sabre/event'] - ); - $newComposer['require']['sabre/dav'] = $version; - mkdir('build/SabreDAV'); - file_put_contents('build/SabreDAV/composer.json', json_encode($newComposer, JSON_PRETTY_PRINT)); - - echo " Downloading dependencies\n"; - system('cd build/SabreDAV; composer install -n', $code); - if (0 !== $code) { - echo "Composer reported error code $code\n"; - exit(1); - } - - echo " Removing pointless files\n"; - unlink('build/SabreDAV/composer.json'); - unlink('build/SabreDAV/composer.lock'); - - echo " Moving important files to the root of the project\n"; - - $fileNames = [ - 'CHANGELOG.md', - 'LICENSE', - 'README.md', - 'examples', - ]; - foreach ($fileNames as $fileName) { - echo " $fileName\n"; - rename('build/SabreDAV/vendor/sabre/dav/'.$fileName, 'build/SabreDAV/'.$fileName); - } - - // - - echo "\n"; - echo "Zipping the sabredav distribution\n\n"; - system('cd build; zip -qr sabredav-'.$version.'.zip SabreDAV'); - - echo 'Done.'; -} diff --git a/lib/vendor/sabre/dav/bin/migrateto20.php b/lib/vendor/sabre/dav/bin/migrateto20.php deleted file mode 100755 index fb24fe5..0000000 --- a/lib/vendor/sabre/dav/bin/migrateto20.php +++ /dev/null @@ -1,414 +0,0 @@ -#!/usr/bin/env php -setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); - -$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - -switch ($driver) { - case 'mysql': - echo "Detected MySQL.\n"; - break; - case 'sqlite': - echo "Detected SQLite.\n"; - break; - default: - echo 'Error: unsupported driver: '.$driver."\n"; - exit(-1); -} - -foreach (['calendar', 'addressbook'] as $itemType) { - $tableName = $itemType.'s'; - $tableNameOld = $tableName.'_old'; - $changesTable = $itemType.'changes'; - - echo "Upgrading '$tableName'\n"; - - // The only cross-db way to do this, is to just fetch a single record. - $row = $pdo->query("SELECT * FROM $tableName LIMIT 1")->fetch(); - - if (!$row) { - echo "No records were found in the '$tableName' table.\n"; - echo "\n"; - echo "We're going to rename the old table to $tableNameOld (just in case).\n"; - echo "and re-create the new table.\n"; - - switch ($driver) { - case 'mysql': - $pdo->exec("RENAME TABLE $tableName TO $tableNameOld"); - switch ($itemType) { - case 'calendar': - $pdo->exec(" - CREATE TABLE calendars ( - id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - principaluri VARCHAR(100), - displayname VARCHAR(100), - uri VARCHAR(200), - synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1', - description TEXT, - calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0', - calendarcolor VARCHAR(10), - timezone TEXT, - components VARCHAR(20), - transparent TINYINT(1) NOT NULL DEFAULT '0', - UNIQUE(principaluri, uri) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; - "); - break; - case 'addressbook': - $pdo->exec(" - CREATE TABLE addressbooks ( - id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - principaluri VARCHAR(255), - displayname VARCHAR(255), - uri VARCHAR(200), - description TEXT, - synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1', - UNIQUE(principaluri, uri) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; - "); - break; - } - break; - - case 'sqlite': - $pdo->exec("ALTER TABLE $tableName RENAME TO $tableNameOld"); - - switch ($itemType) { - case 'calendar': - $pdo->exec(' - CREATE TABLE calendars ( - id integer primary key asc, - principaluri text, - displayname text, - uri text, - synctoken integer, - description text, - calendarorder integer, - calendarcolor text, - timezone text, - components text, - transparent bool - ); - '); - break; - case 'addressbook': - $pdo->exec(' - CREATE TABLE addressbooks ( - id integer primary key asc, - principaluri text, - displayname text, - uri text, - description text, - synctoken integer - ); - '); - - break; - } - break; - } - echo "Creation of 2.0 $tableName table is complete\n"; - } else { - // Checking if there's a synctoken field already. - if (array_key_exists('synctoken', $row)) { - echo "The 'synctoken' field already exists in the $tableName table.\n"; - echo "It's likely you already upgraded, so we're simply leaving\n"; - echo "the $tableName table alone\n"; - } else { - echo "1.8 table schema detected\n"; - switch ($driver) { - case 'mysql': - $pdo->exec("ALTER TABLE $tableName ADD synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1'"); - $pdo->exec("ALTER TABLE $tableName DROP ctag"); - $pdo->exec("UPDATE $tableName SET synctoken = '1'"); - break; - case 'sqlite': - $pdo->exec("ALTER TABLE $tableName ADD synctoken integer"); - $pdo->exec("UPDATE $tableName SET synctoken = '1'"); - echo "Note: there's no easy way to remove fields in sqlite.\n"; - echo "The ctag field is no longer used, but it's kept in place\n"; - break; - } - - echo "Upgraded '$tableName' to 2.0 schema.\n"; - } - } - - try { - $pdo->query("SELECT * FROM $changesTable LIMIT 1"); - - echo "'$changesTable' already exists. Assuming that this part of the\n"; - echo "upgrade was already completed.\n"; - } catch (Exception $e) { - echo "Creating '$changesTable' table.\n"; - - switch ($driver) { - case 'mysql': - $pdo->exec(" - CREATE TABLE $changesTable ( - id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - uri VARCHAR(200) NOT NULL, - synctoken INT(11) UNSIGNED NOT NULL, - {$itemType}id INT(11) UNSIGNED NOT NULL, - operation TINYINT(1) NOT NULL, - INDEX {$itemType}id_synctoken ({$itemType}id, synctoken) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; - - "); - break; - case 'sqlite': - $pdo->exec(" - - CREATE TABLE $changesTable ( - id integer primary key asc, - uri text, - synctoken integer, - {$itemType}id integer, - operation bool - ); - - "); - $pdo->exec("CREATE INDEX {$itemType}id_synctoken ON $changesTable ({$itemType}id, synctoken);"); - break; - } - } -} - -try { - $pdo->query('SELECT * FROM calendarsubscriptions LIMIT 1'); - - echo "'calendarsubscriptions' already exists. Assuming that this part of the\n"; - echo "upgrade was already completed.\n"; -} catch (Exception $e) { - echo "Creating calendarsubscriptions table.\n"; - - switch ($driver) { - case 'mysql': - $pdo->exec(" -CREATE TABLE calendarsubscriptions ( - id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - uri VARCHAR(200) NOT NULL, - principaluri VARCHAR(100) NOT NULL, - source TEXT, - displayname VARCHAR(100), - refreshrate VARCHAR(10), - calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0', - calendarcolor VARCHAR(10), - striptodos TINYINT(1) NULL, - stripalarms TINYINT(1) NULL, - stripattachments TINYINT(1) NULL, - lastmodified INT(11) UNSIGNED, - UNIQUE(principaluri, uri) -); - "); - break; - case 'sqlite': - $pdo->exec(' - -CREATE TABLE calendarsubscriptions ( - id integer primary key asc, - uri text, - principaluri text, - source text, - displayname text, - refreshrate text, - calendarorder integer, - calendarcolor text, - striptodos bool, - stripalarms bool, - stripattachments bool, - lastmodified int -); - '); - - $pdo->exec('CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);'); - break; - } -} - -try { - $pdo->query('SELECT * FROM propertystorage LIMIT 1'); - - echo "'propertystorage' already exists. Assuming that this part of the\n"; - echo "upgrade was already completed.\n"; -} catch (Exception $e) { - echo "Creating propertystorage table.\n"; - - switch ($driver) { - case 'mysql': - $pdo->exec(' -CREATE TABLE propertystorage ( - id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - path VARBINARY(1024) NOT NULL, - name VARBINARY(100) NOT NULL, - value MEDIUMBLOB -); - '); - $pdo->exec(' -CREATE UNIQUE INDEX path_property ON propertystorage (path(600), name(100)); - '); - break; - case 'sqlite': - $pdo->exec(' -CREATE TABLE propertystorage ( - id integer primary key asc, - path TEXT, - name TEXT, - value TEXT -); - '); - $pdo->exec(' -CREATE UNIQUE INDEX path_property ON propertystorage (path, name); - '); - - break; - } -} - -echo "Upgrading cards table to 2.0 schema\n"; - -try { - $create = false; - $row = $pdo->query('SELECT * FROM cards LIMIT 1')->fetch(); - if (!$row) { - $random = mt_rand(1000, 9999); - echo "There was no data in the cards table, so we're re-creating it\n"; - echo "The old table will be renamed to cards_old$random, just in case.\n"; - - $create = true; - - switch ($driver) { - case 'mysql': - $pdo->exec("RENAME TABLE cards TO cards_old$random"); - break; - case 'sqlite': - $pdo->exec("ALTER TABLE cards RENAME TO cards_old$random"); - break; - } - } -} catch (Exception $e) { - echo "Exception while checking cards table. Assuming that the table does not yet exist.\n"; - echo 'Debug: ', $e->getMessage(), "\n"; - $create = true; -} - -if ($create) { - switch ($driver) { - case 'mysql': - $pdo->exec(' -CREATE TABLE cards ( - id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - addressbookid INT(11) UNSIGNED NOT NULL, - carddata MEDIUMBLOB, - uri VARCHAR(200), - lastmodified INT(11) UNSIGNED, - etag VARBINARY(32), - size INT(11) UNSIGNED NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; - - '); - break; - - case 'sqlite': - $pdo->exec(' -CREATE TABLE cards ( - id integer primary key asc, - addressbookid integer, - carddata blob, - uri text, - lastmodified integer, - etag text, - size integer -); - '); - break; - } -} else { - switch ($driver) { - case 'mysql': - $pdo->exec(' - ALTER TABLE cards - ADD etag VARBINARY(32), - ADD size INT(11) UNSIGNED NOT NULL; - '); - break; - - case 'sqlite': - $pdo->exec(' - ALTER TABLE cards ADD etag text; - ALTER TABLE cards ADD size integer; - '); - break; - } - echo "Reading all old vcards and populating etag and size fields.\n"; - $result = $pdo->query('SELECT id, carddata FROM cards'); - $stmt = $pdo->prepare('UPDATE cards SET etag = ?, size = ? WHERE id = ?'); - while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { - $stmt->execute([ - md5($row['carddata']), - strlen($row['carddata']), - $row['id'], - ]); - } -} - -echo "Upgrade to 2.0 schema completed.\n"; diff --git a/lib/vendor/sabre/dav/bin/migrateto21.php b/lib/vendor/sabre/dav/bin/migrateto21.php deleted file mode 100755 index 2c15b0a..0000000 --- a/lib/vendor/sabre/dav/bin/migrateto21.php +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env php -setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); - -$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - -switch ($driver) { - case 'mysql': - echo "Detected MySQL.\n"; - break; - case 'sqlite': - echo "Detected SQLite.\n"; - break; - default: - echo 'Error: unsupported driver: '.$driver."\n"; - exit(-1); -} - -echo "Upgrading 'calendarobjects'\n"; -$addUid = false; -try { - $result = $pdo->query('SELECT * FROM calendarobjects LIMIT 1'); - $row = $result->fetch(\PDO::FETCH_ASSOC); - - if (!$row) { - echo "No data in table. Going to try to add the uid field anyway.\n"; - $addUid = true; - } elseif (array_key_exists('uid', $row)) { - echo "uid field exists. Assuming that this part of the migration has\n"; - echo "Already been completed.\n"; - } else { - echo "2.0 schema detected.\n"; - $addUid = true; - } -} catch (Exception $e) { - echo "Could not find a calendarobjects table. Skipping this part of the\n"; - echo "upgrade.\n"; -} - -if ($addUid) { - switch ($driver) { - case 'mysql': - $pdo->exec('ALTER TABLE calendarobjects ADD uid VARCHAR(200)'); - break; - case 'sqlite': - $pdo->exec('ALTER TABLE calendarobjects ADD uid TEXT'); - break; - } - - $result = $pdo->query('SELECT id, calendardata FROM calendarobjects'); - $stmt = $pdo->prepare('UPDATE calendarobjects SET uid = ? WHERE id = ?'); - $counter = 0; - - while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { - try { - $vobj = \Sabre\VObject\Reader::read($row['calendardata']); - } catch (\Exception $e) { - echo "Warning! Item with id $row[id] could not be parsed!\n"; - continue; - } - $uid = null; - $item = $vobj->getBaseComponent(); - if (!isset($item->UID)) { - echo "Warning! Item with id $item[id] does NOT have a UID property and this is required.\n"; - continue; - } - $uid = (string) $item->UID; - $stmt->execute([$uid, $row['id']]); - ++$counter; - } -} - -echo "Creating 'schedulingobjects'\n"; - -switch ($driver) { - case 'mysql': - $pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects -( - id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - principaluri VARCHAR(255), - calendardata MEDIUMBLOB, - uri VARCHAR(200), - lastmodified INT(11) UNSIGNED, - etag VARCHAR(32), - size INT(11) UNSIGNED NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; - '); - break; - - case 'sqlite': - $pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects ( - id integer primary key asc, - principaluri text, - calendardata blob, - uri text, - lastmodified integer, - etag text, - size integer -) -'); - break; -} - -echo "Done.\n"; - -echo "Upgrade to 2.1 schema completed.\n"; diff --git a/lib/vendor/sabre/dav/bin/migrateto30.php b/lib/vendor/sabre/dav/bin/migrateto30.php deleted file mode 100755 index 9798cad..0000000 --- a/lib/vendor/sabre/dav/bin/migrateto30.php +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env php -setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); - -$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - -switch ($driver) { - case 'mysql': - echo "Detected MySQL.\n"; - break; - case 'sqlite': - echo "Detected SQLite.\n"; - break; - default: - echo 'Error: unsupported driver: '.$driver."\n"; - exit(-1); -} - -echo "Upgrading 'propertystorage'\n"; -$addValueType = false; -try { - $result = $pdo->query('SELECT * FROM propertystorage LIMIT 1'); - $row = $result->fetch(\PDO::FETCH_ASSOC); - - if (!$row) { - echo "No data in table. Going to re-create the table.\n"; - $random = mt_rand(1000, 9999); - echo "Renaming propertystorage -> propertystorage_old$random and creating new table.\n"; - - switch ($driver) { - case 'mysql': - $pdo->exec('RENAME TABLE propertystorage TO propertystorage_old'.$random); - $pdo->exec(' - CREATE TABLE propertystorage ( - id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, - path VARBINARY(1024) NOT NULL, - name VARBINARY(100) NOT NULL, - valuetype INT UNSIGNED, - value MEDIUMBLOB - ); - '); - $pdo->exec('CREATE UNIQUE INDEX path_property_'.$random.' ON propertystorage (path(600), name(100));'); - break; - case 'sqlite': - $pdo->exec('ALTER TABLE propertystorage RENAME TO propertystorage_old'.$random); - $pdo->exec(' -CREATE TABLE propertystorage ( - id integer primary key asc, - path text, - name text, - valuetype integer, - value blob -);'); - - $pdo->exec('CREATE UNIQUE INDEX path_property_'.$random.' ON propertystorage (path, name);'); - break; - } - } elseif (array_key_exists('valuetype', $row)) { - echo "valuetype field exists. Assuming that this part of the migration has\n"; - echo "Already been completed.\n"; - } else { - echo "2.1 schema detected. Going to perform upgrade.\n"; - $addValueType = true; - } -} catch (Exception $e) { - echo "Could not find a propertystorage table. Skipping this part of the\n"; - echo "upgrade.\n"; - echo $e->getMessage(), "\n"; -} - -if ($addValueType) { - switch ($driver) { - case 'mysql': - $pdo->exec('ALTER TABLE propertystorage ADD valuetype INT UNSIGNED'); - break; - case 'sqlite': - $pdo->exec('ALTER TABLE propertystorage ADD valuetype INT'); - - break; - } - - $pdo->exec('UPDATE propertystorage SET valuetype = 1 WHERE valuetype IS NULL '); -} - -echo "Migrating vcardurl\n"; - -$result = $pdo->query('SELECT id, uri, vcardurl FROM principals WHERE vcardurl IS NOT NULL'); -$stmt1 = $pdo->prepare('INSERT INTO propertystorage (path, name, valuetype, value) VALUES (?, ?, 3, ?)'); - -while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { - // Inserting the new record - $stmt1->execute([ - 'addressbooks/'.basename($row['uri']), - '{http://calendarserver.org/ns/}me-card', - serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl'])), - ]); - - echo serialize(new Sabre\DAV\Xml\Property\Href($row['vcardurl'])); -} - -echo "Done.\n"; -echo "Upgrade to 3.0 schema completed.\n"; diff --git a/lib/vendor/sabre/dav/bin/migrateto32.php b/lib/vendor/sabre/dav/bin/migrateto32.php deleted file mode 100755 index 09ac55d..0000000 --- a/lib/vendor/sabre/dav/bin/migrateto32.php +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env php -setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); - -$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - -switch ($driver) { - case 'mysql': - echo "Detected MySQL.\n"; - break; - case 'sqlite': - echo "Detected SQLite.\n"; - break; - default: - echo 'Error: unsupported driver: '.$driver."\n"; - exit(-1); -} - -echo "Creating 'calendarinstances'\n"; -$addValueType = false; -try { - $result = $pdo->query('SELECT * FROM calendarinstances LIMIT 1'); - $result->fetch(\PDO::FETCH_ASSOC); - echo "calendarinstances exists. Assuming this part of the migration has already been done.\n"; -} catch (Exception $e) { - echo "calendarinstances does not yet exist. Creating table and migrating data.\n"; - - switch ($driver) { - case 'mysql': - $pdo->exec(<<exec(' -INSERT INTO calendarinstances - ( - calendarid, - principaluri, - access, - displayname, - uri, - description, - calendarorder, - calendarcolor, - transparent - ) -SELECT - id, - principaluri, - 1, - displayname, - uri, - description, - calendarorder, - calendarcolor, - transparent -FROM calendars -'); - break; - case 'sqlite': - $pdo->exec(<<exec(' -INSERT INTO calendarinstances - ( - calendarid, - principaluri, - access, - displayname, - uri, - description, - calendarorder, - calendarcolor, - transparent - ) -SELECT - id, - principaluri, - 1, - displayname, - uri, - description, - calendarorder, - calendarcolor, - transparent -FROM calendars -'); - break; - } -} -try { - $result = $pdo->query('SELECT * FROM calendars LIMIT 1'); - $row = $result->fetch(\PDO::FETCH_ASSOC); - - if (!$row) { - echo "Source table is empty.\n"; - $migrateCalendars = true; - } - - $columnCount = count($row); - if (3 === $columnCount) { - echo "The calendars table has 3 columns already. Assuming this part of the migration was already done.\n"; - $migrateCalendars = false; - } else { - echo 'The calendars table has '.$columnCount." columns.\n"; - $migrateCalendars = true; - } -} catch (Exception $e) { - echo "calendars table does not exist. This is a major problem. Exiting.\n"; - exit(-1); -} - -if ($migrateCalendars) { - $calendarBackup = 'calendars_3_1_'.$backupPostfix; - echo "Backing up 'calendars' to '", $calendarBackup, "'\n"; - - switch ($driver) { - case 'mysql': - $pdo->exec('RENAME TABLE calendars TO '.$calendarBackup); - break; - case 'sqlite': - $pdo->exec('ALTER TABLE calendars RENAME TO '.$calendarBackup); - break; - } - - echo "Creating new calendars table.\n"; - switch ($driver) { - case 'mysql': - $pdo->exec(<<exec(<<exec(<<0): - print "Bytes to go before we hit threshold:", bytes - else: - print "Threshold exceeded with:", -bytes, "bytes" - dir = os.listdir(cacheDir) - dir2 = [] - for file in dir: - path = cacheDir + '/' + file - dir2.append({ - "path" : path, - "atime": os.stat(path).st_atime, - "size" : os.stat(path).st_size - }) - - dir2.sort(lambda x,y: int(x["atime"]-y["atime"])) - - filesunlinked = 0 - gainedspace = 0 - - # Left is the amount of bytes that need to be freed up - # The default is the 'min_erase setting' - left = min_erase - - # If the min_erase setting is lower than the amount of bytes over - # the threshold, we use that number instead. - if left < -bytes : - left = -bytes - - print "Need to delete at least:", left; - - for file in dir2: - - # Only deleting files if we're not simulating - if not simulate: os.unlink(file["path"]) - left = int(left - file["size"]) - gainedspace = gainedspace + file["size"] - filesunlinked = filesunlinked + 1 - - if(left<0): - break - - print "%d files deleted (%d bytes)" % (filesunlinked, gainedspace) - - - time.sleep(sleep) - - - -def main(): - parser = OptionParser( - version="naturalselection v0.3", - description="Cache directory manager. Deletes cache entries based on accesstime and free space thresholds.\n" + - "This utility is distributed alongside SabreDAV.", - usage="usage: %prog [options] cacheDirectory", - ) - parser.add_option( - '-s', - dest="simulate", - action="store_true", - help="Don't actually make changes, but just simulate the behaviour", - ) - parser.add_option( - '-r','--runs', - help="How many times to check before exiting. -1 is infinite, which is the default", - type="int", - dest="runs", - default=-1 - ) - parser.add_option( - '-n','--interval', - help="Sleep time in seconds (default = 5)", - type="int", - dest="sleep", - default=5 - ) - parser.add_option( - '-l','--threshold', - help="Threshold in bytes (default = 10737418240, which is 10GB)", - type="int", - dest="threshold", - default=10737418240 - ) - parser.add_option( - '-m', '--min-erase', - help="Minimum number of bytes to erase when the threshold is reached. " + - "Setting this option higher will reduce the number of times the cache directory will need to be scanned. " + - "(the default is 1073741824, which is 1GB.)", - type="int", - dest="min_erase", - default=1073741824 - ) - - options,args = parser.parse_args() - if len(args)<1: - parser.error("This utility requires at least 1 argument") - cacheDir = args[0] - - print "Natural Selection" - print "Cache directory:", cacheDir - free = getfreespace(cacheDir); - print "Current free disk space:", free - - runs = options.runs; - while runs!=0 : - run( - cacheDir, - sleep=options.sleep, - simulate=options.simulate, - threshold=options.threshold, - min_erase=options.min_erase - ) - if runs>0: - runs = runs - 1 - -if __name__ == '__main__' : - main() diff --git a/lib/vendor/sabre/dav/bin/sabredav b/lib/vendor/sabre/dav/bin/sabredav deleted file mode 100755 index 032371b..0000000 --- a/lib/vendor/sabre/dav/bin/sabredav +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -php -S 0.0.0.0:8080 `dirname $0`/sabredav.php diff --git a/lib/vendor/sabre/dav/bin/sabredav.php b/lib/vendor/sabre/dav/bin/sabredav.php deleted file mode 100755 index 71047b8..0000000 --- a/lib/vendor/sabre/dav/bin/sabredav.php +++ /dev/null @@ -1,51 +0,0 @@ -stream = fopen('php://stdout', 'w'); - } - - public function log($msg) - { - fwrite($this->stream, $msg."\n"); - } -} - -$log = new CliLog(); - -if ('cli-server' !== php_sapi_name()) { - exit('This script is intended to run on the built-in php webserver'); -} - -// Finding composer - -$paths = [ - __DIR__.'/../vendor/autoload.php', - __DIR__.'/../../../autoload.php', -]; - -foreach ($paths as $path) { - if (file_exists($path)) { - include $path; - break; - } -} - -use Sabre\DAV; - -// Root -$root = new DAV\FS\Directory(getcwd()); - -// Setting up server. -$server = new DAV\Server($root); - -// Browser plugin -$server->addPlugin(new DAV\Browser\Plugin()); - -$server->exec(); diff --git a/lib/vendor/sabre/dav/composer.json b/lib/vendor/sabre/dav/composer.json deleted file mode 100644 index 3154173..0000000 --- a/lib/vendor/sabre/dav/composer.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "sabre/dav", - "type": "library", - "description": "WebDAV Framework for PHP", - "keywords": ["Framework", "WebDAV", "CalDAV", "CardDAV", "iCalendar"], - "homepage": "http://sabre.io/", - "license" : "BSD-3-Clause", - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage" : "http://evertpot.com/", - "role" : "Developer" - } - ], - "require": { - "php": "^7.1.0 || ^8.0", - "sabre/vobject": "^4.2.1", - "sabre/event" : "^5.0", - "sabre/xml" : "^2.0.1", - "sabre/http" : "^5.0.5", - "sabre/uri" : "^2.0", - "ext-dom": "*", - "ext-pcre": "*", - "ext-spl": "*", - "ext-simplexml": "*", - "ext-mbstring" : "*", - "ext-ctype" : "*", - "ext-date" : "*", - "ext-iconv" : "*", - "lib-libxml" : ">=2.7.0", - "psr/log": "^1.0 || ^2.0 || ^3.0", - "ext-json": "*" - }, - "require-dev" : { - "friendsofphp/php-cs-fixer": "^2.19", - "monolog/monolog": "^1.27 || ^2.0", - "phpstan/phpstan": "^0.12 || ^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" - }, - "suggest" : { - "ext-curl" : "*", - "ext-pdo" : "*", - "ext-imap": "*" - }, - "autoload": { - "psr-4" : { - "Sabre\\" : "lib/" - } - }, - "autoload-dev" : { - "psr-4" : { - "Sabre\\" : "tests/Sabre/" - } - }, - "support" : { - "forum" : "https://groups.google.com/group/sabredav-discuss", - "source" : "https://github.com/fruux/sabre-dav" - }, - "bin" : [ - "bin/sabredav", - "bin/naturalselection" - ], - "scripts": { - "phpstan": [ - "phpstan analyse lib tests" - ], - "cs-fixer": [ - "php-cs-fixer fix" - ], - "phpunit": [ - "phpunit --configuration tests/phpunit.xml" - ], - "test": [ - "composer phpstan", - "composer cs-fixer", - "composer phpunit" - ] - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php b/lib/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php deleted file mode 100644 index c761bff..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Backend/AbstractBackend.php +++ /dev/null @@ -1,216 +0,0 @@ -getCalendarObject($calendarId, $uri); - }, $uris); - } - - /** - * Performs a calendar-query on the contents of this calendar. - * - * The calendar-query is defined in RFC4791 : CalDAV. Using the - * calendar-query it is possible for a client to request a specific set of - * object, based on contents of iCalendar properties, date-ranges and - * iCalendar component types (VTODO, VEVENT). - * - * This method should just return a list of (relative) urls that match this - * query. - * - * The list of filters are specified as an array. The exact array is - * documented by \Sabre\CalDAV\CalendarQueryParser. - * - * Note that it is extremely likely that getCalendarObject for every path - * returned from this method will be called almost immediately after. You - * may want to anticipate this to speed up these requests. - * - * This method provides a default implementation, which parses *all* the - * iCalendar objects in the specified calendar. - * - * This default may well be good enough for personal use, and calendars - * that aren't very large. But if you anticipate high usage, big calendars - * or high loads, you are strongly advised to optimize certain paths. - * - * The best way to do so is override this method and to optimize - * specifically for 'common filters'. - * - * Requests that are extremely common are: - * * requests for just VEVENTS - * * requests for just VTODO - * * requests with a time-range-filter on either VEVENT or VTODO. - * - * ..and combinations of these requests. It may not be worth it to try to - * handle every possible situation and just rely on the (relatively - * easy to use) CalendarQueryValidator to handle the rest. - * - * Note that especially time-range-filters may be difficult to parse. A - * time-range filter specified on a VEVENT must for instance also handle - * recurrence rules correctly. - * A good example of how to interpret all these filters can also simply - * be found in \Sabre\CalDAV\CalendarQueryFilter. This class is as correct - * as possible, so it gives you a good idea on what type of stuff you need - * to think of. - * - * @param mixed $calendarId - * - * @return array - */ - public function calendarQuery($calendarId, array $filters) - { - $result = []; - $objects = $this->getCalendarObjects($calendarId); - - foreach ($objects as $object) { - if ($this->validateFilterForObject($object, $filters)) { - $result[] = $object['uri']; - } - } - - return $result; - } - - /** - * This method validates if a filter (as passed to calendarQuery) matches - * the given object. - * - * @return bool - */ - protected function validateFilterForObject(array $object, array $filters) - { - // Unfortunately, setting the 'calendardata' here is optional. If - // it was excluded, we actually need another call to get this as - // well. - if (!isset($object['calendardata'])) { - $object = $this->getCalendarObject($object['calendarid'], $object['uri']); - } - - $vObject = VObject\Reader::read($object['calendardata']); - - $validator = new CalDAV\CalendarQueryValidator(); - $result = $validator->validate($vObject, $filters); - - // Destroy circular references so PHP will GC the object. - $vObject->destroy(); - - return $result; - } - - /** - * Searches through all of a users calendars and calendar objects to find - * an object with a specific UID. - * - * This method should return the path to this object, relative to the - * calendar home, so this path usually only contains two parts: - * - * calendarpath/objectpath.ics - * - * If the uid is not found, return null. - * - * This method should only consider * objects that the principal owns, so - * any calendars owned by other principals that also appear in this - * collection should be ignored. - * - * @param string $principalUri - * @param string $uid - * - * @return string|null - */ - public function getCalendarObjectByUID($principalUri, $uid) - { - // Note: this is a super slow naive implementation of this method. You - // are highly recommended to optimize it, if your backend allows it. - foreach ($this->getCalendarsForUser($principalUri) as $calendar) { - // We must ignore calendars owned by other principals. - if ($calendar['principaluri'] !== $principalUri) { - continue; - } - - // Ignore calendars that are shared. - if (isset($calendar['{http://sabredav.org/ns}owner-principal']) && $calendar['{http://sabredav.org/ns}owner-principal'] !== $principalUri) { - continue; - } - - $results = $this->calendarQuery( - $calendar['id'], - [ - 'name' => 'VCALENDAR', - 'prop-filters' => [], - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'is-not-defined' => false, - 'time-range' => null, - 'comp-filters' => [], - 'prop-filters' => [ - [ - 'name' => 'UID', - 'is-not-defined' => false, - 'time-range' => null, - 'text-match' => [ - 'value' => $uid, - 'negate-condition' => false, - 'collation' => 'i;octet', - ], - 'param-filters' => [], - ], - ], - ], - ], - ] - ); - if ($results) { - // We have a match - return $calendar['uri'].'/'.$results[0]; - } - } - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php b/lib/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php deleted file mode 100644 index ccaa251..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php +++ /dev/null @@ -1,273 +0,0 @@ - 'displayname', - '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description', - '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone', - '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', - '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', - ]; - - /** - * List of subscription properties, and how they map to database fieldnames. - * - * @var array - */ - public $subscriptionPropertyMap = [ - '{DAV:}displayname' => 'displayname', - '{http://apple.com/ns/ical/}refreshrate' => 'refreshrate', - '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', - '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', - '{http://calendarserver.org/ns/}subscribed-strip-todos' => 'striptodos', - '{http://calendarserver.org/ns/}subscribed-strip-alarms' => 'stripalarms', - '{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments', - ]; - - /** - * Creates the backend. - */ - public function __construct(\PDO $pdo) - { - $this->pdo = $pdo; - } - - /** - * Returns a list of calendars for a principal. - * - * 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. This is just the 'base uri' or 'filename' of the calendar. - * * 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'. - * - * Many clients also require: - * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set - * For this property, you can just return an instance of - * Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet. - * - * If you return {http://sabredav.org/ns}read-only and set the value to 1, - * ACL will automatically be put in read-only mode. - * - * @param string $principalUri - * - * @return array - */ - public function getCalendarsForUser($principalUri) - { - $fields = array_values($this->propertyMap); - $fields[] = 'calendarid'; - $fields[] = 'uri'; - $fields[] = 'synctoken'; - $fields[] = 'components'; - $fields[] = 'principaluri'; - $fields[] = 'transparent'; - $fields[] = 'access'; - - // Making fields a comma-delimited list - $fields = implode(', ', $fields); - $stmt = $this->pdo->prepare(<<calendarInstancesTableName}.id as id, $fields FROM {$this->calendarInstancesTableName} - LEFT JOIN {$this->calendarTableName} ON - {$this->calendarInstancesTableName}.calendarid = {$this->calendarTableName}.id -WHERE principaluri = ? ORDER BY calendarorder ASC -SQL - ); - $stmt->execute([$principalUri]); - - $calendars = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $components = []; - if ($row['components']) { - $components = explode(',', $row['components']); - } - - $calendar = [ - 'id' => [(int) $row['calendarid'], (int) $row['id']], - 'uri' => $row['uri'], - 'principaluri' => $row['principaluri'], - '{'.CalDAV\Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'), - '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0', - '{'.CalDAV\Plugin::NS_CALDAV.'}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet($components), - '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'), - 'share-resource-uri' => '/ns/share/'.$row['calendarid'], - ]; - - $calendar['share-access'] = (int) $row['access']; - // 1 = owner, 2 = readonly, 3 = readwrite - if ($row['access'] > 1) { - // We need to find more information about the original owner. - //$stmt2 = $this->pdo->prepare('SELECT principaluri FROM ' . $this->calendarInstancesTableName . ' WHERE access = 1 AND id = ?'); - //$stmt2->execute([$row['id']]); - - // read-only is for backwards compatibility. Might go away in - // the future. - $calendar['read-only'] = \Sabre\DAV\Sharing\Plugin::ACCESS_READ === (int) $row['access']; - } - - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } - - $calendars[] = $calendar; - } - - return $calendars; - } - - /** - * Creates a new calendar for a principal. - * - * If the creation was a success, an id must be returned that can be used - * to reference this calendar in other methods, such as updateCalendar. - * - * @param string $principalUri - * @param string $calendarUri - * - * @return string - */ - public function createCalendar($principalUri, $calendarUri, array $properties) - { - $fieldNames = [ - 'principaluri', - 'uri', - 'transparent', - 'calendarid', - ]; - $values = [ - ':principaluri' => $principalUri, - ':uri' => $calendarUri, - ':transparent' => 0, - ]; - - $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'; - if (!isset($properties[$sccs])) { - // Default value - $components = 'VEVENT,VTODO'; - } else { - if (!($properties[$sccs] instanceof CalDAV\Xml\Property\SupportedCalendarComponentSet)) { - throw new DAV\Exception('The '.$sccs.' property must be of type: \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet'); - } - $components = implode(',', $properties[$sccs]->getValue()); - } - $transp = '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp'; - if (isset($properties[$transp])) { - $values[':transparent'] = 'transparent' === $properties[$transp]->getValue() ? 1 : 0; - } - $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarTableName.' (synctoken, components) VALUES (1, ?)'); - $stmt->execute([$components]); - - $calendarId = $this->pdo->lastInsertId( - $this->calendarTableName.'_id_seq' - ); - - $values[':calendarid'] = $calendarId; - - foreach ($this->propertyMap as $xmlName => $dbName) { - if (isset($properties[$xmlName])) { - $values[':'.$dbName] = $properties[$xmlName]; - $fieldNames[] = $dbName; - } - } - - $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarInstancesTableName.' ('.implode(', ', $fieldNames).') VALUES ('.implode(', ', array_keys($values)).')'); - - $stmt->execute($values); - - return [ - $calendarId, - $this->pdo->lastInsertId($this->calendarInstancesTableName.'_id_seq'), - ]; - } - - /** - * Updates properties for a calendar. - * - * The list of mutations is stored in a Sabre\DAV\PropPatch object. - * To do the actual updates, you must tell this object which properties - * you're going to process with the handle() method. - * - * Calling the handle method is like telling the PropPatch object "I - * promise I can handle updating this property". - * - * Read the PropPatch documentation for more info and examples. - * - * @param mixed $calendarId - */ - public function updateCalendar($calendarId, PropPatch $propPatch) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $supportedProperties = array_keys($this->propertyMap); - $supportedProperties[] = '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp'; - - $propPatch->handle($supportedProperties, function ($mutations) use ($calendarId, $instanceId) { - $newValues = []; - foreach ($mutations as $propertyName => $propertyValue) { - switch ($propertyName) { - case '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp': - $fieldName = 'transparent'; - $newValues[$fieldName] = 'transparent' === $propertyValue->getValue(); - break; - default: - $fieldName = $this->propertyMap[$propertyName]; - $newValues[$fieldName] = $propertyValue; - break; - } - } - $valuesSql = []; - foreach ($newValues as $fieldName => $value) { - $valuesSql[] = $fieldName.' = ?'; - } - - $stmt = $this->pdo->prepare('UPDATE '.$this->calendarInstancesTableName.' SET '.implode(', ', $valuesSql).' WHERE id = ?'); - $newValues['id'] = $instanceId; - $stmt->execute(array_values($newValues)); - - $this->addChange($calendarId, '', 2); - - return true; - }); - } - - /** - * Delete a calendar and all it's objects. - * - * @param mixed $calendarId - */ - public function deleteCalendar($calendarId) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $stmt = $this->pdo->prepare('SELECT access FROM '.$this->calendarInstancesTableName.' where id = ?'); - $stmt->execute([$instanceId]); - $access = (int) $stmt->fetchColumn(); - - if (\Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER === $access) { - /** - * If the user is the owner of the calendar, we delete all data and all - * instances. - **/ - $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'); - $stmt->execute([$calendarId]); - - $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarChangesTableName.' WHERE calendarid = ?'); - $stmt->execute([$calendarId]); - - $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarInstancesTableName.' WHERE calendarid = ?'); - $stmt->execute([$calendarId]); - - $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarTableName.' WHERE id = ?'); - $stmt->execute([$calendarId]); - } else { - /** - * If it was an instance of a shared calendar, we only delete that - * instance. - */ - $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarInstancesTableName.' WHERE id = ?'); - $stmt->execute([$instanceId]); - } - } - - /** - * Returns all calendar objects within a calendar. - * - * Every item contains an array with the following keys: - * * calendardata - The iCalendar-compatible calendar data - * * uri - a unique key which will be used to construct the uri. This can - * be any arbitrary string, but making sure it ends with '.ics' is a - * good idea. This is only the basename, or filename, not the full - * path. - * * lastmodified - a timestamp of the last modification time - * * etag - An arbitrary string, surrounded by double-quotes. (e.g.: - * ' "abcdef"') - * * size - The size of the calendar objects, in bytes. - * * component - optional, a string containing the type of object, such - * as 'vevent' or 'vtodo'. If specified, this will be used to populate - * the Content-Type header. - * - * 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 - * calendardata. - * - * 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 mixed $calendarId - * - * @return array - */ - public function getCalendarObjects($calendarId) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, componenttype FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'); - $stmt->execute([$calendarId]); - - $result = []; - foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { - $result[] = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'lastmodified' => (int) $row['lastmodified'], - 'etag' => '"'.$row['etag'].'"', - 'size' => (int) $row['size'], - 'component' => strtolower($row['componenttype']), - ]; - } - - return $result; - } - - /** - * Returns information from a single calendar object, based on it's object - * uri. - * - * The object uri is only the basename, or filename and not a full path. - * - * The returned array must have the same keys as getCalendarObjects. The - * 'calendardata' object is required here though, while it's not required - * for getCalendarObjects. - * - * This method must return null if the object did not exist. - * - * @param mixed $calendarId - * @param string $objectUri - * - * @return array|null - */ - public function getCalendarObject($calendarId, $objectUri) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?'); - $stmt->execute([$calendarId, $objectUri]); - $row = $stmt->fetch(\PDO::FETCH_ASSOC); - - if (!$row) { - return null; - } - - return [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'lastmodified' => (int) $row['lastmodified'], - 'etag' => '"'.$row['etag'].'"', - 'size' => (int) $row['size'], - 'calendardata' => $row['calendardata'], - 'component' => strtolower($row['componenttype']), - ]; - } - - /** - * Returns a list of calendar objects. - * - * This method should work identical to getCalendarObject, but instead - * return all the calendar objects in the list as an array. - * - * If the backend supports this, it may allow for some speed-ups. - * - * @param mixed $calendarId - * - * @return array - */ - public function getMultipleCalendarObjects($calendarId, array $uris) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $result = []; - foreach (array_chunk($uris, 900) as $chunk) { - $query = 'SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri IN ('; - // Inserting a whole bunch of question marks - $query .= implode(',', array_fill(0, count($chunk), '?')); - $query .= ')'; - - $stmt = $this->pdo->prepare($query); - $stmt->execute(array_merge([$calendarId], $chunk)); - - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $result[] = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'lastmodified' => (int) $row['lastmodified'], - 'etag' => '"'.$row['etag'].'"', - 'size' => (int) $row['size'], - 'calendardata' => $row['calendardata'], - 'component' => strtolower($row['componenttype']), - ]; - } - } - - return $result; - } - - /** - * Creates a new calendar object. - * - * The object uri is only the basename, or filename and not a full path. - * - * It is possible return an etag from this function, which will be used in - * the response to this PUT request. Note that the ETag must be surrounded - * by double-quotes. - * - * However, you should only really return this ETag if you don't mangle the - * calendar-data. If the result of a subsequent GET to this object is not - * the exact same as this request body, you should omit the ETag. - * - * @param mixed $calendarId - * @param string $objectUri - * @param string $calendarData - * - * @return string|null - */ - public function createCalendarObject($calendarId, $objectUri, $calendarData) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $extraData = $this->getDenormalizedData($calendarData); - - $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarObjectTableName.' (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence, uid) VALUES (?,?,?,?,?,?,?,?,?,?)'); - $stmt->execute([ - $calendarId, - $objectUri, - $calendarData, - time(), - $extraData['etag'], - $extraData['size'], - $extraData['componentType'], - $extraData['firstOccurence'], - $extraData['lastOccurence'], - $extraData['uid'], - ]); - $this->addChange($calendarId, $objectUri, 1); - - return '"'.$extraData['etag'].'"'; - } - - /** - * Updates an existing calendarobject, based on it's uri. - * - * The object uri is only the basename, or filename and not a full path. - * - * It is possible return an etag from this function, which will be used in - * the response to this PUT request. Note that the ETag must be surrounded - * by double-quotes. - * - * However, you should only really return this ETag if you don't mangle the - * calendar-data. If the result of a subsequent GET to this object is not - * the exact same as this request body, you should omit the ETag. - * - * @param mixed $calendarId - * @param string $objectUri - * @param string $calendarData - * - * @return string|null - */ - public function updateCalendarObject($calendarId, $objectUri, $calendarData) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $extraData = $this->getDenormalizedData($calendarData); - - $stmt = $this->pdo->prepare('UPDATE '.$this->calendarObjectTableName.' SET calendardata = ?, lastmodified = ?, etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ?, uid = ? WHERE calendarid = ? AND uri = ?'); - $stmt->execute([$calendarData, time(), $extraData['etag'], $extraData['size'], $extraData['componentType'], $extraData['firstOccurence'], $extraData['lastOccurence'], $extraData['uid'], $calendarId, $objectUri]); - - $this->addChange($calendarId, $objectUri, 2); - - return '"'.$extraData['etag'].'"'; - } - - /** - * Parses some information from calendar objects, used for optimized - * calendar-queries. - * - * Returns an array with the following keys: - * * etag - An md5 checksum of the object without the quotes. - * * size - Size of the object in bytes - * * componentType - VEVENT, VTODO or VJOURNAL - * * firstOccurence - * * lastOccurence - * * uid - value of the UID property - * - * @param string $calendarData - * - * @return array - */ - protected function getDenormalizedData($calendarData) - { - $vObject = VObject\Reader::read($calendarData); - $componentType = null; - $component = null; - $firstOccurence = null; - $lastOccurence = null; - $uid = null; - foreach ($vObject->getComponents() as $component) { - if ('VTIMEZONE' !== $component->name) { - $componentType = $component->name; - $uid = (string) $component->UID; - break; - } - } - if (!$componentType) { - throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); - } - if ('VEVENT' === $componentType) { - $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp(); - // Finding the last occurence is a bit harder - if (!isset($component->RRULE)) { - if (isset($component->DTEND)) { - $lastOccurence = $component->DTEND->getDateTime()->getTimeStamp(); - } elseif (isset($component->DURATION)) { - $endDate = clone $component->DTSTART->getDateTime(); - $endDate = $endDate->add(VObject\DateTimeParser::parse($component->DURATION->getValue())); - $lastOccurence = $endDate->getTimeStamp(); - } elseif (!$component->DTSTART->hasTime()) { - $endDate = clone $component->DTSTART->getDateTime(); - $endDate = $endDate->modify('+1 day'); - $lastOccurence = $endDate->getTimeStamp(); - } else { - $lastOccurence = $firstOccurence; - } - } else { - $it = new VObject\Recur\EventIterator($vObject, (string) $component->UID); - $maxDate = new \DateTime(self::MAX_DATE); - if ($it->isInfinite()) { - $lastOccurence = $maxDate->getTimeStamp(); - } else { - $end = $it->getDtEnd(); - while ($it->valid() && $end < $maxDate) { - $end = $it->getDtEnd(); - $it->next(); - } - $lastOccurence = $end->getTimeStamp(); - } - } - - // Ensure Occurence values are positive - if ($firstOccurence < 0) { - $firstOccurence = 0; - } - if ($lastOccurence < 0) { - $lastOccurence = 0; - } - } - - // Destroy circular references to PHP will GC the object. - $vObject->destroy(); - - return [ - 'etag' => md5($calendarData), - 'size' => strlen($calendarData), - 'componentType' => $componentType, - 'firstOccurence' => $firstOccurence, - 'lastOccurence' => $lastOccurence, - 'uid' => $uid, - ]; - } - - /** - * Deletes an existing calendar object. - * - * The object uri is only the basename, or filename and not a full path. - * - * @param mixed $calendarId - * @param string $objectUri - */ - public function deleteCalendarObject($calendarId, $objectUri) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?'); - $stmt->execute([$calendarId, $objectUri]); - - $this->addChange($calendarId, $objectUri, 3); - } - - /** - * Performs a calendar-query on the contents of this calendar. - * - * The calendar-query is defined in RFC4791 : CalDAV. Using the - * calendar-query it is possible for a client to request a specific set of - * object, based on contents of iCalendar properties, date-ranges and - * iCalendar component types (VTODO, VEVENT). - * - * This method should just return a list of (relative) urls that match this - * query. - * - * The list of filters are specified as an array. The exact array is - * documented by \Sabre\CalDAV\CalendarQueryParser. - * - * Note that it is extremely likely that getCalendarObject for every path - * returned from this method will be called almost immediately after. You - * may want to anticipate this to speed up these requests. - * - * This method provides a default implementation, which parses *all* the - * iCalendar objects in the specified calendar. - * - * This default may well be good enough for personal use, and calendars - * that aren't very large. But if you anticipate high usage, big calendars - * or high loads, you are strongly advised to optimize certain paths. - * - * The best way to do so is override this method and to optimize - * specifically for 'common filters'. - * - * Requests that are extremely common are: - * * requests for just VEVENTS - * * requests for just VTODO - * * requests with a time-range-filter on a VEVENT. - * - * ..and combinations of these requests. It may not be worth it to try to - * handle every possible situation and just rely on the (relatively - * easy to use) CalendarQueryValidator to handle the rest. - * - * Note that especially time-range-filters may be difficult to parse. A - * time-range filter specified on a VEVENT must for instance also handle - * recurrence rules correctly. - * A good example of how to interpret all these filters can also simply - * be found in \Sabre\CalDAV\CalendarQueryFilter. This class is as correct - * as possible, so it gives you a good idea on what type of stuff you need - * to think of. - * - * This specific implementation (for the PDO) backend optimizes filters on - * specific components, and VEVENT time-ranges. - * - * @param mixed $calendarId - * - * @return array - */ - public function calendarQuery($calendarId, array $filters) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $componentType = null; - $requirePostFilter = true; - $timeRange = null; - - // if no filters were specified, we don't need to filter after a query - if (!$filters['prop-filters'] && !$filters['comp-filters']) { - $requirePostFilter = false; - } - - // Figuring out if there's a component filter - if (count($filters['comp-filters']) > 0 && !$filters['comp-filters'][0]['is-not-defined']) { - $componentType = $filters['comp-filters'][0]['name']; - - // Checking if we need post-filters - $has_time_range = array_key_exists('time-range', $filters['comp-filters'][0]) && $filters['comp-filters'][0]['time-range']; - if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$has_time_range && !$filters['comp-filters'][0]['prop-filters']) { - $requirePostFilter = false; - } - // There was a time-range filter - if ('VEVENT' == $componentType && $has_time_range) { - $timeRange = $filters['comp-filters'][0]['time-range']; - - // If start time OR the end time is not specified, we can do a - // 100% accurate mysql query. - if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && $timeRange) { - if ((array_key_exists('start', $timeRange) && !$timeRange['start']) || (array_key_exists('end', $timeRange) && !$timeRange['end'])) { - $requirePostFilter = false; - } - } - } - } - - if ($requirePostFilter) { - $query = 'SELECT uri, calendardata FROM '.$this->calendarObjectTableName.' WHERE calendarid = :calendarid'; - } else { - $query = 'SELECT uri FROM '.$this->calendarObjectTableName.' WHERE calendarid = :calendarid'; - } - - $values = [ - 'calendarid' => $calendarId, - ]; - - if ($componentType) { - $query .= ' AND componenttype = :componenttype'; - $values['componenttype'] = $componentType; - } - - if ($timeRange && array_key_exists('start', $timeRange) && $timeRange['start']) { - $query .= ' AND lastoccurence > :startdate'; - $values['startdate'] = $timeRange['start']->getTimeStamp(); - } - if ($timeRange && array_key_exists('end', $timeRange) && $timeRange['end']) { - $query .= ' AND firstoccurence < :enddate'; - $values['enddate'] = $timeRange['end']->getTimeStamp(); - } - - $stmt = $this->pdo->prepare($query); - $stmt->execute($values); - - $result = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - if ($requirePostFilter) { - if (!$this->validateFilterForObject($row, $filters)) { - continue; - } - } - $result[] = $row['uri']; - } - - return $result; - } - - /** - * Searches through all of a users calendars and calendar objects to find - * an object with a specific UID. - * - * This method should return the path to this object, relative to the - * calendar home, so this path usually only contains two parts: - * - * calendarpath/objectpath.ics - * - * If the uid is not found, return null. - * - * This method should only consider * objects that the principal owns, so - * any calendars owned by other principals that also appear in this - * collection should be ignored. - * - * @param string $principalUri - * @param string $uid - * - * @return string|null - */ - public function getCalendarObjectByUID($principalUri, $uid) - { - $query = <<calendarObjectTableName AS calendarobjects -LEFT JOIN - $this->calendarInstancesTableName AS calendar_instances - ON calendarobjects.calendarid = calendar_instances.calendarid -WHERE - calendar_instances.principaluri = ? - AND - calendarobjects.uid = ? - AND - calendar_instances.access = 1 -SQL; - - $stmt = $this->pdo->prepare($query); - $stmt->execute([$principalUri, $uid]); - - if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - return $row['calendaruri'].'/'.$row['objecturi']; - } - } - - /** - * The getChanges method returns all the changes that have happened, since - * the specified syncToken in the specified calendar. - * - * This function should return an array, such as the following: - * - * [ - * 'syncToken' => 'The current synctoken', - * 'added' => [ - * 'new.txt', - * ], - * 'modified' => [ - * 'modified.txt', - * ], - * 'deleted' => [ - * 'foo.php.bak', - * 'old.txt' - * ] - * ]; - * - * The returned syncToken property should reflect the *current* syncToken - * of the calendar, as reported in the {http://sabredav.org/ns}sync-token - * property this is needed here too, to ensure the operation is atomic. - * - * If the $syncToken argument is specified as null, this is an initial - * sync, and all members should be reported. - * - * The modified property is an array of nodenames that have changed since - * the last token. - * - * The deleted property is an array with nodenames, that have been deleted - * from collection. - * - * The $syncLevel argument is basically the 'depth' of the report. If it's - * 1, you only have to report changes that happened only directly in - * immediate descendants. If it's 2, it should also include changes from - * the nodes below the child collections. (grandchildren) - * - * The $limit argument allows a client to specify how many results should - * be returned at most. If the limit is not specified, it should be treated - * as infinite. - * - * If the limit (infinite or not) is higher than you're willing to return, - * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception. - * - * If the syncToken is expired (due to data cleanup) or unknown, you must - * return null. - * - * The limit is 'suggestive'. You are free to ignore it. - * - * @param mixed $calendarId - * @param string $syncToken - * @param int $syncLevel - * @param int $limit - * - * @return array|null - */ - public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $result = [ - 'added' => [], - 'modified' => [], - 'deleted' => [], - ]; - - if ($syncToken) { - $query = 'SELECT uri, operation, synctoken FROM '.$this->calendarChangesTableName.' WHERE synctoken >= ? AND calendarid = ? ORDER BY synctoken'; - if ($limit > 0) { - // Fetch one more raw to detect result truncation - $query .= ' LIMIT '.((int) $limit + 1); - } - - // Fetching all changes - $stmt = $this->pdo->prepare($query); - $stmt->execute([$syncToken, $calendarId]); - - $changes = []; - - // This loop ensures that any duplicates are overwritten, only the - // last change on a node is relevant. - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $changes[$row['uri']] = $row; - } - $currentToken = null; - - $result_count = 0; - foreach ($changes as $uri => $operation) { - if (!is_null($limit) && $result_count >= $limit) { - $result['result_truncated'] = true; - break; - } - - if (null === $currentToken || $currentToken < $operation['synctoken'] + 1) { - // SyncToken in CalDAV perspective is consistently the next number of the last synced change event in this class. - $currentToken = $operation['synctoken'] + 1; - } - - ++$result_count; - switch ($operation['operation']) { - case 1: - $result['added'][] = $uri; - break; - case 2: - $result['modified'][] = $uri; - break; - case 3: - $result['deleted'][] = $uri; - break; - } - } - - if (!is_null($currentToken)) { - $result['syncToken'] = $currentToken; - } else { - // This means returned value is equivalent to syncToken - $result['syncToken'] = $syncToken; - } - } else { - // Current synctoken - $stmt = $this->pdo->prepare('SELECT synctoken FROM '.$this->calendarTableName.' WHERE id = ?'); - $stmt->execute([$calendarId]); - $currentToken = $stmt->fetchColumn(0); - - if (is_null($currentToken)) { - return null; - } - $result['syncToken'] = $currentToken; - - // No synctoken supplied, this is the initial sync. - $query = 'SELECT uri FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'; - $stmt = $this->pdo->prepare($query); - $stmt->execute([$calendarId]); - - $result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN); - } - - return $result; - } - - /** - * Adds a change record to the calendarchanges table. - * - * @param mixed $calendarId - * @param string $objectUri - * @param int $operation 1 = add, 2 = modify, 3 = delete - */ - protected function addChange($calendarId, $objectUri, $operation) - { - $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarChangesTableName.' (uri, synctoken, calendarid, operation) SELECT ?, synctoken, ?, ? FROM '.$this->calendarTableName.' WHERE id = ?'); - $stmt->execute([ - $objectUri, - $calendarId, - $operation, - $calendarId, - ]); - $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET synctoken = synctoken + 1 WHERE id = ?'); - $stmt->execute([ - $calendarId, - ]); - } - - /** - * Returns a list of subscriptions for a principal. - * - * Every subscription is an array with the following keys: - * * id, a unique id that will be used by other functions to modify the - * subscription. This can be the same as the uri or a database key. - * * uri. This is just the 'base uri' or 'filename' of the subscription. - * * principaluri. The owner of the subscription. Almost always the same as - * principalUri passed to this method. - * * source. Url to the actual feed - * - * Furthermore, all the subscription info must be returned too: - * - * 1. {DAV:}displayname - * 2. {http://apple.com/ns/ical/}refreshrate - * 3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos - * should not be stripped). - * 4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms - * should not be stripped). - * 5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if - * attachments should not be stripped). - * 7. {http://apple.com/ns/ical/}calendar-color - * 8. {http://apple.com/ns/ical/}calendar-order - * 9. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set - * (should just be an instance of - * Sabre\CalDAV\Property\SupportedCalendarComponentSet, with a bunch of - * default components). - * - * @param string $principalUri - * - * @return array - */ - public function getSubscriptionsForUser($principalUri) - { - $fields = array_values($this->subscriptionPropertyMap); - $fields[] = 'id'; - $fields[] = 'uri'; - $fields[] = 'source'; - $fields[] = 'principaluri'; - $fields[] = 'lastmodified'; - - // Making fields a comma-delimited list - $fields = implode(', ', $fields); - $stmt = $this->pdo->prepare('SELECT '.$fields.' FROM '.$this->calendarSubscriptionsTableName.' WHERE principaluri = ? ORDER BY calendarorder ASC'); - $stmt->execute([$principalUri]); - - $subscriptions = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $subscription = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'principaluri' => $row['principaluri'], - 'source' => $row['source'], - 'lastmodified' => $row['lastmodified'], - - '{'.CalDAV\Plugin::NS_CALDAV.'}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VTODO', 'VEVENT']), - ]; - - foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { - if (!is_null($row[$dbName])) { - $subscription[$xmlName] = $row[$dbName]; - } - } - - $subscriptions[] = $subscription; - } - - return $subscriptions; - } - - /** - * Creates a new subscription for a principal. - * - * If the creation was a success, an id must be returned that can be used to reference - * this subscription in other methods, such as updateSubscription. - * - * @param string $principalUri - * @param string $uri - * - * @return mixed - */ - public function createSubscription($principalUri, $uri, array $properties) - { - $fieldNames = [ - 'principaluri', - 'uri', - 'source', - 'lastmodified', - ]; - - if (!isset($properties['{http://calendarserver.org/ns/}source'])) { - throw new Forbidden('The {http://calendarserver.org/ns/}source property is required when creating subscriptions'); - } - - $values = [ - ':principaluri' => $principalUri, - ':uri' => $uri, - ':source' => $properties['{http://calendarserver.org/ns/}source']->getHref(), - ':lastmodified' => time(), - ]; - - foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { - if (isset($properties[$xmlName])) { - $values[':'.$dbName] = $properties[$xmlName]; - $fieldNames[] = $dbName; - } - } - - $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarSubscriptionsTableName.' ('.implode(', ', $fieldNames).') VALUES ('.implode(', ', array_keys($values)).')'); - $stmt->execute($values); - - return $this->pdo->lastInsertId( - $this->calendarSubscriptionsTableName.'_id_seq' - ); - } - - /** - * Updates a subscription. - * - * The list of mutations is stored in a Sabre\DAV\PropPatch object. - * To do the actual updates, you must tell this object which properties - * you're going to process with the handle() method. - * - * Calling the handle method is like telling the PropPatch object "I - * promise I can handle updating this property". - * - * Read the PropPatch documentation for more info and examples. - * - * @param mixed $subscriptionId - */ - public function updateSubscription($subscriptionId, PropPatch $propPatch) - { - $supportedProperties = array_keys($this->subscriptionPropertyMap); - $supportedProperties[] = '{http://calendarserver.org/ns/}source'; - - $propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) { - $newValues = []; - - foreach ($mutations as $propertyName => $propertyValue) { - if ('{http://calendarserver.org/ns/}source' === $propertyName) { - $newValues['source'] = $propertyValue->getHref(); - } else { - $fieldName = $this->subscriptionPropertyMap[$propertyName]; - $newValues[$fieldName] = $propertyValue; - } - } - - // Now we're generating the sql query. - $valuesSql = []; - foreach ($newValues as $fieldName => $value) { - $valuesSql[] = $fieldName.' = ?'; - } - - $stmt = $this->pdo->prepare('UPDATE '.$this->calendarSubscriptionsTableName.' SET '.implode(', ', $valuesSql).', lastmodified = ? WHERE id = ?'); - $newValues['lastmodified'] = time(); - $newValues['id'] = $subscriptionId; - $stmt->execute(array_values($newValues)); - - return true; - }); - } - - /** - * Deletes a subscription. - * - * @param mixed $subscriptionId - */ - public function deleteSubscription($subscriptionId) - { - $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarSubscriptionsTableName.' WHERE id = ?'); - $stmt->execute([$subscriptionId]); - } - - /** - * Returns a single scheduling object. - * - * The returned array should contain the following elements: - * * uri - A unique basename for the object. This will be used to - * construct a full uri. - * * calendardata - The iCalendar object - * * lastmodified - The last modification date. Can be an int for a unix - * timestamp, or a PHP DateTime object. - * * etag - A unique token that must change if the object changed. - * * size - The size of the object, in bytes. - * - * @param string $principalUri - * @param string $objectUri - * - * @return array - */ - public function getSchedulingObject($principalUri, $objectUri) - { - $stmt = $this->pdo->prepare('SELECT uri, calendardata, lastmodified, etag, size FROM '.$this->schedulingObjectTableName.' WHERE principaluri = ? AND uri = ?'); - $stmt->execute([$principalUri, $objectUri]); - $row = $stmt->fetch(\PDO::FETCH_ASSOC); - - if (!$row) { - return null; - } - - return [ - 'uri' => $row['uri'], - 'calendardata' => $row['calendardata'], - 'lastmodified' => $row['lastmodified'], - 'etag' => '"'.$row['etag'].'"', - 'size' => (int) $row['size'], - ]; - } - - /** - * Returns all scheduling objects for the inbox collection. - * - * These objects should be returned as an array. Every item in the array - * should follow the same structure as returned from getSchedulingObject. - * - * The main difference is that 'calendardata' is optional. - * - * @param string $principalUri - * - * @return array - */ - public function getSchedulingObjects($principalUri) - { - $stmt = $this->pdo->prepare('SELECT id, calendardata, uri, lastmodified, etag, size FROM '.$this->schedulingObjectTableName.' WHERE principaluri = ?'); - $stmt->execute([$principalUri]); - - $result = []; - foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { - $result[] = [ - 'calendardata' => $row['calendardata'], - 'uri' => $row['uri'], - 'lastmodified' => $row['lastmodified'], - 'etag' => '"'.$row['etag'].'"', - 'size' => (int) $row['size'], - ]; - } - - return $result; - } - - /** - * Deletes a scheduling object. - * - * @param string $principalUri - * @param string $objectUri - */ - public function deleteSchedulingObject($principalUri, $objectUri) - { - $stmt = $this->pdo->prepare('DELETE FROM '.$this->schedulingObjectTableName.' WHERE principaluri = ? AND uri = ?'); - $stmt->execute([$principalUri, $objectUri]); - } - - /** - * Creates a new scheduling object. This should land in a users' inbox. - * - * @param string $principalUri - * @param string $objectUri - * @param string|resource $objectData - */ - public function createSchedulingObject($principalUri, $objectUri, $objectData) - { - $stmt = $this->pdo->prepare('INSERT INTO '.$this->schedulingObjectTableName.' (principaluri, calendardata, uri, lastmodified, etag, size) VALUES (?, ?, ?, ?, ?, ?)'); - - if (is_resource($objectData)) { - $objectData = stream_get_contents($objectData); - } - - $stmt->execute([$principalUri, $objectData, $objectUri, time(), md5($objectData), strlen($objectData)]); - } - - /** - * Updates the list of shares. - * - * @param mixed $calendarId - * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees - */ - public function updateInvites($calendarId, array $sharees) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); - } - $currentInvites = $this->getInvites($calendarId); - list($calendarId, $instanceId) = $calendarId; - - $removeStmt = $this->pdo->prepare('DELETE FROM '.$this->calendarInstancesTableName.' WHERE calendarid = ? AND share_href = ? AND access IN (2,3)'); - $updateStmt = $this->pdo->prepare('UPDATE '.$this->calendarInstancesTableName.' SET access = ?, share_displayname = ?, share_invitestatus = ? WHERE calendarid = ? AND share_href = ?'); - - $insertStmt = $this->pdo->prepare(' -INSERT INTO '.$this->calendarInstancesTableName.' - ( - calendarid, - principaluri, - access, - displayname, - uri, - description, - calendarorder, - calendarcolor, - timezone, - transparent, - share_href, - share_displayname, - share_invitestatus - ) - SELECT - ?, - ?, - ?, - displayname, - ?, - description, - calendarorder, - calendarcolor, - timezone, - 1, - ?, - ?, - ? - FROM '.$this->calendarInstancesTableName.' WHERE id = ?'); - - foreach ($sharees as $sharee) { - if (\Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS === $sharee->access) { - // if access was set no NOACCESS, it means access for an - // existing sharee was removed. - $removeStmt->execute([$calendarId, $sharee->href]); - continue; - } - - if (is_null($sharee->principal)) { - // If the server could not determine the principal automatically, - // we will mark the invite status as invalid. - $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_INVALID; - } else { - // Because sabre/dav does not yet have an invitation system, - // every invite is automatically accepted for now. - $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED; - } - - foreach ($currentInvites as $oldSharee) { - if ($oldSharee->href === $sharee->href) { - // This is an update - $sharee->properties = array_merge( - $oldSharee->properties, - $sharee->properties - ); - $updateStmt->execute([ - $sharee->access, - isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null, - $sharee->inviteStatus ?: $oldSharee->inviteStatus, - $calendarId, - $sharee->href, - ]); - continue 2; - } - } - // If we got here, it means it was a new sharee - $insertStmt->execute([ - $calendarId, - $sharee->principal, - $sharee->access, - \Sabre\DAV\UUIDUtil::getUUID(), - $sharee->href, - isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null, - $sharee->inviteStatus ?: \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE, - $instanceId, - ]); - } - } - - /** - * Returns the list of people whom a calendar is shared with. - * - * Every item in the returned list must be a Sharee object with at - * least the following properties set: - * $href - * $shareAccess - * $inviteStatus - * - * and optionally: - * $properties - * - * @param mixed $calendarId - * - * @return \Sabre\DAV\Xml\Element\Sharee[] - */ - public function getInvites($calendarId) - { - if (!is_array($calendarId)) { - throw new \InvalidArgumentException('The value passed to getInvites() is expected to be an array with a calendarId and an instanceId'); - } - list($calendarId, $instanceId) = $calendarId; - - $query = <<calendarInstancesTableName} -WHERE - calendarid = ? -SQL; - - $stmt = $this->pdo->prepare($query); - $stmt->execute([$calendarId]); - - $result = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $result[] = new Sharee([ - 'href' => isset($row['share_href']) ? $row['share_href'] : \Sabre\HTTP\encodePath($row['principaluri']), - 'access' => (int) $row['access'], - /// Everyone is always immediately accepted, for now. - 'inviteStatus' => (int) $row['share_invitestatus'], - 'properties' => !empty($row['share_displayname']) - ? ['{DAV:}displayname' => $row['share_displayname']] - : [], - 'principal' => $row['principaluri'], - ]); - } - - return $result; - } - - /** - * Publishes a calendar. - * - * @param mixed $calendarId - * @param bool $value - */ - public function setPublishStatus($calendarId, $value) - { - throw new DAV\Exception\NotImplemented('Not implemented'); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php b/lib/vendor/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php deleted file mode 100644 index 69467e5..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Backend/SchedulingSupport.php +++ /dev/null @@ -1,66 +0,0 @@ -pdo = $pdo; - } - - /** - * Returns a list of calendars for a principal. - * - * 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. This is just the 'base uri' or 'filename' of the calendar. - * * 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'. - * - * Many clients also require: - * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set - * For this property, you can just return an instance of - * Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet. - * - * If you return {http://sabredav.org/ns}read-only and set the value to 1, - * ACL will automatically be put in read-only mode. - * - * @param string $principalUri - * - * @return array - */ - public function getCalendarsForUser($principalUri) - { - // Making fields a comma-delimited list - $stmt = $this->pdo->prepare('SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY id ASC'); - $stmt->execute([$principalUri]); - - $calendars = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $calendars[] = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'principaluri' => $principalUri, - ]; - } - - return $calendars; - } - - /** - * Creates a new calendar for a principal. - * - * If the creation was a success, an id must be returned that can be used - * to reference this calendar in other methods, such as updateCalendar. - * - * @param string $principalUri - * @param string $calendarUri - * - * @return string - */ - public function createCalendar($principalUri, $calendarUri, array $properties) - { - $stmt = $this->pdo->prepare('INSERT INTO simple_calendars (principaluri, uri) VALUES (?, ?)'); - $stmt->execute([$principalUri, $calendarUri]); - - return $this->pdo->lastInsertId(); - } - - /** - * Delete a calendar and all it's objects. - * - * @param string $calendarId - */ - public function deleteCalendar($calendarId) - { - $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ?'); - $stmt->execute([$calendarId]); - - $stmt = $this->pdo->prepare('DELETE FROM simple_calendars WHERE id = ?'); - $stmt->execute([$calendarId]); - } - - /** - * Returns all calendar objects within a calendar. - * - * Every item contains an array with the following keys: - * * calendardata - The iCalendar-compatible calendar data - * * uri - a unique key which will be used to construct the uri. This can - * be any arbitrary string, but making sure it ends with '.ics' is a - * good idea. This is only the basename, or filename, not the full - * path. - * * lastmodified - a timestamp of the last modification time - * * etag - An arbitrary string, surrounded by double-quotes. (e.g.: - * ' "abcdef"') - * * size - The size of the calendar objects, in bytes. - * * component - optional, a string containing the type of object, such - * as 'vevent' or 'vtodo'. If specified, this will be used to populate - * the Content-Type header. - * - * 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 - * calendardata. - * - * 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 id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ?'); - $stmt->execute([$calendarId]); - - $result = []; - foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { - $result[] = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'etag' => '"'.md5($row['calendardata']).'"', - 'calendarid' => $calendarId, - 'size' => strlen($row['calendardata']), - 'calendardata' => $row['calendardata'], - ]; - } - - return $result; - } - - /** - * Returns information from a single calendar object, based on it's object - * uri. - * - * The object uri is only the basename, or filename and not a full path. - * - * The returned array must have the same keys as getCalendarObjects. The - * 'calendardata' object is required here though, while it's not required - * for getCalendarObjects. - * - * This method must return null if the object did not exist. - * - * @param string $calendarId - * @param string $objectUri - * - * @return array|null - */ - public function getCalendarObject($calendarId, $objectUri) - { - $stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?'); - $stmt->execute([$calendarId, $objectUri]); - $row = $stmt->fetch(\PDO::FETCH_ASSOC); - - if (!$row) { - return null; - } - - return [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'etag' => '"'.md5($row['calendardata']).'"', - 'calendarid' => $calendarId, - 'size' => strlen($row['calendardata']), - 'calendardata' => $row['calendardata'], - ]; - } - - /** - * Creates a new calendar object. - * - * The object uri is only the basename, or filename and not a full path. - * - * It is possible return an etag from this function, which will be used in - * the response to this PUT request. Note that the ETag must be surrounded - * by double-quotes. - * - * However, you should only really return this ETag if you don't mangle the - * calendar-data. If the result of a subsequent GET to this object is not - * the exact same as this request body, you should omit the ETag. - * - * @param mixed $calendarId - * @param string $objectUri - * @param string $calendarData - * - * @return string|null - */ - public function createCalendarObject($calendarId, $objectUri, $calendarData) - { - $stmt = $this->pdo->prepare('INSERT INTO simple_calendarobjects (calendarid, uri, calendardata) VALUES (?,?,?)'); - $stmt->execute([ - $calendarId, - $objectUri, - $calendarData, - ]); - - return '"'.md5($calendarData).'"'; - } - - /** - * Updates an existing calendarobject, based on it's uri. - * - * The object uri is only the basename, or filename and not a full path. - * - * It is possible return an etag from this function, which will be used in - * the response to this PUT request. Note that the ETag must be surrounded - * by double-quotes. - * - * However, you should only really return this ETag if you don't mangle the - * calendar-data. If the result of a subsequent GET to this object is not - * the exact same as this request body, you should omit the ETag. - * - * @param mixed $calendarId - * @param string $objectUri - * @param string $calendarData - * - * @return string|null - */ - public function updateCalendarObject($calendarId, $objectUri, $calendarData) - { - $stmt = $this->pdo->prepare('UPDATE simple_calendarobjects SET calendardata = ? WHERE calendarid = ? AND uri = ?'); - $stmt->execute([$calendarData, $calendarId, $objectUri]); - - return '"'.md5($calendarData).'"'; - } - - /** - * Deletes an existing calendar object. - * - * The object uri is only the basename, or filename and not a full path. - * - * @param string $calendarId - * @param string $objectUri - */ - public function deleteCalendarObject($calendarId, $objectUri) - { - $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?'); - $stmt->execute([$calendarId, $objectUri]); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php b/lib/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php deleted file mode 100644 index 7655c2e..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Backend/SubscriptionSupport.php +++ /dev/null @@ -1,89 +0,0 @@ - 'The current synctoken', - * 'added' => [ - * 'new.txt', - * ], - * 'modified' => [ - * 'modified.txt', - * ], - * 'deleted' => [ - * 'foo.php.bak', - * 'old.txt' - * ] - * ); - * - * The returned syncToken property should reflect the *current* syncToken - * of the calendar, as reported in the {http://sabredav.org/ns}sync-token - * property This is * needed here too, to ensure the operation is atomic. - * - * If the $syncToken argument is specified as null, this is an initial - * sync, and all members should be reported. - * - * The modified property is an array of nodenames that have changed since - * the last token. - * - * The deleted property is an array with nodenames, that have been deleted - * from collection. - * - * The $syncLevel argument is basically the 'depth' of the report. If it's - * 1, you only have to report changes that happened only directly in - * immediate descendants. If it's 2, it should also include changes from - * the nodes below the child collections. (grandchildren) - * - * The $limit argument allows a client to specify how many results should - * be returned at most. If the limit is not specified, it should be treated - * as infinite. - * - * If the limit (infinite or not) is higher than you're willing to return, - * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception. - * - * If the syncToken is expired (due to data cleanup) or unknown, you must - * return null. - * - * The limit is 'suggestive'. You are free to ignore it. - * - * @param string $calendarId - * @param string $syncToken - * @param int $syncLevel - * @param int $limit - * - * @return array|null - */ - public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null); -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Calendar.php b/lib/vendor/sabre/dav/lib/CalDAV/Calendar.php deleted file mode 100644 index ba8c704..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Calendar.php +++ /dev/null @@ -1,460 +0,0 @@ -caldavBackend = $caldavBackend; - $this->calendarInfo = $calendarInfo; - } - - /** - * Returns the name of the calendar. - * - * @return string - */ - public function getName() - { - return $this->calendarInfo['uri']; - } - - /** - * Updates properties on this node. - * - * This method received a PropPatch object, which contains all the - * information about the update. - * - * To update specific properties, call the 'handle' method on this object. - * Read the PropPatch documentation for more information. - */ - public function propPatch(PropPatch $propPatch) - { - return $this->caldavBackend->updateCalendar($this->calendarInfo['id'], $propPatch); - } - - /** - * Returns the list of properties. - * - * @param array $requestedProperties - * - * @return array - */ - public function getProperties($requestedProperties) - { - $response = []; - - foreach ($this->calendarInfo as $propName => $propValue) { - if (!is_null($propValue) && '{' === $propName[0]) { - $response[$propName] = $this->calendarInfo[$propName]; - } - } - - return $response; - } - - /** - * Returns a calendar object. - * - * The contained calendar objects are for example Events or Todo's. - * - * @param string $name - * - * @return \Sabre\CalDAV\ICalendarObject - */ - public function getChild($name) - { - $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $name); - - if (!$obj) { - throw new DAV\Exception\NotFound('Calendar object not found'); - } - $obj['acl'] = $this->getChildACL(); - - return new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj); - } - - /** - * Returns the full list of calendar objects. - * - * @return array - */ - public function getChildren() - { - $objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']); - $children = []; - foreach ($objs as $obj) { - $obj['acl'] = $this->getChildACL(); - $children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj); - } - - return $children; - } - - /** - * This method receives a list of paths in it's first argument. - * It must return an array with Node objects. - * - * If any children are not found, you do not have to return them. - * - * @param string[] $paths - * - * @return array - */ - public function getMultipleChildren(array $paths) - { - $objs = $this->caldavBackend->getMultipleCalendarObjects($this->calendarInfo['id'], $paths); - $children = []; - foreach ($objs as $obj) { - $obj['acl'] = $this->getChildACL(); - $children[] = new CalendarObject($this->caldavBackend, $this->calendarInfo, $obj); - } - - return $children; - } - - /** - * 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) { - return false; - } else { - return true; - } - } - - /** - * Creates a new directory. - * - * We actually block this, as subdirectories are not allowed in calendars. - * - * @param string $name - */ - public function createDirectory($name) - { - throw new DAV\Exception\MethodNotAllowed('Creating collections in calendar objects is not allowed'); - } - - /** - * Creates a new file. - * - * The contents of the new file must be a valid ICalendar string. - * - * @param string $name - * @param resource $data - * - * @return string|null - */ - public function createFile($name, $data = null) - { - if (is_resource($data)) { - $data = stream_get_contents($data); - } - - return $this->caldavBackend->createCalendarObject($this->calendarInfo['id'], $name, $data); - } - - /** - * Deletes the calendar. - */ - public function delete() - { - $this->caldavBackend->deleteCalendar($this->calendarInfo['id']); - } - - /** - * Renames the calendar. Note that most calendars use the - * {DAV:}displayname to display a name to display a name. - * - * @param string $newName - */ - public function setName($newName) - { - throw new DAV\Exception\MethodNotAllowed('Renaming calendars is not yet supported'); - } - - /** - * Returns the last modification date as a unix timestamp. - */ - public function getLastModified() - { - return null; - } - - /** - * 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->calendarInfo['principaluri']; - } - - /** - * 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() - { - $acl = [ - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner().'/calendar-proxy-read', - 'protected' => true, - ], - [ - 'privilege' => '{'.Plugin::NS_CALDAV.'}read-free-busy', - 'principal' => '{DAV:}authenticated', - 'protected' => true, - ], - ]; - if (empty($this->calendarInfo['{http://sabredav.org/ns}read-only'])) { - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->getOwner(), - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ]; - } - - return $acl; - } - - /** - * This method returns the ACL's for calendar objects in this calendar. - * The result of this method automatically gets passed to the - * calendar-object nodes in the calendar. - * - * @return array - */ - public function getChildACL() - { - $acl = [ - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner().'/calendar-proxy-read', - 'protected' => true, - ], - ]; - if (empty($this->calendarInfo['{http://sabredav.org/ns}read-only'])) { - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->getOwner(), - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ]; - } - - return $acl; - } - - /** - * Performs a calendar-query on the contents of this calendar. - * - * The calendar-query is defined in RFC4791 : CalDAV. Using the - * calendar-query it is possible for a client to request a specific set of - * object, based on contents of iCalendar properties, date-ranges and - * iCalendar component types (VTODO, VEVENT). - * - * This method should just return a list of (relative) urls that match this - * query. - * - * The list of filters are specified as an array. The exact array is - * documented by Sabre\CalDAV\CalendarQueryParser. - * - * @return array - */ - public function calendarQuery(array $filters) - { - return $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters); - } - - /** - * This method returns the current sync-token for this collection. - * This can be any string. - * - * If null is returned from this function, the plugin assumes there's no - * sync information available. - * - * @return string|null - */ - public function getSyncToken() - { - if ( - $this->caldavBackend instanceof Backend\SyncSupport && - isset($this->calendarInfo['{DAV:}sync-token']) - ) { - return $this->calendarInfo['{DAV:}sync-token']; - } - if ( - $this->caldavBackend instanceof Backend\SyncSupport && - isset($this->calendarInfo['{http://sabredav.org/ns}sync-token']) - ) { - return $this->calendarInfo['{http://sabredav.org/ns}sync-token']; - } - } - - /** - * The getChanges method returns all the changes that have happened, since - * the specified syncToken and the current collection. - * - * This function should return an array, such as the following: - * - * [ - * 'syncToken' => 'The current synctoken', - * 'added' => [ - * 'new.txt', - * ], - * 'modified' => [ - * 'modified.txt', - * ], - * 'deleted' => [ - * 'foo.php.bak', - * 'old.txt' - * ], - * 'result_truncated' : true - * ]; - * - * The syncToken property should reflect the *current* syncToken of the - * collection, as reported getSyncToken(). This is needed here too, to - * ensure the operation is atomic. - * - * If the syncToken is specified as null, this is an initial sync, and all - * members should be reported. - * - * If result is truncated due to server limitation or limit by client, - * set result_truncated to true, otherwise set to false or do not add the key. - * - * The modified property is an array of nodenames that have changed since - * the last token. - * - * The deleted property is an array with nodenames, that have been deleted - * from collection. - * - * The second argument is basically the 'depth' of the report. If it's 1, - * you only have to report changes that happened only directly in immediate - * descendants. If it's 2, it should also include changes from the nodes - * below the child collections. (grandchildren) - * - * The third (optional) argument allows a client to specify how many - * results should be returned at most. If the limit is not specified, it - * should be treated as infinite. - * - * If the limit (infinite or not) is higher than you're willing to return, - * the result should be truncated to fit the limit. - * Note that even when the result is truncated, syncToken must be consistent - * with the truncated result, not the result before truncation. - * (See RFC6578 Section 3.6 for detail) - * - * If the syncToken is expired (due to data cleanup) or unknown, you must - * return null. - * - * The limit is 'suggestive'. You are free to ignore it. - * TODO: RFC6578 Section 3.7 says that the server must fail when the server - * cannot truncate according to the limit, so it may not be just suggestive. - * - * @param string $syncToken - * @param int $syncLevel - * @param int $limit - * - * @return array|null - */ - public function getChanges($syncToken, $syncLevel, $limit = null) - { - if (!$this->caldavBackend instanceof Backend\SyncSupport) { - return null; - } - - return $this->caldavBackend->getChangesForCalendar( - $this->calendarInfo['id'], - $syncToken, - $syncLevel, - $limit - ); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/CalendarHome.php b/lib/vendor/sabre/dav/lib/CalDAV/CalendarHome.php deleted file mode 100644 index 49c54a3..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/CalendarHome.php +++ /dev/null @@ -1,356 +0,0 @@ -caldavBackend = $caldavBackend; - $this->principalInfo = $principalInfo; - } - - /** - * Returns the name of this object. - * - * @return string - */ - public function getName() - { - list(, $name) = Uri\split($this->principalInfo['uri']); - - return $name; - } - - /** - * Updates the name of this object. - * - * @param string $name - */ - public function setName($name) - { - throw new DAV\Exception\Forbidden(); - } - - /** - * Deletes this object. - */ - public function delete() - { - throw new DAV\Exception\Forbidden(); - } - - /** - * Returns the last modification date. - * - * @return int - */ - public function getLastModified() - { - return null; - } - - /** - * Creates a new file under this object. - * - * This is currently not allowed - * - * @param string $name - * @param resource $data - */ - public function createFile($name, $data = null) - { - throw new DAV\Exception\MethodNotAllowed('Creating new files in this collection is not supported'); - } - - /** - * Creates a new directory under this object. - * - * This is currently not allowed. - * - * @param string $filename - */ - public function createDirectory($filename) - { - throw new DAV\Exception\MethodNotAllowed('Creating new collections in this collection is not supported'); - } - - /** - * Returns a single calendar, by name. - * - * @param string $name - * - * @return Calendar - */ - public function getChild($name) - { - // Special nodes - if ('inbox' === $name && $this->caldavBackend instanceof Backend\SchedulingSupport) { - return new Schedule\Inbox($this->caldavBackend, $this->principalInfo['uri']); - } - if ('outbox' === $name && $this->caldavBackend instanceof Backend\SchedulingSupport) { - return new Schedule\Outbox($this->principalInfo['uri']); - } - if ('notifications' === $name && $this->caldavBackend instanceof Backend\NotificationSupport) { - return new Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']); - } - - // Calendars - foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) { - if ($calendar['uri'] === $name) { - if ($this->caldavBackend instanceof Backend\SharingSupport) { - return new SharedCalendar($this->caldavBackend, $calendar); - } else { - return new Calendar($this->caldavBackend, $calendar); - } - } - } - - if ($this->caldavBackend instanceof Backend\SubscriptionSupport) { - foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) { - if ($subscription['uri'] === $name) { - return new Subscriptions\Subscription($this->caldavBackend, $subscription); - } - } - } - - throw new NotFound('Node with name \''.$name.'\' could not be found'); - } - - /** - * Checks if a calendar exists. - * - * @param string $name - * - * @return bool - */ - public function childExists($name) - { - try { - return (bool) $this->getChild($name); - } catch (NotFound $e) { - return false; - } - } - - /** - * Returns a list of calendars. - * - * @return array - */ - public function getChildren() - { - $calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']); - $objs = []; - foreach ($calendars as $calendar) { - if ($this->caldavBackend instanceof Backend\SharingSupport) { - $objs[] = new SharedCalendar($this->caldavBackend, $calendar); - } else { - $objs[] = new Calendar($this->caldavBackend, $calendar); - } - } - - if ($this->caldavBackend instanceof Backend\SchedulingSupport) { - $objs[] = new Schedule\Inbox($this->caldavBackend, $this->principalInfo['uri']); - $objs[] = new Schedule\Outbox($this->principalInfo['uri']); - } - - // We're adding a notifications node, if it's supported by the backend. - if ($this->caldavBackend instanceof Backend\NotificationSupport) { - $objs[] = new Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']); - } - - // If the backend supports subscriptions, we'll add those as well, - if ($this->caldavBackend instanceof Backend\SubscriptionSupport) { - foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) { - $objs[] = new Subscriptions\Subscription($this->caldavBackend, $subscription); - } - } - - return $objs; - } - - /** - * Creates a new calendar or subscription. - * - * @param string $name - * - * @throws DAV\Exception\InvalidResourceType - */ - public function createExtendedCollection($name, MkCol $mkCol) - { - $isCalendar = false; - $isSubscription = false; - foreach ($mkCol->getResourceType() as $rt) { - switch ($rt) { - case '{DAV:}collection': - case '{http://calendarserver.org/ns/}shared-owner': - // ignore - break; - case '{urn:ietf:params:xml:ns:caldav}calendar': - $isCalendar = true; - break; - case '{http://calendarserver.org/ns/}subscribed': - $isSubscription = true; - break; - default: - throw new DAV\Exception\InvalidResourceType('Unknown resourceType: '.$rt); - } - } - - $properties = $mkCol->getRemainingValues(); - $mkCol->setRemainingResultCode(201); - - if ($isSubscription) { - if (!$this->caldavBackend instanceof Backend\SubscriptionSupport) { - throw new DAV\Exception\InvalidResourceType('This backend does not support subscriptions'); - } - $this->caldavBackend->createSubscription($this->principalInfo['uri'], $name, $properties); - } elseif ($isCalendar) { - $this->caldavBackend->createCalendar($this->principalInfo['uri'], $name, $properties); - } else { - throw new DAV\Exception\InvalidResourceType('You can only create calendars and subscriptions in this collection'); - } - } - - /** - * Returns the owner of the calendar home. - * - * @return string - */ - public function getOwner() - { - return $this->principalInfo['uri']; - } - - /** - * 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 [ - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->principalInfo['uri'], - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => $this->principalInfo['uri'], - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->principalInfo['uri'].'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write', - 'principal' => $this->principalInfo['uri'].'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->principalInfo['uri'].'/calendar-proxy-read', - 'protected' => true, - ], - ]; - } - - /** - * This method is called when a user replied to a request to share. - * - * This method should return the url of the newly created calendar if the - * share was accepted. - * - * @param string $href The sharee who is replying (often a mailto: address) - * @param int $status One of the SharingPlugin::STATUS_* constants - * @param string $calendarUri The url to the calendar thats being shared - * @param string $inReplyTo The unique id this message is a response to - * @param string $summary A description of the reply - * - * @return string|null - */ - public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) - { - if (!$this->caldavBackend instanceof Backend\SharingSupport) { - throw new DAV\Exception\NotImplemented('Sharing support is not implemented by this backend.'); - } - - return $this->caldavBackend->shareReply($href, $status, $calendarUri, $inReplyTo, $summary); - } - - /** - * Searches through all of a users calendars and calendar objects to find - * an object with a specific UID. - * - * This method should return the path to this object, relative to the - * calendar home, so this path usually only contains two parts: - * - * calendarpath/objectpath.ics - * - * If the uid is not found, return null. - * - * This method should only consider * objects that the principal owns, so - * any calendars owned by other principals that also appear in this - * collection should be ignored. - * - * @param string $uid - * - * @return string|null - */ - public function getCalendarObjectByUID($uid) - { - return $this->caldavBackend->getCalendarObjectByUID($this->principalInfo['uri'], $uid); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/CalendarObject.php b/lib/vendor/sabre/dav/lib/CalDAV/CalendarObject.php deleted file mode 100644 index 671f4b5..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/CalendarObject.php +++ /dev/null @@ -1,223 +0,0 @@ -caldavBackend = $caldavBackend; - - if (!isset($objectData['uri'])) { - throw new \InvalidArgumentException('The objectData argument must contain an \'uri\' property'); - } - - $this->calendarInfo = $calendarInfo; - $this->objectData = $objectData; - } - - /** - * Returns the uri for this object. - * - * @return string - */ - public function getName() - { - return $this->objectData['uri']; - } - - /** - * Returns the ICalendar-formatted object. - * - * @return string - */ - public function get() - { - // Pre-populating the 'calendardata' is optional, if we don't have it - // already we fetch it from the backend. - if (!isset($this->objectData['calendardata'])) { - $this->objectData = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'], $this->objectData['uri']); - } - - return $this->objectData['calendardata']; - } - - /** - * Updates the ICalendar-formatted object. - * - * @param string|resource $calendarData - * - * @return string - */ - public function put($calendarData) - { - if (is_resource($calendarData)) { - $calendarData = stream_get_contents($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. - */ - public function delete() - { - $this->caldavBackend->deleteCalendarObject($this->calendarInfo['id'], $this->objectData['uri']); - } - - /** - * Returns the mime content-type. - * - * @return string - */ - public function getContentType() - { - $mime = 'text/calendar; charset=utf-8'; - if (isset($this->objectData['component']) && $this->objectData['component']) { - $mime .= '; component='.$this->objectData['component']; - } - - return $mime; - } - - /** - * Returns an ETag for this object. - * - * The ETag is an arbitrary string, but MUST be surrounded by double-quotes. - * - * @return string - */ - public function getETag() - { - if (isset($this->objectData['etag'])) { - return $this->objectData['etag']; - } else { - return '"'.md5($this->get()).'"'; - } - } - - /** - * Returns the last modification date as a unix timestamp. - * - * @return int - */ - public function getLastModified() - { - return $this->objectData['lastmodified']; - } - - /** - * Returns the size of this object in bytes. - * - * @return int - */ - public function getSize() - { - 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 - * - * @return string|null - */ - public function getOwner() - { - return $this->calendarInfo['principaluri']; - } - - /** - * 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() - { - // An alternative acl may be specified in the object data. - if (isset($this->objectData['acl'])) { - return $this->objectData['acl']; - } - - // The default ACL - return [ - [ - 'privilege' => '{DAV:}all', - 'principal' => $this->calendarInfo['principaluri'], - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}all', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-read', - 'protected' => true, - ], - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php b/lib/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php deleted file mode 100644 index ee525da..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/CalendarQueryValidator.php +++ /dev/null @@ -1,354 +0,0 @@ -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. - * - * @return bool - */ - protected function validateCompFilters(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 (array_key_exists('time-range', $filter) && $filter['time-range']) { - foreach ($parent->{$filter['name']} as $subComponent) { - $start = null; - $end = null; - if (array_key_exists('start', $filter['time-range'])) { - $start = $filter['time-range']['start']; - } - if (array_key_exists('end', $filter['time-range'])) { - $end = $filter['time-range']['end']; - } - if ($this->validateTimeRange($subComponent, $start, $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. - * - * @return bool - */ - protected function validatePropFilters(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 (array_key_exists('time-range', $filter) && $filter['time-range']) { - foreach ($parent->{$filter['name']} as $subComponent) { - $start = null; - $end = null; - if (array_key_exists('start', $filter['time-range'])) { - $start = $filter['time-range']['start']; - } - if (array_key_exists('end', $filter['time-range'])) { - $end = $filter['time-range']['end']; - } - if ($this->validateTimeRange($subComponent, $start, $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. - * - * @return bool - */ - protected function validateParamFilters(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']]->getParts() as $paramPart) { - if ($this->validateTextMatch($paramPart, $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 VObject\Node|string $check value to check against - * - * @return bool - */ - protected function validateTextMatch($check, array $textMatch) - { - if ($check instanceof VObject\Node) { - $check = $check->getValue(); - } - - $isMatching = \Sabre\DAV\StringUtil::textMatch($check, $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 DateTime $start - * @param DateTime $end - * - * @return bool - */ - protected function validateTimeRange(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 ('VEVENT' === $component->parent->name && $component->parent->RRULE) { - // Fire up the iterator! - $it = new VObject\Recur\EventIterator($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; - if (null !== $expandedEvent->VALARM) { - foreach ($expandedEvent->VALARM as $expandedAlarm) { - $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime(); - if ($expandedAlarm->isInTimeRange($start, $end)) { - return true; - } - - if ('DATE-TIME' === (string) $expandedAlarm->TRIGGER['VALUE']) { - // This is an alarm with a non-relative trigger - // time, likely created by a buggy client. The - // implication is that every alarm in this - // recurring event trigger at the exact same - // time. It doesn't make sense to traverse - // further. - } else { - // We store the first alarm as a means to - // figure out when we can stop traversing. - if (!$firstAlarm || $effectiveTrigger < $firstAlarm) { - $firstAlarm = $effectiveTrigger; - } - } - } - } - if (is_null($firstAlarm)) { - // No alarm was found. - // - // Or technically: No alarm that will change for - // every instance of the recurrence was found, - // which means we can assume there was no match. - return false; - } - if ($firstAlarm > $end) { - return false; - } - $it->next(); - } - - return false; - } else { - return $component->isInTimeRange($start, $end); - } - - // no break - 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/lib/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php b/lib/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php deleted file mode 100644 index 3038d21..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/CalendarRoot.php +++ /dev/null @@ -1,75 +0,0 @@ -caldavBackend = $caldavBackend; - } - - /** - * 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 string - */ - public function getName() - { - return Plugin::CALENDAR_ROOT; - } - - /** - * This method returns a node for a principal. - * - * 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. - * - * @return \Sabre\DAV\INode - */ - public function getChildForPrincipal(array $principal) - { - return new CalendarHome($this->caldavBackend, $principal); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php b/lib/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php deleted file mode 100644 index e94378a..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Exception/InvalidComponentType.php +++ /dev/null @@ -1,31 +0,0 @@ -ownerDocument; - - $np = $doc->createElementNS(CalDAV\Plugin::NS_CALDAV, 'cal:supported-calendar-component'); - $errorNode->appendChild($np); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php b/lib/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php deleted file mode 100644 index 9171e36..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php +++ /dev/null @@ -1,377 +0,0 @@ -server = $server; - $server->on('method:GET', [$this, 'httpGet'], 90); - $server->on('browserButtonActions', function ($path, $node, &$actions) { - if ($node instanceof ICalendar) { - $actions .= ''; - } - }); - } - - /** - * Intercepts GET requests on calendar urls ending with ?export. - * - * @throws BadRequest - * @throws DAV\Exception\NotFound - * @throws VObject\InvalidDataException - * - * @return bool - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - $queryParams = $request->getQueryParameters(); - if (!array_key_exists('export', $queryParams)) { - return; - } - - $path = $request->getPath(); - - $node = $this->server->getProperties($path, [ - '{DAV:}resourcetype', - '{DAV:}displayname', - '{http://sabredav.org/ns}sync-token', - '{DAV:}sync-token', - '{http://apple.com/ns/ical/}calendar-color', - ]); - - if (!isset($node['{DAV:}resourcetype']) || !$node['{DAV:}resourcetype']->is('{'.Plugin::NS_CALDAV.'}calendar')) { - return; - } - // Marking the transactionType, for logging purposes. - $this->server->transactionType = 'get-calendar-export'; - - $properties = $node; - - $start = null; - $end = null; - $expand = false; - $componentType = false; - if (isset($queryParams['start'])) { - if (!ctype_digit($queryParams['start'])) { - throw new BadRequest('The start= parameter must contain a unix timestamp'); - } - $start = DateTime::createFromFormat('U', $queryParams['start']); - } - if (isset($queryParams['end'])) { - if (!ctype_digit($queryParams['end'])) { - throw new BadRequest('The end= parameter must contain a unix timestamp'); - } - $end = DateTime::createFromFormat('U', $queryParams['end']); - } - if (isset($queryParams['expand']) && (bool) $queryParams['expand']) { - if (!$start || !$end) { - throw new BadRequest('If you\'d like to expand recurrences, you must specify both a start= and end= parameter.'); - } - $expand = true; - $componentType = 'VEVENT'; - } - if (isset($queryParams['componentType'])) { - if (!in_array($queryParams['componentType'], ['VEVENT', 'VTODO', 'VJOURNAL'])) { - throw new BadRequest('You are not allowed to search for components of type: '.$queryParams['componentType'].' here'); - } - $componentType = $queryParams['componentType']; - } - - $format = \Sabre\HTTP\negotiateContentType( - $request->getHeader('Accept'), - [ - 'text/calendar', - 'application/calendar+json', - ] - ); - - if (isset($queryParams['accept'])) { - if ('application/calendar+json' === $queryParams['accept'] || 'jcal' === $queryParams['accept']) { - $format = 'application/calendar+json'; - } - } - if (!$format) { - $format = 'text/calendar'; - } - - $this->generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, $response); - - // Returning false to break the event chain - return false; - } - - /** - * This method is responsible for generating the actual, full response. - * - * @param string $path - * @param DateTime|null $start - * @param DateTime|null $end - * @param bool $expand - * @param string $componentType - * @param string $format - * @param array $properties - * - * @throws DAV\Exception\NotFound - * @throws VObject\InvalidDataException - */ - protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response) - { - $calDataProp = '{'.Plugin::NS_CALDAV.'}calendar-data'; - $calendarNode = $this->server->tree->getNodeForPath($path); - - $blobs = []; - if ($start || $end || $componentType) { - // If there was a start or end filter, we need to enlist - // calendarQuery for speed. - $queryResult = $calendarNode->calendarQuery([ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => $componentType, - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => $start, - 'end' => $end, - ], - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]); - - // queryResult is just a list of base urls. We need to prefix the - // calendar path. - $queryResult = array_map( - function ($item) use ($path) { - return $path.'/'.$item; - }, - $queryResult - ); - $nodes = $this->server->getPropertiesForMultiplePaths($queryResult, [$calDataProp]); - unset($queryResult); - } else { - $nodes = $this->server->getPropertiesForPath($path, [$calDataProp], 1); - } - - // Flattening the arrays - foreach ($nodes as $node) { - if (isset($node[200][$calDataProp])) { - $blobs[$node['href']] = $node[200][$calDataProp]; - } - } - unset($nodes); - - $mergedCalendar = $this->mergeObjects( - $properties, - $blobs - ); - - if ($expand) { - $calendarTimeZone = null; - // We're expanding, and for that we need to figure out the - // calendar's timezone. - $tzProp = '{'.Plugin::NS_CALDAV.'}calendar-timezone'; - $tzResult = $this->server->getProperties($path, [$tzProp]); - if (isset($tzResult[$tzProp])) { - // This property contains a VCALENDAR with a single - // VTIMEZONE. - $vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]); - $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); - // Destroy circular references to PHP will GC the object. - $vtimezoneObj->destroy(); - unset($vtimezoneObj); - } else { - // Defaulting to UTC. - $calendarTimeZone = new DateTimeZone('UTC'); - } - - $mergedCalendar = $mergedCalendar->expand($start, $end, $calendarTimeZone); - } - - $filenameExtension = '.ics'; - - switch ($format) { - case 'text/calendar': - $mergedCalendar = $mergedCalendar->serialize(); - $filenameExtension = '.ics'; - break; - case 'application/calendar+json': - $mergedCalendar = json_encode($mergedCalendar->jsonSerialize()); - $filenameExtension = '.json'; - break; - } - - $filename = preg_replace( - '/[^a-zA-Z0-9-_ ]/um', - '', - $calendarNode->getName() - ); - $filename .= '-'.date('Y-m-d').$filenameExtension; - - $response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"'); - $response->setHeader('Content-Type', $format); - - $response->setStatus(200); - $response->setBody($mergedCalendar); - } - - /** - * Merges all calendar objects, and builds one big iCalendar blob. - * - * @param array $properties Some CalDAV properties - * - * @return VObject\Component\VCalendar - */ - public function mergeObjects(array $properties, array $inputObjects) - { - $calendar = new VObject\Component\VCalendar(); - $calendar->VERSION = '2.0'; - if (DAV\Server::$exposeVersion) { - $calendar->PRODID = '-//SabreDAV//SabreDAV '.DAV\Version::VERSION.'//EN'; - } else { - $calendar->PRODID = '-//SabreDAV//SabreDAV//EN'; - } - if (isset($properties['{DAV:}displayname'])) { - $calendar->{'X-WR-CALNAME'} = $properties['{DAV:}displayname']; - } - if (isset($properties['{http://apple.com/ns/ical/}calendar-color'])) { - $calendar->{'X-APPLE-CALENDAR-COLOR'} = $properties['{http://apple.com/ns/ical/}calendar-color']; - } - - $collectedTimezones = []; - - $timezones = []; - $objects = []; - - foreach ($inputObjects as $href => $inputObject) { - $nodeComp = VObject\Reader::read($inputObject); - - foreach ($nodeComp->children() as $child) { - switch ($child->name) { - case 'VEVENT': - case 'VTODO': - case 'VJOURNAL': - $objects[] = clone $child; - break; - - // VTIMEZONE is special, because we need to filter out the duplicates - case 'VTIMEZONE': - // Naively just checking tzid. - if (in_array((string) $child->TZID, $collectedTimezones)) { - break; - } - - $timezones[] = clone $child; - $collectedTimezones[] = $child->TZID; - break; - } - } - // Destroy circular references to PHP will GC the object. - $nodeComp->destroy(); - unset($nodeComp); - } - - foreach ($timezones as $tz) { - $calendar->add($tz); - } - foreach ($objects as $obj) { - $calendar->add($obj); - } - - return $calendar; - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using \Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'ics-export'; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds the ability to export CalDAV calendars as a single iCalendar file.', - 'link' => 'http://sabre.io/dav/ics-export-plugin/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/ICalendar.php b/lib/vendor/sabre/dav/lib/CalDAV/ICalendar.php deleted file mode 100644 index 8636e0b..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/ICalendar.php +++ /dev/null @@ -1,20 +0,0 @@ -caldavBackend = $caldavBackend; - $this->principalUri = $principalUri; - } - - /** - * Returns all notifications for a principal. - * - * @return array - */ - public function getChildren() - { - $children = []; - $notifications = $this->caldavBackend->getNotificationsForPrincipal($this->principalUri); - - foreach ($notifications as $notification) { - $children[] = new Node( - $this->caldavBackend, - $this->principalUri, - $notification - ); - } - - return $children; - } - - /** - * Returns the name of this object. - * - * @return string - */ - public function getName() - { - return 'notifications'; - } - - /** - * 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; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Notifications/ICollection.php b/lib/vendor/sabre/dav/lib/CalDAV/Notifications/ICollection.php deleted file mode 100644 index b12fb39..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Notifications/ICollection.php +++ /dev/null @@ -1,25 +0,0 @@ -caldavBackend = $caldavBackend; - $this->principalUri = $principalUri; - $this->notification = $notification; - } - - /** - * Returns the path name for this notification. - * - * @return string - */ - public function getName() - { - return $this->notification->getId().'.xml'; - } - - /** - * Returns the etag for the notification. - * - * The etag must be surrounded by literal double-quotes. - * - * @return string - */ - public function getETag() - { - return $this->notification->getETag(); - } - - /** - * This method must return an xml element, using the - * Sabre\CalDAV\Xml\Notification\NotificationInterface classes. - * - * @return NotificationInterface - */ - public function getNotificationType() - { - return $this->notification; - } - - /** - * Deletes this notification. - */ - public function delete() - { - $this->caldavBackend->deleteNotification($this->getOwner(), $this->notification); - } - - /** - * Returns the owner principal. - * - * This must be an url to a principal, or null if there's no owner - * - * @return string|null - */ - public function getOwner() - { - return $this->principalUri; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php b/lib/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php deleted file mode 100644 index 56b2fe9..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Notifications/Plugin.php +++ /dev/null @@ -1,161 +0,0 @@ -server = $server; - $server->on('method:GET', [$this, 'httpGet'], 90); - $server->on('propFind', [$this, 'propFind']); - - $server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs'; - $server->resourceTypeMapping['\\Sabre\\CalDAV\\Notifications\\ICollection'] = '{'.self::NS_CALENDARSERVER.'}notification'; - - array_push($server->protectedProperties, - '{'.self::NS_CALENDARSERVER.'}notification-URL', - '{'.self::NS_CALENDARSERVER.'}notificationtype' - ); - } - - /** - * PropFind. - */ - public function propFind(PropFind $propFind, BaseINode $node) - { - $caldavPlugin = $this->server->getPlugin('caldav'); - - if ($node instanceof DAVACL\IPrincipal) { - $principalUrl = $node->getPrincipalUrl(); - - // notification-URL property - $propFind->handle('{'.self::NS_CALENDARSERVER.'}notification-URL', function () use ($principalUrl, $caldavPlugin) { - $notificationPath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl).'/notifications/'; - - return new DAV\Xml\Property\Href($notificationPath); - }); - } - - if ($node instanceof INode) { - $propFind->handle( - '{'.self::NS_CALENDARSERVER.'}notificationtype', - [$node, 'getNotificationType'] - ); - } - } - - /** - * This event is triggered before the usual GET request handler. - * - * We use this to intercept GET calls to notification nodes, and return the - * proper response. - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - try { - $node = $this->server->tree->getNodeForPath($path); - } catch (DAV\Exception\NotFound $e) { - return; - } - - if (!$node instanceof INode) { - return; - } - - $writer = $this->server->xml->getWriter(); - $writer->contextUri = $this->server->getBaseUri(); - $writer->openMemory(); - $writer->startDocument('1.0', 'UTF-8'); - $writer->startElement('{http://calendarserver.org/ns/}notification'); - $node->getNotificationType()->xmlSerializeFull($writer); - $writer->endElement(); - - $response->setHeader('Content-Type', 'application/xml'); - $response->setHeader('ETag', $node->getETag()); - $response->setStatus(200); - $response->setBody($writer->outputMemory()); - - // Return false to break the event chain. - return false; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds support for caldav-notifications, which is required to enable caldav-sharing.', - 'link' => 'http://sabre.io/dav/caldav-sharing/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Plugin.php b/lib/vendor/sabre/dav/lib/CalDAV/Plugin.php deleted file mode 100644 index ccb722f..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Plugin.php +++ /dev/null @@ -1,1011 +0,0 @@ -server->tree->getNodeForPath($parent); - - if ($node instanceof DAV\IExtendedCollection) { - try { - $node->getChild($name); - } catch (DAV\Exception\NotFound $e) { - return ['MKCALENDAR']; - } - } - - return []; - } - - /** - * Returns the path to a principal's calendar home. - * - * The return url must not end with a slash. - * This function should return null in case a principal did not have - * a calendar home. - * - * @param string $principalUrl - * - * @return string - */ - public function getCalendarHomeForPrincipal($principalUrl) - { - // The default behavior for most sabre/dav servers is that there is a - // principals root node, which contains users directly under it. - // - // This function assumes that there are two components in a principal - // path. If there's more, we don't return a calendar home. This - // excludes things like the calendar-proxy-read principal (which it - // should). - $parts = explode('/', trim($principalUrl, '/')); - if (2 !== count($parts)) { - return; - } - if ('principals' !== $parts[0]) { - return; - } - - return self::CALENDAR_ROOT.'/'.$parts[1]; - } - - /** - * Returns a list of features for the DAV: HTTP header. - * - * @return array - */ - public function getFeatures() - { - return ['calendar-access', 'calendar-proxy']; - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'caldav'; - } - - /** - * 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 - * - * @param string $uri - * - * @return array - */ - public function getSupportedReportSet($uri) - { - $node = $this->server->tree->getNodeForPath($uri); - - $reports = []; - if ($node instanceof ICalendarObjectContainer || $node instanceof ICalendarObject) { - $reports[] = '{'.self::NS_CALDAV.'}calendar-multiget'; - $reports[] = '{'.self::NS_CALDAV.'}calendar-query'; - } - if ($node instanceof ICalendar) { - $reports[] = '{'.self::NS_CALDAV.'}free-busy-query'; - } - // iCal has a bug where it assumes that sync support is enabled, only - // if we say we support it on the calendar-home, even though this is - // not actually the case. - if ($node instanceof CalendarHome && $this->server->getPlugin('sync')) { - $reports[] = '{DAV:}sync-collection'; - } - - return $reports; - } - - /** - * Initializes the plugin. - */ - public function initialize(DAV\Server $server) - { - $this->server = $server; - - $server->on('method:MKCALENDAR', [$this, 'httpMkCalendar']); - $server->on('report', [$this, 'report']); - $server->on('propFind', [$this, 'propFind']); - $server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']); - $server->on('beforeCreateFile', [$this, 'beforeCreateFile']); - $server->on('beforeWriteContent', [$this, 'beforeWriteContent']); - $server->on('afterMethod:GET', [$this, 'httpAfterGET']); - $server->on('getSupportedPrivilegeSet', [$this, 'getSupportedPrivilegeSet']); - - $server->xml->namespaceMap[self::NS_CALDAV] = 'cal'; - $server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs'; - - $server->xml->elementMap['{'.self::NS_CALDAV.'}supported-calendar-component-set'] = 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet'; - $server->xml->elementMap['{'.self::NS_CALDAV.'}calendar-query'] = 'Sabre\\CalDAV\\Xml\\Request\\CalendarQueryReport'; - $server->xml->elementMap['{'.self::NS_CALDAV.'}calendar-multiget'] = 'Sabre\\CalDAV\\Xml\\Request\\CalendarMultiGetReport'; - $server->xml->elementMap['{'.self::NS_CALDAV.'}free-busy-query'] = 'Sabre\\CalDAV\\Xml\\Request\\FreeBusyQueryReport'; - $server->xml->elementMap['{'.self::NS_CALDAV.'}mkcalendar'] = 'Sabre\\CalDAV\\Xml\\Request\\MkCalendar'; - $server->xml->elementMap['{'.self::NS_CALDAV.'}schedule-calendar-transp'] = 'Sabre\\CalDAV\\Xml\\Property\\ScheduleCalendarTransp'; - $server->xml->elementMap['{'.self::NS_CALDAV.'}supported-calendar-component-set'] = 'Sabre\\CalDAV\\Xml\\Property\\SupportedCalendarComponentSet'; - - $server->resourceTypeMapping['\\Sabre\\CalDAV\\ICalendar'] = '{urn:ietf:params:xml:ns:caldav}calendar'; - - $server->resourceTypeMapping['\\Sabre\\CalDAV\\Principal\\IProxyRead'] = '{http://calendarserver.org/ns/}calendar-proxy-read'; - $server->resourceTypeMapping['\\Sabre\\CalDAV\\Principal\\IProxyWrite'] = '{http://calendarserver.org/ns/}calendar-proxy-write'; - - array_push($server->protectedProperties, - '{'.self::NS_CALDAV.'}supported-calendar-component-set', - '{'.self::NS_CALDAV.'}supported-calendar-data', - '{'.self::NS_CALDAV.'}max-resource-size', - '{'.self::NS_CALDAV.'}min-date-time', - '{'.self::NS_CALDAV.'}max-date-time', - '{'.self::NS_CALDAV.'}max-instances', - '{'.self::NS_CALDAV.'}max-attendees-per-instance', - '{'.self::NS_CALDAV.'}calendar-home-set', - '{'.self::NS_CALDAV.'}supported-collation-set', - '{'.self::NS_CALDAV.'}calendar-data', - - // CalendarServer extensions - '{'.self::NS_CALENDARSERVER.'}getctag', - '{'.self::NS_CALENDARSERVER.'}calendar-proxy-read-for', - '{'.self::NS_CALENDARSERVER.'}calendar-proxy-write-for' - ); - - if ($aclPlugin = $server->getPlugin('acl')) { - $aclPlugin->principalSearchPropertySet['{'.self::NS_CALDAV.'}calendar-user-address-set'] = 'Calendar address'; - } - } - - /** - * This functions handles REPORT requests specific to CalDAV. - * - * @param string $reportName - * @param mixed $report - * @param mixed $path - * - * @return bool|null - */ - public function report($reportName, $report, $path) - { - switch ($reportName) { - case '{'.self::NS_CALDAV.'}calendar-multiget': - $this->server->transactionType = 'report-calendar-multiget'; - $this->calendarMultiGetReport($report); - - return false; - case '{'.self::NS_CALDAV.'}calendar-query': - $this->server->transactionType = 'report-calendar-query'; - $this->calendarQueryReport($report); - - return false; - case '{'.self::NS_CALDAV.'}free-busy-query': - $this->server->transactionType = 'report-free-busy-query'; - $this->freeBusyQueryReport($report); - - return false; - } - } - - /** - * This function handles the MKCALENDAR HTTP method, which creates - * a new calendar. - * - * @return bool - */ - public function httpMkCalendar(RequestInterface $request, ResponseInterface $response) - { - $body = $request->getBodyAsString(); - $path = $request->getPath(); - - $properties = []; - - if ($body) { - try { - $mkcalendar = $this->server->xml->expect( - '{urn:ietf:params:xml:ns:caldav}mkcalendar', - $body - ); - } catch (\Sabre\Xml\ParseException $e) { - throw new BadRequest($e->getMessage(), 0, $e); - } - $properties = $mkcalendar->getProperties(); - } - - // iCal abuses MKCALENDAR since iCal 10.9.2 to create server-stored - // subscriptions. Before that it used MKCOL which was the correct way - // to do this. - // - // If the body had a {DAV:}resourcetype, it means we stumbled upon this - // request, and we simply use it instead of the pre-defined list. - if (isset($properties['{DAV:}resourcetype'])) { - $resourceType = $properties['{DAV:}resourcetype']->getValue(); - } else { - $resourceType = ['{DAV:}collection', '{urn:ietf:params:xml:ns:caldav}calendar']; - } - - $this->server->createCollection($path, new MkCol($resourceType, $properties)); - - $response->setStatus(201); - $response->setHeader('Content-Length', 0); - - // This breaks the method chain. - return false; - } - - /** - * PropFind. - * - * This method handler is invoked before any after properties for a - * resource are fetched. This allows us to add in any CalDAV specific - * properties. - */ - public function propFind(DAV\PropFind $propFind, DAV\INode $node) - { - $ns = '{'.self::NS_CALDAV.'}'; - - if ($node instanceof ICalendarObjectContainer) { - $propFind->handle($ns.'max-resource-size', $this->maxResourceSize); - $propFind->handle($ns.'supported-calendar-data', function () { - return new Xml\Property\SupportedCalendarData(); - }); - $propFind->handle($ns.'supported-collation-set', function () { - return new Xml\Property\SupportedCollationSet(); - }); - } - - if ($node instanceof DAVACL\IPrincipal) { - $principalUrl = $node->getPrincipalUrl(); - - $propFind->handle('{'.self::NS_CALDAV.'}calendar-home-set', function () use ($principalUrl) { - $calendarHomePath = $this->getCalendarHomeForPrincipal($principalUrl); - if (is_null($calendarHomePath)) { - return null; - } - - return new LocalHref($calendarHomePath.'/'); - }); - // The calendar-user-address-set property is basically mapped to - // the {DAV:}alternate-URI-set property. - $propFind->handle('{'.self::NS_CALDAV.'}calendar-user-address-set', function () use ($node) { - $addresses = $node->getAlternateUriSet(); - $addresses[] = $this->server->getBaseUri().$node->getPrincipalUrl().'/'; - - return new LocalHref($addresses); - }); - // For some reason somebody thought it was a good idea to add - // another one of these properties. We're supporting it too. - $propFind->handle('{'.self::NS_CALENDARSERVER.'}email-address-set', function () use ($node) { - $addresses = $node->getAlternateUriSet(); - $emails = []; - foreach ($addresses as $address) { - if ('mailto:' === substr($address, 0, 7)) { - $emails[] = substr($address, 7); - } - } - - return new Xml\Property\EmailAddressSet($emails); - }); - - // 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'; - - if (404 === $propFind->getStatus($propRead) || 404 === $propFind->getStatus($propWrite)) { - $aclPlugin = $this->server->getPlugin('acl'); - $membership = $aclPlugin->getPrincipalMembership($propFind->getPath()); - $readList = []; - $writeList = []; - - foreach ($membership as $group) { - $groupNode = $this->server->tree->getNodeForPath($group); - - $listItem = Uri\split($group)[0].'/'; - - // 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 Principal\IProxyRead) { - $readList[] = $listItem; - } - if ($groupNode instanceof Principal\IProxyWrite) { - $writeList[] = $listItem; - } - } - - $propFind->set($propRead, new LocalHref($readList)); - $propFind->set($propWrite, new LocalHref($writeList)); - } - } // instanceof IPrincipal - - if ($node instanceof 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. - // Therefore we simply expose it as a property. - $propFind->handle('{'.self::NS_CALDAV.'}calendar-data', function () use ($node) { - $val = $node->get(); - if (is_resource($val)) { - $val = stream_get_contents($val); - } - - // Taking out \r to not screw up the xml output - return str_replace("\r", '', $val); - }); - } - } - - /** - * This function handles the calendar-multiget REPORT. - * - * This report is used by the client to fetch the content of a series - * of urls. Effectively avoiding a lot of redundant requests. - * - * @param CalendarMultiGetReport $report - */ - public function calendarMultiGetReport($report) - { - $needsJson = 'application/calendar+json' === $report->contentType; - - $timeZones = []; - $propertyList = []; - - $paths = array_map( - [$this->server, 'calculateUri'], - $report->hrefs - ); - - foreach ($this->server->getPropertiesForMultiplePaths($paths, $report->properties) as $uri => $objProps) { - if (($needsJson || $report->expand) && isset($objProps[200]['{'.self::NS_CALDAV.'}calendar-data'])) { - $vObject = VObject\Reader::read($objProps[200]['{'.self::NS_CALDAV.'}calendar-data']); - - if ($report->expand) { - // We're expanding, and for that we need to figure out the - // calendar's timezone. - list($calendarPath) = Uri\split($uri); - if (!isset($timeZones[$calendarPath])) { - // Checking the calendar-timezone property. - $tzProp = '{'.self::NS_CALDAV.'}calendar-timezone'; - $tzResult = $this->server->getProperties($calendarPath, [$tzProp]); - if (isset($tzResult[$tzProp])) { - // This property contains a VCALENDAR with a single - // VTIMEZONE. - $vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]); - $timeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); - } else { - // Defaulting to UTC. - $timeZone = new DateTimeZone('UTC'); - } - $timeZones[$calendarPath] = $timeZone; - } - - $vObject = $vObject->expand($report->expand['start'], $report->expand['end'], $timeZones[$calendarPath]); - } - if ($needsJson) { - $objProps[200]['{'.self::NS_CALDAV.'}calendar-data'] = json_encode($vObject->jsonSerialize()); - } else { - $objProps[200]['{'.self::NS_CALDAV.'}calendar-data'] = $vObject->serialize(); - } - // Destroy circular references so PHP will garbage collect the - // object. - $vObject->destroy(); - } - - $propertyList[] = $objProps; - } - - $prefer = $this->server->getHTTPPrefer(); - - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); - $this->server->httpResponse->setBody($this->server->generateMultiStatus($propertyList, 'minimal' === $prefer['return'])); - } - - /** - * This function handles the calendar-query REPORT. - * - * This report is used by clients to request calendar objects based on - * complex conditions. - * - * @param Xml\Request\CalendarQueryReport $report - */ - public function calendarQueryReport($report) - { - $path = $this->server->getRequestUri(); - - $needsJson = 'application/calendar+json' === $report->contentType; - - $node = $this->server->tree->getNodeForPath($this->server->getRequestUri()); - $depth = $this->server->getHTTPDepth(0); - - // The default result is an empty array - $result = []; - - $calendarTimeZone = null; - if ($report->expand) { - // We're expanding, and for that we need to figure out the - // calendar's timezone. - $tzProp = '{'.self::NS_CALDAV.'}calendar-timezone'; - $tzResult = $this->server->getProperties($path, [$tzProp]); - if (isset($tzResult[$tzProp])) { - // This property contains a VCALENDAR with a single - // VTIMEZONE. - $vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]); - $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); - - // Destroy circular references so PHP will garbage collect the - // object. - $vtimezoneObj->destroy(); - } else { - // Defaulting to UTC. - $calendarTimeZone = new DateTimeZone('UTC'); - } - } - - // The calendarobject was requested directly. In this case we handle - // this locally. - if (0 == $depth && $node instanceof ICalendarObject) { - $requestedCalendarData = true; - $requestedProperties = $report->properties; - - 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 - // it after processing. - $requestedCalendarData = false; - } - - $properties = $this->server->getPropertiesForPath( - $path, - $requestedProperties, - 0 - ); - - // This array should have only 1 element, the first calendar - // object. - $properties = current($properties); - - // If there wasn't any calendar-data returned somehow, we ignore - // this. - if (isset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'])) { - $validator = new CalendarQueryValidator(); - - $vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']); - if ($validator->validate($vObject, $report->filters)) { - // If the client didn't require the calendar-data property, - // we won't give it back. - if (!$requestedCalendarData) { - unset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']); - } else { - if ($report->expand) { - $vObject = $vObject->expand($report->expand['start'], $report->expand['end'], $calendarTimeZone); - } - if ($needsJson) { - $properties[200]['{'.self::NS_CALDAV.'}calendar-data'] = json_encode($vObject->jsonSerialize()); - } elseif ($report->expand) { - $properties[200]['{'.self::NS_CALDAV.'}calendar-data'] = $vObject->serialize(); - } - } - - $result = [$properties]; - } - // Destroy circular references so PHP will garbage collect the - // object. - $vObject->destroy(); - } - } - - if ($node instanceof ICalendarObjectContainer && 0 === $depth) { - if (0 === strpos((string) $this->server->httpRequest->getHeader('User-Agent'), 'MSFT-')) { - // Microsoft clients incorrectly supplied depth as 0, when it actually - // should have set depth to 1. We're implementing a workaround here - // to deal with this. - // - // This targets at least the following clients: - // Windows 10 - // Windows Phone 8, 10 - $depth = 1; - } else { - throw new BadRequest('A calendar-query REPORT on a calendar with a Depth: 0 is undefined. Set Depth to 1'); - } - } - - // If we're dealing with a calendar, the calendar itself is responsible - // for the calendar-query. - if ($node instanceof ICalendarObjectContainer && 1 == $depth) { - $nodePaths = $node->calendarQuery($report->filters); - - foreach ($nodePaths as $path) { - list($properties) = - $this->server->getPropertiesForPath($this->server->getRequestUri().'/'.$path, $report->properties); - - if (($needsJson || $report->expand)) { - $vObject = VObject\Reader::read($properties[200]['{'.self::NS_CALDAV.'}calendar-data']); - - if ($report->expand) { - $vObject = $vObject->expand($report->expand['start'], $report->expand['end'], $calendarTimeZone); - } - - if ($needsJson) { - $properties[200]['{'.self::NS_CALDAV.'}calendar-data'] = json_encode($vObject->jsonSerialize()); - } else { - $properties[200]['{'.self::NS_CALDAV.'}calendar-data'] = $vObject->serialize(); - } - - // Destroy circular references so PHP will garbage collect the - // object. - $vObject->destroy(); - } - $result[] = $properties; - } - } - - $prefer = $this->server->getHTTPPrefer(); - - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); - $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, 'minimal' === $prefer['return'])); - } - - /** - * This method is responsible for parsing the request and generating the - * response for the CALDAV:free-busy-query REPORT. - */ - protected function freeBusyQueryReport(Xml\Request\FreeBusyQueryReport $report) - { - $uri = $this->server->getRequestUri(); - - $acl = $this->server->getPlugin('acl'); - if ($acl) { - $acl->checkPrivileges($uri, '{'.self::NS_CALDAV.'}read-free-busy'); - } - - $calendar = $this->server->tree->getNodeForPath($uri); - if (!$calendar instanceof ICalendar) { - throw new DAV\Exception\NotImplemented('The free-busy-query REPORT is only implemented on calendars'); - } - - $tzProp = '{'.self::NS_CALDAV.'}calendar-timezone'; - - // Figuring out the default timezone for the calendar, for floating - // times. - $calendarProps = $this->server->getProperties($uri, [$tzProp]); - - if (isset($calendarProps[$tzProp])) { - $vtimezoneObj = VObject\Reader::read($calendarProps[$tzProp]); - $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); - // Destroy circular references so PHP will garbage collect the object. - $vtimezoneObj->destroy(); - } else { - $calendarTimeZone = new DateTimeZone('UTC'); - } - - // Doing a calendar-query first, to make sure we get the most - // performance. - $urls = $calendar->calendarQuery([ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => $report->start, - 'end' => $report->end, - ], - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]); - - $objects = array_map(function ($url) use ($calendar) { - $obj = $calendar->getChild($url)->get(); - - return $obj; - }, $urls); - - $generator = new VObject\FreeBusyGenerator(); - $generator->setObjects($objects); - $generator->setTimeRange($report->start, $report->end); - $generator->setTimeZone($calendarTimeZone); - $result = $generator->getResult(); - $result = $result->serialize(); - - $this->server->httpResponse->setStatus(200); - $this->server->httpResponse->setHeader('Content-Type', 'text/calendar'); - $this->server->httpResponse->setHeader('Content-Length', strlen($result)); - $this->server->httpResponse->setBody($result); - } - - /** - * 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 resource $data - * @param bool $modified should be set to true, if this event handler - * changed &$data - */ - public function beforeWriteContent($path, DAV\IFile $node, &$data, &$modified) - { - if (!$node instanceof ICalendarObject) { - return; - } - - // We're only interested in ICalendarObject nodes that are inside of a - // real calendar. This is to avoid triggering validation and scheduling - // for non-calendars (such as an inbox). - list($parent) = Uri\split($path); - $parentNode = $this->server->tree->getNodeForPath($parent); - - if (!$parentNode instanceof ICalendar) { - return; - } - - $this->validateICalendar( - $data, - $path, - $modified, - $this->server->httpRequest, - $this->server->httpResponse, - false - ); - } - - /** - * 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 bool $modified should be set to true, if this event handler - * changed &$data - */ - public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode, &$modified) - { - if (!$parentNode instanceof ICalendar) { - return; - } - - $this->validateICalendar( - $data, - $path, - $modified, - $this->server->httpRequest, - $this->server->httpResponse, - true - ); - } - - /** - * Checks if the submitted iCalendar data is in fact, valid. - * - * An exception is thrown if it's not. - * - * @param resource|string $data - * @param string $path - * @param bool $modified should be set to true, if this event handler - * changed &$data - * @param RequestInterface $request the http request - * @param ResponseInterface $response the http response - * @param bool $isNew is the item a new one, or an update - */ - protected function validateICalendar(&$data, $path, &$modified, RequestInterface $request, ResponseInterface $response, $isNew) - { - // If it's a stream, we convert it to a string first. - if (is_resource($data)) { - $data = stream_get_contents($data); - } - - $before = $data; - - try { - // If the data starts with a [, we can reasonably assume we're dealing - // with a jCal object. - if ('[' === substr($data, 0, 1)) { - $vobj = VObject\Reader::readJson($data); - - // Converting $data back to iCalendar, as that's what we - // technically support everywhere. - $data = $vobj->serialize(); - $modified = true; - } else { - $vobj = VObject\Reader::read($data); - } - } catch (VObject\ParseException $e) { - throw new DAV\Exception\UnsupportedMediaType('This resource only supports valid iCalendar 2.0 data. Parse error: '.$e->getMessage()); - } - - if ('VCALENDAR' !== $vobj->name) { - throw new DAV\Exception\UnsupportedMediaType('This collection can only support iCalendar objects.'); - } - - $sCCS = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'; - - // Get the Supported Components for the target calendar - list($parentPath) = Uri\split($path); - $calendarProperties = $this->server->getProperties($parentPath, [$sCCS]); - - if (isset($calendarProperties[$sCCS])) { - $supportedComponents = $calendarProperties[$sCCS]->getValue(); - } else { - $supportedComponents = ['VJOURNAL', 'VTODO', 'VEVENT']; - } - - $foundType = null; - - foreach ($vobj->getComponents() as $component) { - switch ($component->name) { - case 'VTIMEZONE': - continue 2; - case 'VEVENT': - case 'VTODO': - case 'VJOURNAL': - $foundType = $component->name; - break; - } - } - - if (!$foundType || !in_array($foundType, $supportedComponents)) { - throw new Exception\InvalidComponentType('iCalendar objects must at least have a component of type '.implode(', ', $supportedComponents)); - } - - $options = VObject\Node::PROFILE_CALDAV; - $prefer = $this->server->getHTTPPrefer(); - - if ('strict' !== $prefer['handling']) { - $options |= VObject\Node::REPAIR; - } - - $messages = $vobj->validate($options); - - $highestLevel = 0; - $warningMessage = null; - - // $messages contains a list of problems with the vcard, along with - // their severity. - foreach ($messages as $message) { - if ($message['level'] > $highestLevel) { - // Recording the highest reported error level. - $highestLevel = $message['level']; - $warningMessage = $message['message']; - } - switch ($message['level']) { - case 1: - // Level 1 means that there was a problem, but it was repaired. - $modified = true; - break; - case 2: - // Level 2 means a warning, but not critical - break; - case 3: - // Level 3 means a critical error - throw new DAV\Exception\UnsupportedMediaType('Validation error in iCalendar: '.$message['message']); - } - } - if ($warningMessage) { - $response->setHeader( - 'X-Sabre-Ew-Gross', - 'iCalendar validation warning: '.$warningMessage - ); - } - - // We use an extra variable to allow event handles to tell us whether - // the object was modified or not. - // - // This helps us determine if we need to re-serialize the object. - $subModified = false; - - $this->server->emit( - 'calendarObjectChange', - [ - $request, - $response, - $vobj, - $parentPath, - &$subModified, - $isNew, - ] - ); - - if ($modified || $subModified) { - // An event handler told us that it modified the object. - $data = $vobj->serialize(); - - // Using md5 to figure out if there was an *actual* change. - if (!$modified && 0 !== strcmp($data, $before)) { - $modified = true; - } - } - - // Destroy circular references so PHP will garbage collect the object. - $vobj->destroy(); - } - - /** - * This method is triggered whenever a subsystem requests the privileges - * that are supported on a particular node. - */ - public function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilegeSet) - { - if ($node instanceof ICalendar) { - $supportedPrivilegeSet['{DAV:}read']['aggregates']['{'.self::NS_CALDAV.'}read-free-busy'] = [ - 'abstract' => false, - 'aggregates' => [], - ]; - } - } - - /** - * This method is used to generate HTML output for the - * DAV\Browser\Plugin. This allows us to generate an interface users - * can use to create new calendars. - * - * @param string $output - * - * @return bool - */ - public function htmlActionsPanel(DAV\INode $node, &$output) - { - if (!$node instanceof CalendarHome) { - return; - } - - $output .= '
-

Create new calendar

- - -
-
- -
- '; - - return false; - } - - /** - * This event is triggered after GET requests. - * - * This is used to transform data into jCal, if this was requested. - */ - public function httpAfterGet(RequestInterface $request, ResponseInterface $response) - { - $contentType = $response->getHeader('Content-Type'); - if (null === $contentType || false === strpos($contentType, 'text/calendar')) { - return; - } - - $result = HTTP\negotiateContentType( - $request->getHeader('Accept'), - ['text/calendar', 'application/calendar+json'] - ); - - if ('application/calendar+json' !== $result) { - // Do nothing - return; - } - - // Transforming. - $vobj = VObject\Reader::read($response->getBody()); - - $jsonBody = json_encode($vobj->jsonSerialize()); - $response->setBody($jsonBody); - - // Destroy circular references so PHP will garbage collect the object. - $vobj->destroy(); - - $response->setHeader('Content-Type', 'application/calendar+json'); - $response->setHeader('Content-Length', strlen($jsonBody)); - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds support for CalDAV (rfc4791)', - 'link' => 'http://sabre.io/dav/caldav/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Principal/Collection.php b/lib/vendor/sabre/dav/lib/CalDAV/Principal/Collection.php deleted file mode 100644 index 6d02303..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Principal/Collection.php +++ /dev/null @@ -1,32 +0,0 @@ -principalBackend, $principalInfo); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Principal/IProxyRead.php b/lib/vendor/sabre/dav/lib/CalDAV/Principal/IProxyRead.php deleted file mode 100644 index 96e6991..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Principal/IProxyRead.php +++ /dev/null @@ -1,21 +0,0 @@ -principalInfo = $principalInfo; - $this->principalBackend = $principalBackend; - } - - /** - * Returns this principals name. - * - * @return string - */ - public function getName() - { - return 'calendar-proxy-read'; - } - - /** - * Returns the last modification time. - */ - public function getLastModified() - { - return null; - } - - /** - * Deletes the current node. - * - * @throws DAV\Exception\Forbidden - */ - public function delete() - { - throw new DAV\Exception\Forbidden('Permission denied to delete node'); - } - - /** - * Renames the node. - * - * @param string $name The new name - * - * @throws DAV\Exception\Forbidden - */ - public function setName($name) - { - throw new DAV\Exception\Forbidden('Permission denied to rename file'); - } - - /** - * Returns a list of alternative urls for a principal. - * - * This can for example be an email address, or ldap url. - * - * @return array - */ - public function getAlternateUriSet() - { - return []; - } - - /** - * Returns the full principal url. - * - * @return string - */ - public function getPrincipalUrl() - { - 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. - * - * @return array - */ - public function getGroupMemberSet() - { - 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 - */ - public function getGroupMembership() - { - return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); - } - - /** - * Sets a list of group members. - * - * 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. - */ - public function setGroupMemberSet(array $principals) - { - $this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals); - } - - /** - * Returns the displayname. - * - * This should be a human readable name for the principal. - * If none is available, return the nodename. - * - * @return string - */ - public function getDisplayName() - { - return $this->getName(); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php b/lib/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php deleted file mode 100644 index 2d1ce7c..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Principal/ProxyWrite.php +++ /dev/null @@ -1,161 +0,0 @@ -principalInfo = $principalInfo; - $this->principalBackend = $principalBackend; - } - - /** - * Returns this principals name. - * - * @return string - */ - public function getName() - { - return 'calendar-proxy-write'; - } - - /** - * Returns the last modification time. - */ - public function getLastModified() - { - return null; - } - - /** - * Deletes the current node. - * - * @throws DAV\Exception\Forbidden - */ - public function delete() - { - throw new DAV\Exception\Forbidden('Permission denied to delete node'); - } - - /** - * Renames the node. - * - * @param string $name The new name - * - * @throws DAV\Exception\Forbidden - */ - public function setName($name) - { - throw new DAV\Exception\Forbidden('Permission denied to rename file'); - } - - /** - * Returns a list of alternative urls for a principal. - * - * This can for example be an email address, or ldap url. - * - * @return array - */ - public function getAlternateUriSet() - { - return []; - } - - /** - * Returns the full principal url. - * - * @return string - */ - public function getPrincipalUrl() - { - 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. - * - * @return array - */ - public function getGroupMemberSet() - { - 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 - */ - public function getGroupMembership() - { - return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); - } - - /** - * Sets a list of group members. - * - * 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. - */ - public function setGroupMemberSet(array $principals) - { - $this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals); - } - - /** - * Returns the displayname. - * - * This should be a human readable name for the principal. - * If none is available, return the nodename. - * - * @return string - */ - public function getDisplayName() - { - return $this->getName(); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Principal/User.php b/lib/vendor/sabre/dav/lib/CalDAV/Principal/User.php deleted file mode 100644 index 88bf4b4..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Principal/User.php +++ /dev/null @@ -1,136 +0,0 @@ -principalBackend->getPrincipalByPath($this->getPrincipalURL().'/'.$name); - if (!$principal) { - throw new DAV\Exception\NotFound('Node with name '.$name.' was not found'); - } - if ('calendar-proxy-read' === $name) { - return new ProxyRead($this->principalBackend, $this->principalProperties); - } - - if ('calendar-proxy-write' === $name) { - return new ProxyWrite($this->principalBackend, $this->principalProperties); - } - - throw new DAV\Exception\NotFound('Node with name '.$name.' was not found'); - } - - /** - * Returns an array with all the child nodes. - * - * @return DAV\INode[] - */ - public function getChildren() - { - $r = []; - if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL().'/calendar-proxy-read')) { - $r[] = new ProxyRead($this->principalBackend, $this->principalProperties); - } - if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL().'/calendar-proxy-write')) { - $r[] = new ProxyWrite($this->principalBackend, $this->principalProperties); - } - - return $r; - } - - /** - * Returns whether or not the child node exists. - * - * @param string $name - * - * @return bool - */ - public function childExists($name) - { - try { - $this->getChild($name); - - return true; - } catch (DAV\Exception\NotFound $e) { - return false; - } - } - - /** - * 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() - { - $acl = parent::getACL(); - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->principalProperties['uri'].'/calendar-proxy-read', - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->principalProperties['uri'].'/calendar-proxy-write', - 'protected' => true, - ]; - - return $acl; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/IInbox.php b/lib/vendor/sabre/dav/lib/CalDAV/Schedule/IInbox.php deleted file mode 100644 index 64a94be..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/IInbox.php +++ /dev/null @@ -1,17 +0,0 @@ -senderEmail = $senderEmail; - } - - /* - * This initializes the plugin. - * - * This function is called by Sabre\DAV\Server, after - * addPlugin is called. - * - * This method should set up the required event subscriptions. - * - * @param DAV\Server $server - * @return void - */ - public function initialize(DAV\Server $server) - { - $server->on('schedule', [$this, 'schedule'], 120); - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using \Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'imip'; - } - - /** - * Event handler for the 'schedule' event. - */ - public function schedule(ITip\Message $iTipMessage) - { - // Not sending any emails if the system considers the update - // insignificant. - if (!$iTipMessage->significantChange) { - if (!$iTipMessage->scheduleStatus) { - $iTipMessage->scheduleStatus = '1.0;We got the message, but it\'s not significant enough to warrant an email'; - } - - return; - } - - $summary = $iTipMessage->message->VEVENT->SUMMARY; - - if ('mailto' !== parse_url($iTipMessage->sender, PHP_URL_SCHEME)) { - return; - } - - if ('mailto' !== parse_url($iTipMessage->recipient, PHP_URL_SCHEME)) { - return; - } - - $sender = substr($iTipMessage->sender, 7); - $recipient = substr($iTipMessage->recipient, 7); - - if ($iTipMessage->senderName) { - $sender = $iTipMessage->senderName.' <'.$sender.'>'; - } - if ($iTipMessage->recipientName && $iTipMessage->recipientName != $recipient) { - $recipient = $iTipMessage->recipientName.' <'.$recipient.'>'; - } - - $subject = 'SabreDAV iTIP message'; - switch (strtoupper($iTipMessage->method)) { - case 'REPLY': - $subject = 'Re: '.$summary; - break; - case 'REQUEST': - $subject = 'Invitation: '.$summary; - break; - case 'CANCEL': - $subject = 'Cancelled: '.$summary; - break; - } - - $headers = [ - 'Reply-To: '.$sender, - 'From: '.$iTipMessage->senderName.' <'.$this->senderEmail.'>', - 'MIME-Version: 1.0', - 'Content-Type: text/calendar; charset=UTF-8; method='.$iTipMessage->method, - ]; - if (DAV\Server::$exposeVersion) { - $headers[] = 'X-Sabre-Version: '.DAV\Version::VERSION; - } - $this->mail( - $recipient, - $subject, - $iTipMessage->message->serialize(), - $headers - ); - $iTipMessage->scheduleStatus = '1.1; Scheduling message is sent via iMip'; - } - - // @codeCoverageIgnoreStart - // This is deemed untestable in a reasonable manner - - /** - * This function is responsible 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 - */ - protected function mail($to, $subject, $body, array $headers) - { - mail($to, $subject, $body, implode("\r\n", $headers)); - } - - // @codeCoverageIgnoreEnd - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Email delivery (rfc6047) for CalDAV scheduling', - 'link' => 'http://sabre.io/dav/scheduling/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/IOutbox.php b/lib/vendor/sabre/dav/lib/CalDAV/Schedule/IOutbox.php deleted file mode 100644 index 384b503..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/IOutbox.php +++ /dev/null @@ -1,17 +0,0 @@ -caldavBackend = $caldavBackend; - $this->principalUri = $principalUri; - } - - /** - * Returns the name of the node. - * - * This is used to generate the url. - * - * @return string - */ - public function getName() - { - return 'inbox'; - } - - /** - * Returns an array with all the child nodes. - * - * @return \Sabre\DAV\INode[] - */ - public function getChildren() - { - $objs = $this->caldavBackend->getSchedulingObjects($this->principalUri); - $children = []; - foreach ($objs as $obj) { - //$obj['acl'] = $this->getACL(); - $obj['principaluri'] = $this->principalUri; - $children[] = new SchedulingObject($this->caldavBackend, $obj); - } - - return $children; - } - - /** - * 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 successful 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 string|null - */ - public function createFile($name, $data = null) - { - $this->caldavBackend->createSchedulingObject($this->principalUri, $name, $data); - } - - /** - * 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 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 [ - [ - 'privilege' => '{DAV:}read', - 'principal' => '{DAV:}authenticated', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}write-properties', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}unbind', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}unbind', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-deliver', - 'principal' => '{DAV:}authenticated', - 'protected' => true, - ], - ]; - } - - /** - * Performs a calendar-query on the contents of this calendar. - * - * The calendar-query is defined in RFC4791 : CalDAV. Using the - * calendar-query it is possible for a client to request a specific set of - * object, based on contents of iCalendar properties, date-ranges and - * iCalendar component types (VTODO, VEVENT). - * - * This method should just return a list of (relative) urls that match this - * query. - * - * The list of filters are specified as an array. The exact array is - * documented by \Sabre\CalDAV\CalendarQueryParser. - * - * @return array - */ - public function calendarQuery(array $filters) - { - $result = []; - $validator = new CalDAV\CalendarQueryValidator(); - - $objects = $this->caldavBackend->getSchedulingObjects($this->principalUri); - foreach ($objects as $object) { - $vObject = VObject\Reader::read($object['calendardata']); - if ($validator->validate($vObject, $filters)) { - $result[] = $object['uri']; - } - - // Destroy circular references to PHP will GC the object. - $vObject->destroy(); - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php b/lib/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php deleted file mode 100644 index 1442c4c..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php +++ /dev/null @@ -1,119 +0,0 @@ -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 []; - } - - /** - * 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 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 [ - [ - 'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-send', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - [ - 'privilege' => '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-send', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner().'/calendar-proxy-read', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ], - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php b/lib/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php deleted file mode 100644 index 5bca56d..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php +++ /dev/null @@ -1,1006 +0,0 @@ -server = $server; - $server->on('method:POST', [$this, 'httpPost']); - $server->on('propFind', [$this, 'propFind']); - $server->on('propPatch', [$this, 'propPatch']); - $server->on('calendarObjectChange', [$this, 'calendarObjectChange']); - $server->on('beforeUnbind', [$this, 'beforeUnbind']); - $server->on('schedule', [$this, 'scheduleLocalDelivery']); - $server->on('getSupportedPrivilegeSet', [$this, 'getSupportedPrivilegeSet']); - - $ns = '{'.self::NS_CALDAV.'}'; - - /* - * This information ensures that the {DAV:}resourcetype property has - * the correct values. - */ - $server->resourceTypeMapping['\\Sabre\\CalDAV\\Schedule\\IOutbox'] = $ns.'schedule-outbox'; - $server->resourceTypeMapping['\\Sabre\\CalDAV\\Schedule\\IInbox'] = $ns.'schedule-inbox'; - - /* - * Properties we protect are made read-only by the server. - */ - array_push($server->protectedProperties, - $ns.'schedule-inbox-URL', - $ns.'schedule-outbox-URL', - $ns.'calendar-user-address-set', - $ns.'calendar-user-type', - $ns.'schedule-default-calendar-URL' - ); - } - - /** - * 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 - * available for the specified uri. - * - * @param string $uri - * - * @return array - */ - public function getHTTPMethods($uri) - { - try { - $node = $this->server->tree->getNodeForPath($uri); - } catch (NotFound $e) { - return []; - } - - if ($node instanceof IOutbox) { - return ['POST']; - } - - return []; - } - - /** - * This method handles POST request for the outbox. - * - * @return bool - */ - public function httpPost(RequestInterface $request, ResponseInterface $response) - { - // Checking if this is a text/calendar content type - $contentType = $request->getHeader('Content-Type'); - if (!$contentType || 0 !== strpos($contentType, 'text/calendar')) { - return; - } - - $path = $request->getPath(); - - // Checking if we're talking to an outbox - try { - $node = $this->server->tree->getNodeForPath($path); - } catch (NotFound $e) { - return; - } - if (!$node instanceof IOutbox) { - return; - } - - $this->server->transactionType = 'post-caldav-outbox'; - $this->outboxRequest($node, $request, $response); - - // Returning false breaks the event chain and tells the server we've - // handled the request. - return false; - } - - /** - * This method handler is invoked during fetching of properties. - * - * We use this event to add calendar-auto-schedule-specific properties. - */ - public function propFind(PropFind $propFind, INode $node) - { - if ($node instanceof DAVACL\IPrincipal) { - $caldavPlugin = $this->server->getPlugin('caldav'); - $principalUrl = $node->getPrincipalUrl(); - - // schedule-outbox-URL property - $propFind->handle('{'.self::NS_CALDAV.'}schedule-outbox-URL', function () use ($principalUrl, $caldavPlugin) { - $calendarHomePath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl); - if (!$calendarHomePath) { - return null; - } - $outboxPath = $calendarHomePath.'/outbox/'; - - return new LocalHref($outboxPath); - }); - // schedule-inbox-URL property - $propFind->handle('{'.self::NS_CALDAV.'}schedule-inbox-URL', function () use ($principalUrl, $caldavPlugin) { - $calendarHomePath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl); - if (!$calendarHomePath) { - return null; - } - $inboxPath = $calendarHomePath.'/inbox/'; - - return new LocalHref($inboxPath); - }); - - $propFind->handle('{'.self::NS_CALDAV.'}schedule-default-calendar-URL', function () use ($principalUrl, $caldavPlugin) { - // We don't support customizing this property yet, so in the - // meantime we just grab the first calendar in the home-set. - $calendarHomePath = $caldavPlugin->getCalendarHomeForPrincipal($principalUrl); - - if (!$calendarHomePath) { - return null; - } - - $sccs = '{'.self::NS_CALDAV.'}supported-calendar-component-set'; - - $result = $this->server->getPropertiesForPath($calendarHomePath, [ - '{DAV:}resourcetype', - '{DAV:}share-access', - $sccs, - ], 1); - - foreach ($result as $child) { - if (!isset($child[200]['{DAV:}resourcetype']) || !$child[200]['{DAV:}resourcetype']->is('{'.self::NS_CALDAV.'}calendar')) { - // Node is either not a calendar - continue; - } - if (isset($child[200]['{DAV:}share-access'])) { - $shareAccess = $child[200]['{DAV:}share-access']->getValue(); - if (Sharing\Plugin::ACCESS_NOTSHARED !== $shareAccess && Sharing\Plugin::ACCESS_SHAREDOWNER !== $shareAccess) { - // Node is a shared node, not owned by the relevant - // user. - continue; - } - } - if (!isset($child[200][$sccs]) || in_array('VEVENT', $child[200][$sccs]->getValue())) { - // Either there is no supported-calendar-component-set - // (which is fine) or we found one that supports VEVENT. - return new LocalHref($child['href']); - } - } - }); - - // The server currently reports every principal to be of type - // 'INDIVIDUAL' - $propFind->handle('{'.self::NS_CALDAV.'}calendar-user-type', function () { - return 'INDIVIDUAL'; - }); - } - - // Mapping the old property to the new property. - $propFind->handle('{http://calendarserver.org/ns/}calendar-availability', function () use ($propFind, $node) { - // In case it wasn't clear, the only difference is that we map the - // old property to a different namespace. - $availProp = '{'.self::NS_CALDAV.'}calendar-availability'; - $subPropFind = new PropFind( - $propFind->getPath(), - [$availProp] - ); - - $this->server->getPropertiesByNode( - $subPropFind, - $node - ); - - $propFind->set( - '{http://calendarserver.org/ns/}calendar-availability', - $subPropFind->get($availProp), - $subPropFind->getStatus($availProp) - ); - }); - } - - /** - * This method is called during property updates. - * - * @param string $path - */ - public function propPatch($path, PropPatch $propPatch) - { - // Mapping the old property to the new property. - $propPatch->handle('{http://calendarserver.org/ns/}calendar-availability', function ($value) use ($path) { - $availProp = '{'.self::NS_CALDAV.'}calendar-availability'; - $subPropPatch = new PropPatch([$availProp => $value]); - $this->server->emit('propPatch', [$path, $subPropPatch]); - $subPropPatch->commit(); - - return $subPropPatch->getResult()[$availProp]; - }); - } - - /** - * This method is triggered whenever there was a calendar object gets - * created or updated. - * - * @param RequestInterface $request HTTP request - * @param ResponseInterface $response HTTP Response - * @param VCalendar $vCal Parsed iCalendar object - * @param mixed $calendarPath Path to calendar collection - * @param mixed $modified the iCalendar object has been touched - * @param mixed $isNew Whether this was a new item or we're updating one - */ - public function calendarObjectChange(RequestInterface $request, ResponseInterface $response, VCalendar $vCal, $calendarPath, &$modified, $isNew) - { - if (!$this->scheduleReply($this->server->httpRequest)) { - return; - } - - $calendarNode = $this->server->tree->getNodeForPath($calendarPath); - - $addresses = $this->getAddressesForPrincipal( - $calendarNode->getOwner() - ); - - if (!$isNew) { - $node = $this->server->tree->getNodeForPath($request->getPath()); - $oldObj = Reader::read($node->get()); - } else { - $oldObj = null; - } - - $this->processICalendarChange($oldObj, $vCal, $addresses, [], $modified); - - if ($oldObj) { - // Destroy circular references so PHP will GC the object. - $oldObj->destroy(); - } - } - - /** - * This method is responsible for delivering the ITip message. - */ - public function deliver(ITip\Message $iTipMessage) - { - $this->server->emit('schedule', [$iTipMessage]); - if (!$iTipMessage->scheduleStatus) { - $iTipMessage->scheduleStatus = '5.2;There was no system capable of delivering the scheduling message'; - } - // In case the change was considered 'insignificant', we are going to - // remove any error statuses, if any. See ticket #525. - list($baseCode) = explode('.', $iTipMessage->scheduleStatus); - if (!$iTipMessage->significantChange && in_array($baseCode, ['3', '5'])) { - $iTipMessage->scheduleStatus = null; - } - } - - /** - * This method is triggered before a file gets deleted. - * - * We use this event to make sure that when this happens, attendees get - * cancellations, and organizers get 'DECLINED' statuses. - * - * @param string $path - */ - public function beforeUnbind($path) - { - // FIXME: We shouldn't trigger this functionality when we're issuing a - // MOVE. This is a hack. - if ('MOVE' === $this->server->httpRequest->getMethod()) { - return; - } - - $node = $this->server->tree->getNodeForPath($path); - - if (!$node instanceof ICalendarObject || $node instanceof ISchedulingObject) { - return; - } - - if (!$this->scheduleReply($this->server->httpRequest)) { - return; - } - - $addresses = $this->getAddressesForPrincipal( - $node->getOwner() - ); - - $broker = $this->createITipBroker(); - $messages = $broker->parseEvent(null, $addresses, $node->get()); - - foreach ($messages as $message) { - $this->deliver($message); - } - } - - /** - * Event handler for the 'schedule' event. - * - * This handler attempts to look at local accounts to deliver the - * scheduling object. - */ - public function scheduleLocalDelivery(ITip\Message $iTipMessage) - { - $aclPlugin = $this->server->getPlugin('acl'); - - // Local delivery is not available if the ACL plugin is not loaded. - if (!$aclPlugin) { - return; - } - - $caldavNS = '{'.self::NS_CALDAV.'}'; - - $principalUri = $aclPlugin->getPrincipalByUri($iTipMessage->recipient); - if (!$principalUri) { - $iTipMessage->scheduleStatus = '3.7;Could not find principal.'; - - return; - } - - // We found a principal URL, now we need to find its inbox. - // Unfortunately we may not have sufficient privileges to find this, so - // we are temporarily turning off ACL to let this come through. - // - // Once we support PHP 5.5, this should be wrapped in a try..finally - // block so we can ensure that this privilege gets added again after. - $this->server->removeListener('propFind', [$aclPlugin, 'propFind']); - - $result = $this->server->getProperties( - $principalUri, - [ - '{DAV:}principal-URL', - $caldavNS.'calendar-home-set', - $caldavNS.'schedule-inbox-URL', - $caldavNS.'schedule-default-calendar-URL', - '{http://sabredav.org/ns}email-address', - ] - ); - - // Re-registering the ACL event - $this->server->on('propFind', [$aclPlugin, 'propFind'], 20); - - if (!isset($result[$caldavNS.'schedule-inbox-URL'])) { - $iTipMessage->scheduleStatus = '5.2;Could not find local inbox'; - - return; - } - if (!isset($result[$caldavNS.'calendar-home-set'])) { - $iTipMessage->scheduleStatus = '5.2;Could not locate a calendar-home-set'; - - return; - } - if (!isset($result[$caldavNS.'schedule-default-calendar-URL'])) { - $iTipMessage->scheduleStatus = '5.2;Could not find a schedule-default-calendar-URL property'; - - return; - } - - $calendarPath = $result[$caldavNS.'schedule-default-calendar-URL']->getHref(); - $homePath = $result[$caldavNS.'calendar-home-set']->getHref(); - $inboxPath = $result[$caldavNS.'schedule-inbox-URL']->getHref(); - - if ('REPLY' === $iTipMessage->method) { - $privilege = 'schedule-deliver-reply'; - } else { - $privilege = 'schedule-deliver-invite'; - } - - if (!$aclPlugin->checkPrivileges($inboxPath, $caldavNS.$privilege, DAVACL\Plugin::R_PARENT, false)) { - $iTipMessage->scheduleStatus = '3.8;insufficient privileges: '.$privilege.' is required on the recipient schedule inbox.'; - - return; - } - - // Next, we're going to find out if the item already exits in one of - // the users' calendars. - $uid = $iTipMessage->uid; - - $newFileName = 'sabredav-'.\Sabre\DAV\UUIDUtil::getUUID().'.ics'; - - $home = $this->server->tree->getNodeForPath($homePath); - $inbox = $this->server->tree->getNodeForPath($inboxPath); - - $currentObject = null; - $objectNode = null; - $oldICalendarData = null; - $isNewNode = false; - - $result = $home->getCalendarObjectByUID($uid); - if ($result) { - // There was an existing object, we need to update probably. - $objectPath = $homePath.'/'.$result; - $objectNode = $this->server->tree->getNodeForPath($objectPath); - $oldICalendarData = $objectNode->get(); - $currentObject = Reader::read($oldICalendarData); - } else { - $isNewNode = true; - } - - $broker = $this->createITipBroker(); - $newObject = $broker->processMessage($iTipMessage, $currentObject); - - $inbox->createFile($newFileName, $iTipMessage->message->serialize()); - - if (!$newObject) { - // We received an iTip message referring to a UID that we don't - // have in any calendars yet, and processMessage did not give us a - // calendarobject back. - // - // The implication is that processMessage did not understand the - // iTip message. - $iTipMessage->scheduleStatus = '5.0;iTip message was not processed by the server, likely because we didn\'t understand it.'; - - return; - } - - // Note that we are bypassing ACL on purpose by calling this directly. - // We may need to look a bit deeper into this later. Supporting ACL - // here would be nice. - if ($isNewNode) { - $calendar = $this->server->tree->getNodeForPath($calendarPath); - $calendar->createFile($newFileName, $newObject->serialize()); - } else { - // If the message was a reply, we may have to inform other - // attendees of this attendees status. Therefore we're shooting off - // another itipMessage. - if ('REPLY' === $iTipMessage->method) { - $this->processICalendarChange( - $oldICalendarData, - $newObject, - [$iTipMessage->recipient], - [$iTipMessage->sender] - ); - } - $objectNode->put($newObject->serialize()); - } - $iTipMessage->scheduleStatus = '1.2;Message delivered locally'; - } - - /** - * This method is triggered whenever a subsystem requests the privileges - * that are supported on a particular node. - * - * We need to add a number of privileges for scheduling purposes. - */ - public function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilegeSet) - { - $ns = '{'.self::NS_CALDAV.'}'; - if ($node instanceof IOutbox) { - $supportedPrivilegeSet[$ns.'schedule-send'] = [ - 'abstract' => false, - 'aggregates' => [ - $ns.'schedule-send-invite' => [ - 'abstract' => false, - 'aggregates' => [], - ], - $ns.'schedule-send-reply' => [ - 'abstract' => false, - 'aggregates' => [], - ], - $ns.'schedule-send-freebusy' => [ - 'abstract' => false, - 'aggregates' => [], - ], - // Privilege from an earlier scheduling draft, but still - // used by some clients. - $ns.'schedule-post-vevent' => [ - 'abstract' => false, - 'aggregates' => [], - ], - ], - ]; - } - if ($node instanceof IInbox) { - $supportedPrivilegeSet[$ns.'schedule-deliver'] = [ - 'abstract' => false, - 'aggregates' => [ - $ns.'schedule-deliver-invite' => [ - 'abstract' => false, - 'aggregates' => [], - ], - $ns.'schedule-deliver-reply' => [ - 'abstract' => false, - 'aggregates' => [], - ], - $ns.'schedule-query-freebusy' => [ - 'abstract' => false, - 'aggregates' => [], - ], - ], - ]; - } - } - - /** - * This method looks at an old iCalendar object, a new iCalendar object and - * starts sending scheduling messages based on the changes. - * - * A list of addresses needs to be specified, so the system knows who made - * the update, because the behavior may be different based on if it's an - * attendee or an organizer. - * - * This method may update $newObject to add any status changes. - * - * @param VCalendar|string|null $oldObject - * @param array $ignore any addresses to not send messages to - * @param bool $modified a marker to indicate that the original object modified by this process - */ - protected function processICalendarChange($oldObject, VCalendar $newObject, array $addresses, array $ignore = [], &$modified = false) - { - $broker = $this->createITipBroker(); - $messages = $broker->parseEvent($newObject, $addresses, $oldObject); - - if ($messages) { - $modified = true; - } - - foreach ($messages as $message) { - if (in_array($message->recipient, $ignore)) { - continue; - } - - $this->deliver($message); - - if (isset($newObject->VEVENT->ORGANIZER) && ($newObject->VEVENT->ORGANIZER->getNormalizedValue() === $message->recipient)) { - if ($message->scheduleStatus) { - $newObject->VEVENT->ORGANIZER['SCHEDULE-STATUS'] = $message->getScheduleStatus(); - } - unset($newObject->VEVENT->ORGANIZER['SCHEDULE-FORCE-SEND']); - } else { - if (isset($newObject->VEVENT->ATTENDEE)) { - foreach ($newObject->VEVENT->ATTENDEE as $attendee) { - if ($attendee->getNormalizedValue() === $message->recipient) { - if ($message->scheduleStatus) { - $attendee['SCHEDULE-STATUS'] = $message->getScheduleStatus(); - } - unset($attendee['SCHEDULE-FORCE-SEND']); - break; - } - } - } - } - } - } - - /** - * Returns a list of addresses that are associated with a principal. - * - * @param string $principal - * - * @return array - */ - protected function getAddressesForPrincipal($principal) - { - $CUAS = '{'.self::NS_CALDAV.'}calendar-user-address-set'; - - $properties = $this->server->getProperties( - $principal, - [$CUAS] - ); - - // If we can't find this information, we'll stop processing - if (!isset($properties[$CUAS])) { - return []; - } - - $addresses = $properties[$CUAS]->getHrefs(); - - return $addresses; - } - - /** - * This method handles POST requests to the schedule-outbox. - * - * Currently, two types of requests are supported: - * * FREEBUSY requests from RFC 6638 - * * Simple iTIP messages from draft-desruisseaux-caldav-sched-04 - * - * The latter is from an expired early draft of the CalDAV scheduling - * extensions, but iCal depends on a feature from that spec, so we - * implement it. - */ - public function outboxRequest(IOutbox $outboxNode, RequestInterface $request, ResponseInterface $response) - { - $outboxPath = $request->getPath(); - - // Parsing the request body - try { - $vObject = VObject\Reader::read($request->getBody()); - } catch (VObject\ParseException $e) { - throw new BadRequest('The request body must be a valid iCalendar object. Parse error: '.$e->getMessage()); - } - - // The incoming iCalendar object must have a METHOD property, and a - // component. The combination of both determines what type of request - // this is. - $componentType = null; - foreach ($vObject->getComponents() as $component) { - if ('VTIMEZONE' !== $component->name) { - $componentType = $component->name; - break; - } - } - if (is_null($componentType)) { - throw new BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component'); - } - - // Validating the METHOD - $method = strtoupper((string) $vObject->METHOD); - if (!$method) { - throw new BadRequest('A METHOD property must be specified in iTIP messages'); - } - - // So we support one type of request: - // - // REQUEST with a VFREEBUSY component - - $acl = $this->server->getPlugin('acl'); - - if ('VFREEBUSY' === $componentType && 'REQUEST' === $method) { - $acl && $acl->checkPrivileges($outboxPath, '{'.self::NS_CALDAV.'}schedule-send-freebusy'); - $this->handleFreeBusyRequest($outboxNode, $vObject, $request, $response); - - // Destroy circular references so PHP can GC the object. - $vObject->destroy(); - unset($vObject); - } else { - throw new NotImplemented('We only support VFREEBUSY (REQUEST) on this endpoint'); - } - } - - /** - * This method is responsible for parsing a free-busy query request and - * returning its result in $response. - */ - protected function handleFreeBusyRequest(IOutbox $outbox, VObject\Component $vObject, RequestInterface $request, ResponseInterface $response) - { - $vFreeBusy = $vObject->VFREEBUSY; - $organizer = $vFreeBusy->ORGANIZER; - - $organizer = (string) $organizer; - - // Validating if the organizer matches the owner of the inbox. - $owner = $outbox->getOwner(); - - $caldavNS = '{'.self::NS_CALDAV.'}'; - - $uas = $caldavNS.'calendar-user-address-set'; - $props = $this->server->getProperties($owner, [$uas]); - - if (empty($props[$uas]) || !in_array($organizer, $props[$uas]->getHrefs())) { - throw new Forbidden('The organizer in the request did not match any of the addresses for the owner of this inbox'); - } - - if (!isset($vFreeBusy->ATTENDEE)) { - throw new BadRequest('You must at least specify 1 attendee'); - } - - $attendees = []; - foreach ($vFreeBusy->ATTENDEE as $attendee) { - $attendees[] = (string) $attendee; - } - - if (!isset($vFreeBusy->DTSTART) || !isset($vFreeBusy->DTEND)) { - throw new BadRequest('DTSTART and DTEND must both be specified'); - } - - $startRange = $vFreeBusy->DTSTART->getDateTime(); - $endRange = $vFreeBusy->DTEND->getDateTime(); - - $results = []; - foreach ($attendees as $attendee) { - $results[] = $this->getFreeBusyForEmail($attendee, $startRange, $endRange, $vObject); - } - - $dom = new \DOMDocument('1.0', 'utf-8'); - $dom->formatOutput = true; - $scheduleResponse = $dom->createElement('cal:schedule-response'); - foreach ($this->server->xml->namespaceMap as $namespace => $prefix) { - $scheduleResponse->setAttribute('xmlns:'.$prefix, $namespace); - } - $dom->appendChild($scheduleResponse); - - foreach ($results as $result) { - $xresponse = $dom->createElement('cal:response'); - - $recipient = $dom->createElement('cal:recipient'); - $recipientHref = $dom->createElement('d:href'); - - $recipientHref->appendChild($dom->createTextNode($result['href'])); - $recipient->appendChild($recipientHref); - $xresponse->appendChild($recipient); - - $reqStatus = $dom->createElement('cal:request-status'); - $reqStatus->appendChild($dom->createTextNode($result['request-status'])); - $xresponse->appendChild($reqStatus); - - if (isset($result['calendar-data'])) { - $calendardata = $dom->createElement('cal:calendar-data'); - $calendardata->appendChild($dom->createTextNode(str_replace("\r\n", "\n", $result['calendar-data']->serialize()))); - $xresponse->appendChild($calendardata); - } - $scheduleResponse->appendChild($xresponse); - } - - $response->setStatus(200); - $response->setHeader('Content-Type', 'application/xml'); - $response->setBody($dom->saveXML()); - } - - /** - * Returns free-busy information for a specific address. The returned - * data is an array containing the following properties:. - * - * calendar-data : A VFREEBUSY VObject - * request-status : an iTip status code. - * href: The principal's email address, as requested - * - * The following request status codes may be returned: - * * 2.0;description - * * 3.7;description - * - * @param string $email address - * - * @return array - */ - protected function getFreeBusyForEmail($email, \DateTimeInterface $start, \DateTimeInterface $end, VObject\Component $request) - { - $caldavNS = '{'.self::NS_CALDAV.'}'; - - $aclPlugin = $this->server->getPlugin('acl'); - if ('mailto:' === substr($email, 0, 7)) { - $email = substr($email, 7); - } - - $result = $aclPlugin->principalSearch( - ['{http://sabredav.org/ns}email-address' => $email], - [ - '{DAV:}principal-URL', - $caldavNS.'calendar-home-set', - $caldavNS.'schedule-inbox-URL', - '{http://sabredav.org/ns}email-address', - ] - ); - - if (!count($result)) { - return [ - 'request-status' => '3.7;Could not find principal', - 'href' => 'mailto:'.$email, - ]; - } - - if (!isset($result[0][200][$caldavNS.'calendar-home-set'])) { - return [ - 'request-status' => '3.7;No calendar-home-set property found', - 'href' => 'mailto:'.$email, - ]; - } - if (!isset($result[0][200][$caldavNS.'schedule-inbox-URL'])) { - return [ - 'request-status' => '3.7;No schedule-inbox-URL property found', - 'href' => 'mailto:'.$email, - ]; - } - $homeSet = $result[0][200][$caldavNS.'calendar-home-set']->getHref(); - $inboxUrl = $result[0][200][$caldavNS.'schedule-inbox-URL']->getHref(); - - // Do we have permission? - $aclPlugin->checkPrivileges($inboxUrl, $caldavNS.'schedule-query-freebusy'); - - // Grabbing the calendar list - $objects = []; - $calendarTimeZone = new DateTimeZone('UTC'); - - foreach ($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) { - if (!$node instanceof ICalendar) { - continue; - } - - $sct = $caldavNS.'schedule-calendar-transp'; - $ctz = $caldavNS.'calendar-timezone'; - $props = $node->getProperties([$sct, $ctz]); - - if (isset($props[$sct]) && ScheduleCalendarTransp::TRANSPARENT == $props[$sct]->getValue()) { - // If a calendar is marked as 'transparent', it means we must - // ignore it for free-busy purposes. - continue; - } - - if (isset($props[$ctz])) { - $vtimezoneObj = VObject\Reader::read($props[$ctz]); - $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); - - // Destroy circular references so PHP can garbage collect the object. - $vtimezoneObj->destroy(); - } - - // Getting the list of object uris within the time-range - $urls = $node->calendarQuery([ - 'name' => 'VCALENDAR', - 'comp-filters' => [ - [ - 'name' => 'VEVENT', - 'comp-filters' => [], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => [ - 'start' => $start, - 'end' => $end, - ], - ], - ], - 'prop-filters' => [], - 'is-not-defined' => false, - 'time-range' => null, - ]); - - $calObjects = array_map(function ($url) use ($node) { - $obj = $node->getChild($url)->get(); - - return $obj; - }, $urls); - - $objects = array_merge($objects, $calObjects); - } - - $inboxProps = $this->server->getProperties( - $inboxUrl, - $caldavNS.'calendar-availability' - ); - - $vcalendar = new VObject\Component\VCalendar(); - $vcalendar->METHOD = 'REPLY'; - - $generator = new VObject\FreeBusyGenerator(); - $generator->setObjects($objects); - $generator->setTimeRange($start, $end); - $generator->setBaseObject($vcalendar); - $generator->setTimeZone($calendarTimeZone); - - if ($inboxProps) { - $generator->setVAvailability( - VObject\Reader::read( - $inboxProps[$caldavNS.'calendar-availability'] - ) - ); - } - - $result = $generator->getResult(); - - $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:'.$email; - $vcalendar->VFREEBUSY->UID = (string) $request->VFREEBUSY->UID; - $vcalendar->VFREEBUSY->ORGANIZER = clone $request->VFREEBUSY->ORGANIZER; - - return [ - 'calendar-data' => $result, - 'request-status' => '2.0;Success', - 'href' => 'mailto:'.$email, - ]; - } - - /** - * This method checks the 'Schedule-Reply' header - * and returns false if it's 'F', otherwise true. - * - * @return bool - */ - protected function scheduleReply(RequestInterface $request) - { - $scheduleReply = $request->getHeader('Schedule-Reply'); - - return 'F' !== $scheduleReply; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds calendar-auto-schedule, as defined in rfc6638', - 'link' => 'http://sabre.io/dav/scheduling/', - ]; - } - - /** - * Returns an instance of the iTip\Broker. - */ - protected function createITipBroker(): Broker - { - return new Broker(); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php b/lib/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php deleted file mode 100644 index b40f28a..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php +++ /dev/null @@ -1,130 +0,0 @@ -objectData['calendardata'])) { - $this->objectData = $this->caldavBackend->getSchedulingObject($this->objectData['principaluri'], $this->objectData['uri']); - } - - return $this->objectData['calendardata']; - } - - /** - * Updates the ICalendar-formatted object. - * - * @param string|resource $calendarData - * - * @return string - */ - public function put($calendarData) - { - throw new MethodNotAllowed('Updating scheduling objects is not supported'); - } - - /** - * Deletes the scheduling message. - */ - public function delete() - { - $this->caldavBackend->deleteSchedulingObject($this->objectData['principaluri'], $this->objectData['uri']); - } - - /** - * 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->objectData['principaluri']; - } - - /** - * 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() - { - // An alternative acl may be specified in the object data. - // - - if (isset($this->objectData['acl'])) { - return $this->objectData['acl']; - } - - // The default ACL - return [ - [ - 'privilege' => '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}all', - 'principal' => $this->objectData['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->objectData['principaluri'].'/calendar-proxy-read', - 'protected' => true, - ], - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php b/lib/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php deleted file mode 100644 index 818392f..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php +++ /dev/null @@ -1,219 +0,0 @@ -calendarInfo['share-access']) ? $this->calendarInfo['share-access'] : SPlugin::ACCESS_NOTSHARED; - } - - /** - * This function must return a URI that uniquely identifies the shared - * resource. This URI should be identical across instances, and is - * also used in several other XML bodies to connect invites to - * resources. - * - * This may simply be a relative reference to the original shared instance, - * but it could also be a urn. As long as it's a valid URI and unique. - * - * @return string - */ - public function getShareResourceUri() - { - return $this->calendarInfo['share-resource-uri']; - } - - /** - * Updates the list of sharees. - * - * Every item must be a Sharee object. - * - * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees - */ - public function updateInvites(array $sharees) - { - $this->caldavBackend->updateInvites($this->calendarInfo['id'], $sharees); - } - - /** - * Returns the list of people whom this resource is shared with. - * - * Every item in the returned array must be a Sharee object with - * at least the following properties set: - * - * * $href - * * $shareAccess - * * $inviteStatus - * - * and optionally: - * - * * $properties - * - * @return \Sabre\DAV\Xml\Element\Sharee[] - */ - public function getInvites() - { - return $this->caldavBackend->getInvites($this->calendarInfo['id']); - } - - /** - * Marks this calendar as published. - * - * Publishing a calendar should automatically create a read-only, public, - * subscribable calendar. - * - * @param bool $value - */ - public function setPublishStatus($value) - { - $this->caldavBackend->setPublishStatus($this->calendarInfo['id'], $value); - } - - /** - * 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() - { - $acl = []; - - switch ($this->getShareAccess()) { - case SPlugin::ACCESS_NOTSHARED: - case SPlugin::ACCESS_SHAREDOWNER: - $acl[] = [ - 'privilege' => '{DAV:}share', - 'principal' => $this->calendarInfo['principaluri'], - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}share', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ]; - // no break intentional! - case SPlugin::ACCESS_READWRITE: - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->calendarInfo['principaluri'], - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ]; - // no break intentional! - case SPlugin::ACCESS_READ: - $acl[] = [ - 'privilege' => '{DAV:}write-properties', - 'principal' => $this->calendarInfo['principaluri'], - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}write-properties', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->calendarInfo['principaluri'], - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-read', - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{'.Plugin::NS_CALDAV.'}read-free-busy', - 'principal' => '{DAV:}authenticated', - 'protected' => true, - ]; - break; - } - - return $acl; - } - - /** - * This method returns the ACL's for calendar objects in this calendar. - * The result of this method automatically gets passed to the - * calendar-object nodes in the calendar. - * - * @return array - */ - public function getChildACL() - { - $acl = []; - - switch ($this->getShareAccess()) { - case SPlugin::ACCESS_NOTSHARED: - case SPlugin::ACCESS_SHAREDOWNER: - case SPlugin::ACCESS_READWRITE: - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->calendarInfo['principaluri'], - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}write', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ]; - // no break intentional - case SPlugin::ACCESS_READ: - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->calendarInfo['principaluri'], - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-write', - 'protected' => true, - ]; - $acl[] = [ - 'privilege' => '{DAV:}read', - 'principal' => $this->calendarInfo['principaluri'].'/calendar-proxy-read', - 'protected' => true, - ]; - break; - } - - return $acl; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php b/lib/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php deleted file mode 100644 index bacfe04..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php +++ /dev/null @@ -1,346 +0,0 @@ -server = $server; - - if (is_null($this->server->getPlugin('sharing'))) { - throw new \LogicException('The generic "sharing" plugin must be loaded before the caldav sharing plugin. Call $server->addPlugin(new \Sabre\DAV\Sharing\Plugin()); before this one.'); - } - - array_push( - $this->server->protectedProperties, - '{'.Plugin::NS_CALENDARSERVER.'}invite', - '{'.Plugin::NS_CALENDARSERVER.'}allowed-sharing-modes', - '{'.Plugin::NS_CALENDARSERVER.'}shared-url' - ); - - $this->server->xml->elementMap['{'.Plugin::NS_CALENDARSERVER.'}share'] = 'Sabre\\CalDAV\\Xml\\Request\\Share'; - $this->server->xml->elementMap['{'.Plugin::NS_CALENDARSERVER.'}invite-reply'] = 'Sabre\\CalDAV\\Xml\\Request\\InviteReply'; - - $this->server->on('propFind', [$this, 'propFindEarly']); - $this->server->on('propFind', [$this, 'propFindLate'], 150); - $this->server->on('propPatch', [$this, 'propPatch'], 40); - $this->server->on('method:POST', [$this, 'httpPost']); - } - - /** - * This event is triggered when properties are requested for a certain - * node. - * - * This allows us to inject any properties early. - */ - public function propFindEarly(DAV\PropFind $propFind, DAV\INode $node) - { - if ($node instanceof ISharedCalendar) { - $propFind->handle('{'.Plugin::NS_CALENDARSERVER.'}invite', function () use ($node) { - return new Xml\Property\Invite( - $node->getInvites() - ); - }); - } - } - - /** - * This method is triggered *after* all properties have been retrieved. - * This allows us to inject the correct resourcetype for calendars that - * have been shared. - */ - public function propFindLate(DAV\PropFind $propFind, DAV\INode $node) - { - if ($node instanceof ISharedCalendar) { - $shareAccess = $node->getShareAccess(); - if ($rt = $propFind->get('{DAV:}resourcetype')) { - switch ($shareAccess) { - case \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER: - $rt->add('{'.Plugin::NS_CALENDARSERVER.'}shared-owner'); - break; - case \Sabre\DAV\Sharing\Plugin::ACCESS_READ: - case \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE: - $rt->add('{'.Plugin::NS_CALENDARSERVER.'}shared'); - break; - } - } - $propFind->handle('{'.Plugin::NS_CALENDARSERVER.'}allowed-sharing-modes', function () { - return new Xml\Property\AllowedSharingModes(true, false); - }); - } - } - - /** - * This method is triggered when a user attempts to update a node's - * properties. - * - * A previous draft of the sharing spec stated that it was possible to use - * PROPPATCH to remove 'shared-owner' from the resourcetype, thus unsharing - * the calendar. - * - * Even though this is no longer in the current spec, we keep this around - * because OS X 10.7 may still make use of this feature. - * - * @param string $path - */ - public function propPatch($path, DAV\PropPatch $propPatch) - { - $node = $this->server->tree->getNodeForPath($path); - if (!$node instanceof ISharedCalendar) { - return; - } - - if (\Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER === $node->getShareAccess() || \Sabre\DAV\Sharing\Plugin::ACCESS_NOTSHARED === $node->getShareAccess()) { - $propPatch->handle('{DAV:}resourcetype', function ($value) use ($node) { - if ($value->is('{'.Plugin::NS_CALENDARSERVER.'}shared-owner')) { - return false; - } - $shares = $node->getInvites(); - foreach ($shares as $share) { - $share->access = DAV\Sharing\Plugin::ACCESS_NOACCESS; - } - $node->updateInvites($shares); - - return true; - }); - } - } - - /** - * We intercept this to handle POST requests on calendars. - * - * @return bool|null - */ - public function httpPost(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - // Only handling xml - $contentType = $request->getHeader('Content-Type'); - if (null === $contentType) { - return; - } - if (false === strpos($contentType, 'application/xml') && false === strpos($contentType, 'text/xml')) { - return; - } - - // Making sure the node exists - try { - $node = $this->server->tree->getNodeForPath($path); - } catch (DAV\Exception\NotFound $e) { - return; - } - - $requestBody = $request->getBodyAsString(); - - // If this request handler could not deal with this POST request, it - // will return 'null' and other plugins get a chance to handle the - // request. - // - // However, we already requested the full body. This is a problem, - // because a body can only be read once. This is why we preemptively - // re-populated the request body with the existing data. - $request->setBody($requestBody); - - $message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType); - - switch ($documentType) { - // Both the DAV:share-resource and CALENDARSERVER:share requests - // behave identically. - case '{'.Plugin::NS_CALENDARSERVER.'}share': - $sharingPlugin = $this->server->getPlugin('sharing'); - $sharingPlugin->shareResource($path, $message->sharees); - - $response->setStatus(200); - // Adding this because sending a response body may cause issues, - // and I wanted some type of indicator the response was handled. - $response->setHeader('X-Sabre-Status', 'everything-went-well'); - - // Breaking the event chain - return false; - - // The invite-reply document is sent when the user replies to an - // invitation of a calendar share. - case '{'.Plugin::NS_CALENDARSERVER.'}invite-reply': - // This only works on the calendar-home-root node. - if (!$node instanceof CalendarHome) { - return; - } - $this->server->transactionType = 'post-invite-reply'; - - // Getting ACL info - $acl = $this->server->getPlugin('acl'); - - // If there's no ACL support, we allow everything - if ($acl) { - $acl->checkPrivileges($path, '{DAV:}write'); - } - - $url = $node->shareReply( - $message->href, - $message->status, - $message->calendarUri, - $message->inReplyTo, - $message->summary - ); - - $response->setStatus(200); - // Adding this because sending a response body may cause issues, - // and I wanted some type of indicator the response was handled. - $response->setHeader('X-Sabre-Status', 'everything-went-well'); - - if ($url) { - $writer = $this->server->xml->getWriter(); - $writer->contextUri = $request->getUrl(); - $writer->openMemory(); - $writer->startDocument(); - $writer->startElement('{'.Plugin::NS_CALENDARSERVER.'}shared-as'); - $writer->write(new LocalHref($url)); - $writer->endElement(); - $response->setHeader('Content-Type', 'application/xml'); - $response->setBody($writer->outputMemory()); - } - - // Breaking the event chain - return false; - - case '{'.Plugin::NS_CALENDARSERVER.'}publish-calendar': - // We can only deal with IShareableCalendar objects - if (!$node instanceof ISharedCalendar) { - return; - } - $this->server->transactionType = 'post-publish-calendar'; - - // Getting ACL info - $acl = $this->server->getPlugin('acl'); - - // If there's no ACL support, we allow everything - if ($acl) { - $acl->checkPrivileges($path, '{DAV:}share'); - } - - $node->setPublishStatus(true); - - // iCloud sends back the 202, so we will too. - $response->setStatus(202); - - // Adding this because sending a response body may cause issues, - // and I wanted some type of indicator the response was handled. - $response->setHeader('X-Sabre-Status', 'everything-went-well'); - - // Breaking the event chain - return false; - - case '{'.Plugin::NS_CALENDARSERVER.'}unpublish-calendar': - // We can only deal with IShareableCalendar objects - if (!$node instanceof ISharedCalendar) { - return; - } - $this->server->transactionType = 'post-unpublish-calendar'; - - // Getting ACL info - $acl = $this->server->getPlugin('acl'); - - // If there's no ACL support, we allow everything - if ($acl) { - $acl->checkPrivileges($path, '{DAV:}share'); - } - - $node->setPublishStatus(false); - - $response->setStatus(200); - - // Adding this because sending a response body may cause issues, - // and I wanted some type of indicator the response was handled. - $response->setHeader('X-Sabre-Status', 'everything-went-well'); - - // Breaking the event chain - return false; - } - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds support for caldav-sharing.', - 'link' => 'http://sabre.io/dav/caldav-sharing/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php b/lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php deleted file mode 100644 index e83082c..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/ISubscription.php +++ /dev/null @@ -1,41 +0,0 @@ -resourceTypeMapping['Sabre\\CalDAV\\Subscriptions\\ISubscription'] = - '{http://calendarserver.org/ns/}subscribed'; - - $server->xml->elementMap['{http://calendarserver.org/ns/}source'] = - 'Sabre\\DAV\\Xml\\Property\\Href'; - - $server->on('propFind', [$this, 'propFind'], 150); - } - - /** - * 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() - { - return ['calendarserver-subscribed']; - } - - /** - * Triggered after properties have been fetched. - */ - public function propFind(PropFind $propFind, INode $node) - { - // There's a bunch of properties that must appear as a self-closing - // xml-element. This event handler ensures that this will be the case. - $props = [ - '{http://calendarserver.org/ns/}subscribed-strip-alarms', - '{http://calendarserver.org/ns/}subscribed-strip-attachments', - '{http://calendarserver.org/ns/}subscribed-strip-todos', - ]; - - foreach ($props as $prop) { - if (200 === $propFind->getStatus($prop)) { - $propFind->set($prop, '', 200); - } - } - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using \Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'subscriptions'; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'This plugin allows users to store iCalendar subscriptions in their calendar-home.', - 'link' => null, - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php b/lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php deleted file mode 100644 index 8d56e64..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php +++ /dev/null @@ -1,204 +0,0 @@ -caldavBackend = $caldavBackend; - $this->subscriptionInfo = $subscriptionInfo; - - $required = [ - 'id', - 'uri', - 'principaluri', - 'source', - ]; - - foreach ($required as $r) { - if (!isset($subscriptionInfo[$r])) { - throw new \InvalidArgumentException('The '.$r.' field is required when creating a subscription node'); - } - } - } - - /** - * Returns the name of the node. - * - * This is used to generate the url. - * - * @return string - */ - public function getName() - { - return $this->subscriptionInfo['uri']; - } - - /** - * Returns the last modification time. - * - * @return int|null - */ - public function getLastModified() - { - if (isset($this->subscriptionInfo['lastmodified'])) { - return $this->subscriptionInfo['lastmodified']; - } - } - - /** - * Deletes the current node. - */ - public function delete() - { - $this->caldavBackend->deleteSubscription( - $this->subscriptionInfo['id'] - ); - } - - /** - * Returns an array with all the child nodes. - * - * @return \Sabre\DAV\INode[] - */ - public function getChildren() - { - return []; - } - - /** - * Updates properties on this node. - * - * This method received a PropPatch object, which contains all the - * information about the update. - * - * To update specific properties, call the 'handle' method on this object. - * Read the PropPatch documentation for more information. - */ - public function propPatch(PropPatch $propPatch) - { - return $this->caldavBackend->updateSubscription( - $this->subscriptionInfo['id'], - $propPatch - ); - } - - /** - * Returns a list of properties for this nodes. - * - * The properties list is a list of propertynames the client requested, - * encoded in clark-notation {xmlnamespace}tagname. - * - * If the array is empty, it means 'all properties' were requested. - * - * Note that it's fine to liberally give properties back, instead of - * conforming to the list of requested properties. - * The Server class will filter out the extra. - * - * @param array $properties - * - * @return array - */ - public function getProperties($properties) - { - $r = []; - - foreach ($properties as $prop) { - switch ($prop) { - case '{http://calendarserver.org/ns/}source': - $r[$prop] = new Href($this->subscriptionInfo['source']); - break; - default: - if (array_key_exists($prop, $this->subscriptionInfo)) { - $r[$prop] = $this->subscriptionInfo[$prop]; - } - break; - } - } - - return $r; - } - - /** - * 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->subscriptionInfo['principaluri']; - } - - /** - * 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 [ - [ - 'privilege' => '{DAV:}all', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}all', - 'principal' => $this->getOwner().'/calendar-proxy-write', - 'protected' => true, - ], - [ - 'privilege' => '{DAV:}read', - 'principal' => $this->getOwner().'/calendar-proxy-read', - 'protected' => true, - ], - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php deleted file mode 100644 index c9656d8..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CalendarData.php +++ /dev/null @@ -1,80 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = [ - 'contentType' => $reader->getAttribute('content-type') ?: 'text/calendar', - 'version' => $reader->getAttribute('version') ?: '2.0', - ]; - - $elems = (array) $reader->parseInnerTree(); - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{'.Plugin::NS_CALDAV.'}expand': - $result['expand'] = [ - 'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, - 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null, - ]; - - if (!$result['expand']['start'] || !$result['expand']['end']) { - throw new BadRequest('The "start" and "end" attributes are required when expanding calendar-data'); - } - if ($result['expand']['end'] <= $result['expand']['start']) { - throw new BadRequest('The end-date must be larger than the start-date when expanding calendar-data'); - } - break; - } - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php deleted file mode 100644 index 929000b..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/CompFilter.php +++ /dev/null @@ -1,94 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = [ - 'name' => null, - 'is-not-defined' => false, - 'comp-filters' => [], - 'prop-filters' => [], - 'time-range' => false, - ]; - - $att = $reader->parseAttributes(); - $result['name'] = $att['name']; - - $elems = $reader->parseInnerTree(); - - if (is_array($elems)) { - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{'.Plugin::NS_CALDAV.'}comp-filter': - $result['comp-filters'][] = $elem['value']; - break; - case '{'.Plugin::NS_CALDAV.'}prop-filter': - $result['prop-filters'][] = $elem['value']; - break; - case '{'.Plugin::NS_CALDAV.'}is-not-defined': - $result['is-not-defined'] = true; - break; - case '{'.Plugin::NS_CALDAV.'}time-range': - if ('VCALENDAR' === $result['name']) { - throw new BadRequest('You cannot add time-range filters on the VCALENDAR component'); - } - $result['time-range'] = [ - 'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, - 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null, - ]; - if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) { - throw new BadRequest('The end-date must be larger than the start-date'); - } - break; - } - } - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php deleted file mode 100644 index 1e6dd59..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/ParamFilter.php +++ /dev/null @@ -1,79 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = [ - 'name' => null, - 'is-not-defined' => false, - 'text-match' => null, - ]; - - $att = $reader->parseAttributes(); - $result['name'] = $att['name']; - - $elems = $reader->parseInnerTree(); - - if (is_array($elems)) { - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{'.Plugin::NS_CALDAV.'}is-not-defined': - $result['is-not-defined'] = true; - break; - case '{'.Plugin::NS_CALDAV.'}text-match': - $result['text-match'] = [ - 'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'], - 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap', - 'value' => $elem['value'], - ]; - break; - } - } - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php deleted file mode 100644 index f1d66cc..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Filter/PropFilter.php +++ /dev/null @@ -1,95 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = [ - 'name' => null, - 'is-not-defined' => false, - 'param-filters' => [], - 'text-match' => null, - 'time-range' => [], - ]; - - $att = $reader->parseAttributes(); - $result['name'] = $att['name']; - - $elems = $reader->parseInnerTree(); - - if (is_array($elems)) { - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{'.Plugin::NS_CALDAV.'}param-filter': - $result['param-filters'][] = $elem['value']; - break; - case '{'.Plugin::NS_CALDAV.'}is-not-defined': - $result['is-not-defined'] = true; - break; - case '{'.Plugin::NS_CALDAV.'}time-range': - $result['time-range'] = [ - 'start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, - 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null, - ]; - if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) { - throw new BadRequest('The end-date must be larger than the start-date'); - } - break; - case '{'.Plugin::NS_CALDAV.'}text-match': - $result['text-match'] = [ - 'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'], - 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap', - 'value' => $elem['value'], - ]; - break; - } - } - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php deleted file mode 100644 index 2dbb0f4..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php +++ /dev/null @@ -1,290 +0,0 @@ - $value) { - if (!property_exists($this, $key)) { - throw new \InvalidArgumentException('Unknown option: '.$key); - } - $this->$key = $value; - } - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - $writer->writeElement('{'.CalDAV\Plugin::NS_CALENDARSERVER.'}invite-notification'); - } - - /** - * This method serializes the entire notification, as it is used in the - * response body. - */ - public function xmlSerializeFull(Writer $writer) - { - $cs = '{'.CalDAV\Plugin::NS_CALENDARSERVER.'}'; - - $this->dtStamp->setTimezone(new \DateTimeZone('GMT')); - $writer->writeElement($cs.'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z')); - - $writer->startElement($cs.'invite-notification'); - - $writer->writeElement($cs.'uid', $this->id); - $writer->writeElement('{DAV:}href', $this->href); - - switch ($this->type) { - case DAV\Sharing\Plugin::INVITE_ACCEPTED: - $writer->writeElement($cs.'invite-accepted'); - break; - case DAV\Sharing\Plugin::INVITE_NORESPONSE: - $writer->writeElement($cs.'invite-noresponse'); - break; - } - - $writer->writeElement($cs.'hosturl', [ - '{DAV:}href' => $writer->contextUri.$this->hostUrl, - ]); - - if ($this->summary) { - $writer->writeElement($cs.'summary', $this->summary); - } - - $writer->startElement($cs.'access'); - if ($this->readOnly) { - $writer->writeElement($cs.'read'); - } else { - $writer->writeElement($cs.'read-write'); - } - $writer->endElement(); // access - - $writer->startElement($cs.'organizer'); - // If the organizer contains a 'mailto:' part, it means it should be - // treated as absolute. - if ('mailto:' === strtolower(substr($this->organizer, 0, 7))) { - $writer->writeElement('{DAV:}href', $this->organizer); - } else { - $writer->writeElement('{DAV:}href', $writer->contextUri.$this->organizer); - } - if ($this->commonName) { - $writer->writeElement($cs.'common-name', $this->commonName); - } - if ($this->firstName) { - $writer->writeElement($cs.'first-name', $this->firstName); - } - if ($this->lastName) { - $writer->writeElement($cs.'last-name', $this->lastName); - } - $writer->endElement(); // organizer - - if ($this->commonName) { - $writer->writeElement($cs.'organizer-cn', $this->commonName); - } - if ($this->firstName) { - $writer->writeElement($cs.'organizer-first', $this->firstName); - } - if ($this->lastName) { - $writer->writeElement($cs.'organizer-last', $this->lastName); - } - if ($this->supportedComponents) { - $writer->writeElement('{'.CalDAV\Plugin::NS_CALDAV.'}supported-calendar-component-set', $this->supportedComponents); - } - - $writer->endElement(); // invite-notification - } - - /** - * Returns a unique id for this notification. - * - * This is just the base url. This should generally be some kind of unique - * id. - * - * @return string - */ - public function getId() - { - return $this->id; - } - - /** - * Returns the ETag for this notification. - * - * The ETag must be surrounded by literal double-quotes. - * - * @return string - */ - public function getETag() - { - return $this->etag; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php deleted file mode 100644 index dbdba3b..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php +++ /dev/null @@ -1,199 +0,0 @@ - $value) { - if (!property_exists($this, $key)) { - throw new \InvalidArgumentException('Unknown option: '.$key); - } - $this->$key = $value; - } - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - $writer->writeElement('{'.CalDAV\Plugin::NS_CALENDARSERVER.'}invite-reply'); - } - - /** - * This method serializes the entire notification, as it is used in the - * response body. - */ - public function xmlSerializeFull(Writer $writer) - { - $cs = '{'.CalDAV\Plugin::NS_CALENDARSERVER.'}'; - - $this->dtStamp->setTimezone(new \DateTimeZone('GMT')); - $writer->writeElement($cs.'dtstamp', $this->dtStamp->format('Ymd\\THis\\Z')); - - $writer->startElement($cs.'invite-reply'); - - $writer->writeElement($cs.'uid', $this->id); - $writer->writeElement($cs.'in-reply-to', $this->inReplyTo); - $writer->writeElement('{DAV:}href', $this->href); - - switch ($this->type) { - case DAV\Sharing\Plugin::INVITE_ACCEPTED: - $writer->writeElement($cs.'invite-accepted'); - break; - case DAV\Sharing\Plugin::INVITE_DECLINED: - $writer->writeElement($cs.'invite-declined'); - break; - } - - $writer->writeElement($cs.'hosturl', [ - '{DAV:}href' => $writer->contextUri.$this->hostUrl, - ]); - - if ($this->summary) { - $writer->writeElement($cs.'summary', $this->summary); - } - $writer->endElement(); // invite-reply - } - - /** - * Returns a unique id for this notification. - * - * This is just the base url. This should generally be some kind of unique - * id. - * - * @return string - */ - public function getId() - { - return $this->id; - } - - /** - * Returns the ETag for this notification. - * - * The ETag must be surrounded by literal double-quotes. - * - * @return string - */ - public function getETag() - { - return $this->etag; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php deleted file mode 100644 index e1b393f..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Notification/NotificationInterface.php +++ /dev/null @@ -1,43 +0,0 @@ -id = $id; - $this->type = $type; - $this->description = $description; - $this->href = $href; - $this->etag = $etag; - } - - /** - * The serialize method is called during xml writing. - * - * It should use the $writer argument to encode this object into XML. - * - * Important note: it is not needed to create the parent element. The - * parent element is already created, and we only have to worry about - * attributes, child elements and text (if any). - * - * Important note 2: If you are writing any new elements, you are also - * responsible for closing them. - */ - public function xmlSerialize(Writer $writer) - { - switch ($this->type) { - case self::TYPE_LOW: - $type = 'low'; - break; - case self::TYPE_MEDIUM: - $type = 'medium'; - break; - default: - case self::TYPE_HIGH: - $type = 'high'; - break; - } - - $writer->startElement('{'.Plugin::NS_CALENDARSERVER.'}systemstatus'); - $writer->writeAttribute('type', $type); - $writer->endElement(); - } - - /** - * This method serializes the entire notification, as it is used in the - * response body. - */ - public function xmlSerializeFull(Writer $writer) - { - $cs = '{'.Plugin::NS_CALENDARSERVER.'}'; - switch ($this->type) { - case self::TYPE_LOW: - $type = 'low'; - break; - case self::TYPE_MEDIUM: - $type = 'medium'; - break; - default: - case self::TYPE_HIGH: - $type = 'high'; - break; - } - - $writer->startElement($cs.'systemstatus'); - $writer->writeAttribute('type', $type); - - if ($this->description) { - $writer->writeElement($cs.'description', $this->description); - } - if ($this->href) { - $writer->writeElement('{DAV:}href', $this->href); - } - - $writer->endElement(); // systemstatus - } - - /** - * Returns a unique id for this notification. - * - * This is just the base url. This should generally be some kind of unique - * id. - * - * @return string - */ - public function getId() - { - return $this->id; - } - - /* - * Returns the ETag for this notification. - * - * The ETag must be surrounded by literal double-quotes. - * - * @return string - */ - public function getETag() - { - return $this->etag; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php deleted file mode 100644 index 58acb6d..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/AllowedSharingModes.php +++ /dev/null @@ -1,81 +0,0 @@ -canBeShared = $canBeShared; - $this->canBePublished = $canBePublished; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - if ($this->canBeShared) { - $writer->writeElement('{'.Plugin::NS_CALENDARSERVER.'}can-be-shared'); - } - if ($this->canBePublished) { - $writer->writeElement('{'.Plugin::NS_CALENDARSERVER.'}can-be-published'); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php deleted file mode 100644 index 84f7ae0..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/EmailAddressSet.php +++ /dev/null @@ -1,71 +0,0 @@ -emails = $emails; - } - - /** - * Returns the email addresses. - * - * @return array - */ - public function getValue() - { - return $this->emails; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->emails as $email) { - $writer->writeElement('{http://calendarserver.org/ns/}email-address', $email); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php deleted file mode 100644 index c389ca8..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php +++ /dev/null @@ -1,120 +0,0 @@ -sharees = $sharees; - } - - /** - * Returns the list of users, as it was passed to the constructor. - * - * @return array - */ - public function getValue() - { - return $this->sharees; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - $cs = '{'.Plugin::NS_CALENDARSERVER.'}'; - - foreach ($this->sharees as $sharee) { - if (DAV\Sharing\Plugin::ACCESS_SHAREDOWNER === $sharee->access) { - $writer->startElement($cs.'organizer'); - } else { - $writer->startElement($cs.'user'); - - switch ($sharee->inviteStatus) { - case DAV\Sharing\Plugin::INVITE_ACCEPTED: - $writer->writeElement($cs.'invite-accepted'); - break; - case DAV\Sharing\Plugin::INVITE_DECLINED: - $writer->writeElement($cs.'invite-declined'); - break; - case DAV\Sharing\Plugin::INVITE_NORESPONSE: - $writer->writeElement($cs.'invite-noresponse'); - break; - case DAV\Sharing\Plugin::INVITE_INVALID: - $writer->writeElement($cs.'invite-invalid'); - break; - } - - $writer->startElement($cs.'access'); - switch ($sharee->access) { - case DAV\Sharing\Plugin::ACCESS_READWRITE: - $writer->writeElement($cs.'read-write'); - break; - case DAV\Sharing\Plugin::ACCESS_READ: - $writer->writeElement($cs.'read'); - break; - } - $writer->endElement(); // access - } - - $href = new DAV\Xml\Property\Href($sharee->href); - $href->xmlSerialize($writer); - - if (isset($sharee->properties['{DAV:}displayname'])) { - $writer->writeElement($cs.'common-name', $sharee->properties['{DAV:}displayname']); - } - if ($sharee->comment) { - $writer->writeElement($cs.'summary', $sharee->comment); - } - $writer->endElement(); // organizer or user - } - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php deleted file mode 100644 index 1595220..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php +++ /dev/null @@ -1,124 +0,0 @@ -value = $value; - } - - /** - * Returns the current value. - * - * @return string - */ - public function getValue() - { - return $this->value; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - switch ($this->value) { - case self::TRANSPARENT: - $writer->writeElement('{'.Plugin::NS_CALDAV.'}transparent'); - break; - case self::OPAQUE: - $writer->writeElement('{'.Plugin::NS_CALDAV.'}opaque'); - break; - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = Deserializer\enum($reader, Plugin::NS_CALDAV); - - if (in_array('transparent', $elems)) { - $value = self::TRANSPARENT; - } else { - $value = self::OPAQUE; - } - - return new self($value); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php deleted file mode 100644 index d86e7b7..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarComponentSet.php +++ /dev/null @@ -1,118 +0,0 @@ -components = $components; - } - - /** - * Returns the list of supported components. - * - * @return array - */ - public function getValue() - { - return $this->components; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->components as $component) { - $writer->startElement('{'.Plugin::NS_CALDAV.'}comp'); - $writer->writeAttributes(['name' => $component]); - $writer->endElement(); - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseInnerTree(); - - $components = []; - - foreach ((array) $elems as $elem) { - if ($elem['name'] === '{'.Plugin::NS_CALDAV.'}comp') { - $components[] = $elem['attributes']['name']; - } - } - - if (!$components) { - throw new ParseException('supported-calendar-component-set must have at least one CALDAV:comp element'); - } - - return new self($components); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php deleted file mode 100644 index 5b08933..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCalendarData.php +++ /dev/null @@ -1,57 +0,0 @@ -startElement('{'.Plugin::NS_CALDAV.'}calendar-data'); - $writer->writeAttributes([ - 'content-type' => 'text/calendar', - 'version' => '2.0', - ]); - $writer->endElement(); // calendar-data - $writer->startElement('{'.Plugin::NS_CALDAV.'}calendar-data'); - $writer->writeAttributes([ - 'content-type' => 'application/calendar+json', - ]); - $writer->endElement(); // calendar-data - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php deleted file mode 100644 index c5ffeee..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Property/SupportedCollationSet.php +++ /dev/null @@ -1,54 +0,0 @@ -writeElement('{'.Plugin::NS_CALDAV.'}supported-collation', $collation); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php deleted file mode 100644 index 4771a20..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarMultiGetReport.php +++ /dev/null @@ -1,119 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseInnerTree([ - '{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData', - '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', - ]); - - $newProps = [ - 'hrefs' => [], - 'properties' => [], - ]; - - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{DAV:}prop': - $newProps['properties'] = array_keys($elem['value']); - if (isset($elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data'])) { - $newProps += $elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data']; - } - break; - case '{DAV:}href': - $newProps['hrefs'][] = Uri\resolve($reader->contextUri, $elem['value']); - break; - } - } - - $obj = new self(); - foreach ($newProps as $key => $value) { - $obj->$key = $value; - } - - return $obj; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php deleted file mode 100644 index 5a4df46..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/CalendarQueryReport.php +++ /dev/null @@ -1,137 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseInnerTree([ - '{urn:ietf:params:xml:ns:caldav}comp-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter', - '{urn:ietf:params:xml:ns:caldav}prop-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter', - '{urn:ietf:params:xml:ns:caldav}param-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter', - '{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData', - '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', - ]); - - $newProps = [ - 'filters' => null, - 'properties' => [], - ]; - - if (!is_array($elems)) { - $elems = []; - } - - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{DAV:}prop': - $newProps['properties'] = array_keys($elem['value']); - if (isset($elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data'])) { - $newProps += $elem['value']['{'.Plugin::NS_CALDAV.'}calendar-data']; - } - break; - case '{'.Plugin::NS_CALDAV.'}filter': - foreach ($elem['value'] as $subElem) { - if ($subElem['name'] === '{'.Plugin::NS_CALDAV.'}comp-filter') { - if (!is_null($newProps['filters'])) { - throw new BadRequest('Only one top-level comp-filter may be defined'); - } - $newProps['filters'] = $subElem['value']; - } - } - break; - } - } - - if (is_null($newProps['filters'])) { - throw new BadRequest('The {'.Plugin::NS_CALDAV.'}filter element is required for this request'); - } - - $obj = new self(); - foreach ($newProps as $key => $value) { - $obj->$key = $value; - } - - return $obj; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php deleted file mode 100644 index 17df05a..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/FreeBusyQueryReport.php +++ /dev/null @@ -1,90 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $timeRange = '{'.Plugin::NS_CALDAV.'}time-range'; - - $start = null; - $end = null; - - foreach ((array) $reader->parseInnerTree([]) as $elem) { - if ($elem['name'] !== $timeRange) { - continue; - } - - $start = empty($elem['attributes']['start']) ?: $elem['attributes']['start']; - $end = empty($elem['attributes']['end']) ?: $elem['attributes']['end']; - } - if (!$start && !$end) { - throw new BadRequest('The freebusy report must have a time-range element'); - } - if ($start) { - $start = DateTimeParser::parseDateTime($start); - } - if ($end) { - $end = DateTimeParser::parseDateTime($end); - } - $result = new self(); - $result->start = $start; - $result->end = $end; - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php deleted file mode 100644 index 166721e..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php +++ /dev/null @@ -1,145 +0,0 @@ -href = $href; - $this->calendarUri = $calendarUri; - $this->inReplyTo = $inReplyTo; - $this->summary = $summary; - $this->status = $status; - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = KeyValue::xmlDeserialize($reader); - - $href = null; - $calendarUri = null; - $inReplyTo = null; - $summary = null; - $status = null; - - foreach ($elems as $name => $value) { - switch ($name) { - case '{'.Plugin::NS_CALENDARSERVER.'}hosturl': - foreach ($value as $bla) { - if ('{DAV:}href' === $bla['name']) { - $calendarUri = $bla['value']; - } - } - break; - case '{'.Plugin::NS_CALENDARSERVER.'}invite-accepted': - $status = DAV\Sharing\Plugin::INVITE_ACCEPTED; - break; - case '{'.Plugin::NS_CALENDARSERVER.'}invite-declined': - $status = DAV\Sharing\Plugin::INVITE_DECLINED; - break; - case '{'.Plugin::NS_CALENDARSERVER.'}in-reply-to': - $inReplyTo = $value; - break; - case '{'.Plugin::NS_CALENDARSERVER.'}summary': - $summary = $value; - break; - case '{DAV:}href': - $href = $value; - break; - } - } - if (is_null($calendarUri)) { - throw new BadRequest('The {http://calendarserver.org/ns/}hosturl/{DAV:}href element must exist'); - } - - return new self($href, $calendarUri, $inReplyTo, $summary, $status); - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php deleted file mode 100644 index b5701e2..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/MkCalendar.php +++ /dev/null @@ -1,77 +0,0 @@ -properties; - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $self = new self(); - - $elementMap = $reader->elementMap; - $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop'; - $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue'; - $elems = $reader->parseInnerTree($elementMap); - - foreach ($elems as $elem) { - if ('{DAV:}set' === $elem['name']) { - $self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']); - } - } - - return $self; - } -} diff --git a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php b/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php deleted file mode 100644 index d597b76..0000000 --- a/lib/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php +++ /dev/null @@ -1,107 +0,0 @@ -sharees = $sharees; - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseGetElements([ - '{'.Plugin::NS_CALENDARSERVER.'}set' => 'Sabre\\Xml\\Element\\KeyValue', - '{'.Plugin::NS_CALENDARSERVER.'}remove' => 'Sabre\\Xml\\Element\\KeyValue', - ]); - - $sharees = []; - - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{'.Plugin::NS_CALENDARSERVER.'}set': - $sharee = $elem['value']; - - $sumElem = '{'.Plugin::NS_CALENDARSERVER.'}summary'; - $commonName = '{'.Plugin::NS_CALENDARSERVER.'}common-name'; - - $properties = []; - if (isset($sharee[$commonName])) { - $properties['{DAV:}displayname'] = $sharee[$commonName]; - } - - $access = array_key_exists('{'.Plugin::NS_CALENDARSERVER.'}read-write', $sharee) - ? \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE - : \Sabre\DAV\Sharing\Plugin::ACCESS_READ; - - $sharees[] = new Sharee([ - 'href' => $sharee['{DAV:}href'], - 'properties' => $properties, - 'access' => $access, - 'comment' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null, - ]); - break; - - case '{'.Plugin::NS_CALENDARSERVER.'}remove': - $sharees[] = new Sharee([ - 'href' => $elem['value']['{DAV:}href'], - 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS, - ]); - break; - } - } - - return new self($sharees); - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/AddressBook.php b/lib/vendor/sabre/dav/lib/CardDAV/AddressBook.php deleted file mode 100644 index f5744f6..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/AddressBook.php +++ /dev/null @@ -1,335 +0,0 @@ -carddavBackend = $carddavBackend; - $this->addressBookInfo = $addressBookInfo; - } - - /** - * Returns the name of the addressbook. - * - * @return string - */ - public function getName() - { - return $this->addressBookInfo['uri']; - } - - /** - * Returns a card. - * - * @param string $name - * - * @return Card - */ - public function getChild($name) - { - $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name); - if (!$obj) { - throw new DAV\Exception\NotFound('Card not found'); - } - - return new Card($this->carddavBackend, $this->addressBookInfo, $obj); - } - - /** - * Returns the full list of cards. - * - * @return array - */ - public function getChildren() - { - $objs = $this->carddavBackend->getCards($this->addressBookInfo['id']); - $children = []; - foreach ($objs as $obj) { - $obj['acl'] = $this->getChildACL(); - $children[] = new Card($this->carddavBackend, $this->addressBookInfo, $obj); - } - - return $children; - } - - /** - * This method receives a list of paths in it's first argument. - * It must return an array with Node objects. - * - * If any children are not found, you do not have to return them. - * - * @param string[] $paths - * - * @return array - */ - public function getMultipleChildren(array $paths) - { - $objs = $this->carddavBackend->getMultipleCards($this->addressBookInfo['id'], $paths); - $children = []; - foreach ($objs as $obj) { - $obj['acl'] = $this->getChildACL(); - $children[] = new Card($this->carddavBackend, $this->addressBookInfo, $obj); - } - - return $children; - } - - /** - * Creates a new directory. - * - * We actually block this, as subdirectories are not allowed in addressbooks. - * - * @param string $name - */ - public function createDirectory($name) - { - throw new DAV\Exception\MethodNotAllowed('Creating collections in addressbooks is not allowed'); - } - - /** - * Creates a new file. - * - * The contents of the new file must be a valid VCARD. - * - * This method may return an ETag. - * - * @param string $name - * @param resource $data - * - * @return string|null - */ - public function createFile($name, $data = null) - { - if (is_resource($data)) { - $data = stream_get_contents($data); - } - // Converting to UTF-8, if needed - $data = DAV\StringUtil::ensureUTF8($data); - - return $this->carddavBackend->createCard($this->addressBookInfo['id'], $name, $data); - } - - /** - * Deletes the entire addressbook. - */ - public function delete() - { - $this->carddavBackend->deleteAddressBook($this->addressBookInfo['id']); - } - - /** - * Renames the addressbook. - * - * @param string $newName - */ - public function setName($newName) - { - throw new DAV\Exception\MethodNotAllowed('Renaming addressbooks is not yet supported'); - } - - /** - * Returns the last modification date as a unix timestamp. - */ - public function getLastModified() - { - return null; - } - - /** - * Updates properties on this node. - * - * This method received a PropPatch object, which contains all the - * information about the update. - * - * To update specific properties, call the 'handle' method on this object. - * Read the PropPatch documentation for more information. - */ - public function propPatch(DAV\PropPatch $propPatch) - { - return $this->carddavBackend->updateAddressBook($this->addressBookInfo['id'], $propPatch); - } - - /** - * Returns a list of properties for this nodes. - * - * The properties list is a list of propertynames the client requested, - * encoded in clark-notation {xmlnamespace}tagname - * - * If the array is empty, it means 'all properties' were requested. - * - * @param array $properties - * - * @return array - */ - public function getProperties($properties) - { - $response = []; - foreach ($properties as $propertyName) { - if (isset($this->addressBookInfo[$propertyName])) { - $response[$propertyName] = $this->addressBookInfo[$propertyName]; - } - } - - return $response; - } - - /** - * 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->addressBookInfo['principaluri']; - } - - /** - * This method returns the ACL's for card nodes in this address book. - * The result of this method automatically gets passed to the - * card nodes in this address book. - * - * @return array - */ - public function getChildACL() - { - return [ - [ - 'privilege' => '{DAV:}all', - 'principal' => $this->getOwner(), - 'protected' => true, - ], - ]; - } - - /** - * This method returns the current sync-token for this collection. - * This can be any string. - * - * If null is returned from this function, the plugin assumes there's no - * sync information available. - * - * @return string|null - */ - public function getSyncToken() - { - if ( - $this->carddavBackend instanceof Backend\SyncSupport && - isset($this->addressBookInfo['{DAV:}sync-token']) - ) { - return $this->addressBookInfo['{DAV:}sync-token']; - } - if ( - $this->carddavBackend instanceof Backend\SyncSupport && - isset($this->addressBookInfo['{http://sabredav.org/ns}sync-token']) - ) { - return $this->addressBookInfo['{http://sabredav.org/ns}sync-token']; - } - } - - /** - * The getChanges method returns all the changes that have happened, since - * the specified syncToken and the current collection. - * - * This function should return an array, such as the following: - * - * [ - * 'syncToken' => 'The current synctoken', - * 'added' => [ - * 'new.txt', - * ], - * 'modified' => [ - * 'modified.txt', - * ], - * 'deleted' => [ - * 'foo.php.bak', - * 'old.txt' - * ] - * ]; - * - * The syncToken property should reflect the *current* syncToken of the - * collection, as reported getSyncToken(). This is needed here too, to - * ensure the operation is atomic. - * - * If the syncToken is specified as null, this is an initial sync, and all - * members should be reported. - * - * The modified property is an array of nodenames that have changed since - * the last token. - * - * The deleted property is an array with nodenames, that have been deleted - * from collection. - * - * The second argument is basically the 'depth' of the report. If it's 1, - * you only have to report changes that happened only directly in immediate - * descendants. If it's 2, it should also include changes from the nodes - * below the child collections. (grandchildren) - * - * The third (optional) argument allows a client to specify how many - * results should be returned at most. If the limit is not specified, it - * should be treated as infinite. - * - * If the limit (infinite or not) is higher than you're willing to return, - * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception. - * - * If the syncToken is expired (due to data cleanup) or unknown, you must - * return null. - * - * The limit is 'suggestive'. You are free to ignore it. - * - * @param string $syncToken - * @param int $syncLevel - * @param int $limit - * - * @return array|null - */ - public function getChanges($syncToken, $syncLevel, $limit = null) - { - if (!$this->carddavBackend instanceof Backend\SyncSupport) { - return null; - } - - return $this->carddavBackend->getChangesForAddressBook( - $this->addressBookInfo['id'], - $syncToken, - $syncLevel, - $limit - ); - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php b/lib/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php deleted file mode 100644 index d7365fb..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php +++ /dev/null @@ -1,178 +0,0 @@ -carddavBackend = $carddavBackend; - $this->principalUri = $principalUri; - } - - /** - * Returns the name of this object. - * - * @return string - */ - public function getName() - { - list(, $name) = Uri\split($this->principalUri); - - return $name; - } - - /** - * Updates the name of this object. - * - * @param string $name - */ - public function setName($name) - { - throw new DAV\Exception\MethodNotAllowed(); - } - - /** - * Deletes this object. - */ - public function delete() - { - throw new DAV\Exception\MethodNotAllowed(); - } - - /** - * Returns the last modification date. - * - * @return int - */ - public function getLastModified() - { - return null; - } - - /** - * Creates a new file under this object. - * - * This is currently not allowed - * - * @param string $name - * @param resource $data - */ - public function createFile($name, $data = null) - { - throw new DAV\Exception\MethodNotAllowed('Creating new files in this collection is not supported'); - } - - /** - * Creates a new directory under this object. - * - * This is currently not allowed. - * - * @param string $filename - */ - public function createDirectory($filename) - { - throw new DAV\Exception\MethodNotAllowed('Creating new collections in this collection is not supported'); - } - - /** - * Returns a single addressbook, by name. - * - * @param string $name - * - * @todo needs optimizing - * - * @return AddressBook - */ - public function getChild($name) - { - foreach ($this->getChildren() as $child) { - if ($name == $child->getName()) { - return $child; - } - } - throw new DAV\Exception\NotFound('Addressbook with name \''.$name.'\' could not be found'); - } - - /** - * Returns a list of addressbooks. - * - * @return array - */ - public function getChildren() - { - $addressbooks = $this->carddavBackend->getAddressBooksForUser($this->principalUri); - $objs = []; - foreach ($addressbooks as $addressbook) { - $objs[] = new AddressBook($this->carddavBackend, $addressbook); - } - - return $objs; - } - - /** - * Creates a new address book. - * - * @param string $name - * - * @throws DAV\Exception\InvalidResourceType - */ - public function createExtendedCollection($name, MkCol $mkCol) - { - if (!$mkCol->hasResourceType('{'.Plugin::NS_CARDDAV.'}addressbook')) { - throw new DAV\Exception\InvalidResourceType('Unknown resourceType for this collection'); - } - $properties = $mkCol->getRemainingValues(); - $mkCol->setRemainingResultCode(201); - $this->carddavBackend->createAddressBook($this->principalUri, $name, $properties); - } - - /** - * 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; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php b/lib/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php deleted file mode 100644 index ee1721a..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/AddressBookRoot.php +++ /dev/null @@ -1,75 +0,0 @@ -carddavBackend = $carddavBackend; - parent::__construct($principalBackend, $principalPrefix); - } - - /** - * Returns the name of the node. - * - * @return string - */ - public function getName() - { - return Plugin::ADDRESSBOOK_ROOT; - } - - /** - * This method returns a node for a principal. - * - * 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. - * - * @return \Sabre\DAV\INode - */ - public function getChildForPrincipal(array $principal) - { - return new AddressBookHome($this->carddavBackend, $principal['uri']); - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php b/lib/vendor/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php deleted file mode 100644 index a900c62..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Backend/AbstractBackend.php +++ /dev/null @@ -1,38 +0,0 @@ -getCard($addressBookId, $uri); - }, $uris); - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php b/lib/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php deleted file mode 100644 index f9955ac..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php +++ /dev/null @@ -1,194 +0,0 @@ -pdo = $pdo; - } - - /** - * 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, synctoken FROM '.$this->addressBooksTableName.' WHERE principaluri = ?'); - $stmt->execute([$principalUri]); - - $addressBooks = []; - - foreach ($stmt->fetchAll() as $row) { - $addressBooks[] = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'principaluri' => $row['principaluri'], - '{DAV:}displayname' => $row['displayname'], - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description' => $row['description'], - '{http://calendarserver.org/ns/}getctag' => $row['synctoken'], - '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0', - ]; - } - - return $addressBooks; - } - - /** - * Updates properties for an address book. - * - * The list of mutations is stored in a Sabre\DAV\PropPatch object. - * To do the actual updates, you must tell this object which properties - * you're going to process with the handle() method. - * - * Calling the handle method is like telling the PropPatch object "I - * promise I can handle updating this property". - * - * Read the PropPatch documentation for more info and examples. - * - * @param string $addressBookId - */ - public function updateAddressBook($addressBookId, PropPatch $propPatch) - { - $supportedProperties = [ - '{DAV:}displayname', - '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description', - ]; - - $propPatch->handle($supportedProperties, function ($mutations) use ($addressBookId) { - $updates = []; - foreach ($mutations as $property => $newValue) { - switch ($property) { - case '{DAV:}displayname': - $updates['displayname'] = $newValue; - break; - case '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description': - $updates['description'] = $newValue; - break; - } - } - $query = 'UPDATE '.$this->addressBooksTableName.' SET '; - $first = true; - foreach ($updates as $key => $value) { - if ($first) { - $first = false; - } else { - $query .= ', '; - } - $query .= ' '.$key.' = :'.$key.' '; - } - $query .= ' WHERE id = :addressbookid'; - - $stmt = $this->pdo->prepare($query); - $updates['addressbookid'] = $addressBookId; - - $stmt->execute($updates); - - $this->addChange($addressBookId, '', 2); - - return true; - }); - } - - /** - * Creates a new address book. - * - * @param string $principalUri - * @param string $url just the 'basename' of the url - * - * @return int Last insert id - */ - public function createAddressBook($principalUri, $url, array $properties) - { - $values = [ - 'displayname' => null, - 'description' => null, - 'principaluri' => $principalUri, - 'uri' => $url, - ]; - - foreach ($properties as $property => $newValue) { - switch ($property) { - case '{DAV:}displayname': - $values['displayname'] = $newValue; - break; - case '{'.CardDAV\Plugin::NS_CARDDAV.'}addressbook-description': - $values['description'] = $newValue; - break; - default: - throw new DAV\Exception\BadRequest('Unknown property: '.$property); - } - } - - $query = 'INSERT INTO '.$this->addressBooksTableName.' (uri, displayname, description, principaluri, synctoken) VALUES (:uri, :displayname, :description, :principaluri, 1)'; - $stmt = $this->pdo->prepare($query); - $stmt->execute($values); - - return $this->pdo->lastInsertId( - $this->addressBooksTableName.'_id_seq' - ); - } - - /** - * Deletes an entire addressbook and all its contents. - * - * @param int $addressBookId - */ - public function deleteAddressBook($addressBookId) - { - $stmt = $this->pdo->prepare('DELETE FROM '.$this->cardsTableName.' WHERE addressbookid = ?'); - $stmt->execute([$addressBookId]); - - $stmt = $this->pdo->prepare('DELETE FROM '.$this->addressBooksTableName.' WHERE id = ?'); - $stmt->execute([$addressBookId]); - - $stmt = $this->pdo->prepare('DELETE FROM '.$this->addressBookChangesTableName.' WHERE addressbookid = ?'); - $stmt->execute([$addressBookId]); - } - - /** - * 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 omit 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, uri, lastmodified, etag, size FROM '.$this->cardsTableName.' WHERE addressbookid = ?'); - $stmt->execute([$addressbookId]); - - $result = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $row['etag'] = '"'.$row['etag'].'"'; - $row['lastmodified'] = (int) $row['lastmodified']; - $result[] = $row; - } - - return $result; - } - - /** - * Returns a specific card. - * - * The same set of properties must be returned as with getCards. The only - * exception is that 'carddata' is absolutely required. - * - * If the card does not exist, you must return false. - * - * @param mixed $addressBookId - * @param string $cardUri - * - * @return array - */ - public function getCard($addressBookId, $cardUri) - { - $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified, etag, size FROM '.$this->cardsTableName.' WHERE addressbookid = ? AND uri = ? LIMIT 1'); - $stmt->execute([$addressBookId, $cardUri]); - - $result = $stmt->fetch(\PDO::FETCH_ASSOC); - - if (!$result) { - return false; - } - - $result['etag'] = '"'.$result['etag'].'"'; - $result['lastmodified'] = (int) $result['lastmodified']; - - return $result; - } - - /** - * Returns a list of cards. - * - * This method should work identical to getCard, but instead return all the - * cards in the list as an array. - * - * If the backend supports this, it may allow for some speed-ups. - * - * @param mixed $addressBookId - * - * @return array - */ - public function getMultipleCards($addressBookId, array $uris) - { - $query = 'SELECT id, uri, lastmodified, etag, size, carddata FROM '.$this->cardsTableName.' WHERE addressbookid = ? AND uri IN ('; - // Inserting a whole bunch of question marks - $query .= implode(',', array_fill(0, count($uris), '?')); - $query .= ')'; - - $stmt = $this->pdo->prepare($query); - $stmt->execute(array_merge([$addressBookId], $uris)); - $result = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $row['etag'] = '"'.$row['etag'].'"'; - $row['lastmodified'] = (int) $row['lastmodified']; - $result[] = $row; - } - - return $result; - } - - /** - * 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, size, etag) VALUES (?, ?, ?, ?, ?, ?)'); - - $etag = md5($cardData); - - $stmt->execute([ - $cardData, - $cardUri, - time(), - $addressBookId, - strlen($cardData), - $etag, - ]); - - $this->addChange($addressBookId, $cardUri, 1); - - return '"'.$etag.'"'; - } - - /** - * 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 = ?, size = ?, etag = ? WHERE uri = ? AND addressbookid =?'); - - $etag = md5($cardData); - $stmt->execute([ - $cardData, - time(), - strlen($cardData), - $etag, - $cardUri, - $addressBookId, - ]); - - $this->addChange($addressBookId, $cardUri, 2); - - return '"'.$etag.'"'; - } - - /** - * Deletes a card. - * - * @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->execute([$addressBookId, $cardUri]); - - $this->addChange($addressBookId, $cardUri, 3); - - return 1 === $stmt->rowCount(); - } - - /** - * The getChanges method returns all the changes that have happened, since - * the specified syncToken in the specified address book. - * - * This function should return an array, such as the following: - * - * [ - * 'syncToken' => 'The current synctoken', - * 'added' => [ - * 'new.txt', - * ], - * 'modified' => [ - * 'updated.txt', - * ], - * 'deleted' => [ - * 'foo.php.bak', - * 'old.txt' - * ] - * ]; - * - * The returned syncToken property should reflect the *current* syncToken - * of the addressbook, as reported in the {http://sabredav.org/ns}sync-token - * property. This is needed here too, to ensure the operation is atomic. - * - * If the $syncToken argument is specified as null, this is an initial - * sync, and all members should be reported. - * - * The modified property is an array of nodenames that have changed since - * the last token. - * - * The deleted property is an array with nodenames, that have been deleted - * from collection. - * - * The $syncLevel argument is basically the 'depth' of the report. If it's - * 1, you only have to report changes that happened only directly in - * immediate descendants. If it's 2, it should also include changes from - * the nodes below the child collections. (grandchildren) - * - * The $limit argument allows a client to specify how many results should - * be returned at most. If the limit is not specified, it should be treated - * as infinite. - * - * If the limit (infinite or not) is higher than you're willing to return, - * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception. - * - * If the syncToken is expired (due to data cleanup) or unknown, you must - * return null. - * - * The limit is 'suggestive'. You are free to ignore it. - * - * @param string $addressBookId - * @param string $syncToken - * @param int $syncLevel - * @param int $limit - * - * @return array|null - */ - public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null) - { - // Current synctoken - $stmt = $this->pdo->prepare('SELECT synctoken FROM '.$this->addressBooksTableName.' WHERE id = ?'); - $stmt->execute([$addressBookId]); - $currentToken = $stmt->fetchColumn(0); - - if (is_null($currentToken)) { - return null; - } - - $result = [ - 'syncToken' => $currentToken, - 'added' => [], - 'modified' => [], - 'deleted' => [], - ]; - - if ($syncToken) { - $query = 'SELECT uri, operation FROM '.$this->addressBookChangesTableName.' WHERE synctoken >= ? AND synctoken < ? AND addressbookid = ? ORDER BY synctoken'; - if ($limit > 0) { - $query .= ' LIMIT '.(int) $limit; - } - - // Fetching all changes - $stmt = $this->pdo->prepare($query); - $stmt->execute([$syncToken, $currentToken, $addressBookId]); - - $changes = []; - - // This loop ensures that any duplicates are overwritten, only the - // last change on a node is relevant. - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $changes[$row['uri']] = $row['operation']; - } - - foreach ($changes as $uri => $operation) { - switch ($operation) { - case 1: - $result['added'][] = $uri; - break; - case 2: - $result['modified'][] = $uri; - break; - case 3: - $result['deleted'][] = $uri; - break; - } - } - } else { - // No synctoken supplied, this is the initial sync. - $query = 'SELECT uri FROM '.$this->cardsTableName.' WHERE addressbookid = ?'; - $stmt = $this->pdo->prepare($query); - $stmt->execute([$addressBookId]); - - $result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN); - } - - return $result; - } - - /** - * Adds a change record to the addressbookchanges table. - * - * @param mixed $addressBookId - * @param string $objectUri - * @param int $operation 1 = add, 2 = modify, 3 = delete - */ - protected function addChange($addressBookId, $objectUri, $operation) - { - $stmt = $this->pdo->prepare('INSERT INTO '.$this->addressBookChangesTableName.' (uri, synctoken, addressbookid, operation) SELECT ?, synctoken, ?, ? FROM '.$this->addressBooksTableName.' WHERE id = ?'); - $stmt->execute([ - $objectUri, - $addressBookId, - $operation, - $addressBookId, - ]); - $stmt = $this->pdo->prepare('UPDATE '.$this->addressBooksTableName.' SET synctoken = synctoken + 1 WHERE id = ?'); - $stmt->execute([ - $addressBookId, - ]); - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Backend/SyncSupport.php b/lib/vendor/sabre/dav/lib/CardDAV/Backend/SyncSupport.php deleted file mode 100644 index 6aaad14..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Backend/SyncSupport.php +++ /dev/null @@ -1,83 +0,0 @@ - 'The current synctoken', - * 'added' => [ - * 'new.txt', - * ], - * 'modified' => [ - * 'modified.txt', - * ], - * 'deleted' => [ - * 'foo.php.bak', - * 'old.txt' - * ] - * ]; - * - * The returned syncToken property should reflect the *current* syncToken - * of the calendar, as reported in the {http://sabredav.org/ns}sync-token - * property. This is needed here too, to ensure the operation is atomic. - * - * If the $syncToken argument is specified as null, this is an initial - * sync, and all members should be reported. - * - * The modified property is an array of nodenames that have changed since - * the last token. - * - * The deleted property is an array with nodenames, that have been deleted - * from collection. - * - * The $syncLevel argument is basically the 'depth' of the report. If it's - * 1, you only have to report changes that happened only directly in - * immediate descendants. If it's 2, it should also include changes from - * the nodes below the child collections. (grandchildren) - * - * The $limit argument allows a client to specify how many results should - * be returned at most. If the limit is not specified, it should be treated - * as infinite. - * - * If the limit (infinite or not) is higher than you're willing to return, - * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception. - * - * If the syncToken is expired (due to data cleanup) or unknown, you must - * return null. - * - * The limit is 'suggestive'. You are free to ignore it. - * - * @param string $addressBookId - * @param string $syncToken - * @param int $syncLevel - * @param int $limit - * - * @return array|null - */ - public function getChangesForAddressBook($addressBookId, $syncToken, $syncLevel, $limit = null); -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Card.php b/lib/vendor/sabre/dav/lib/CardDAV/Card.php deleted file mode 100644 index c9cd2bb..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Card.php +++ /dev/null @@ -1,202 +0,0 @@ -carddavBackend = $carddavBackend; - $this->addressBookInfo = $addressBookInfo; - $this->cardData = $cardData; - } - - /** - * Returns the uri for this object. - * - * @return string - */ - public function getName() - { - return $this->cardData['uri']; - } - - /** - * Returns the VCard-formatted object. - * - * @return string - */ - public function get() - { - // 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 string|null - */ - public function put($cardData) - { - if (is_resource($cardData)) { - $cardData = stream_get_contents($cardData); - } - - // Converting to UTF-8, if needed - $cardData = DAV\StringUtil::ensureUTF8($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. - */ - public function delete() - { - $this->carddavBackend->deleteCard($this->addressBookInfo['id'], $this->cardData['uri']); - } - - /** - * Returns the mime content-type. - * - * @return string - */ - public function getContentType() - { - return 'text/vcard; charset=utf-8'; - } - - /** - * Returns an ETag for this object. - * - * @return string - */ - public function getETag() - { - if (isset($this->cardData['etag'])) { - return $this->cardData['etag']; - } else { - $data = $this->get(); - if (is_string($data)) { - return '"'.md5($data).'"'; - } else { - // We refuse to calculate the md5 if it's a stream. - return null; - } - } - } - - /** - * Returns the last modification date as a unix timestamp. - * - * @return int - */ - public function getLastModified() - { - return isset($this->cardData['lastmodified']) ? $this->cardData['lastmodified'] : null; - } - - /** - * Returns the size of this object in bytes. - * - * @return int - */ - public function getSize() - { - 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 - * - * @return string|null - */ - public function getOwner() - { - return $this->addressBookInfo['principaluri']; - } - - /** - * 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() - { - // An alternative acl may be specified through the cardData array. - if (isset($this->cardData['acl'])) { - return $this->cardData['acl']; - } - - return [ - [ - 'privilege' => '{DAV:}all', - 'principal' => $this->addressBookInfo['principaluri'], - 'protected' => true, - ], - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/IAddressBook.php b/lib/vendor/sabre/dav/lib/CardDAV/IAddressBook.php deleted file mode 100644 index 3f489f4..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/IAddressBook.php +++ /dev/null @@ -1,20 +0,0 @@ -on('propFind', [$this, 'propFindEarly']); - $server->on('propFind', [$this, 'propFindLate'], 150); - $server->on('report', [$this, 'report']); - $server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']); - $server->on('beforeWriteContent', [$this, 'beforeWriteContent']); - $server->on('beforeCreateFile', [$this, 'beforeCreateFile']); - $server->on('afterMethod:GET', [$this, 'httpAfterGet']); - - $server->xml->namespaceMap[self::NS_CARDDAV] = 'card'; - - $server->xml->elementMap['{'.self::NS_CARDDAV.'}addressbook-query'] = 'Sabre\\CardDAV\\Xml\\Request\\AddressBookQueryReport'; - $server->xml->elementMap['{'.self::NS_CARDDAV.'}addressbook-multiget'] = 'Sabre\\CardDAV\\Xml\\Request\\AddressBookMultiGetReport'; - - /* 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->xml->elementMap['{http://calendarserver.org/ns/}me-card'] = 'Sabre\\DAV\\Xml\\Property\\Href'; - - $this->server = $server; - } - - /** - * Returns a list of supported features. - * - * This is used in the DAV: header in the OPTIONS and PROPFIND requests. - * - * @return array - */ - public function getFeatures() - { - return ['addressbook']; - } - - /** - * 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 - * - * @param string $uri - * - * @return array - */ - public function getSupportedReportSet($uri) - { - $node = $this->server->tree->getNodeForPath($uri); - if ($node instanceof IAddressBook || $node instanceof ICard) { - return [ - '{'.self::NS_CARDDAV.'}addressbook-multiget', - '{'.self::NS_CARDDAV.'}addressbook-query', - ]; - } - - return []; - } - - /** - * Adds all CardDAV-specific properties. - */ - public function propFindEarly(DAV\PropFind $propFind, DAV\INode $node) - { - $ns = '{'.self::NS_CARDDAV.'}'; - - if ($node instanceof IAddressBook) { - $propFind->handle($ns.'max-resource-size', $this->maxResourceSize); - $propFind->handle($ns.'supported-address-data', function () { - return new Xml\Property\SupportedAddressData(); - }); - $propFind->handle($ns.'supported-collation-set', function () { - return new Xml\Property\SupportedCollationSet(); - }); - } - if ($node instanceof DAVACL\IPrincipal) { - $path = $propFind->getPath(); - - $propFind->handle('{'.self::NS_CARDDAV.'}addressbook-home-set', function () use ($path) { - return new LocalHref($this->getAddressBookHomeForPrincipal($path).'/'); - }); - - if ($this->directories) { - $propFind->handle('{'.self::NS_CARDDAV.'}directory-gateway', function () { - return new LocalHref($this->directories); - }); - } - } - - if ($node instanceof 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. - // Therefore we simply expose it as a property. - $propFind->handle('{'.self::NS_CARDDAV.'}address-data', function () use ($node) { - $val = $node->get(); - if (is_resource($val)) { - $val = stream_get_contents($val); - } - - return $val; - }); - } - } - - /** - * This functions handles REPORT requests specific to CardDAV. - * - * @param string $reportName - * @param \DOMNode $dom - * @param mixed $path - * - * @return bool - */ - public function report($reportName, $dom, $path) - { - switch ($reportName) { - case '{'.self::NS_CARDDAV.'}addressbook-multiget': - $this->server->transactionType = 'report-addressbook-multiget'; - $this->addressbookMultiGetReport($dom); - - return false; - case '{'.self::NS_CARDDAV.'}addressbook-query': - $this->server->transactionType = 'report-addressbook-query'; - $this->addressBookQueryReport($dom); - - return false; - default: - return; - } - } - - /** - * Returns the addressbook home for a given principal. - * - * @param string $principal - * - * @return string - */ - protected function getAddressbookHomeForPrincipal($principal) - { - list(, $principalId) = Uri\split($principal); - - return self::ADDRESSBOOK_ROOT.'/'.$principalId; - } - - /** - * This function handles the addressbook-multiget REPORT. - * - * This report is used by the client to fetch the content of a series - * of urls. Effectively avoiding a lot of redundant requests. - * - * @param Xml\Request\AddressBookMultiGetReport $report - */ - public function addressbookMultiGetReport($report) - { - $contentType = $report->contentType; - $version = $report->version; - if ($version) { - $contentType .= '; version='.$version; - } - - $vcardType = $this->negotiateVCard( - $contentType - ); - - $propertyList = []; - $paths = array_map( - [$this->server, 'calculateUri'], - $report->hrefs - ); - foreach ($this->server->getPropertiesForMultiplePaths($paths, $report->properties) as $props) { - if (isset($props['200']['{'.self::NS_CARDDAV.'}address-data'])) { - $props['200']['{'.self::NS_CARDDAV.'}address-data'] = $this->convertVCard( - $props[200]['{'.self::NS_CARDDAV.'}address-data'], - $vcardType - ); - } - $propertyList[] = $props; - } - - $prefer = $this->server->getHTTPPrefer(); - - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); - $this->server->httpResponse->setBody($this->server->generateMultiStatus($propertyList, 'minimal' === $prefer['return'])); - } - - /** - * This method is triggered before a file gets updated with new content. - * - * This plugin uses this method to ensure that Card nodes receive valid - * vcard data. - * - * @param string $path - * @param resource $data - * @param bool $modified should be set to true, if this event handler - * changed &$data - */ - public function beforeWriteContent($path, DAV\IFile $node, &$data, &$modified) - { - if (!$node instanceof ICard) { - return; - } - - $this->validateVCard($data, $modified); - } - - /** - * This method is triggered before a new file is created. - * - * This plugin uses this method to ensure that Card nodes receive valid - * vcard data. - * - * @param string $path - * @param resource $data - * @param bool $modified should be set to true, if this event handler - * changed &$data - */ - public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode, &$modified) - { - if (!$parentNode instanceof IAddressBook) { - return; - } - - $this->validateVCard($data, $modified); - } - - /** - * Checks if the submitted iCalendar data is in fact, valid. - * - * An exception is thrown if it's not. - * - * @param resource|string $data - * @param bool $modified should be set to true, if this event handler - * changed &$data - */ - protected function validateVCard(&$data, &$modified) - { - // If it's a stream, we convert it to a string first. - if (is_resource($data)) { - $data = stream_get_contents($data); - } - - $before = $data; - - try { - // If the data starts with a [, we can reasonably assume we're dealing - // with a jCal object. - if ('[' === substr($data, 0, 1)) { - $vobj = VObject\Reader::readJson($data); - - // Converting $data back to iCalendar, as that's what we - // technically support everywhere. - $data = $vobj->serialize(); - $modified = true; - } else { - $vobj = VObject\Reader::read($data); - } - } catch (VObject\ParseException $e) { - throw new DAV\Exception\UnsupportedMediaType('This resource only supports valid vCard or jCard data. Parse error: '.$e->getMessage()); - } - - if ('VCARD' !== $vobj->name) { - throw new DAV\Exception\UnsupportedMediaType('This collection can only support vcard objects.'); - } - - $options = VObject\Node::PROFILE_CARDDAV; - $prefer = $this->server->getHTTPPrefer(); - - if ('strict' !== $prefer['handling']) { - $options |= VObject\Node::REPAIR; - } - - $messages = $vobj->validate($options); - - $highestLevel = 0; - $warningMessage = null; - - // $messages contains a list of problems with the vcard, along with - // their severity. - foreach ($messages as $message) { - if ($message['level'] > $highestLevel) { - // Recording the highest reported error level. - $highestLevel = $message['level']; - $warningMessage = $message['message']; - } - - switch ($message['level']) { - case 1: - // Level 1 means that there was a problem, but it was repaired. - $modified = true; - break; - case 2: - // Level 2 means a warning, but not critical - break; - case 3: - // Level 3 means a critical error - throw new DAV\Exception\UnsupportedMediaType('Validation error in vCard: '.$message['message']); - } - } - if ($warningMessage) { - $this->server->httpResponse->setHeader( - 'X-Sabre-Ew-Gross', - 'vCard validation warning: '.$warningMessage - ); - - // Re-serializing object. - $data = $vobj->serialize(); - if (!$modified && 0 !== strcmp($data, $before)) { - // This ensures that the system does not send an ETag back. - $modified = true; - } - } - - // Destroy circular references to PHP will GC the object. - $vobj->destroy(); - } - - /** - * This function handles the addressbook-query REPORT. - * - * This report is used by the client to filter an addressbook based on a - * complex query. - * - * @param Xml\Request\AddressBookQueryReport $report - */ - protected function addressbookQueryReport($report) - { - $depth = $this->server->getHTTPDepth(0); - - if (0 == $depth) { - $candidateNodes = [ - $this->server->tree->getNodeForPath($this->server->getRequestUri()), - ]; - if (!$candidateNodes[0] instanceof ICard) { - throw new ReportNotSupported('The addressbook-query report is not supported on this url with Depth: 0'); - } - } else { - $candidateNodes = $this->server->tree->getChildren($this->server->getRequestUri()); - } - - $contentType = $report->contentType; - if ($report->version) { - $contentType .= '; version='.$report->version; - } - - $vcardType = $this->negotiateVCard( - $contentType - ); - - $validNodes = []; - foreach ($candidateNodes as $node) { - if (!$node instanceof ICard) { - continue; - } - - $blob = $node->get(); - if (is_resource($blob)) { - $blob = stream_get_contents($blob); - } - - if (!$this->validateFilters($blob, $report->filters, $report->test)) { - continue; - } - - $validNodes[] = $node; - - if ($report->limit && $report->limit <= count($validNodes)) { - // We hit the maximum number of items, we can stop now. - break; - } - } - - $result = []; - foreach ($validNodes as $validNode) { - if (0 == $depth) { - $href = $this->server->getRequestUri(); - } else { - $href = $this->server->getRequestUri().'/'.$validNode->getName(); - } - - list($props) = $this->server->getPropertiesForPath($href, $report->properties, 0); - - if (isset($props[200]['{'.self::NS_CARDDAV.'}address-data'])) { - $props[200]['{'.self::NS_CARDDAV.'}address-data'] = $this->convertVCard( - $props[200]['{'.self::NS_CARDDAV.'}address-data'], - $vcardType, - $report->addressDataProperties - ); - } - $result[] = $props; - } - - $prefer = $this->server->getHTTPPrefer(); - - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); - $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, 'minimal' === $prefer['return'])); - } - - /** - * Validates if a vcard makes it throught a list of filters. - * - * @param string $vcardData - * @param string $test anyof or allof (which means OR or AND) - * - * @return bool - */ - public function validateFilters($vcardData, array $filters, $test) - { - if (!$filters) { - return true; - } - $vcard = VObject\Reader::read($vcardData); - - foreach ($filters as $filter) { - $isDefined = isset($vcard->{$filter['name']}); - if ($filter['is-not-defined']) { - if ($isDefined) { - $success = false; - } else { - $success = true; - } - } elseif ((!$filter['param-filters'] && !$filter['text-matches']) || !$isDefined) { - // We only need to check for existence - $success = $isDefined; - } else { - $vProperties = $vcard->select($filter['name']); - - $results = []; - if ($filter['param-filters']) { - $results[] = $this->validateParamFilters($vProperties, $filter['param-filters'], $filter['test']); - } - if ($filter['text-matches']) { - $texts = []; - foreach ($vProperties as $vProperty) { - $texts[] = $vProperty->getValue(); - } - - $results[] = $this->validateTextMatches($texts, $filter['text-matches'], $filter['test']); - } - - if (1 === count($results)) { - $success = $results[0]; - } else { - if ('anyof' === $filter['test']) { - $success = $results[0] || $results[1]; - } else { - $success = $results[0] && $results[1]; - } - } - } // else - - // There are two conditions where we can already determine whether - // or not this filter succeeds. - if ('anyof' === $test && $success) { - // Destroy circular references to PHP will GC the object. - $vcard->destroy(); - - return true; - } - if ('allof' === $test && !$success) { - // Destroy circular references to PHP will GC the object. - $vcard->destroy(); - - return false; - } - } // foreach - - // Destroy circular references to PHP will GC the object. - $vcard->destroy(); - - // 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 - // we succeeded. Sounds weird, but makes sense. - return 'allof' === $test; - } - - /** - * 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 string $test - * - * @return bool - */ - protected function validateParamFilters(array $vProperties, array $filters, $test) - { - foreach ($filters as $filter) { - $isDefined = false; - foreach ($vProperties as $vProperty) { - $isDefined = isset($vProperty[$filter['name']]); - if ($isDefined) { - break; - } - } - - if ($filter['is-not-defined']) { - if ($isDefined) { - $success = false; - } else { - $success = true; - } - - // If there's no text-match, we can just check for existence - } elseif (!$filter['text-match'] || !$isDefined) { - $success = $isDefined; - } else { - $success = false; - foreach ($vProperties as $vProperty) { - // If we got all the way here, we'll need to validate the - // text-match filter. - if (isset($vProperty[$filter['name']])) { - $success = DAV\StringUtil::textMatch( - $vProperty[$filter['name']]->getValue(), - $filter['text-match']['value'], - $filter['text-match']['collation'], - $filter['text-match']['match-type'] - ); - if ($filter['text-match']['negate-condition']) { - $success = !$success; - } - } - if ($success) { - break; - } - } - } // else - - // There are two conditions where we can already determine whether - // or not this filter succeeds. - if ('anyof' === $test && $success) { - return true; - } - if ('allof' === $test && !$success) { - return false; - } - } - - // 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 - // we succeeded. Sounds weird, but makes sense. - return 'allof' === $test; - } - - /** - * Validates if a text-filter can be applied to a specific property. - * - * @param string $test - * - * @return bool - */ - protected function validateTextMatches(array $texts, array $filters, $test) - { - foreach ($filters as $filter) { - $success = false; - foreach ($texts as $haystack) { - $success = DAV\StringUtil::textMatch($haystack, $filter['value'], $filter['collation'], $filter['match-type']); - if ($filter['negate-condition']) { - $success = !$success; - } - - // Breaking on the first match - if ($success) { - break; - } - } - - if ($success && 'anyof' === $test) { - return true; - } - - if (!$success && 'allof' == $test) { - return false; - } - } - - // 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 - // we succeeded. Sounds weird, but makes sense. - return 'allof' === $test; - } - - /** - * This event is triggered when fetching properties. - * - * This event is scheduled late in the process, after most work for - * propfind has been done. - */ - public function propFindLate(DAV\PropFind $propFind, DAV\INode $node) - { - // If the request was made using the SOGO connector, we must rewrite - // the content-type property. By default SabreDAV will send back - // text/x-vcard; charset=utf-8, but for SOGO we must strip that last - // part. - if (false === strpos((string) $this->server->httpRequest->getHeader('User-Agent'), 'Thunderbird')) { - return; - } - $contentType = $propFind->get('{DAV:}getcontenttype'); - if (null !== $contentType) { - list($part) = explode(';', $contentType); - if ('text/x-vcard' === $part || 'text/vcard' === $part) { - $propFind->set('{DAV:}getcontenttype', 'text/x-vcard'); - } - } - } - - /** - * 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 addressbooks. - * - * @param string $output - * - * @return bool - */ - public function htmlActionsPanel(DAV\INode $node, &$output) - { - if (!$node instanceof AddressBookHome) { - return; - } - - $output .= '
-

Create new address book

- - -
-
- -
- '; - - return false; - } - - /** - * This event is triggered after GET requests. - * - * This is used to transform data into jCal, if this was requested. - */ - public function httpAfterGet(RequestInterface $request, ResponseInterface $response) - { - $contentType = $response->getHeader('Content-Type'); - if (null === $contentType || false === strpos($contentType, 'text/vcard')) { - return; - } - - $target = $this->negotiateVCard($request->getHeader('Accept'), $mimeType); - - $newBody = $this->convertVCard( - $response->getBody(), - $target - ); - - $response->setBody($newBody); - $response->setHeader('Content-Type', $mimeType.'; charset=utf-8'); - $response->setHeader('Content-Length', strlen($newBody)); - } - - /** - * This helper function performs the content-type negotiation for vcards. - * - * It will return one of the following strings: - * 1. vcard3 - * 2. vcard4 - * 3. jcard - * - * It defaults to vcard3. - * - * @param string $input - * @param string $mimeType - * - * @return string - */ - protected function negotiateVCard($input, &$mimeType = null) - { - $result = HTTP\negotiateContentType( - $input, - [ - // Most often used mime-type. Version 3 - 'text/x-vcard', - // The correct standard mime-type. Defaults to version 3 as - // well. - 'text/vcard', - // vCard 4 - 'text/vcard; version=4.0', - // vCard 3 - 'text/vcard; version=3.0', - // jCard - 'application/vcard+json', - ] - ); - - $mimeType = $result; - switch ($result) { - default: - case 'text/x-vcard': - case 'text/vcard': - case 'text/vcard; version=3.0': - $mimeType = 'text/vcard'; - - return 'vcard3'; - case 'text/vcard; version=4.0': - return 'vcard4'; - case 'application/vcard+json': - return 'jcard'; - - // @codeCoverageIgnoreStart - } - // @codeCoverageIgnoreEnd - } - - /** - * Converts a vcard blob to a different version, or jcard. - * - * @param string|resource $data - * @param string $target - * @param array $propertiesFilter - * - * @return string - */ - protected function convertVCard($data, $target, ?array $propertiesFilter = null) - { - if (is_resource($data)) { - $data = stream_get_contents($data); - } - $input = VObject\Reader::read($data); - if (!empty($propertiesFilter)) { - $propertiesFilter = array_merge(['UID', 'VERSION', 'FN'], $propertiesFilter); - $keys = array_unique(array_map(function ($child) { - return $child->name; - }, $input->children())); - $keys = array_diff($keys, $propertiesFilter); - foreach ($keys as $key) { - unset($input->$key); - } - $data = $input->serialize(); - } - $output = null; - try { - switch ($target) { - default: - case 'vcard3': - if (VObject\Document::VCARD30 === $input->getDocumentType()) { - // Do nothing - return $data; - } - $output = $input->convert(VObject\Document::VCARD30); - - return $output->serialize(); - case 'vcard4': - if (VObject\Document::VCARD40 === $input->getDocumentType()) { - // Do nothing - return $data; - } - $output = $input->convert(VObject\Document::VCARD40); - - return $output->serialize(); - case 'jcard': - $output = $input->convert(VObject\Document::VCARD40); - - return json_encode($output); - } - } finally { - // Destroy circular references to PHP will GC the object. - $input->destroy(); - if (!is_null($output)) { - $output->destroy(); - } - } - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'carddav'; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds support for CardDAV (rfc6352)', - 'link' => 'http://sabre.io/dav/carddav/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php b/lib/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php deleted file mode 100644 index 431391e..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php +++ /dev/null @@ -1,165 +0,0 @@ -server = $server; - $this->server->on('method:GET', [$this, 'httpGet'], 90); - $server->on('browserButtonActions', function ($path, $node, &$actions) { - if ($node instanceof IAddressBook) { - $actions .= ''; - } - }); - } - - /** - * Intercepts GET requests on addressbook urls ending with ?export. - * - * @return bool - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - $queryParams = $request->getQueryParameters(); - if (!array_key_exists('export', $queryParams)) { - return; - } - - $path = $request->getPath(); - - $node = $this->server->tree->getNodeForPath($path); - - if (!($node instanceof IAddressBook)) { - return; - } - - $this->server->transactionType = 'get-addressbook-export'; - - // Checking ACL, if available. - if ($aclPlugin = $this->server->getPlugin('acl')) { - $aclPlugin->checkPrivileges($path, '{DAV:}read'); - } - - $nodes = $this->server->getPropertiesForPath($path, [ - '{'.Plugin::NS_CARDDAV.'}address-data', - ], 1); - - $format = 'text/directory'; - - $output = null; - $filenameExtension = null; - - switch ($format) { - case 'text/directory': - $output = $this->generateVCF($nodes); - $filenameExtension = '.vcf'; - break; - } - - $filename = preg_replace( - '/[^a-zA-Z0-9-_ ]/um', - '', - $node->getName() - ); - $filename .= '-'.date('Y-m-d').$filenameExtension; - - $response->setHeader('Content-Disposition', 'attachment; filename="'.$filename.'"'); - $response->setHeader('Content-Type', $format); - - $response->setStatus(200); - $response->setBody($output); - - // Returning false to break the event chain - return false; - } - - /** - * Merges all vcard objects, and builds one big vcf export. - * - * @return string - */ - public function generateVCF(array $nodes) - { - $output = ''; - - foreach ($nodes as $node) { - if (!isset($node[200]['{'.Plugin::NS_CARDDAV.'}address-data'])) { - continue; - } - $nodeData = $node[200]['{'.Plugin::NS_CARDDAV.'}address-data']; - - // Parsing this node so VObject can clean up the output. - $vcard = VObject\Reader::read($nodeData); - $output .= $vcard->serialize(); - - // Destroy circular references to PHP will GC the object. - $vcard->destroy(); - } - - return $output; - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using \Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'vcf-export'; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds the ability to export CardDAV addressbooks as a single vCard file.', - 'link' => 'http://sabre.io/dav/vcf-export-plugin/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php b/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php deleted file mode 100644 index b60fceb..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/AddressData.php +++ /dev/null @@ -1,66 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = [ - 'contentType' => $reader->getAttribute('content-type') ?: 'text/vcard', - 'version' => $reader->getAttribute('version') ?: '3.0', - ]; - - $elems = (array) $reader->parseInnerTree(); - $elems = array_filter($elems, function ($element) { - return '{urn:ietf:params:xml:ns:carddav}prop' === $element['name'] && - isset($element['attributes']['name']); - }); - $result['addressDataProperties'] = array_map(function ($element) { - return $element['attributes']['name']; - }, $elems); - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php b/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php deleted file mode 100644 index 0a7ec06..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/ParamFilter.php +++ /dev/null @@ -1,86 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = [ - 'name' => null, - 'is-not-defined' => false, - 'text-match' => null, - ]; - - $att = $reader->parseAttributes(); - $result['name'] = $att['name']; - - $elems = $reader->parseInnerTree(); - - if (is_array($elems)) { - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{'.Plugin::NS_CARDDAV.'}is-not-defined': - $result['is-not-defined'] = true; - break; - case '{'.Plugin::NS_CARDDAV.'}text-match': - $matchType = isset($elem['attributes']['match-type']) ? $elem['attributes']['match-type'] : 'contains'; - - if (!in_array($matchType, ['contains', 'equals', 'starts-with', 'ends-with'])) { - throw new BadRequest('Unknown match-type: '.$matchType); - } - $result['text-match'] = [ - 'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'], - 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;unicode-casemap', - 'value' => $elem['value'], - 'match-type' => $matchType, - ]; - break; - } - } - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php b/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php deleted file mode 100644 index 5dedac8..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Filter/PropFilter.php +++ /dev/null @@ -1,95 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = [ - 'name' => null, - 'test' => 'anyof', - 'is-not-defined' => false, - 'param-filters' => [], - 'text-matches' => [], - ]; - - $att = $reader->parseAttributes(); - $result['name'] = $att['name']; - - if (isset($att['test']) && 'allof' === $att['test']) { - $result['test'] = 'allof'; - } - - $elems = $reader->parseInnerTree(); - - if (is_array($elems)) { - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{'.Plugin::NS_CARDDAV.'}param-filter': - $result['param-filters'][] = $elem['value']; - break; - case '{'.Plugin::NS_CARDDAV.'}is-not-defined': - $result['is-not-defined'] = true; - break; - case '{'.Plugin::NS_CARDDAV.'}text-match': - $matchType = isset($elem['attributes']['match-type']) ? $elem['attributes']['match-type'] : 'contains'; - - if (!in_array($matchType, ['contains', 'equals', 'starts-with', 'ends-with'])) { - throw new BadRequest('Unknown match-type: '.$matchType); - } - $result['text-matches'][] = [ - 'negate-condition' => isset($elem['attributes']['negate-condition']) && 'yes' === $elem['attributes']['negate-condition'], - 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;unicode-casemap', - 'value' => $elem['value'], - 'match-type' => $matchType, - ]; - break; - } - } - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php b/lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php deleted file mode 100644 index 536c5a1..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedAddressData.php +++ /dev/null @@ -1,77 +0,0 @@ - 'text/vcard', 'version' => '3.0'], - ['contentType' => 'text/vcard', 'version' => '4.0'], - ['contentType' => 'application/vcard+json', 'version' => '4.0'], - ]; - } - - $this->supportedData = $supportedData; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->supportedData as $supported) { - $writer->startElement('{'.Plugin::NS_CARDDAV.'}address-data-type'); - $writer->writeAttributes([ - 'content-type' => $supported['contentType'], - 'version' => $supported['version'], - ]); - $writer->endElement(); // address-data-type - } - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php b/lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php deleted file mode 100644 index b19eddd..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Property/SupportedCollationSet.php +++ /dev/null @@ -1,44 +0,0 @@ -writeElement('{urn:ietf:params:xml:ns:carddav}supported-collation', $coll); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php b/lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php deleted file mode 100644 index 491f969..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookMultiGetReport.php +++ /dev/null @@ -1,116 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseInnerTree([ - '{urn:ietf:params:xml:ns:carddav}address-data' => 'Sabre\\CardDAV\\Xml\\Filter\\AddressData', - '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', - ]); - - $newProps = [ - 'hrefs' => [], - 'properties' => [], - ]; - - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{DAV:}prop': - $newProps['properties'] = array_keys($elem['value']); - if (isset($elem['value']['{'.Plugin::NS_CARDDAV.'}address-data'])) { - $newProps += $elem['value']['{'.Plugin::NS_CARDDAV.'}address-data']; - } - break; - case '{DAV:}href': - $newProps['hrefs'][] = Uri\resolve($reader->contextUri, $elem['value']); - break; - } - } - - $obj = new self(); - foreach ($newProps as $key => $value) { - $obj->$key = $value; - } - - return $obj; - } -} diff --git a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php b/lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php deleted file mode 100644 index 02402f6..0000000 --- a/lib/vendor/sabre/dav/lib/CardDAV/Xml/Request/AddressBookQueryReport.php +++ /dev/null @@ -1,193 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = (array) $reader->parseInnerTree([ - '{urn:ietf:params:xml:ns:carddav}prop-filter' => 'Sabre\\CardDAV\\Xml\\Filter\\PropFilter', - '{urn:ietf:params:xml:ns:carddav}param-filter' => 'Sabre\\CardDAV\\Xml\\Filter\\ParamFilter', - '{urn:ietf:params:xml:ns:carddav}address-data' => 'Sabre\\CardDAV\\Xml\\Filter\\AddressData', - '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', - ]); - - $newProps = [ - 'filters' => null, - 'properties' => [], - 'test' => 'anyof', - 'limit' => null, - ]; - - if (!is_array($elems)) { - $elems = []; - } - - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{DAV:}prop': - $newProps['properties'] = array_keys($elem['value']); - if (isset($elem['value']['{'.Plugin::NS_CARDDAV.'}address-data'])) { - $newProps += $elem['value']['{'.Plugin::NS_CARDDAV.'}address-data']; - } - break; - case '{'.Plugin::NS_CARDDAV.'}filter': - if (!is_null($newProps['filters'])) { - throw new BadRequest('You can only include 1 {'.Plugin::NS_CARDDAV.'}filter element'); - } - if (isset($elem['attributes']['test'])) { - $newProps['test'] = $elem['attributes']['test']; - if ('allof' !== $newProps['test'] && 'anyof' !== $newProps['test']) { - throw new BadRequest('The "test" attribute must be one of "allof" or "anyof"'); - } - } - - $newProps['filters'] = []; - foreach ((array) $elem['value'] as $subElem) { - if ($subElem['name'] === '{'.Plugin::NS_CARDDAV.'}prop-filter') { - $newProps['filters'][] = $subElem['value']; - } - } - break; - case '{'.Plugin::NS_CARDDAV.'}limit': - foreach ($elem['value'] as $child) { - if ($child['name'] === '{'.Plugin::NS_CARDDAV.'}nresults') { - $newProps['limit'] = (int) $child['value']; - } - } - break; - } - } - - if (is_null($newProps['filters'])) { - /* - * We are supposed to throw this error, but KDE sometimes does not - * include the filter element, and we need to treat it as if no - * filters are supplied - */ - //throw new BadRequest('The {' . Plugin::NS_CARDDAV . '}filter element is required for this request'); - $newProps['filters'] = []; - } - - $obj = new self(); - foreach ($newProps as $key => $value) { - $obj->$key = $value; - } - - return $obj; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php deleted file mode 100644 index 3132333..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php +++ /dev/null @@ -1,136 +0,0 @@ -realm = $realm; - } - - /** - * When this method is called, the backend must check if authentication was - * successful. - * - * The returned value must be one of the following - * - * [true, "principals/username"] - * [false, "reason for failure"] - * - * If authentication was successful, it's expected that the authentication - * backend returns a so-called principal url. - * - * Examples of a principal url: - * - * principals/admin - * principals/user1 - * principals/users/joe - * principals/uid/123457 - * - * If you don't use WebDAV ACL (RFC3744) we recommend that you simply - * return a string such as: - * - * principals/users/[username] - * - * @return array - */ - public function check(RequestInterface $request, ResponseInterface $response) - { - $auth = new HTTP\Auth\Basic( - $this->realm, - $request, - $response - ); - - $userpass = $auth->getCredentials(); - if (!$userpass) { - return [false, "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured"]; - } - if (!$this->validateUserPass($userpass[0], $userpass[1])) { - return [false, 'Username or password was incorrect']; - } - - return [true, $this->principalPrefix.$userpass[0]]; - } - - /** - * This method is called when a user could not be authenticated, and - * authentication was required for the current request. - * - * This gives you the opportunity to set authentication headers. The 401 - * status code will already be set. - * - * In this case of Basic Auth, this would for example mean that the - * following header needs to be set: - * - * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); - * - * Keep in mind that in the case of multiple authentication backends, other - * WWW-Authenticate headers may already have been set, and you'll want to - * append your own WWW-Authenticate header instead of overwriting the - * existing one. - */ - public function challenge(RequestInterface $request, ResponseInterface $response) - { - $auth = new HTTP\Auth\Basic( - $this->realm, - $request, - $response - ); - $auth->requireLogin(); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php deleted file mode 100644 index b681747..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php +++ /dev/null @@ -1,130 +0,0 @@ -realm = $realm; - } - - /** - * When this method is called, the backend must check if authentication was - * successful. - * - * The returned value must be one of the following - * - * [true, "principals/username"] - * [false, "reason for failure"] - * - * If authentication was successful, it's expected that the authentication - * backend returns a so-called principal url. - * - * Examples of a principal url: - * - * principals/admin - * principals/user1 - * principals/users/joe - * principals/uid/123457 - * - * If you don't use WebDAV ACL (RFC3744) we recommend that you simply - * return a string such as: - * - * principals/users/[username] - * - * @return array - */ - public function check(RequestInterface $request, ResponseInterface $response) - { - $auth = new HTTP\Auth\Bearer( - $this->realm, - $request, - $response - ); - - $bearerToken = $auth->getToken($request); - if (!$bearerToken) { - return [false, "No 'Authorization: Bearer' header found. Either the client didn't send one, or the server is mis-configured"]; - } - $principalUrl = $this->validateBearerToken($bearerToken); - if (!$principalUrl) { - return [false, 'Bearer token was incorrect']; - } - - return [true, $principalUrl]; - } - - /** - * This method is called when a user could not be authenticated, and - * authentication was required for the current request. - * - * This gives you the opportunity to set authentication headers. The 401 - * status code will already be set. - * - * In this case of Bearer Auth, this would for example mean that the - * following header needs to be set: - * - * $response->addHeader('WWW-Authenticate', 'Bearer realm=SabreDAV'); - * - * Keep in mind that in the case of multiple authentication backends, other - * WWW-Authenticate headers may already have been set, and you'll want to - * append your own WWW-Authenticate header instead of overwriting the - * existing one. - */ - public function challenge(RequestInterface $request, ResponseInterface $response) - { - $auth = new HTTP\Auth\Bearer( - $this->realm, - $request, - $response - ); - $auth->requireLogin(); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php deleted file mode 100644 index 297655d..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php +++ /dev/null @@ -1,160 +0,0 @@ -realm = $realm; - } - - /** - * Returns a users digest hash based on the username and realm. - * - * If the user was not known, null must be returned. - * - * @param string $realm - * @param string $username - * - * @return string|null - */ - abstract public function getDigestHash($realm, $username); - - /** - * When this method is called, the backend must check if authentication was - * successful. - * - * The returned value must be one of the following - * - * [true, "principals/username"] - * [false, "reason for failure"] - * - * If authentication was successful, it's expected that the authentication - * backend returns a so-called principal url. - * - * Examples of a principal url: - * - * principals/admin - * principals/user1 - * principals/users/joe - * principals/uid/123457 - * - * If you don't use WebDAV ACL (RFC3744) we recommend that you simply - * return a string such as: - * - * principals/users/[username] - * - * @return array - */ - public function check(RequestInterface $request, ResponseInterface $response) - { - $digest = new HTTP\Auth\Digest( - $this->realm, - $request, - $response - ); - $digest->init(); - - $username = $digest->getUsername(); - - // No username was given - if (!$username) { - return [false, "No 'Authorization: Digest' header found. Either the client didn't send one, or the server is misconfigured"]; - } - - $hash = $this->getDigestHash($this->realm, $username); - // If this was false, the user account didn't exist - if (false === $hash || is_null($hash)) { - return [false, 'Username or password was incorrect']; - } - if (!is_string($hash)) { - throw new DAV\Exception('The returned value from getDigestHash must be a string or null'); - } - - // If this was false, the password or part of the hash was incorrect. - if (!$digest->validateA1($hash)) { - return [false, 'Username or password was incorrect']; - } - - return [true, $this->principalPrefix.$username]; - } - - /** - * This method is called when a user could not be authenticated, and - * authentication was required for the current request. - * - * This gives you the opportunity to set authentication headers. The 401 - * status code will already be set. - * - * In this case of Basic Auth, this would for example mean that the - * following header needs to be set: - * - * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); - * - * Keep in mind that in the case of multiple authentication backends, other - * WWW-Authenticate headers may already have been set, and you'll want to - * append your own WWW-Authenticate header instead of overwriting the - * existing one. - */ - public function challenge(RequestInterface $request, ResponseInterface $response) - { - $auth = new HTTP\Auth\Digest( - $this->realm, - $request, - $response - ); - $auth->init(); - - $oldStatus = $response->getStatus() ?: 200; - $auth->requireLogin(); - - // Preventing the digest utility from modifying the http status code, - // this should be handled by the main plugin. - $response->setStatus($oldStatus); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php deleted file mode 100644 index ebf67ca..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php +++ /dev/null @@ -1,93 +0,0 @@ -getRawServerValue('REMOTE_USER'); - if (is_null($remoteUser)) { - $remoteUser = $request->getRawServerValue('REDIRECT_REMOTE_USER'); - } - if (is_null($remoteUser)) { - $remoteUser = $request->getRawServerValue('PHP_AUTH_USER'); - } - if (is_null($remoteUser)) { - return [false, 'No REMOTE_USER, REDIRECT_REMOTE_USER, or PHP_AUTH_USER property was found in the PHP $_SERVER super-global. This likely means your server is not configured correctly']; - } - - return [true, $this->principalPrefix.$remoteUser]; - } - - /** - * This method is called when a user could not be authenticated, and - * authentication was required for the current request. - * - * This gives you the opportunity to set authentication headers. The 401 - * status code will already be set. - * - * In this case of Basic Auth, this would for example mean that the - * following header needs to be set: - * - * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); - * - * Keep in mind that in the case of multiple authentication backends, other - * WWW-Authenticate headers may already have been set, and you'll want to - * append your own WWW-Authenticate header instead of overwriting the - * existing one. - */ - public function challenge(RequestInterface $request, ResponseInterface $response) - { - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php deleted file mode 100644 index 133eac9..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php +++ /dev/null @@ -1,65 +0,0 @@ -addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); - * - * Keep in mind that in the case of multiple authentication backends, other - * WWW-Authenticate headers may already have been set, and you'll want to - * append your own WWW-Authenticate header instead of overwriting the - * existing one. - */ - public function challenge(RequestInterface $request, ResponseInterface $response); -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php deleted file mode 100644 index 5a8bb98..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php +++ /dev/null @@ -1,56 +0,0 @@ -callBack = $callBack; - } - - /** - * Validates a username and password. - * - * This method should return true or false depending on if login - * succeeded. - * - * @param string $username - * @param string $password - * - * @return bool - */ - protected function validateUserPass($username, $password) - { - $cb = $this->callBack; - - return $cb($username, $password); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php deleted file mode 100644 index ea2d396..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php +++ /dev/null @@ -1,74 +0,0 @@ -loadFile($filename); - } - } - - /** - * Loads an htdigest-formatted file. This method can be called multiple times if - * more than 1 file is used. - * - * @param string $filename - */ - public function loadFile($filename) - { - foreach (file($filename, FILE_IGNORE_NEW_LINES) as $line) { - if (2 !== substr_count($line, ':')) { - throw new 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 DAV\Exception('Malformed htdigest file. Invalid md5 hash'); - } - $this->users[$realm.':'.$username] = $A1; - } - } - - /** - * Returns a users' information. - * - * @param string $realm - * @param string $username - * - * @return string - */ - public function getDigestHash($realm, $username) - { - return isset($this->users[$realm.':'.$username]) ? $this->users[$realm.':'.$username] : false; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/IMAP.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/IMAP.php deleted file mode 100644 index 3a18311..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/IMAP.php +++ /dev/null @@ -1,82 +0,0 @@ -mailbox = $mailbox; - } - - /** - * Connects to an IMAP server and tries to authenticate. - * - * @param string $username - * @param string $password - * - * @return bool - */ - protected function imapOpen($username, $password) - { - $success = false; - - try { - $imap = imap_open($this->mailbox, $username, $password, OP_HALFOPEN | OP_READONLY, 1); - if ($imap) { - $success = true; - } - } catch (\ErrorException $e) { - error_log($e->getMessage()); - } - - $errors = imap_errors(); - if ($errors) { - foreach ($errors as $error) { - error_log($error); - } - } - - if (isset($imap) && $imap) { - imap_close($imap); - } - - return $success; - } - - /** - * Validates a username and password by trying to authenticate against IMAP. - * - * @param string $username - * @param string $password - * - * @return bool - */ - protected function validateUserPass($username, $password) - { - return $this->imapOpen($username, $password); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php deleted file mode 100644 index 9a06912..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php +++ /dev/null @@ -1,55 +0,0 @@ -pdo = $pdo; - } - - /** - * 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 digesta1 FROM '.$this->tableName.' WHERE username = ?'); - $stmt->execute([$username]); - - return $stmt->fetchColumn() ?: null; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDOBasicAuth.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDOBasicAuth.php deleted file mode 100644 index d142cbf..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Backend/PDOBasicAuth.php +++ /dev/null @@ -1,114 +0,0 @@ -pdo = $pdo; - if (isset($options['tableName'])) { - $this->tableName = $options['tableName']; - } else { - $this->tableName = 'users'; - } - if (isset($options['digestColumn'])) { - $this->digestColumn = $options['digestColumn']; - } else { - $this->digestColumn = 'digest'; - } - if (isset($options['uuidColumn'])) { - $this->uuidColumn = $options['uuidColumn']; - } else { - $this->uuidColumn = 'username'; - } - if (isset($options['digestPrefix'])) { - $this->digestPrefix = $options['digestPrefix']; - } - } - - /** - * Validates a username and password. - * - * This method should return true or false depending on if login - * succeeded. - * - * @param string $username - * @param string $password - * - * @return bool - */ - public function validateUserPass($username, $password) - { - $stmt = $this->pdo->prepare('SELECT '.$this->digestColumn.' FROM '.$this->tableName.' WHERE '.$this->uuidColumn.' = ?'); - $stmt->execute([$username]); - $result = $stmt->fetchAll(); - - if (!count($result)) { - return false; - } else { - $digest = $result[0][$this->digestColumn]; - - if (isset($this->digestPrefix)) { - $digest = substr($digest, strlen($this->digestPrefix)); - } - - if (password_verify($password, $digest)) { - return true; - } - - return false; - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Auth/Plugin.php b/lib/vendor/sabre/dav/lib/DAV/Auth/Plugin.php deleted file mode 100644 index 47fbe20..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Auth/Plugin.php +++ /dev/null @@ -1,255 +0,0 @@ -addBackend($authBackend); - } - } - - /** - * Adds an authentication backend to the plugin. - */ - public function addBackend(Backend\BackendInterface $authBackend) - { - $this->backends[] = $authBackend; - } - - /** - * Initializes the plugin. This function is automatically called by the server. - */ - public function initialize(Server $server) - { - $server->on('beforeMethod:*', [$this, 'beforeMethod'], 10); - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'auth'; - } - - /** - * Returns the currently logged-in principal. - * - * This will return a string such as: - * - * principals/username - * principals/users/username - * - * This method will return null if nobody is logged in. - * - * @return string|null - */ - public function getCurrentPrincipal() - { - return $this->currentPrincipal; - } - - /** - * This method is called before any HTTP method and forces users to be authenticated. - */ - public function beforeMethod(RequestInterface $request, ResponseInterface $response) - { - if ($this->currentPrincipal) { - // We already have authentication information. This means that the - // event has already fired earlier, and is now likely fired for a - // sub-request. - // - // We don't want to authenticate users twice, so we simply don't do - // anything here. See Issue #700 for additional reasoning. - // - // This is not a perfect solution, but will be fixed once the - // "currently authenticated principal" is information that's not - // not associated with the plugin, but rather per-request. - // - // See issue #580 for more information about that. - return; - } - - $authResult = $this->check($request, $response); - - if ($authResult[0]) { - // Auth was successful - $this->currentPrincipal = $authResult[1]; - $this->loginFailedReasons = null; - - return; - } - - // If we got here, it means that no authentication backend was - // successful in authenticating the user. - $this->currentPrincipal = null; - $this->loginFailedReasons = $authResult[1]; - - if ($this->autoRequireLogin) { - $this->challenge($request, $response); - throw new NotAuthenticated(implode(', ', $authResult[1])); - } - } - - /** - * Checks authentication credentials, and logs the user in if possible. - * - * This method returns an array. The first item in the array is a boolean - * indicating if login was successful. - * - * If login was successful, the second item in the array will contain the - * current principal url/path of the logged in user. - * - * If login was not successful, the second item in the array will contain a - * an array with strings. The strings are a list of reasons why login was - * unsuccessful. For every auth backend there will be one reason, so usually - * there's just one. - * - * @return array - */ - public function check(RequestInterface $request, ResponseInterface $response) - { - if (!$this->backends) { - throw new \Sabre\DAV\Exception('No authentication backends were configured on this server.'); - } - $reasons = []; - foreach ($this->backends as $backend) { - $result = $backend->check( - $request, - $response - ); - - if (!is_array($result) || 2 !== count($result) || !is_bool($result[0]) || !is_string($result[1])) { - throw new \Sabre\DAV\Exception('The authentication backend did not return a correct value from the check() method.'); - } - - if ($result[0]) { - $this->currentPrincipal = $result[1]; - // Exit early - return [true, $result[1]]; - } - $reasons[] = $result[1]; - } - - return [false, $reasons]; - } - - /** - * This method sends authentication challenges to the user. - * - * This method will for example cause a HTTP Basic backend to set a - * WWW-Authorization header, indicating to the client that it should - * authenticate. - */ - public function challenge(RequestInterface $request, ResponseInterface $response) - { - foreach ($this->backends as $backend) { - $backend->challenge($request, $response); - } - } - - /** - * List of reasons why login failed for the last login operation. - * - * @var string[]|null - */ - protected $loginFailedReasons; - - /** - * Returns a list of reasons why login was unsuccessful. - * - * This method will return the login failed reasons for the last login - * operation. One for each auth backend. - * - * This method returns null if the last authentication attempt was - * successful, or if there was no authentication attempt yet. - * - * @return string[]|null - */ - public function getLoginFailedReasons() - { - return $this->loginFailedReasons; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Generic authentication plugin', - 'link' => 'http://sabre.io/dav/authentication/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php b/lib/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php deleted file mode 100644 index 5cda0b8..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/GuessContentType.php +++ /dev/null @@ -1,93 +0,0 @@ - 'image/jpeg', - 'gif' => 'image/gif', - 'png' => 'image/png', - - // groupware - 'ics' => 'text/calendar', - 'vcf' => 'text/vcard', - - // text - 'txt' => 'text/plain', - ]; - - /** - * Initializes the plugin. - */ - public function initialize(DAV\Server $server) - { - // Using a relatively low priority (200) to allow other extensions - // to set the content-type first. - $server->on('propFind', [$this, 'propFind'], 200); - } - - /** - * Our PROPFIND handler. - * - * Here we set a contenttype, if the node didn't already have one. - */ - public function propFind(PropFind $propFind, INode $node) - { - $propFind->handle('{DAV:}getcontenttype', function () use ($propFind) { - list(, $fileName) = Uri\split($propFind->getPath()); - - return $this->getContentType($fileName); - }); - } - - /** - * Simple method to return the contenttype. - * - * @param string $fileName - * - * @return string - */ - protected function getContentType($fileName) - { - if (null !== $fileName) { - // Just grabbing the extension - $extension = strtolower(substr($fileName, strrpos($fileName, '.') + 1)); - if (isset($this->extensionMap[$extension])) { - return $this->extensionMap[$extension]; - } - } - - return 'application/octet-stream'; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/HtmlOutput.php b/lib/vendor/sabre/dav/lib/DAV/Browser/HtmlOutput.php deleted file mode 100644 index be5a284..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/HtmlOutput.php +++ /dev/null @@ -1,34 +0,0 @@ -baseUri = $baseUri; - $this->namespaceMap = $namespaceMap; - } - - /** - * Generates a 'full' url based on a relative one. - * - * For relative urls, the base of the application is taken as the reference - * url, not the 'current url of the current request'. - * - * Absolute urls are left alone. - * - * @param string $path - * - * @return string - */ - public function fullUrl($path) - { - return Uri\resolve($this->baseUri, $path); - } - - /** - * Escape string for HTML output. - * - * @param scalar $input - * - * @return string - */ - public function h($input) - { - return htmlspecialchars((string) $input, ENT_COMPAT, 'UTF-8'); - } - - /** - * Generates a full -tag. - * - * Url is automatically expanded. If label is not specified, we re-use the - * url. - * - * @param string $url - * @param string $label - * - * @return string - */ - public function link($url, $label = null) - { - $url = $this->h($this->fullUrl($url)); - - return ''.($label ? $this->h($label) : $url).''; - } - - /** - * This method takes an xml element in clark-notation, and turns it into a - * shortened version with a prefix, if it was a known namespace. - * - * @param string $element - * - * @return string - */ - public function xmlName($element) - { - list($ns, $localName) = XmlService::parseClarkNotation($element); - if (isset($this->namespaceMap[$ns])) { - $propName = $this->namespaceMap[$ns].':'.$localName; - } else { - $propName = $element; - } - - return ''.$this->h($propName).''; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php b/lib/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php deleted file mode 100644 index 0bbe70c..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/MapGetToPropFind.php +++ /dev/null @@ -1,58 +0,0 @@ -server = $server; - $this->server->on('method:GET', [$this, 'httpGet'], 90); - } - - /** - * This method intercepts GET requests to non-files, and changes it into an HTTP PROPFIND request. - * - * @return bool - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - $node = $this->server->tree->getNodeForPath($request->getPath()); - if ($node instanceof DAV\IFile) { - return; - } - - $subRequest = clone $request; - $subRequest->setMethod('PROPFIND'); - - $this->server->invokeMethod($subRequest, $response); - - return false; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/Plugin.php b/lib/vendor/sabre/dav/lib/DAV/Browser/Plugin.php deleted file mode 100644 index a8a6f43..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/Plugin.php +++ /dev/null @@ -1,789 +0,0 @@ -enablePost = $enablePost; - } - - /** - * Initializes the plugin and subscribes to events. - */ - public function initialize(DAV\Server $server) - { - $this->server = $server; - $this->server->on('method:GET', [$this, 'httpGetEarly'], 90); - $this->server->on('method:GET', [$this, 'httpGet'], 200); - $this->server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel'], 200); - if ($this->enablePost) { - $this->server->on('method:POST', [$this, 'httpPOST']); - } - } - - /** - * This method intercepts GET requests that have ?sabreAction=info - * appended to the URL. - */ - public function httpGetEarly(RequestInterface $request, ResponseInterface $response) - { - $params = $request->getQueryParameters(); - if (isset($params['sabreAction']) && 'info' === $params['sabreAction']) { - return $this->httpGet($request, $response); - } - } - - /** - * This method intercepts GET requests to collections and returns the html. - * - * @return bool - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - // We're not using straight-up $_GET, because we want everything to be - // unit testable. - $getVars = $request->getQueryParameters(); - - // CSP headers - $response->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"); - - $sabreAction = isset($getVars['sabreAction']) ? $getVars['sabreAction'] : null; - - switch ($sabreAction) { - case 'asset': - // Asset handling, such as images - $this->serveAsset(isset($getVars['assetName']) ? $getVars['assetName'] : null); - - return false; - default: - case 'info': - try { - $this->server->tree->getNodeForPath($request->getPath()); - } catch (DAV\Exception\NotFound $e) { - // We're simply stopping when the file isn't found to not interfere - // with other plugins. - return; - } - - $response->setStatus(200); - $response->setHeader('Content-Type', 'text/html; charset=utf-8'); - - $response->setBody( - $this->generateDirectoryIndex($request->getPath()) - ); - - return false; - - case 'plugins': - $response->setStatus(200); - $response->setHeader('Content-Type', 'text/html; charset=utf-8'); - - $response->setBody( - $this->generatePluginListing() - ); - - return false; - } - } - - /** - * Handles POST requests for tree operations. - * - * @return bool - */ - public function httpPOST(RequestInterface $request, ResponseInterface $response) - { - $contentType = $request->getHeader('Content-Type'); - if (!\is_string($contentType)) { - return; - } - list($contentType) = explode(';', $contentType); - if ('application/x-www-form-urlencoded' !== $contentType && - 'multipart/form-data' !== $contentType) { - return; - } - $postVars = $request->getPostData(); - - if (!isset($postVars['sabreAction'])) { - return; - } - - $uri = $request->getPath(); - - if ($this->server->emit('onBrowserPostAction', [$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) = Uri\split(trim($postVars['name'])); - - if (isset($postVars['resourceType'])) { - $resourceType = explode(',', $postVars['resourceType']); - } else { - $resourceType = ['{DAV:}collection']; - } - - $properties = []; - foreach ($postVars as $varName => $varValue) { - // Any _POST variable in clark notation is treated - // like a property. - if ('{' === $varName[0]) { - // PHP will convert any dots to underscores. - // This leaves us with no way to differentiate - // the two. - // Therefore we replace the string *DOT* with a - // real dot. * is not allowed in uris so we - // should be good. - $varName = str_replace('*DOT*', '.', $varName); - $properties[$varName] = $varValue; - } - } - - $mkCol = new MkCol( - $resourceType, - $properties - ); - $this->server->createCollection($uri.'/'.$folderName, $mkCol); - } - break; - - // @codeCoverageIgnoreStart - case 'put': - if ($_FILES) { - $file = current($_FILES); - } else { - break; - } - - list(, $newName) = Uri\split(trim($file['name'])); - if (isset($postVars['name']) && trim($postVars['name'])) { - $newName = trim($postVars['name']); - } - - // Making sure we only have a 'basename' component - list(, $newName) = Uri\split($newName); - - if (is_uploaded_file($file['tmp_name'])) { - $this->server->createFile($uri.'/'.$newName, fopen($file['tmp_name'], 'r')); - } - break; - // @codeCoverageIgnoreEnd - } - } - $response->setHeader('Location', $request->getUrl()); - $response->setStatus(302); - - return false; - } - - /** - * Escapes a string for html. - * - * @param string $value - * - * @return string - */ - public function escapeHTML($value) - { - return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); - } - - /** - * Generates the html directory index for a given url. - * - * @param string $path - * - * @return string - */ - public function generateDirectoryIndex($path) - { - $html = $this->generateHeader($path ? $path : '/', $path); - - $node = $this->server->tree->getNodeForPath($path); - if ($node instanceof DAV\ICollection) { - $html .= "

Nodes

\n"; - $html .= ''; - - $subNodes = $this->server->getPropertiesForChildren($path, [ - '{DAV:}displayname', - '{DAV:}resourcetype', - '{DAV:}getcontenttype', - '{DAV:}getcontentlength', - '{DAV:}getlastmodified', - ]); - - foreach ($subNodes as $subPath => $subProps) { - $subNode = $this->server->tree->getNodeForPath($subPath); - $fullPath = $this->server->getBaseUri().HTTP\encodePath($subPath); - list(, $displayPath) = Uri\split($subPath); - - $subNodes[$subPath]['subNode'] = $subNode; - $subNodes[$subPath]['fullPath'] = $fullPath; - $subNodes[$subPath]['displayPath'] = $displayPath; - } - uasort($subNodes, [$this, 'compareNodes']); - - foreach ($subNodes as $subProps) { - $type = [ - 'string' => 'Unknown', - 'icon' => 'cog', - ]; - if (isset($subProps['{DAV:}resourcetype'])) { - $type = $this->mapResourceType($subProps['{DAV:}resourcetype']->getValue(), $subProps['subNode']); - } - - $html .= ''; - $html .= ''; - $html .= ''; - $html .= ''; - - $buttonActions = ''; - if ($subProps['subNode'] instanceof DAV\IFile) { - $buttonActions = ''; - } - $this->server->emit('browserButtonActions', [$subProps['fullPath'], $subProps['subNode'], &$buttonActions]); - - $html .= ''; - $html .= ''; - } - - $html .= '
'.$this->escapeHTML($subProps['displayPath']).''.$this->escapeHTML($type['string']).''; - if (isset($subProps['{DAV:}getcontentlength'])) { - $html .= $this->escapeHTML($subProps['{DAV:}getcontentlength'].' bytes'); - } - $html .= ''; - if (isset($subProps['{DAV:}getlastmodified'])) { - $lastMod = $subProps['{DAV:}getlastmodified']->getTime(); - $html .= $this->escapeHTML($lastMod->format('F j, Y, g:i a')); - } - $html .= ''; - if (isset($subProps['{DAV:}displayname'])) { - $html .= $this->escapeHTML($subProps['{DAV:}displayname']); - } - $html .= ''.$buttonActions.'
'; - } - - $html .= '
'; - $html .= '

Properties

'; - $html .= ''; - - // Allprops request - $propFind = new PropFindAll($path); - $properties = $this->server->getPropertiesByNode($propFind, $node); - - $properties = $propFind->getResultForMultiStatus()[200]; - - foreach ($properties as $propName => $propValue) { - if (!in_array($propName, $this->uninterestingProperties)) { - $html .= $this->drawPropertyRow($propName, $propValue); - } - } - - $html .= '
'; - $html .= '
'; - - /* Start of generating actions */ - - $output = ''; - if ($this->enablePost) { - $this->server->emit('onHTMLActionsPanel', [$node, &$output, $path]); - } - - if ($output) { - $html .= '

Actions

'; - $html .= "
\n"; - $html .= $output; - $html .= "
\n"; - $html .= "
\n"; - } - - $html .= $this->generateFooter(); - - $this->server->httpResponse->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"); - - return $html; - } - - /** - * Generates the 'plugins' page. - * - * @return string - */ - public function generatePluginListing() - { - $html = $this->generateHeader('Plugins'); - - $html .= '

Plugins

'; - $html .= ''; - foreach ($this->server->getPlugins() as $plugin) { - $info = $plugin->getPluginInfo(); - $html .= ''; - $html .= ''; - $html .= ''; - } - $html .= '
'.$info['name'].''.$info['description'].''; - if (isset($info['link']) && $info['link']) { - $html .= ''; - } - $html .= '
'; - $html .= '
'; - - /* Start of generating actions */ - - $html .= $this->generateFooter(); - - return $html; - } - - /** - * Generates the first block of HTML, including the tag and page - * header. - * - * Returns footer. - * - * @param string $title - * @param string $path - * - * @return string - */ - public function generateHeader($title, $path = null) - { - $version = ''; - if (DAV\Server::$exposeVersion) { - $version = DAV\Version::VERSION; - } - - $vars = [ - 'title' => $this->escapeHTML($title), - 'favicon' => $this->escapeHTML($this->getAssetUrl('favicon.ico')), - 'style' => $this->escapeHTML($this->getAssetUrl('sabredav.css')), - 'iconstyle' => $this->escapeHTML($this->getAssetUrl('openiconic/open-iconic.css')), - 'logo' => $this->escapeHTML($this->getAssetUrl('sabredav.png')), - 'baseUrl' => $this->server->getBaseUri(), - ]; - - $html = << - - - $vars[title] - sabre/dav $version - - - - - - -
- -
- - '; - - return $html; - } - - /** - * Generates the page footer. - * - * Returns html. - * - * @return string - */ - public function generateFooter() - { - $version = ''; - if (DAV\Server::$exposeVersion) { - $version = DAV\Version::VERSION; - } - $year = date('Y'); - - return <<Generated by SabreDAV $version (c)2007-$year http://sabre.io/ - - -HTML; - } - - /** - * 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 mixed $output - * @param string $path - */ - public function htmlActionsPanel(DAV\INode $node, &$output, $path) - { - if (!$node instanceof 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 ('Sabre\\DAV\\SimpleCollection' === get_class($node)) { - return; - } - - $output .= << -

Create new folder

- -
- - -
-

Upload file

- -
-
- -
-HTML; - } - - /** - * This method takes a path/name of an asset and turns it into url - * suitable for http access. - * - * @param string $assetName - * - * @return string - */ - protected function getAssetUrl($assetName) - { - return $this->server->getBaseUri().'?sabreAction=asset&assetName='.urlencode($assetName); - } - - /** - * This method returns a local pathname to an asset. - * - * @param string $assetName - * - * @throws DAV\Exception\NotFound - * - * @return string - */ - protected function getLocalAssetPath($assetName) - { - $assetDir = __DIR__.'/assets/'; - $path = $assetDir.$assetName; - - // Making sure people aren't trying to escape from the base path. - $path = str_replace('\\', '/', $path); - if (false !== strpos($path, '/../') || '/..' === strrchr($path, '/')) { - throw new DAV\Exception\NotFound('Path does not exist, or escaping from the base path was detected'); - } - $realPath = realpath($path); - if ($realPath && 0 === strpos($realPath, realpath($assetDir)) && file_exists($path)) { - return $path; - } - throw new DAV\Exception\NotFound('Path does not exist, or escaping from the base path was detected'); - } - - /** - * This method reads an asset from disk and generates a full http response. - * - * @param string $assetName - */ - protected function serveAsset($assetName) - { - $assetPath = $this->getLocalAssetPath($assetName); - - // Rudimentary mime type detection - $mime = 'application/octet-stream'; - $map = [ - 'ico' => 'image/vnd.microsoft.icon', - 'png' => 'image/png', - 'css' => 'text/css', - ]; - - $ext = substr($assetName, strrpos($assetName, '.') + 1); - if (isset($map[$ext])) { - $mime = $map[$ext]; - } - - $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->setStatus(200); - $this->server->httpResponse->setBody(fopen($assetPath, 'r')); - } - - /** - * Sort helper function: compares two directory entries based on type and - * display name. Collections sort above other types. - * - * @param array $a - * @param array $b - * - * @return int - */ - protected function compareNodes($a, $b) - { - $typeA = (isset($a['{DAV:}resourcetype'])) - ? (in_array('{DAV:}collection', $a['{DAV:}resourcetype']->getValue())) - : false; - - $typeB = (isset($b['{DAV:}resourcetype'])) - ? (in_array('{DAV:}collection', $b['{DAV:}resourcetype']->getValue())) - : false; - - // If same type, sort alphabetically by filename: - if ($typeA === $typeB) { - return strnatcasecmp($a['displayPath'], $b['displayPath']); - } - - return ($typeA < $typeB) ? 1 : -1; - } - - /** - * Maps a resource type to a human-readable string and icon. - * - * @param DAV\INode $node - * - * @return array - */ - private function mapResourceType(array $resourceTypes, $node) - { - if (!$resourceTypes) { - if ($node instanceof DAV\IFile) { - return [ - 'string' => 'File', - 'icon' => 'file', - ]; - } else { - return [ - 'string' => 'Unknown', - 'icon' => 'cog', - ]; - } - } - - $types = [ - '{http://calendarserver.org/ns/}calendar-proxy-write' => [ - 'string' => 'Proxy-Write', - 'icon' => 'people', - ], - '{http://calendarserver.org/ns/}calendar-proxy-read' => [ - 'string' => 'Proxy-Read', - 'icon' => 'people', - ], - '{urn:ietf:params:xml:ns:caldav}schedule-outbox' => [ - 'string' => 'Outbox', - 'icon' => 'inbox', - ], - '{urn:ietf:params:xml:ns:caldav}schedule-inbox' => [ - 'string' => 'Inbox', - 'icon' => 'inbox', - ], - '{urn:ietf:params:xml:ns:caldav}calendar' => [ - 'string' => 'Calendar', - 'icon' => 'calendar', - ], - '{http://calendarserver.org/ns/}shared-owner' => [ - 'string' => 'Shared', - 'icon' => 'calendar', - ], - '{http://calendarserver.org/ns/}subscribed' => [ - 'string' => 'Subscription', - 'icon' => 'calendar', - ], - '{urn:ietf:params:xml:ns:carddav}directory' => [ - 'string' => 'Directory', - 'icon' => 'globe', - ], - '{urn:ietf:params:xml:ns:carddav}addressbook' => [ - 'string' => 'Address book', - 'icon' => 'book', - ], - '{DAV:}principal' => [ - 'string' => 'Principal', - 'icon' => 'person', - ], - '{DAV:}collection' => [ - 'string' => 'Collection', - 'icon' => 'folder', - ], - ]; - - $info = [ - 'string' => [], - 'icon' => 'cog', - ]; - foreach ($resourceTypes as $k => $resourceType) { - if (isset($types[$resourceType])) { - $info['string'][] = $types[$resourceType]['string']; - } else { - $info['string'][] = $resourceType; - } - } - foreach ($types as $key => $resourceInfo) { - if (in_array($key, $resourceTypes)) { - $info['icon'] = $resourceInfo['icon']; - break; - } - } - $info['string'] = implode(', ', $info['string']); - - return $info; - } - - /** - * Draws a table row for a property. - * - * @param string $name - * @param mixed $value - * - * @return string - */ - private function drawPropertyRow($name, $value) - { - $html = new HtmlOutputHelper( - $this->server->getBaseUri(), - $this->server->xml->namespaceMap - ); - - return ''.$html->xmlName($name).''.$this->drawPropertyValue($html, $value).''; - } - - /** - * Draws a table row for a property. - * - * @param HtmlOutputHelper $html - * @param mixed $value - * - * @return string - */ - private function drawPropertyValue($html, $value) - { - if (is_scalar($value)) { - return $html->h($value); - } elseif ($value instanceof HtmlOutput) { - return $value->toHtml($html); - } elseif ($value instanceof \Sabre\Xml\XmlSerializable) { - // There's no default html output for this property, we're going - // to output the actual xml serialization instead. - $xml = $this->server->xml->write('{DAV:}root', $value, $this->server->getBaseUri()); - // removing first and last line, as they contain our root - // element. - $xml = explode("\n", $xml); - $xml = array_slice($xml, 2, -2); - - return '
'.$html->h(implode("\n", $xml)).'
'; - } else { - return 'unknown'; - } - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins; - * using \Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'browser'; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Generates HTML indexes and debug information for your sabre/dav server', - 'link' => 'http://sabre.io/dav/browser-plugin/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php b/lib/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php deleted file mode 100644 index 34702bd..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/PropFindAll.php +++ /dev/null @@ -1,128 +0,0 @@ -handle('{DAV:}displayname', function() { - * return 'hello'; - * }); - * - * Note that handle will only work the first time. If null is returned, the - * value is ignored. - * - * It's also possible to not pass a callback, but immediately pass a value - * - * @param string $propertyName - * @param mixed $valueOrCallBack - */ - public function handle($propertyName, $valueOrCallBack) - { - if (is_callable($valueOrCallBack)) { - $value = $valueOrCallBack(); - } else { - $value = $valueOrCallBack; - } - if (!is_null($value)) { - $this->result[$propertyName] = [200, $value]; - } - } - - /** - * Sets the value of the property. - * - * If status is not supplied, the status will default to 200 for non-null - * properties, and 404 for null properties. - * - * @param string $propertyName - * @param mixed $value - * @param int $status - */ - public function set($propertyName, $value, $status = null) - { - if (is_null($status)) { - $status = is_null($value) ? 404 : 200; - } - $this->result[$propertyName] = [$status, $value]; - } - - /** - * Returns the current value for a property. - * - * @param string $propertyName - * - * @return mixed - */ - public function get($propertyName) - { - return isset($this->result[$propertyName]) ? $this->result[$propertyName][1] : null; - } - - /** - * Returns the current status code for a property name. - * - * If the property does not appear in the list of requested properties, - * null will be returned. - * - * @param string $propertyName - * - * @return int|null - */ - public function getStatus($propertyName) - { - return isset($this->result[$propertyName]) ? $this->result[$propertyName][0] : 404; - } - - /** - * Returns all propertynames that have a 404 status, and thus don't have a - * value yet. - * - * @return array - */ - public function get404Properties() - { - $result = []; - foreach ($this->result as $propertyName => $stuff) { - if (404 === $stuff[0]) { - $result[] = $propertyName; - } - } - // If there's nothing in this list, we're adding one fictional item. - if (!$result) { - $result[] = '{http://sabredav.org/ns}idk'; - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/favicon.ico b/lib/vendor/sabre/dav/lib/DAV/Browser/assets/favicon.ico deleted file mode 100644 index 2b2c10a22cc7a57c4dc5d7156f184448f2bee92b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4286 zcmc&&O-NKx6uz%14NNBzA}E}JHil3^6a|4&P_&6!RGSD}1rgCAC@`9dTC_@vqNoT8 z0%;dQR0K_{iUM;bf#3*%o1h^C2N7@IH_nmc?Va~t5U6~f`_BE&`Of`&_n~tUev3uN zziw!)bL*XR-2hy!51_yCgT8fb3s`VC=e=KcI5&)PGGQlpSAh?}1mK&Pg8c>z0Y`y$ zAT_6qJ%yV?|0!S$5WO@z3+`QD17OyXL4PyiM}RavtA7Tu7p)pn^p7Ks@m6m7)A}X$ z4Y+@;NrHYq_;V@RoZ|;69MPx!46Ftg*Tc~711C+J`JMuUfYwNBzXPB9sZm3WK9272 z&x|>@f_EO{b3cubqjOyc~J3I$d_lHIpN}q z!{kjX{c{12XF=~Z$w$kazXHB!b53>u!rx}_$e&dD`xNgv+MR&p2yN1xb0>&9t@28Z zV&5u#j_D=P9mI#){2s8@eGGj(?>gooo<%RT14>`VSZ&_l6GlGnan=^bemD56rRN{? zSAqZD$i;oS9SF6#f5I`#^C&hW@13s_lc3LUl(PWmHcop2{vr^kO`kP(*4!m=3Hn3e#Oc!a2;iDn+FbXzcOHEQ zbXZ)u93cj1WA=KS+M>jZ=oYyXq}1?ZdsjsX0A zkJXCvi~cfO@2ffd7r^;>=SsL-3U%l5HRoEZ#0r%`7%&% ziLTXJqU*JeXt3H5`AS#h(dpfl+`Ox|)*~QS%h&VO!d#)!>r3U5_YsDi2fY6Sd&vw% diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/ICON-LICENSE b/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/ICON-LICENSE deleted file mode 100644 index 2199f4a..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/ICON-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Waybury - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.css b/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.css deleted file mode 100644 index e748674..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.css +++ /dev/null @@ -1,510 +0,0 @@ -@font-face { - font-family: 'Icons'; - src: url('?sabreAction=asset&assetName=openiconic/open-iconic.eot'); - src: url('?sabreAction=asset&assetName=openiconic/open-iconic.eot?#iconic-sm') format('embedded-opentype'), url('?sabreAction=asset&assetName=openiconic/open-iconic.woff') format('woff'), url('?sabreAction=asset&assetName=openiconic/open-iconic.ttf') format('truetype'), url('?sabreAction=asset&assetName=openiconic/open-iconic.otf') format('opentype'), url('?sabreAction=asset&assetName=openiconic/open-iconic.svg#iconic-sm') format('svg'); - font-weight: normal; - font-style: normal; -} - -.oi[data-glyph].oi-text-replace { - font-size: 0; - line-height: 0; -} - -.oi[data-glyph].oi-text-replace:before { - width: 1em; - text-align: center; -} - -.oi[data-glyph]:before { - font-family: 'Icons'; - display: inline-block; - speak: none; - line-height: 1; - vertical-align: baseline; - font-weight: normal; - font-style: normal; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.oi[data-glyph]:empty:before { - width: 1em; - text-align: center; - box-sizing: content-box; -} - -.oi[data-glyph].oi-align-left:before { - text-align: left; -} - -.oi[data-glyph].oi-align-right:before { - text-align: right; -} - -.oi[data-glyph].oi-align-center:before { - text-align: center; -} - -.oi[data-glyph].oi-flip-horizontal:before { - -webkit-transform: scale(-1, 1); - -ms-transform: scale(-1, 1); - transform: scale(-1, 1); -} -.oi[data-glyph].oi-flip-vertical:before { - -webkit-transform: scale(1, -1); - -ms-transform: scale(-1, 1); - transform: scale(1, -1); -} -.oi[data-glyph].oi-flip-horizontal-vertical:before { - -webkit-transform: scale(-1, -1); - -ms-transform: scale(-1, 1); - transform: scale(-1, -1); -} - - -.oi[data-glyph=account-login]:before { content:'\e000'; } - -.oi[data-glyph=account-logout]:before { content:'\e001'; } - -.oi[data-glyph=action-redo]:before { content:'\e002'; } - -.oi[data-glyph=action-undo]:before { content:'\e003'; } - -.oi[data-glyph=align-center]:before { content:'\e004'; } - -.oi[data-glyph=align-left]:before { content:'\e005'; } - -.oi[data-glyph=align-right]:before { content:'\e006'; } - -.oi[data-glyph=aperture]:before { content:'\e007'; } - -.oi[data-glyph=arrow-bottom]:before { content:'\e008'; } - -.oi[data-glyph=arrow-circle-bottom]:before { content:'\e009'; } - -.oi[data-glyph=arrow-circle-left]:before { content:'\e00a'; } - -.oi[data-glyph=arrow-circle-right]:before { content:'\e00b'; } - -.oi[data-glyph=arrow-circle-top]:before { content:'\e00c'; } - -.oi[data-glyph=arrow-left]:before { content:'\e00d'; } - -.oi[data-glyph=arrow-right]:before { content:'\e00e'; } - -.oi[data-glyph=arrow-thick-bottom]:before { content:'\e00f'; } - -.oi[data-glyph=arrow-thick-left]:before { content:'\e010'; } - -.oi[data-glyph=arrow-thick-right]:before { content:'\e011'; } - -.oi[data-glyph=arrow-thick-top]:before { content:'\e012'; } - -.oi[data-glyph=arrow-top]:before { content:'\e013'; } - -.oi[data-glyph=audio-spectrum]:before { content:'\e014'; } - -.oi[data-glyph=audio]:before { content:'\e015'; } - -.oi[data-glyph=badge]:before { content:'\e016'; } - -.oi[data-glyph=ban]:before { content:'\e017'; } - -.oi[data-glyph=bar-chart]:before { content:'\e018'; } - -.oi[data-glyph=basket]:before { content:'\e019'; } - -.oi[data-glyph=battery-empty]:before { content:'\e01a'; } - -.oi[data-glyph=battery-full]:before { content:'\e01b'; } - -.oi[data-glyph=beaker]:before { content:'\e01c'; } - -.oi[data-glyph=bell]:before { content:'\e01d'; } - -.oi[data-glyph=bluetooth]:before { content:'\e01e'; } - -.oi[data-glyph=bold]:before { content:'\e01f'; } - -.oi[data-glyph=bolt]:before { content:'\e020'; } - -.oi[data-glyph=book]:before { content:'\e021'; } - -.oi[data-glyph=bookmark]:before { content:'\e022'; } - -.oi[data-glyph=box]:before { content:'\e023'; } - -.oi[data-glyph=briefcase]:before { content:'\e024'; } - -.oi[data-glyph=british-pound]:before { content:'\e025'; } - -.oi[data-glyph=browser]:before { content:'\e026'; } - -.oi[data-glyph=brush]:before { content:'\e027'; } - -.oi[data-glyph=bug]:before { content:'\e028'; } - -.oi[data-glyph=bullhorn]:before { content:'\e029'; } - -.oi[data-glyph=calculator]:before { content:'\e02a'; } - -.oi[data-glyph=calendar]:before { content:'\e02b'; } - -.oi[data-glyph=camera-slr]:before { content:'\e02c'; } - -.oi[data-glyph=caret-bottom]:before { content:'\e02d'; } - -.oi[data-glyph=caret-left]:before { content:'\e02e'; } - -.oi[data-glyph=caret-right]:before { content:'\e02f'; } - -.oi[data-glyph=caret-top]:before { content:'\e030'; } - -.oi[data-glyph=cart]:before { content:'\e031'; } - -.oi[data-glyph=chat]:before { content:'\e032'; } - -.oi[data-glyph=check]:before { content:'\e033'; } - -.oi[data-glyph=chevron-bottom]:before { content:'\e034'; } - -.oi[data-glyph=chevron-left]:before { content:'\e035'; } - -.oi[data-glyph=chevron-right]:before { content:'\e036'; } - -.oi[data-glyph=chevron-top]:before { content:'\e037'; } - -.oi[data-glyph=circle-check]:before { content:'\e038'; } - -.oi[data-glyph=circle-x]:before { content:'\e039'; } - -.oi[data-glyph=clipboard]:before { content:'\e03a'; } - -.oi[data-glyph=clock]:before { content:'\e03b'; } - -.oi[data-glyph=cloud-download]:before { content:'\e03c'; } - -.oi[data-glyph=cloud-upload]:before { content:'\e03d'; } - -.oi[data-glyph=cloud]:before { content:'\e03e'; } - -.oi[data-glyph=cloudy]:before { content:'\e03f'; } - -.oi[data-glyph=code]:before { content:'\e040'; } - -.oi[data-glyph=cog]:before { content:'\e041'; } - -.oi[data-glyph=collapse-down]:before { content:'\e042'; } - -.oi[data-glyph=collapse-left]:before { content:'\e043'; } - -.oi[data-glyph=collapse-right]:before { content:'\e044'; } - -.oi[data-glyph=collapse-up]:before { content:'\e045'; } - -.oi[data-glyph=command]:before { content:'\e046'; } - -.oi[data-glyph=comment-square]:before { content:'\e047'; } - -.oi[data-glyph=compass]:before { content:'\e048'; } - -.oi[data-glyph=contrast]:before { content:'\e049'; } - -.oi[data-glyph=copywriting]:before { content:'\e04a'; } - -.oi[data-glyph=credit-card]:before { content:'\e04b'; } - -.oi[data-glyph=crop]:before { content:'\e04c'; } - -.oi[data-glyph=dashboard]:before { content:'\e04d'; } - -.oi[data-glyph=data-transfer-download]:before { content:'\e04e'; } - -.oi[data-glyph=data-transfer-upload]:before { content:'\e04f'; } - -.oi[data-glyph=delete]:before { content:'\e050'; } - -.oi[data-glyph=dial]:before { content:'\e051'; } - -.oi[data-glyph=document]:before { content:'\e052'; } - -.oi[data-glyph=dollar]:before { content:'\e053'; } - -.oi[data-glyph=double-quote-sans-left]:before { content:'\e054'; } - -.oi[data-glyph=double-quote-sans-right]:before { content:'\e055'; } - -.oi[data-glyph=double-quote-serif-left]:before { content:'\e056'; } - -.oi[data-glyph=double-quote-serif-right]:before { content:'\e057'; } - -.oi[data-glyph=droplet]:before { content:'\e058'; } - -.oi[data-glyph=eject]:before { content:'\e059'; } - -.oi[data-glyph=elevator]:before { content:'\e05a'; } - -.oi[data-glyph=ellipses]:before { content:'\e05b'; } - -.oi[data-glyph=envelope-closed]:before { content:'\e05c'; } - -.oi[data-glyph=envelope-open]:before { content:'\e05d'; } - -.oi[data-glyph=euro]:before { content:'\e05e'; } - -.oi[data-glyph=excerpt]:before { content:'\e05f'; } - -.oi[data-glyph=expand-down]:before { content:'\e060'; } - -.oi[data-glyph=expand-left]:before { content:'\e061'; } - -.oi[data-glyph=expand-right]:before { content:'\e062'; } - -.oi[data-glyph=expand-up]:before { content:'\e063'; } - -.oi[data-glyph=external-link]:before { content:'\e064'; } - -.oi[data-glyph=eye]:before { content:'\e065'; } - -.oi[data-glyph=eyedropper]:before { content:'\e066'; } - -.oi[data-glyph=file]:before { content:'\e067'; } - -.oi[data-glyph=fire]:before { content:'\e068'; } - -.oi[data-glyph=flag]:before { content:'\e069'; } - -.oi[data-glyph=flash]:before { content:'\e06a'; } - -.oi[data-glyph=folder]:before { content:'\e06b'; } - -.oi[data-glyph=fork]:before { content:'\e06c'; } - -.oi[data-glyph=fullscreen-enter]:before { content:'\e06d'; } - -.oi[data-glyph=fullscreen-exit]:before { content:'\e06e'; } - -.oi[data-glyph=globe]:before { content:'\e06f'; } - -.oi[data-glyph=graph]:before { content:'\e070'; } - -.oi[data-glyph=grid-four-up]:before { content:'\e071'; } - -.oi[data-glyph=grid-three-up]:before { content:'\e072'; } - -.oi[data-glyph=grid-two-up]:before { content:'\e073'; } - -.oi[data-glyph=hard-drive]:before { content:'\e074'; } - -.oi[data-glyph=header]:before { content:'\e075'; } - -.oi[data-glyph=headphones]:before { content:'\e076'; } - -.oi[data-glyph=heart]:before { content:'\e077'; } - -.oi[data-glyph=home]:before { content:'\e078'; } - -.oi[data-glyph=image]:before { content:'\e079'; } - -.oi[data-glyph=inbox]:before { content:'\e07a'; } - -.oi[data-glyph=infinity]:before { content:'\e07b'; } - -.oi[data-glyph=info]:before { content:'\e07c'; } - -.oi[data-glyph=italic]:before { content:'\e07d'; } - -.oi[data-glyph=justify-center]:before { content:'\e07e'; } - -.oi[data-glyph=justify-left]:before { content:'\e07f'; } - -.oi[data-glyph=justify-right]:before { content:'\e080'; } - -.oi[data-glyph=key]:before { content:'\e081'; } - -.oi[data-glyph=laptop]:before { content:'\e082'; } - -.oi[data-glyph=layers]:before { content:'\e083'; } - -.oi[data-glyph=lightbulb]:before { content:'\e084'; } - -.oi[data-glyph=link-broken]:before { content:'\e085'; } - -.oi[data-glyph=link-intact]:before { content:'\e086'; } - -.oi[data-glyph=list-rich]:before { content:'\e087'; } - -.oi[data-glyph=list]:before { content:'\e088'; } - -.oi[data-glyph=location]:before { content:'\e089'; } - -.oi[data-glyph=lock-locked]:before { content:'\e08a'; } - -.oi[data-glyph=lock-unlocked]:before { content:'\e08b'; } - -.oi[data-glyph=loop-circular]:before { content:'\e08c'; } - -.oi[data-glyph=loop-square]:before { content:'\e08d'; } - -.oi[data-glyph=loop]:before { content:'\e08e'; } - -.oi[data-glyph=magnifying-glass]:before { content:'\e08f'; } - -.oi[data-glyph=map-marker]:before { content:'\e090'; } - -.oi[data-glyph=map]:before { content:'\e091'; } - -.oi[data-glyph=media-pause]:before { content:'\e092'; } - -.oi[data-glyph=media-play]:before { content:'\e093'; } - -.oi[data-glyph=media-record]:before { content:'\e094'; } - -.oi[data-glyph=media-skip-backward]:before { content:'\e095'; } - -.oi[data-glyph=media-skip-forward]:before { content:'\e096'; } - -.oi[data-glyph=media-step-backward]:before { content:'\e097'; } - -.oi[data-glyph=media-step-forward]:before { content:'\e098'; } - -.oi[data-glyph=media-stop]:before { content:'\e099'; } - -.oi[data-glyph=medical-cross]:before { content:'\e09a'; } - -.oi[data-glyph=menu]:before { content:'\e09b'; } - -.oi[data-glyph=microphone]:before { content:'\e09c'; } - -.oi[data-glyph=minus]:before { content:'\e09d'; } - -.oi[data-glyph=monitor]:before { content:'\e09e'; } - -.oi[data-glyph=moon]:before { content:'\e09f'; } - -.oi[data-glyph=move]:before { content:'\e0a0'; } - -.oi[data-glyph=musical-note]:before { content:'\e0a1'; } - -.oi[data-glyph=paperclip]:before { content:'\e0a2'; } - -.oi[data-glyph=pencil]:before { content:'\e0a3'; } - -.oi[data-glyph=people]:before { content:'\e0a4'; } - -.oi[data-glyph=person]:before { content:'\e0a5'; } - -.oi[data-glyph=phone]:before { content:'\e0a6'; } - -.oi[data-glyph=pie-chart]:before { content:'\e0a7'; } - -.oi[data-glyph=pin]:before { content:'\e0a8'; } - -.oi[data-glyph=play-circle]:before { content:'\e0a9'; } - -.oi[data-glyph=plus]:before { content:'\e0aa'; } - -.oi[data-glyph=power-standby]:before { content:'\e0ab'; } - -.oi[data-glyph=print]:before { content:'\e0ac'; } - -.oi[data-glyph=project]:before { content:'\e0ad'; } - -.oi[data-glyph=pulse]:before { content:'\e0ae'; } - -.oi[data-glyph=puzzle-piece]:before { content:'\e0af'; } - -.oi[data-glyph=question-mark]:before { content:'\e0b0'; } - -.oi[data-glyph=rain]:before { content:'\e0b1'; } - -.oi[data-glyph=random]:before { content:'\e0b2'; } - -.oi[data-glyph=reload]:before { content:'\e0b3'; } - -.oi[data-glyph=resize-both]:before { content:'\e0b4'; } - -.oi[data-glyph=resize-height]:before { content:'\e0b5'; } - -.oi[data-glyph=resize-width]:before { content:'\e0b6'; } - -.oi[data-glyph=rss-alt]:before { content:'\e0b7'; } - -.oi[data-glyph=rss]:before { content:'\e0b8'; } - -.oi[data-glyph=script]:before { content:'\e0b9'; } - -.oi[data-glyph=share-boxed]:before { content:'\e0ba'; } - -.oi[data-glyph=share]:before { content:'\e0bb'; } - -.oi[data-glyph=shield]:before { content:'\e0bc'; } - -.oi[data-glyph=signal]:before { content:'\e0bd'; } - -.oi[data-glyph=signpost]:before { content:'\e0be'; } - -.oi[data-glyph=sort-ascending]:before { content:'\e0bf'; } - -.oi[data-glyph=sort-descending]:before { content:'\e0c0'; } - -.oi[data-glyph=spreadsheet]:before { content:'\e0c1'; } - -.oi[data-glyph=star]:before { content:'\e0c2'; } - -.oi[data-glyph=sun]:before { content:'\e0c3'; } - -.oi[data-glyph=tablet]:before { content:'\e0c4'; } - -.oi[data-glyph=tag]:before { content:'\e0c5'; } - -.oi[data-glyph=tags]:before { content:'\e0c6'; } - -.oi[data-glyph=target]:before { content:'\e0c7'; } - -.oi[data-glyph=task]:before { content:'\e0c8'; } - -.oi[data-glyph=terminal]:before { content:'\e0c9'; } - -.oi[data-glyph=text]:before { content:'\e0ca'; } - -.oi[data-glyph=thumb-down]:before { content:'\e0cb'; } - -.oi[data-glyph=thumb-up]:before { content:'\e0cc'; } - -.oi[data-glyph=timer]:before { content:'\e0cd'; } - -.oi[data-glyph=transfer]:before { content:'\e0ce'; } - -.oi[data-glyph=trash]:before { content:'\e0cf'; } - -.oi[data-glyph=underline]:before { content:'\e0d0'; } - -.oi[data-glyph=vertical-align-bottom]:before { content:'\e0d1'; } - -.oi[data-glyph=vertical-align-center]:before { content:'\e0d2'; } - -.oi[data-glyph=vertical-align-top]:before { content:'\e0d3'; } - -.oi[data-glyph=video]:before { content:'\e0d4'; } - -.oi[data-glyph=volume-high]:before { content:'\e0d5'; } - -.oi[data-glyph=volume-low]:before { content:'\e0d6'; } - -.oi[data-glyph=volume-off]:before { content:'\e0d7'; } - -.oi[data-glyph=warning]:before { content:'\e0d8'; } - -.oi[data-glyph=wifi]:before { content:'\e0d9'; } - -.oi[data-glyph=wrench]:before { content:'\e0da'; } - -.oi[data-glyph=x]:before { content:'\e0db'; } - -.oi[data-glyph=yen]:before { content:'\e0dc'; } - -.oi[data-glyph=zoom-in]:before { content:'\e0dd'; } - -.oi[data-glyph=zoom-out]:before { content:'\e0de'; } diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.eot b/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.eot deleted file mode 100644 index 7ca7c170f1a7780c7ed612e469d746adad4fabeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23144 zcmdsfd3;>eeeeC9JBvmdX=XH=Bx|Huq#0|mEX^*FEZoYPLI_uavict*V{?@TO zMkW-`8y`~?`wHZ(8ar|*sx;95Q5460cy8M@a&Y4EWz?ix|5@Bu?7IB}JD+&;moFlT zv2NJCdwfKrExSW__7i;aoZ)!Dh8|D=_bt2cICSS{9#tA}|E!{@_usyMY~;Hy|K)1b z|54<9>yD8-Cn&2tjC2w2NB51~G5)JjaZFJL@xHiwV*kNIzw~BwMcIz$wlO)OsC{De z@{6~4mj1g^rAARs`R+$fJT`Z|{D>Nt`4#3;p?b6)z5IwWpz^pBH9osEe9M17lR2*| zyUo=T$RnAz0#nX^Hlfp`Vn@F!L^tjyj4R!vq?GTL(*wUeO9Du5*||njzJ6Xg|C;R8 z0KUhO&Ff_SMHM2dE@77Pwf7>(kQRbP~cYFu*RbH+< zUEW_YJ%7CK_Fj1zPSeHtA@`&1QgvN* zclFxp+p8z5zghj`>R;5@Y8q=+)ZAHfs%E<8hc&l5?ewnpj(Sgf zzv+F$x6^l@?~U4M?b_PowO_Bj=&$v+`v?4c{a^6E9#8_&z>2`Ffd>N9fu97g4!#&# z651PjHdG4zbJ!7X4{r(|37-xBxUQ)#UALlcux@AFvAR#xovJ%q_pQ3~_1*RT^#|%d zQU7%P>kZuv0}T%}oNah@fnz~&!Qg_u3m#qYtp&emY;3%}@##o=M2kESIUSjf{2=mH zQ?_Ym)2Eug)bx6@t+}arRrAi~C!3#-c1CZC-Wh#7`orjNV@EJ#yGx%3MW#4d0uU0)$(@zSTAHszP; zuQ=>KS^BgpkW{{+a<-kbpLROvt))+c{C}Cw_%gm!#+PXL!LyG(DuOd_Hqg&xo%m9t z;4e-E=!9avSPq|Na^{erPP(YOX;PoiN+o@QCdKs3YK<;xQ&XB|?5MYwbp~VjmntjE z6_l)^nx;(|TT_!|JwQ;=P=qqhR3?{A#vQ@z%M^bZ4QeO8cS20R{7|}7O7A{#V)sMn zD(~9aa!NE5Onyi;<8+j3vpo-w4t0aPM*6e1+Dtf%`iSr^QuPQI_U3tF0vU9o9N!`Le*GMm=NjI<4i_=) z&DJq#l+e%3uccIauR7$C(3N$})le#-XYbJm;{B2-FOL#)#f@R0yhV>gJXa)JZ8a!g zKPQHG)~>Fro>ufam8BNa8bUGAp#FJTnC|&TSoJXEK zg8y3nrabpu-sykj_v?QJ?qHx4@E2Luql6_-Gj;?RS|CixFoiN{^z}{J@aCKPGjG!5 z@v}vGV$(_e=1n8V&#F<*#KVuAJwCFDo+#d>-&{lzRbxi^i+QwNaY3V0K$_q;#=QCx zV0CYur;8wzb0y}oXOIEH0(qgB$#>ANkW#O-vT92CaHuwn1@Q$OiC8?D^CfZ_e?IJt z*_f3ELh1Z6%C?lH>A_kr{eAczEl@M_i<*FT&xM-0Ns8+K(jI}xBaghOQK}(bZ`AY? zHGx14?bE2<_o1gsk)Rfg%>P2a1U?oY_hX%7X)y6%A{aoAa=vWX7xTHq7hIa=n%Uuk z#1Ye#&zD|sxx`wR#)1gN%V-?j{K^{UN|zOt?Oy(@oXZwv5lUtAeQJysx`TqXVen96 zO0tE#KbMF*67i%x5p+77vBh*#gI~4V=^~FN{fWBxV85>P560_0ktPQPBlPK#V`VRu zjyc4~YonN#2lanj*tfWUaIk;TvV~OrAT>o!Reo^K8&E6Dd0(}H@hfRGjpk!$IG6Qj znDD6o$s_l#dh7hE`?XTvU>|61@R9wwty^>Z9~qo^uC1?+>yfk}l33qrsJc9p89M|* zBIisMQiX6KSa1dlQ)wFh+0XP->5UtwrZ#Sb^qx|qmrg!>>5`d&y$lv)(i!RsDiP2M zBqVps*+g<$av)z{HkpV8LCCnOKI2Lk2aj~F+Q`7#7v(aDr-@)qXN29ILi0-5KJ`3hmQ918kk zaYrDO!A@WrF7#7DL)%(97@2vM*GMF1UhN-J9UT#_3yh~T5}bLJG1^eSNctlk;MgW_ z<2{d^0-{Sna5AHZ0KP)Ls1{}blg|JnNlN7xsq;J3=6dU2U20U*cI}$^ipw>-XHjn$ zy-uMabQvTLGB-#JTda@3*21U^tRa>z7_^VkxAnc?LRVJ@Bd!mA_q#N&f&dU zI=#5Qv0i=Z>F^Eo=FA!Ib^c>_2~S13phou&r_;@ezQ&`C+Q=^LnESfTTJ^f6%{MP! z!?R`XqX0PdLIvyOmpdsq%T+MA5U&u3rC_X-BpW+sIc`&Jb{>;4%)lQ@4l>2})G2dc z6+>d$c*>&}p2)3Ox!L~`jAF==k0{VoB0#Tc>=ze|EJw z9QyxuxaxhI^X_UoI`f--n;+S~deyS^YD8^wxb%;?Z0`JKU%iJa^&^`L`yWXr?p$Bs zc0hxd{{mXkw6Y5$&E_-dW-4@1Kc$<<;S3j$!OX)$m}-Na1e{@GK$j~*# z!Zkxpp;gXEu)4ufOn5Mv@#sQZ1f{AHYg^-qkJ#)EyZyRgBY&X&nT#g~5>;p_ zVp|xEM}mPSPoijN>zLpV)@53$0Iy)`#=>`y&)(`w1>??esD_d$H4&F&E=ISyTsP{+ zD1IqyAE>BFrYd&b=yE+Hrd>17xy1GtPwMWw)cU9WDQ}IRysl?lK$YA8?|H`Rez}X9 zl?3KK#x0pr0`yGSKNLtUI0EtkMuADB2rp|> zo!6?=6oTfC_gn4ZYPH9z4UYwqO8%LxmE_)}j~JOoGjsB|PKjdQbj!H|)%MZcxbnDJ zPI+PO9*APOi;^ZFp@*NTunpTP231 zKWA(p30`XPM&BS$GxJxlJm4;@sxL-hmlI-0pRk_6QiFBCGx8Cua+2vm0!zMZJ@dKD zXZi$}oL8rdVl+vUtRC?*L(Vj#J#z+pkixcfsF`AE4?qMKH;HYqm<$1oO)PO(i+NoD zF>EVUH`tRj9dd3}gH`&e%Ai`4udbXTI|Z9)t1%brI6DWpcVh-mhQpU543_HV4OttZ*8s#fqlWSqU<989HKeF`+Jm%$;32QxP z+jNmL0U)|2gbxQA=6KO@BkJn5y6HLu+codxcfv$uj>UMC;iurM+SYL+@RXXA%c;qQfVrn zMq%vmZtn?3(u};)J({k&DUIQmp*vSZC`0ir|VBpH&4)9y})C1VA!2V7k8g1 z&2K{TAft~ebSmf%lp$!V&Tt~tnh84-1>W&eM1XsXA<4oGZ55g^|IM4rW&_~?5`>-2 z6!c(|raY8bjQv$uOu6OQj^Tm@hGGE3YC;9*#O{FR?acA1gXBVe!?=^X$a6|6ay5NAQaQ5 z@f7x_d9#$?d=Ww;n5Kj65zsRz;1Z}BI&LRR3;@x0C}9+L;{{^}MB2XyLx+4n%{lG7 z?<9YgG|g+21>O%ryu@>iMoLf_)Ud1atqUcF@nt%@Q(_A&IcS%p)y(4{RPxd*%Nu zi7gi!hGc^@X3mJeH@k;zC1H`#CB{a^o^+XrkI|mV=bgY`hHhRk5m>$WRaMPf=b4{_ zgV$Eo@Fo@024gSjA7g(1WzLgbo$YTev|I3WKV$}WtB;Ki38-^Wio!k$Qw)mYi&~n? zNf<}NY5f!pvu>Bx^nPT6GiaQJ{PKC=wF-l$!%~0cYFYE(%;pPyf;9(&d~=0V(t2ji zws!Zw2nk?*SiEL}QAeAbqF7cFU z7{11qzW&V+9-GDVo1X){9{*g!(2#%6RV-hw+QVa!^eQog9U6-p{R=R?@;{){R%R0N z1BIfKCTCUy6tR6)N&tqq454^>u>PP}{70SG)0aQXrYQxc7|>HD9R{%`a!IIj(vTLm zHxcXmuq`EEO-ezc0y(f?hdfWFTDyqldLNavjXlv$t-^Py(oV(O*Q__a9MwQr4uzX{AV3h=tkIf~i^V-88t+QgnyiRL}uVqp>es(r7 zuU%OeYQautYf}Ql-4$ z!6VpDeQm+AeIZz0VN#jt85)kcjod8Ej!;IOr<9x48d$ zZBaqfHXSS8aig}PMZ5R&CKizGSu%$00Q02`W~pF)SPN%&B`<-sOBtBV{(;oW=Hhqb zB~&7DUOA4r68ji<>AkVfyfVO823~q^jP<+l5_%?ikfbrm+g;3anR4L4g=}N>73dR= z&>@Z2mUTQ0x*+>ru(+)1X_t)oF!u2RSXXkqu1&UPs<9>Ftk3p4ER>N-v)_eRneAMF zT6sE|9=m!?Pm9at2yfnT|C)6lxoMrxr@Gs^2CmWWm3D|yWo=_5*i<7$l9-O=R;3Kr^Wd`q zU~KM40@gJGHlP%%2Vn?s+Ni3kGvpaw)p2)wXXnbBYa_vWPrrV`t^b;iF82mMtbh9+ zS}LZ=ck{}Qj?UwqtA=apf|0;V{iK(?bl38lkSFpZ{iXY8skMjM4#jd~PGXcx31i#w zb}oOvLE1!_1=ZNXT{bWwTb3k8O2jx_s#vfl*U_prkA(s=j6Q_ zwRwvxb{D&DUN^Y*rY_@V;g%JvR<7El<BmN6ieAmntSMgT4u)Si%qHi*74#=gevLdda{_h+0LHA8BqkbslFG&Kd8cmFD82Zofl_?m3P&fLU8eHK1L z8y6W%7}i_H2f$6tS$Y2%b_$-)Zr~(oGj#^p-UX4^1>6pRk5zTz10ia79;B=<PmRh&yoU5>5wf%gMMi1Vb|ZJ6U=a@~|Rzi9)}cO0rQq ziHllDLPHLR(%~i*)?~}JLX%t8heFjMS4XYgrdD~p4u4&&raj=G+KQ{IlSOYaz2TmA zH5h5??pZ+8+~ljSwg*-dsZ|cY+WTUn*RJ+CRF~6J=?~5tXYTLxdlD{NP1swdIvqCO zRqI5evMH}RszY})hpt)@sB;DuHhDT@3#)2t>MDa_hrO!WSu6Z^R5rUS>}sIeQ5EVc zlc5}q0a;CKi30o%#>5LF9B;zT97}UWLi>(Ji}`AXbV?nuTrMntJtG0Fu|rv`WRwCh z*>Zy)TJnLfuoTV8i}!PH$q_JH_F3a%{D1eGc@k$<^pqt41SAneu?ODX|9P^Xdu!o< z^7I@gK(NRxJ}6IPyYe3kFzdTque92g{0x#JX2*xGbJ)=EAR9Q5SsOnA3*gHv4NE*- z4Zm`X(LUR+4Gqng^+}JGVW+orR==3?gD0F}Rv?Cg5&z6yzvwfy8NdED&Zmuj_Gjs@ z`TburwU=3*0i2zY+y-W0Y5N1t&c%YbL&HGT(gp}N!b-k%#}3O5U@qw4?EXv36t4O? zC98r5QmQDJ0(RyYxE?4o@Y}O& z17IKc;nRmrH#izQdmPPxk73Be*B%BcKE-KdXvbwcUWt2Pjs&6xOO%EWr;CzOQXc8k zzo>t)j~%Z^2Jv~aPyak!*UR0T>mztM%)roVq2I!(3IM>=z_9`6RQ(Q+%_P4s_{)?R z99aMw@cRldwZLNKGmsP)w8AwY4CLO#<}5E;1$}+KXU3NaX9^jgUtIG0XB>XezpR7P zoCiu`hpfR1Aza`KV0+|3)RGSOvvrq6dol%Q07H$i^dExzbx{obP@?$KEqgM0g39^YHMj>}3UnW7!P#gQf4=BG`Usd9I_pJcpvqax-rF|FQimBG}65#Rs0j zc6^@MloJ*hsNI-hi&N0^-$Ue{x6#22C+(o^raKFveGUhxn9_~j-CeW(E0cynL+n$V z^+RVE9>SFbrQ65Y5ZIXAg!ij9n~dVX24o+*7T5yX6hqkcr=$mZiiX+UY*DB|qt+gg zwqo8TtqHGhDzlX*i7aiTU??YwMeW2v#Zi zBc7@n_|a^3@Fg%ML(=U=4vmtrd|*5~>@6giAAnNp;r;h{{EfX`<|Cd1bEH#S)QC04Z4NaAovO)MB?M}b zgOWqd{v%aX3B&d8B7th=o>{}4!ZN;x4$gRiIY!XL4n|ty2Z$Qp1ke}cH;W!4#j=M( zbl74juQ7^2|%Dk27f75{bH68K1t z3^H?=)COypv};34+kG8w&F;MB`iEYo;k}cP8z&pWP##+I`g*@aPquGQ$wKdKc@^;eeyO)y)Z(IRwksK4{BwuLaQEZNZ5&u%Fz z#sSNS^$}rFf8s)u$;WNz}?_oAzFE&7cVIZD+h8nEhi3!1f09wA5)1|a| zB4Q+l&m@zsJUwv6uz$+AHt1KrXIiFb-{S_^Mryog>UyxXN_z(R0A$(j&X#Dlrt-4M zezV_D+GJ&Y86TSi5gBXQx$)-Q7_g^#{*3|7j$M&^0U9Z+CYT?PZo-$5lVsTV*mlCu znRR%z42#V}V)IbcwDuBY7hdN+Uj8iB;On3-fKMsuB7*taGLg+YXC3}#1TJttI}hNO z0CmLJPXHSTze%B*3TY$jI%iX50065N?U7I3mc|~M=xa;g_Q`;lw)M5y5KD*%LJ?c? zR~!bAW=%t?Bk6soYxnlGwe{_-J-sh&ga+{3%-W&lcqF5{Seos-9IuQnoQw5?Z)2{1 zjFSzlH7~~R6884Y8AL9^nHtz)ME2=!KrikAU>Met0T*b5`*8VbwG!*dc52h&D766a z67q&FobFw>@OvLVec{t$dil!J7wSLonG2^s{5`p@hTm9np9G*DSP(9Jsw5FivC}X? z!)%cOvyuPtB{`3E!&jpoNdv6#L7QXs142D#bI#rP`fV^ZvHLi@K>znYFjKa`(4B8! zLn7!DIj&bK+Vz7*k{-6z#2ff0O<&SkQ|G)Ci9meo7t)l;p2!CFthsB;8;@_H zP%qAS0JdCg8Q9h0UFlu3JYEsEf2uK)G*TlT+oe!m($`O3+Yujr3K zu|2d^)3zQ$Io{JaF^TbT%pvG#UaTRQg%yzJr&kd8pY}t8{e1}^)TpJ{!f8wwWt6eu zW0!SGdSY8CNC0c@qdcZW8n08-8g{Z}lZNA7{YT@p@Sdk$e(0_d^6I;O`Qz+Tl++JW z+pfK}-?;aom$#Dl`xnl&eQ@muB^`ZM^2G%D3Fa^x#V&WF&zbTWEW?PQyGeq5He^9 zX|pn|NPOx5@&L?TpLhXL8Lk^=&fMsdw;Vd-(tqwMm0Z-|LeHTC$V&N4hGk0w<*{_) z5%5Wdu=(MT1mIn_G{Zr6WiOTd7%@d$4fDL8N#2UcS_=8W3S_``3NcS9hnh@5m1?GZ zEv;$T<5}Vv@O=KCsy8GvtJ}6U77tCkRL>4EeVzW*)=#xgHfoK}-uS0K`UCy9LtoP3 zjvhknNZFdeL?@z3H&K6#9X{&^yGk;|LIrW?*jrj`n!Cs;R=&nB2Cx zwa%$k_N*G<+3(9=m%n9kLZhGQjM5XO|;)z{achl5^&1o1nAxYK0_^!%gHg0?V`J|?P=LHqXFMSDayz({; ze#q_<%qJh_NEgB&#iTb+laGJksDAE_8;-IQ{zE&~9Dee1Z@wv}k0Nv54FH=s@5S*S zW__mIf@Piko`j7IM<5XAX?=qK8xb5v3OClCkh~scaHcKDha7VWs5B-1lyNB8U#V*i zvE`oQ&2fY;5yUY+i=**;$dcuJhR?9Ew>oVL)nZ$TmIQ($IgkZcY^zh$_QShNkL$m9 z@)b&!zI+#A8`S9CKh%G8>PZSbuIaD7a@UtxLBro1O;&<;v7Z)u#Kx6&2~-AAGFvNZ zw^U{Ad0I8C-SYT99Q)|c@7FGzmik_sX-S*bpMUmdisK)8_wF(7$Yl^ zSH^fg%?K>81PE@^#Ls~&3{$~0af*b`_2?6zN}7ZOaWkevqy&tiZ6#?@yQH6!I8@$< zWZN9pz@D$=^8>u2Atfx69akHZBC@En37@LyVR8KUq^Nc{(IntQ^C^W%u$#qcsNhm4p-oYvN}V)`rq{BHTy zd)9OMphS~DmEXcAFZ$1AB!!{wn}L%vFO|PxybgamXRedqZ2dx7njwsQBj=~(Pi0yT zi@zj2@mc^eyloB2uy0)4$;UfqK8o)xbn$=6o~Tjev~a%o3C@RJfr006q>XnZBJKq2 zV=@w#V+Ek=yR8E&@_6}0J|l>uDU6-jMlb~GWo`<5g>&t#_(~Nldkn7+NOjxexNbVC zw;K}!%YpHrwCR|P#Fg=`bF^!%p<-cLt2%2%to~gYmHA=07%=C-D0gKDrV+$~2TQii z>Lj3V(_?@b6&${U)fArYLRi3+{V;YWV?pdu5U1p2k0IB}D3>LC;veA?^YjrTuo63i zLx}kx(A0p26B(PBcCB+xn`9P(S<7f1o)@5UNDQ3TDtDB!A2p#y(|v7I>=vDXonWf1 z4`)SSL*N6I>=zZuzBXfQs%et}uQXyz(&1VoXam4e1~GtX0Yid^Rpbs*Z zMA}WEEJ;Qxt)((n5a)rwKMgynG?KzXIy+C`V;{C_n35Hf){A4(Xz~DqYT?(4VN?x&t9ATers*era_Tqb+b1rnNuMIz5-B@vh{n|L=C*_X80~k$pa9jaemf8kdl~=TA zTv@0AmvEmDi!tw7`88KbjN(gwjlX33CG-ot$n~{K;~V{X0q557(Ofq|pVTzI!|BHx zaV?(%K3^h(7>1n%E<{ZFCaW3 zGJT~CywZHcouwr_qA=1$*fk2{|2a*l#*W-@a0<3y0KbM|-TEhsAKOvhLLP zo~Uza4&QAL+~#v=s_M$d;(3>9(jeREoh%ismhJD*$Q5Gz+l!R(va17nP{ za*^$d(0~Z25W8p@!5pVT7vK-&2H|{6s(b=erKF88d0@gbJN!8Jy48=FwhVabsK)8Gk+nT(ju}IT%&Udx#Pg6FJbn{#z^`;e2g>! z+5NSd7C?vp!%VA)BlxwMwkfqVYNqWG$DhI}hOJIit!^`6HdXkyAIYapa}(emAZQ@!OM!@NYs{ z0*t>HznaEB4SGmkjd#27W1u_n_CAz5qyQ3Kbzpqt(6|;I{Xld}*M_d>=6(AQ?1>)T zb7*&T?f!j-*6u&BYdo6n>W(hledy4{lEsU6B6la}b{*W=wQu|o>L~jS()DBe_Z?Kw zS>snph1pHk`_0&KMs1crsCj4SV6h6v0&bqcxD^`FVa)=XY?idGM%Nb(9`r^>8tcLdWQZRJxhO1&(UAdH2oz#PcP8d>96QT`UZWI zUZQW&x2Z&bjb9b~4*e~?Os~*)>3j5j`T_lSI!Av;KcpYgkLmA~w@<3*=@y9C>q(2A zjOfXVo}B2(i=Kk$DTxwNbeMxZjtGMy<225B9j%FoXF%wrXVs!k?9qg5s?`cnK6;k zL}pxMc8YAb$o7bAT4XaKn-$p{oUbBV5ZR*0_KNI?$c~Ean8<1(J1(+2MXp=qdPFWQ zav9jrMJ^|Dd66rKTv6nDMQ%joMn!H+4o_-J;MV3TaWuh(cBra-xtIg@Py)MWI&|Mnqv$6vjkB z6NPb6*eQzLqSzyfX;I9GVpbG$qL>%Of+!Y6u~!sFL~&FU$3#&R#c@&GDSEp_Z;$9r zi{6ar&5GWf=*^4Xg6J)Z-d@o=B6>$f@0jS-MDMuh-6=-8#Ym4BNsEz;7|Du}oEXWA zk%Aa0ijiJ1G9pGs#mJZ#(ZtA3G1@Igd&Fp3jAq1WR*dGvXkLsK#As2B_KMLFF*+(n z$Hb^6M#shIPBGRk#(Kn9T8w4HSXPYX#8_U86~tIkjP;7K5ivF@#>T{$CdS6a*iNB! z3#~_JX`y9=mK9n~XnCO(gjN(i^Ey7PQWIG;<SQt;ScwXs*-`HK=76p0$;!^O`vT-g6sA9SOvHx!L(@xe7gk-ya|LxS+E zDBmc1qGI6lm7?G|&fqXu`)_rbqT~LC7K`IzbFWq?F6BeiDtb`hB1O6SLQ%;ae@}tZ zdPX^OTHbvKz6)`hp4t3FD&`2nlwId*2PupEWfk}Qv%jn<7Uc(jIY_x#z0+R~R<2N| z`^&l#rf%?;ElQ|*6f39(Ux8cE7|pVZm3`M=)|76_=l*h#GEDi&Uk+A!sCoXfuJpn< z&1)@6gt}81tdw9Bxk@R%3-J7T$}D_mDt*yIUzCO`Q4+R5CGg#>CPIkr_o(N;8T|o+ylr?;9K0XF_Rdalbq67?0ZVRNHsj_`XvL zOVP(rC12iX8jATvQ?Q%puc5s%5p@%>|94N`4^KZ*j*G@QSZm>eV~bG|@gI*; z97;;pN9z|ka!TpM(#eGdagqHZ6Jlc$W8!1u(CpG4mGdnXWfbmGg87&zA3hR2(=3`Z zsf;QtnKrR#N@QH$SPWi4lVUWVf`{lbwxZ&~DKUWoO4=a$06+Vw=T2I2c^r(9fCI4M z_{{0wz`19X-+qf!{Vf&M(wU&q_W#e1UjqDANwVqEkE#S?2356N=b2YEOkzLpzZCD! zs`nSodoIXp4|aqoJ;pNT-*vMty`_C``>T4d;480!#J#$geyn>h<)&WuRP|84pzBr0 zpCBxc4gq0R4CM+icsC^sa;S$Au0$x;DA!?G9azR2l_=#FFk7^8yCj!*kYuuw3Szxe zxl0+K3{vg}u@3*CfhJIMd0UC-_)uBeJH>y$U zEovV%TD@KEtH!GFYNDE~rmFqaJJq|?0qP+2ZZ$(4q7GBWk|CQO~I&EAg(ZOe0*$tTzq_dLVRL;QhaiJN_=X3T6}JNUVMIhL40BS_=MPmxP=l9G~>Qj$`W(votM@{;nC3X%$w#wW)n$0f%nCnP5(CnYB* zrzEE)rzPhm=OyPS7bF)Zk57qBiA#x3Nk~adNlHmhNl8gfNlVF1$xF#kDM%?y8J`-P z8kZWMnvj~9nv|NHnv$BDnwFZInwOfNT98_pIzBBnEiNrSEg>y2Eh#NIEhQ~AEiElK zEiWxUtst#1ZG3KQZd`7BZbEKiZc=V?Zc1)yZdz_`ZeDJFZb9z&yx6?By!gC?yu`eu zyyU!;ywtq3yxhFJy!^a^yu!Tk`LX$N`SJM)`HA^S`N{by`KkG7`MLRd`T6+;`Gxu8 z3t|i63gQbA3K9#F3X%&_3Q`Nw3UUkb3i1mI3JRqZ{eM?A=Y_Xl%_!<(kjWAd3InM; z3u37Oz8D0}dbe^9SnytTIf$ngTdNFb&uMlHmk3yd)0mFe)WKQP(7r+rnacBtAA8m)i>0`>Jjx# z^{D!m`nLLx`mXw(`o4Nh{XjjgeyE;MKT`jso>Wh%e^x(M|Dt}PeyV<^ey)C@eyN^T zzf#Yre^vjceyx6^eye_`{$2fE{XzYQ`cJhDr2V7nQGZhZOFgUpOZ{2>1*FbZuiCEu zstVPocBucY{-!CKs%ct~7Od%-MY94;U7>|&p;|ZXN-a#gO1oO?uJzDtTDWG{BD9{` zHQKe>b=vh>FYN}+p*gikt+#fgc9RyR-K^cBxwJmoty;8pn|8YvqxDsmX?JL`TAUWI zC1{CSl9sHcXsKG7)=%rN-KnK(cWHmn251AdLE2#LZtWf|L%UZSq7BuCY4>UOYY%7- zYQwcm?IG=9ZG@JkjnqbIk7$o-+1g{;<64e3S{tLBA-Q`Kq+~fHmk*NVZb*f%FsK+@ zGFRKKy{UZ}1b7+LKWI$Q{Ggq|LxN`pza7l=(R!nP(lW)e$I@Ya%DTk*k+sbTH=em7 z{ECHFd=>I@=!npR-LC0&sM|Z;KJWI=ZtYi=T)FMaFRtWa5n)MTnPJ6Yi^IOVD)Or5 zufFo?Yp))Dbyat@`%T?5x=-lt?$N);q#kuWUhmM|ye>?Y*J* z(Hmd6X;ak7sE=;G^5)(*kG*;A&40fo?v|Oibhr{+J6x~3-gk*U_C7Iv2K5=;XKJ6d zefHft@z&B?KZ*{Io*2FVwqdtTx!r#Iq}%t#*kYcHamT#U_u9Ts_1$qt=p8#^uZ_Dl zZbjTL@saTl#LtL-Hz6jWHsPDZs}g4=?o9L~MJ7Fzv@7W^$%B%gO@2A~yObMJvQxIE z{5>^2bsYpsLE6cF;r#~md$-@&{;vM(`oGuzvpaj=`OKXi>G!4AryooIr7vspW;dx# zP5kMmpr#0Z%KL&iWohy)uzR!l)4ptL81wKP`cvC8Jwf4Tcx!v6Ju<`>C35U8UzE!m z<+Ab|9Q9xTW^s?+tCw!f&u3)eG``N6<~dxvyn;yG_Lcju2V zrY>!oWg8z232n@yi`vMO=!Z`B4)Gs_vG(R5Zxo(0gAJSc@MMF3Easi$WqRhz8Jh<% zLo|wD`yU29b_)|0R`Tq$no@(m$4hjt!MocOA4 z3>M+~VWIykiHDaO`}ipPyCPfX*Vb|UllQr5gq_<&3wA z9LBtEJ#6E2EUStNOmHhbVzd3G5SPo2IY*U6w9-arv10yKk`MwdgRwN|46Smk)bK(p z<~iS8Fq+7XQMU}=yp{U9^u}gOJR5b0hV-q6@m7z@TfJ>|)GkLI_26|AA-Vl$y>2?2 z<8!;ba+Ixnx$Yl5QP_pyAHhSm$ZqBEX=Lb{2&h#YL4AwAYmUBT-#G7e(|J?~+?D3A zl^^NcdkZE_w9tGp<^x63%*qKnKmAyKyTF*t7M}ABusi_@Gbbx5M6|l>zBZ4y4YzUG zZw5iSaBt8#aiWJ9(S!92#c&4=9(^+t8vYKrP7O9roYb@4nDl4%CHwNFzZ`zU@GdxM z&ls#9&U$GOOJOOK24{^lP7Kyhojl-ST*Ke!p9Y;WeEmeE{fQ?^N3krHwK@CcC#auU z>lbWc+u8P&+t;r*_{2ZiGw#;c&ssT^6|tfPrL$&HKQF($`89Tg9VvbNiIB8Iw>fZEh%5L5_V)DG zCK$dHUy45AwdrrO4;b&qufx`l8Qd+p+jl*-aX1^wL_cvIwtgrM-}u-r>W=17%Bdi5 zb4O--v!^2ybLfqVpcV1Dt+aYrWFkE&(?C-G=?n@__4dXB&09LRvT}hT=82smoG}-c z$*1YF>dV(Vyw6+K*VnIidNq$ngjB%T0EX#0Kz=%~u=u5$W5vsP8Rmpj_;vMjHzUhd>0thS%<{1)5y zF8;7(xx1#y;rrTU_qu&iKDQ+dv!(umpZ+-XJfgOmoLy6J0`Ar z^G3s$V|nxEWBe+{jO8mCPbP+^fk@FIw758-IoVB*#H8JuJ8|0M>=C2A*~0!f?NIK{ zv=1Nof&I(iTHLonbGSM(?OFTB96r2%|6zy8)X`vpXe=2M)dM~rFn~u3xqUp~}lhokzPwv`cpd`wMs+2o}s!4}8();yJdT+na-3*2DY9WI26N z)~qpOvK%h&L2E!QIhiN(OmdT9^KRd{ZXY`sct(-qvU@Ca8C~LZS?Den+s~(u4@pfO zG9=Y0qAlj5w~{DmHN^zTv6Uo>UlxK;JV73upXt^MDko2_EHKE~qHgf93aTCXtXR(J^#<~%;*@o!uve?>qn5AOO)JHNhjPm(R01uExn9ub0 zPwhIs=4}H#hyhrG$`5B8VXw12bvxH>T(_}du#QZ<%h201t#TDQGQkXsi5+;b%YJJJ z&xzozn4PksqO!6gC)Viv(urya32z%%yUhXxtU|zT2x_0x{tASHFH~%pH)no{ezNp% z*5<*+)>ZnlXP;YMz0BYnyrFt^%`?v}t}*hObziy9VIP$F;237@&&W2W*ZrJX1%Cv+Ef~n za~W%4IxBs)tY*5Ap07_|R9?!aGdjgqvenCKmm44K(zlG>RnT0rYs2=ftkGaRiY;R` z>`VQbY80xmEn8Y$vw7pXt<0dYJ6R%bv4~a4$r0DuvE*H*1w zw30QlO`Gtwv3&FNWk!0FUbFGpO>DE#BB@JCn|m!)>lUnASZ{Fa5q)j#ss^@>(FwMY zRk^Dc8=~jXqD}gzr_*_V5z6qFF48~iXG|#*JwMQ&uBoW5WW{V|F)K9)HwJmnVNn;j zneT`1m@Y-I_cN1(ePtpW3@C;{mXoL!!%Wisj-3@-^}3Q5Dz?^bt*gV%7|b*D>NRzB zYnZ{RA#l1&NI_&HbdV&}b9AIS&SkQic4@h9~MRlq` z1CpiYeJ>7(UFxZKDFp<$QQiqh9-GG- zLnC2}7cW_4#E4fbDIOV$SzKS4I!aYMKRC)ht2y2Pv>ae7^Yq~F&_Heby$6GfHcK^GO=^-yvy~ZdJ`{;|t(R+y0tWi&oCXFh22Rvci+7czW%O)w3}hIgkXVYMcSp z$ba>XvfoCa;I_N_1Q48<6jCfH!n zkUiBVcI`4S^b)gWxSk&?Y=CaKE2MpRP|nAY}YQ@`H?0Vp!;CkKm< zu?^q@PM-9*%=3O*hzt$%pJBf}Bn-op0+(nG=1O=fY{F){6r9-utaB?W<~j%P){m`g zD(dDs20$#3-V>j??DABH!#cOFVvVESVIgjGwmbX{iJ<_hu-GQr)El~_aEA5v;ad0n6|>YsdJ<4fyyuQ<%RbK7Zt(=(&r9^8}$#vqc# zRi>rX3i|~!=55nqkJ$kNJosZkSC~N^h#ZGhN$MVzAPUe>E3d{Z%RM;+n(f&lv}nEv zZ5cecMTE{T5~11XAvAl{@|c5l!q&=nYL`sYz6bv^SV9idKY%NT*Hs1=mTdycoU^+{Iv;r%MF;lJq~<%%gHromU_X!m;IPX@P}rlpcr>6>pshCwbr;M-vIWWN3s`@& zcv4Ma+Q>JBx%XpRH~~Cl@U>p>((q^!zW(-7Wx|)W6;o^qm-c4AaOtQg;T!4~C<{%2 z;teH@n$uN9LXeXrhZRYjNwD4Ja=|0vb-QQ*UEWbvk0-muz6 z$Ay3*``Fq1=gL=98sEn1w$lTuO7wu~ba>4EEJsOI?6-R5it^{?Goun<6>!xLZEY{L z^0SBRaWwnzh>+LBG*zU-gO&LERQwv}@)eS%;O>EuY;QxSZ7?n<<-;~T!CkBNVW6WsiAG6bA3E2OEwRfN@Fz`%KXiqE2`~!U(NRYI$5GAL;#8j5RxHDknx3}?2L-MjbU56TU`a+tnmal=$L*T}Zcn?HXZ z*vT@VEv#N#ZTx`F*u;h@Tjp#oZ>)NO86Sf{KDL}Va^!@w#mYV$_vX-gL##Ze&#jrU zjje&ESiNf1Y6q{jtYRzNHEtuu66!gtEJjh{t2b^O^?VD8lj=vUc zL${(HT(acy*v{a-qSb0UK~9S^$suT*6G0VkQpG#Tn7A^UHG&5wB~6^DS5$~vQO87) zA=3Eu;(DHj?Rso!4#tZ_Ew8JnGsOMAVGXmogeOh9*6M%JAKo!+Lk6r|lc3LQ zoS<-;02dhA6mz8!Xig}#%V|!zCg;`S-H~=pE%}(H$RKP`Y?gZqildW{GaIdH=FP}dHj?pqQU>jD|*VitrURb>VGwi*M ze}#T$R+Ynb;Frqp-R}$ab!TEL-^y0ido{26?l8T!V#C7K0ULOA<+=s6M&BQfeW1T} zl>IaF=!iG_u!kQuh7ODQ9+G=@?R*Gr_!*WOZVT5%k)8JxJ;e!Z;rtp%JaWR4SO^F@ z(~tmblHYUV^d4vcDz||bps|3&pnMq!nV<~fE4T8;`0M`#4wI11!yLpucH74D4GlOo zn%-`~Xyl0?xP#uU=q(!}V=T=l$i6SuS^DcFW8|=*xb1a7X_7Gs{n8|Z z=Oj{s1d@ICuz{C@p?z!{;mw6*Y-{x(#DK@~jq2)sf~Lh|04qotM<|oJgN%~*lwinq zf(>oXdTWLurdVy?WX{OTVndApesZw4C$?m7S+Sz-IWqEcEMI>3;g`<0thRUFYG^*p zJ}?MIQ8y0TDStPaz*1!}L2@j!*{sEL78yLmYCF@Zxq~JK&z}~8XqUa8WCp?r{X#%r z)%LUtgv;Bw*OVv-yad0*b}W2h!Sor^X4POjwv3Hu#krL)Ox`u2&jU+FyHo!*_XIOu zWwkTh)3W{$|CoyvvI#3Dt=_b6)VDc}rJF}r6s=siec|?{FBsL!mMyDg8`!q-YpU1R z+`(;ow>GS5eq`?9`L7=;eSY<}x`r1ftvAXx==-<-aorJ&yIiRD^<`_Ot|~TWmg!T9 z7ayuvIj=5z-lDaY>)+h+iuBs6?ISPxaYbzWb>Av}PvDaErTUqC5kG9m+*48=s-hdYr zjzGT`)O!%CAR(|h4!}zS!QrHD0q7-?hhth&Up8F*9s=rcn@ARlzO)|9Xc~A}E|&@6 z;fp5q6sRZT5@P`G0w~ zK?va5&P`xhN@Lb`DjVPpJwo%RA$sc$W?7rEcRyk9AH+ZT5B#6{?%kVSV~3%!V!sne zlZcHKNSe4%mMlfgjg1&46HXE!8boPGVdL@Xo8%Z2vdaU%$z@bSdo$D<;wrH8q|cm2 z%iuaEDd{5r1Z*1gMiyV^W$mc;uUxgca_!ZDWd*{Z&fxHeNsE|~OQKz(Kz|=(B-usJ zj9dEjIdKc`>HLhncjV{?M~A*M;tTLx&l5lW_+!RTqNlSTdvL@fPo?{Rs{=Sg_-uAtWNZ7t1z2&fdPf--7v;{~lN(!`WaY>`lVf#svob4O-vWNG9eEed_iByMwx}{!m@f7RR^YwJ`=$+z` zy96BeVFV~dvSs-y{ZszvXZ(>*cs6hh0a=NOqzxCa-~47Ac4koi-?zDJ7~UU$zbFh( zT7u}rv|6wa@*X64cHYNPUOl&Zt|8tMZxJOC8j$qlS-xCf<6h&g$C91TCosJ^FwO0E z681*(fHBCg!-?k5wpVfM~Q^(5c-9Y6oE&t$+F{ z<2}+pDQcXw{)yUIH8a?(rG_s|ye*xgdU`q&JwCnb$cWF%|Fm`c%57^mZ8G-l(^uEl zHL$g2WMU4RQBgUM9%bUhd#duA^7pV~O-*L!wYAUHvpTcg61I5h67up@vV|3k0VVc| zy+FCN;?^*};vYZ!nC|IetMGn>0FgPou0x|ozI0gQ#*JSz^_i*9&Z%R}jDG;5mIA2G zuA8~Ga&2Y9+!nXd;y$tA-FGiDUc*0NtWAz6w`V_l@2ug&&H1{_$S*VMONZRlv};-8 z(#EA579t>QYptzX(<$&Xn*u-6m(5$7{cLB`#I$ew!$i@ydr?jv!b~S4*)ViB%e>=G7hxwV?I@kuqpOT@ewReVNGve&^Cf z%9uSy*)MHDvQTn3(oNuc?B{d^r@~=%8)+=e#(CSB))t}}j-_V4(27WC zO&}6#cwe!KqrQU>ZitpI!@?o2#3%h<$;fZjXo)Y;u zpdUh5aDN06g+L>qe?lz8XjD%S&KibL4N!bGxpqxh&|*4s$)`&i@0TAu-aZtY#HG<5 zOqK0dz60DjZo!1HY%E3U;j#(X>ToaRuo_*$9w@IRPcJb9A~920%GD#Cd0 zX-03W?bmFJL{4xL%Ij?BvVXDg-dniJq3!#?O-K641maec>+nrpG=$N+25^wULv(~h zGDI1q6UcNa62|PBUEp(@C;<%V^54GAygfW`)h6afGLwW27cvgsB}5A$f^>p(Gma9( z$+s=yMMV+>lkaOwSpzyj5R=?fOjVhdI-SjpC}TxqF%Ql9R@UpT$PTn_mlhNUD*~gYm9*ayX(a&mI4R-B^ zgey8XcGLrtGgtTo0f=scVrSFUkU~rkIuH+eugY0cM`=2qgi6X{r4HX1-?&jZ@s*FHUshS=-vqF{vfu3 zDBjNgWbzrtM>3A2VY$Cs^hB;+`WC|%Bd)P$jeKGtvLkQbn|xxV!6)+xGT9X4m-K&W z@?4IeD@i?A_PLHwoRe}{rG&t0nz1wqT(R{2gdh{SQfM5l&%1gceuyW4prvbB3JCi0 zYa-mh)IyjksfA1rp3HP4$w*=HVyU!l4iPg&l)Z4W-v7RleV7O~0xFb4m0}wS@fZBa zk7@54g*zTd-#uABI(pCDtiM4TQffrMrgX5+U;fk414h#h$*)q&K|7Lq#Laq1%gz+j zR^Qifp_utGyZrevrqut=pU}7~kl2D@62Y6^M|6pgA3Q*?cVv2yKjm$UFbfn6#Uy&H zfKV3|!gx8>bI_2n;flm#bGH@(+j^WN+-dl=2=q+CxOlZ;;@{gh# zxFsuEKV#*z>MFQ(=YzS#JhYl;VXKy|T(Z1k%ZvtOLLGhe)uTsW&3(whie}ANFwI@% zrnY<@+O1+Mmo5iWZrxJRFr$%~O>St8}Qk&{sZ{? zUoLN$)iA5Jl$Eg5$)(w2v&UxK$HWyziD#>oo!+^*Wnas_58h||3U+Ar8{_tj+jCz- zDl@VX*&}zHlmSGZB&y^myqE1YnSNmVB9Q-J*k1EvVfIKv_DfF~wlB7A+F8GwHLwkf z);*2W>)t^;_6uqo^Pb%&1P%q7VY!hkrrpqIfMgq@@h zi`L{~#VW?RI<i& zJcKVo&J<$)D{l}D;;&Bl4!jQt!G-Su2e2fa>d&tg*NXmhiZ>#yw@fser^s9a3k*6n1d3GbF8Mr?HMm37xzoAn{Ay$ z($&)QN{%*%?RLtkvf3b9t+v~x5+TYn4I>yOAA|hzCrrq9qWAn=6Pg^}QI@7%yPBN5 zyEH$6ygn@e zSU3Z2Bnz6HfYe8}X!rIP?ZP%n^vDw7j~J7!==Zp|<@3m04~X7ESL!3k{+Nm+ip4cG|{#b zaNXK=Q!IjBzyJf1|C*+Bx5tArEO|+!=2VzeLi$rGv;pK?plKx1G@T3bp3>nU=k9VB zboEA<7f>gdLGwd;Q`(i6EFrSg>)11mY|4g7xF!jtz?U@%koE^nh z`36OMH}egO_G0V$^7>g0AGtc+K5Q0VeIC}C<~WH2azEfC^+zc+I$lYFm(}D95Dd

r5p_BLAu#&L59BB`)Vtc`5zf(^6auU$X0O^jSUb@kM3 z^S0M+t6kk#xxI2*0l$`QHMVZrO7aZBS5m=^QG6eBR<575db-pjBn8cmPk1vSt7a~l zGk?L1c~hgs$XPQD+nJfON){9`1NQw{>qfSIb?thCo#p!)B|ye25k+NNw>lA<-MWWg zQ@g!(`@F`fwT5rJXu*q5qzBz?)qw?&Kn!6WtGH{Lh!9wWyDx)t_b+^P-YZ7TM7{2* zWlyommq6TrGsy7*Ypi;HfwAicy{xvRrliJLF0%#j8XiPQuy|<(KJ3Yc84WXDWDN}s z8~AJd7x*o~f*>X6Ilt$t&E;+T9gmlM8v$7;QlJxI(0dK^0h0Pc$}Zb$QgirC3cO2U zS`il87qUP^W%retk*9!J zo^;w}jR6f&#J-h~AEkeg2!r(p-AzUY6m)nhy?Qh-#G4#3FvK?K$Thlrb85vxMG= z;=?Yy5%q*8BGwA$A8Lo1wclB7jh+Z<+qo90wt)=dP7iJRjb6k}2I7r~h(Yu<5ZO=| zTMICXjAmjIq-PE~TILp!vx46H0_Raw5NJ$#TI8yOxhQ!8?75W>_Snwyzd^>`9b!92 zQJA%?eo6gequTP2l9%bJF^^E?&p23?D?W9CaO6b4MC1sq--=I4kqC1@r z%sq+M29Y+lPc-QT1?>Jk1r0N{RbXD(wiOK<4BpI}^~MD+RK3VJ8M{1~_VtL^tubO^ zOzr=}4?1Fd)mRYUs166I1>T!(fh2nU^W-yWU*Z=TQquY-<1IH4sh|1$%QL6HJe~Sw z%9;KKkK~bh|1-&7rky^0`l~NLKVyhU-dj)ZpO%ataX6j!Rr2Si{RmEwjspm2pww1T zMxdUMJ+!h}A|E}$VjN>7DLV$zM3h2@W4R>h|Dp?CYQQtZn0N;-ay;XeF&&SIrOc||#bpJM7zo%mglNAX)A)9|Yw zi|`{2Tkz8gZ{Vj9&f-T5uEviN#NY=92IJ=frfVzkI{>e1?*{b@8Vdacg^%afs&_Y*HV_&uY8 zQKDKAJ@{n66RL-j|Gjha@+CG~=y|KU^WdBS{4)4{si7Q-cYToRX2sMHkhOMsIH#0b zp;FFULgAYyAO*3ehmuyIH<1AoLq#CJgN}i)LoW>;$y$g2x)GGeMK9#|)d_A8MMI@w z;{{n+g6s?hAd(Y7Mh@^2q8*60;t9-~1>Tk<6(sE=`D`E(sH0Hw!ysM|8pwc`lYm;X z2Z4Jf(gmnTxFS@#p?uT3>JRU9Q_GlVh2KeaUc30+Q=w8Pi4hpz2!DGl64|IUA{eGOFE}CI4>~1l(-?NY%6Mnnl%1jI&Xfi&RCO)$xL4&EjV-j#Pyb zBq1-HlV#2vIdPofcI)%1<{_e^5=WD2}{@nFCs{2o`y|}Oc f&0~6oE_2;^JyG_5=y&0iW9ggm%ZFWmXYv067aL~9 diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.svg b/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.svg deleted file mode 100644 index 0792c00..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.svg +++ /dev/null @@ -1,543 +0,0 @@ - - - - - -Created by FontForge 20120731 at Wed Apr 30 22:56:47 2014 - By P.J. Onori -Created by P.J. Onori with FontForge 2.0 (http://fontforge.sf.net) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.ttf b/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.ttf deleted file mode 100644 index 0f94acd1ebc42d7ae7cf1ada87d4301d73d64e30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25568 zcmdsfd3;<~eeXTz&Z3b<(u`))Hqsr9G^1rCOS8+eWm~pv*-mU(UNXv}XrwD|iEY*K z5{v^W0RwIl6q~9Ep~TM#u7Na+Q7ib=&q0OUx4y8cdmXBXFe&64@ zcSa*;A^m*b`{zlTImNjs)5{{a- zOh^)|MtOX4UwT@qeDl*N--*w_0er$eGlK7k?ZHVulN~>&mw?~q$yNu`Y-Ka3#Yru-G524(=d*7iu zKlcTx7Uf|{l26=zU^4wu^hwM${A0}j&3)-Rr&-$aza?qp4B9LE)BC1=Il+&i`~v3q z==6a*4*iQQl9QzED<#P=Iel-BM6OYc3gOYODQVi-n)zor9|M!W+^XugeN5hwwdxRLrC|QbdXR z)2Cj4whSd|RWBJN1*rkQD8KRg)vNfHu3lBN=Xk_S3j;Ea3i=fP6wg*%|NmE>6K+Vq z;4VPUEJ+c2#2$>;{k1=M<_llouKBlW+0Qh{$OHa^7b1lPtBjl_db{M7>Hv(e$J`P(dyIitw8iamn*A+~E*3QUDwvtg z>`f2lp1V2oeD2#Oo|(43o;y1|_DAh(BRkad=mekZ``M-N^vTzo0_Sf#{Do+DGI!Q~ zbVvQxy(QXxW0!F=agQ88n=%&3s@eaX$HH>f+(icRBW{$eppC#AoS@C51Z*vKzlHhj zm)LceF6F*r3AHD37pXsu@ZMus7~x)Fj2W#*?&9K6vf1|=LmUaac8rA) zvRSO`eb&I}wnU2iqsKybZ5!yH$Hx@GiiufUG|bOkG9_-2%Ad-u)=|{UXROj5oJ1Co9Z3M>}gPtV^`9aB-OzrkoRF5&##?Nk@lY z*2b2I-D(Te+T`(}PHRJJrbUS@U>t$pd=6_b+%JI8FXKZgi@5x3Mpd(_N(t_mxMZLS z=Rsknfg<`CO~CP#R4P@0&If>f9+S)IF$2HjEpD4R7>@>xg(`va!FVhhJUW<44IW*= z_a3EO?vcUz`oTW7y{``$o*LTmk>fjt4u5gWXA?(rPahuI@!Qmzq54o;{ZQY?_N9H> zM*4>8+d}mkPP3T;PKVu2Q&S-7aEBB2p!vvSNARb{Z;sR2MJe}(4oB{7>@pDLVwR}vc~k(gfL`dP(;ckK zE!9XZQV)(i?r~Rna3FT4$?t0l#O(f9#1Z$HeFh?>PIoxIoJE_9^6b7U8~Z!Y-Kw)< z{udQa_3ld*)iX@V{cF3|+wNtRB9RqV!E(8JHFv7Q>8xP;RaRsF$m3bBOLch{e_>r5 zpFACR;GBJ75OJ5^<;03&_Nd41vs?I=Evjmn-(dmA;d7>2`I}7srhw7!GMmi4CG6%} zhio*m%e0&D{nbq){W+3x_u7Ij1j@mT+3M@|g9{l>rvHQP7R z2b>#u_&{vSme_%ZN9Lbx>+2Ik&=(Jgacne_BVq(Y@W;%-L@?n=xDsYpVm8die)hB6 z+3?1Vv$GpFf_u-(%9Ya(UAdxH;4Xs%>3D{*T#^^K0uD*bGB+>*mKf029u4??E+8^e z*{-GR^2m|Us?Dc%&%cI6wXu*&i8|Y#O7+vC*Crb8+_3wUibpeTeY6##o~h$0TDqV= zg0_IeF?)o8R)h$Xb=pESTBA`!Tfp-iK6}E0ncXhCugTTn|d z(ToBh zO(z6oNoXe}(8dTTHyLDuk@lo*)A>h&g3MBxg+%RZJjLglu*NsrYbsf3?#SlEfrkVBJJ%;@9^l~BzvQog2Jga7qwz?%ktMoV zKMOZ7li8C%1rd)*22g9{#A)_u7pG|nS_GDx=`c)Yx6|yEo#sH$OvD8+TEPOb4kogF zJe~-4F-x7J!g`Ol-qgH)$NFYtef>RUr7o|n><*_9I052g+EnTGx@?uJnpdvyx*YW~ zWBvVsfl8ap>#p2n3LB}FanR^IWVNxcS1INJw>NctGI4#X!98I1y2@)!Nq;4P*`%}@ zyy#WtU)$2;|D?faG8%7ic|CU7CXX15Gl8bSkiQI5c@3>flh@^JsPrd|q*ZYG;9TaU z63`05ZXA3Evm0CNL06O6n4lkX+CF} zf7Zgczj!)ly-Tin(h;;(IGD}yw1xB)Oh9*@WOawQMU9dlu=mkSI+p-GGu)pDeZUlr zdY)*%&Np&a65myk$O>H{i(FwLZ3Ywp^$ z$Xz&9yN`ifPV-c5I{!=(G7+9JJ0n$25It~UL6`H->=yl5Zkl>78q>mjY=+H{dPL7O zKGTT#bO_kNg$-eMBlCqTAw=MC1GolDn8tu{iG>{2tfzHg!-i~mtuesn+~zH^t1Nf6 z)FoHM%S&gOk+~Y!77Z5bMZyDBioI;eJzrW`S=x5Kt%fz^wiXD9w>?ioNWL=R+{J0z z{bs1bK_7%u!8xGv0w#077qAf=uh`$9T#i0AY}R9vKyvsJmT-IeIsg58H|KuTKGd{f zv}W+W>(>YGKg8$m8$s2evi`>Eb@vTzM3n}kuz)*wpTm>zSlH~9E3*VZo)Vb_IY;C1 z#3Masj~SrWTFMHgXeQ1=$N@B#g@OB{Iya5SbetlSKhMIP7G@5bgLE`B3LOrmI!#q@ z_sk@179?3T_7qeqtWX_#oDCFoqNG;FB)}A1wlR}LlJB3u!m&w+B|&puvAQxeJDdMo z7%5+aM>LcePtXE8NhQDsVx;);fqW7ZHAX-PhyWLOPc+VO`WwqCau+MgHs=0iBfE@3 zMcMoje9H=GD5_BtcCE{1_3AQyvW$#-MRJfCvw{lfNvJrPfc^fL!&05KIW zC&LKHXq>&c`&37-<#|X>xnI>E8L@w6gKS_X?()uNv$IZFfw9B3y~pJZljIfdiHscC zaS*aHcq%mj3tcq7Q)*l^f6(mDPwjym4gqvI^Xqfom(9K|X1wuA7FP$vB0pC)tIyMa z1%emgia7`uHQBzZXa*rzi>+ycruuXJBS&Z(d`=s!KLx_H<6sf~lt~T1=CB9$46slD z#+ZlK!f01MeEn?~+QQ+QQ>>c+v@kB@F?Mjw>JKM(pUN(tLY%R-Mj1L4^amDU&{oYJ zf3PLuG5ZsA;{}TV_2wx-!ZmFbnlb$>f@Py7;Xx$um>Zd^5|=bs$^1)jzY0+ z3(cx!HbT}DQY^$-jbh7+Cgm^gV-|gMEnT(;X|vD;gal0ei73!si|1L?2U{hr6RdPv zlbf|(1fb$Rg|!(y!r-Ry5G+lfi4+i;hh%c_ebCh)cw?`$Tv{t_#to!%hj}or$yU%n z1Wy2l3QQGb0OC|sz?evaP+v(uAs%hk80d25gD5P7P=HS*5cY@ZvJ@A-0;b^#vpd?o zz-M5<6<{@V+z@dL2%_)OL+fru1MLQQ+rI)shiD(Bns&N(fXpROT7B-E%M60Gl9G9TiIBXb_HPo0t&;L$e9u3wBL<6G?kIoi{`N(sc8LE`inXUzSz8{RYuaffu$t>f zH7J8hRj4n91D%xzG(Gyx)5^oa9E~UXIB5k@C-g#E?ya3UxvqF|j+!Z&~ zK&Kw*Gu>z-z6Nkzd$as#vR^^a4K?w~$Pmuq@&-z`jp{Ftlwl zuD<<-(77QI!`x5cTIeU|DT`6F{%N}=wb#ziKvEGjb)Vc)#Pl`eHXAEq z?}DU;UN5TA=hen3)44BcvaqB1qb;6T@ zV#L?`SXSNGqlDBF`<2ql>QcsfmaUI&TvV64D(XOI-E|Rl%v4z#E^CliSvN(((e9FhPCdMpP~~{0kXbaZ7z?A|rjxbFkL4D!q0DiNLJJoe zTDusAwj(mMrmL5P{k%$Q!kRn{2EiR-(SA7rWeUV!vse-KuuxNZ>*!zt_>&kMZ7sjG z-Fsw&B$zf>+M3Ec4jwqQoG@wmsRIW)%5xjMu8||SPkn8!qI{4FKHr0@e&D}u%EmX|Pykn@V=m}_MpOz35KH&&WsdToa7@cc_p^;S>{7t0K_M7rjMlei%7dmCKb3xRKv(w?p>jrz8Ef$k!^NtgP>ppq& zI=fxAwsj3%uihi<5ZThIdatXYLa-!0=Zmde8ME80ZM!zFg4osAXma=W4u+dl%^+c_ zXmEM!t4al{)935twHjbk+$On-=1Sb&WwbU_nw3JYe8#qb$p2 zcjeeX$4A>kp;fn3d0jP?{kc=t+^^Wt6*kw$a^Jd}E#q^{e#@$kj?nSYz*t4K%j;Z~ zJ8fe&cGrpuccu47xtBi9mgVm-*`bJUEO3lsE}>mJy3WPzYlTgeNKl2r(`5h=GDMl6 zNPZvXvn6$dv5t=At2)bSMAp~S+oP~*kzdi0yC}-CVz4Dw?oM{yvTkJU&0Sidb$I2# zs)0?pd9Ao}La)$isiezg&^KWe^E*JC%pPCN4}2!-Lo^{Tb${n2?Op@AU~d#i$0$n2C z35#{AzvueOBe0(LRbJmiYA}j@{V7}3P)IMmMh}W*8!j@q@?r}aPEBT0 zlL<)|H=AHv4m6qFFeKy8Ox!CGhZVVtC;H`JfQ;G!Byu7E4cX%kdm3a|lk>I}HZ#25 z?Jjp)I;xBYxvbJ=a#Z^&+MOm=RdQW*o z-20-x*C_XyWQ)17)Zr=^XHJA1m41t%!ec9w%_f6=^*Zh^ZHUXJa`(PQ_v)q2YO}Mo zp)%xaEvu@iE_HcK#UUJOgi;YPg##oVv6wH^!JgrV*4QB}ks?w8GT91^9_IN2rLYtg_{9e)=lKYT zE%~gGXn*frSj2G(tfwdgK|mmZf;;fe^)KT6wA#EJP@G?o2@ot&kPnLUxUTd=3@ra$ ztXJme74!_8!e_*X(goR2^B`+-B9S(F0un$;0f&V=T@JspkEDIFUuzngJ!%&oEzM4! zx0*TltOGRRJdpyPa(Nx|dmX$_*Jd2Kr>LH7bdWzQ_qxOJl&-xLXa>$ZBB%|_!ov0k zIXmWap@fMcRSO#+$OtL<`4TxSJ0NpG4=49uSmcoAE}{nJa6N|<=jL_I!Ud%w%}r}* zzRYG^uzvNmN|}TK*zA< zv8{(86`!R%D%9g*9-EMRV2*@D4U#AfA7%>+2u^vVFZY$)SNh2DdSnEj$NF+#VmBbL zuy~E2BxG3lL0c~ceJ*O|7Ur=NLaKK?tz|;bZm0gphsAE1{ z1I$3&Oi^>W*F>-t(E4`ga<|g z13`}r4X9^ZO3TPWoV%#GfZ2@ZFwRXcF7K_XX>cJ}CF}53mQ}!yW-x*-fheKQ<>gOn zuHjkD;j0z0#f7Bot%7@vd7ai;(`6Cl!eF4+@S*|y%m_Js1MLsiH5k-d5NRYtb#0Sy zX-0zq_{a-ICL})r3e+M12HtQD4k(&U5N@IgVtg+Dw{S-6<4x{F`_iSem38n@&o(qP z?x^ditao{i@y|0fwBgjuyO>?8Qed%L;v(;Xgw_>(o zyVuL>LMYT%Vvz6K;4N`tgyQN(o1?mY=@*yYO9~g^no({*yg`8M(iBUj?J$VN0?Wt- z|NnRj|;nHOXEidE;uo}7q&=K|IWOS7rcV%kP#nlDxzTTo<(elXaZ*c?kO!x=l8&CNbD9Sx6rl5 z(uqi7`2rUtic=9Q*L@VA4dkaF5e4aMh!}*d_?vA@;UhURLd0Q49jRK{uBz=iFQ9lG zyVxyy5M{}88LcmyS-Nd07|W3n5EK|@fdB3A+7lkW!~O}B*hyj9zS;Qzw*2Ai#j!-iPZ2;YjZBv6E5iiW}F!?P5>i5-zh zc;!k~4dVj|G(V1j1#C3%3dJx6T?ii&!w@ZY1iNAUZ@FbYxJTa$D z*qw<&S8zD?p}gl=6U>Feav^LOOpCUVmCW(v%t!VsinZge!>5zSuM<+5P8Y#bf#n|1 zi!LEw(MDXp7Laf*PMgFRLO9Zzj+37DMGRz<^W zS(*Pwxx_60@`|$oX6y5+m)()-58c()3e(Ec4fXxxmdeLC;23c}B>M}y0L71z7^nq} z(p|y!3FozTfClWvnh>BFh!>t=g#7IUK=22FmeOLp6gE#pjQH@GA=DLb51iNRp90nz z{)%?GWxCLgCL|lF)=t;;U~3ij3}%NQOLlj%M3Xg@j!mqabV6a172`$hWDZ1RY~Id| zmJ55pohJBe8!YTy5_bU_DXb=d4^Y={j|d=XHa@bQkmyW0yj&!UEt13*Nl|m^OW<8- zPHVjSd7Qxuz%K}&g4209(Y56~8aEdl{(1y1PCjSoYcn905D|pjxAdI7lR0$1%Q??oBPta-gT|7e(c<(2l?EJ zRp&0%eCTtR&VB4vaju$8Ku{k)L_LroB=lB^-xVaMp`VSBMFzx1{NYPbo_v8)Z5)9E zr0_wTBlQDJJ!UX36zu&5n3~9a?5WHB`zQ3A!I`@AOoubC_N=bX}4lTBVt?HzXogIhgThxmBp0|T@(W^8li7t(C>V7Ru<3zG2u)a={o6?2(xq3L zcMUb$R@w&p0_KWp^A)cb>^pZU%p%cKQRkk)yN2I9GtAt*c*g@`%jM>wUCp*tw!sxm zC2m{Ee>RMG8ye)?uc9-NXw=_x2bE<{u;TzJ923xaVYwnHv4@VGb+kVVc{YZ>aw{ey^k z;J??@mJLnKKfCq^Yn$3~);3uIV%u6nAK8&okvn|uTlN)!a|1*DvSZse%AO0r##6Lz z5pR@_7n6%7W6P=gVaw>RMu!i){l)=VIsMA%)34+nfns}Ti>hupL|dm#iCAQcIRqXp ziZukW$Oq&(*eeM94?Cd2{=N_&WF@cI!fDJdizs8w$1cVc_(Zl+pa9O?&f)-xFkS~) zi^oisO*YnK%l&AIwch>s%MaX@X13g}fBA8A8G7dKU~RkhR(<`R2VUO7Y~R0hvF*ca zKP>R*^MWq=u}%<&LKM5WjdpX;u8|BahVEt|?2{P-rVhbrlaSAFBemFdJz_oE*QRMb z2-AjOzkm$S70OFpTejZU7 zmYe3!-((R*3Z1d!es0NTEv(jpl|u&*gOV>SZ%cy(gt!y!fZk;A=pPD6fV^uJW;p1s zZ^ zcDw?FS2FvpGQXkm1xux2ymi7z`5%l}wH^gsU z;^i(wm8q)CVe?pPYT~zcH8{(B?$+wInx>ZOPV45Lf%!Gy(hD@L5!S|a(oFzgA?6G> z6>I2%(ru>22z{@g$qS78ovd81X?aH*EeLK!k9}iTows~==Ww~VF4`HRc(_`ftAnLG zpDoI>FX-`p^dKLC7a1;Zk6L?Htmv@@mJW-MKP&NiVOz`+U!{_!=A&d-RMK$o^8)vR zCn%Qa6qWmLgs_SCy(s=eA5Z67u&k5cli?!65eSL% zTyC2Fv#G^&G8DK--Xxw@)V8W zA$k_m8G46}ywzcYy9(EeH~SGBNr5a#ajnj>wjX{pdnWgb$6jH9>{stXY=f+P^oO}0 zoqdcsZAUb*Y5q@dwv0VhjAyU0(AJ7SFBlFfjFSV^Wsqy&tiZCPPayOO&or2nFJ%Ax6@mCH|WU=_*SYu5eAa0lY}ER}aOG`{im zElXmtC0ky4y|Lkr`J4IXV^5vl(A=n)1^*-Z(p^9IOr;n4j`_O&5W*lgcgkw0P;7A<+t$7=kVmUJYJB&iNKLcYR#?Jf8UCi3}c-IBo&7UFJmBf4N`Qh>>l3(AoQJEhThXHdQjB?k8U}`}uc(8O^K_>xz>mCEd zsNm&0SWV&SPIx$6*$?4nk}QZj3gi^D>=D%FD~fpuz44FmiADN|7Fda!K_SHSBGBxR ziZ?Pg5$@*SbJ`@T5X@SH^YFYtDhJ2F+ginrQu3qvWhLC#HcM{NY1j#7+xqaX2y6)S zLM8b{d7!UN+ncQ0WI!vm7?ZH4N(R>Kk_IQZOSHD8!k0VS-r(40%Z(FIWmAjuks3#%*JVAkVSOW;sdv8Ch_~OTwRvEV zA)8Sn>8{WS{4RR0Lx>_|Rt$<*Cr$N;`HhmMhC?0&a;agrzpG7{4sBy@QbQiU8==9u zA3H1C8!9a?-hy*9m6VLx$oRN>NvLV%a#Ba``DT@D%{}6%Y-q2v%og|#)*xa@gxwU% zk|3nQS}I}%@jejfr)DP=Mp9Tv3vdD*tJK~<0CRov(Pp$t4J}UmJ(Bg zTtaI?EXJa=^eIc0Pv9%}I(>=xvsf2sk>#mU?HlWP9`CK=qgrl)KB=ly!rPBGAuWah zy?>v4rnx0qbD#i!iVV(>b_DE zyu$Q~J8?^RL}8@!l4}&k|BI>+-?UH&%~m4xX*1*{oE%-nAe2R43}HxQwj>_}tXhar z@(0Y&hK0qWlCez#11E^Bwge_V`q2r0Yjy3a?b}z$)gHI3bhP_wXj>%il~$j9_0ejJ zYO>#U?`?LID$ACruPJVkbsQu+y_vW|erDslOmfYb3u6cwO85I0M$p%$uRz;lfiIF> z5gHJKRES%&oWUF?Ll>YAi;ckf7?9}=P?-e`48Q{sp5NiXd#_s@cpH@@3A(s6CTI@n zx+PdU^!+OM^GKNt8Y!TbGV#1={ZH7LFURhC=84b7*s+6?v5nhr*cczbPDt>4Zr{jF zW2qPWw=Y?;y&skw!7w$NfS5@i#;=u{uwo4AiU=|Wb&edbN7@;>hI*^F;+GjlGKp?~8n^erjvr-tKSJ?Hp;oS1aA8mH3>NzH1w7f{2AU z2hyh^4*bdx3B@m7-4MSK^`8R&q~f0(hzKR&U(8*EQAIC<4dLd2>Ja?%ex)GY`}g)N z37G&IDfy)F|8*c|gFhggCKeH%rV`^W-P5$oU=*IFZxW>+Uumn7V}eKvEFiCw0Zlcp z(=OReUZ*`^3Vqcj^6JsuU1+7_#lpHeKKQ!mMXwLA9^r}Ad|>alnm7?=f;T>2|Nft| zTPv6SyHtjohM%JU|8)jXd{}tr$b-x2DSpsLR<1rQ4apy;qTHmN9Od<&pD{)JPb!Ha zI*CSozYpZT_k3RbjPk{0((gaWxcNTC?elf-*Pq%K_bG0B?OKYT{lCn=+q(00`Sb(N zkJBq|`(Ar3Zu3F%ziXWLS|`=N;~CZ{>h$zo+W^0c`xWPl*9%&?Xut2(uDB27@xI2Q zepL5C`(8WN|IIS3VG*p0&l7q5rwaV13ij4b(q8F=bWZxF^mA5^0Ha}ckey;rvTv{- zvtO_ruj0)-4xinF{AvEC%;in;w0u&2MgEPU+Av~J4W|re4bK^VYwR)}G@dhcnZ`^H zn!asznw!ks=6>^a=Fgg+Fu!Vk)BGPLr6u(x%SzOe&zF4LQfgUdx!H2RC1d$bskJmv zy0Y}f(r=djq|8>&?~^)=arnUR~Z*zODSu^2f_xD8E?#iwZ+U zYsGlQ$%@A+o~!tA#cwLBD#t6&Rz6#K#pbkyY#VI%+a9-l*S^VqyZyUWB~@KjYSsCw zpHy9OR5`jGBaTy!Z#(|kS>kMU4ml4wA9H@g6?J{t-Q*r|pK)j0ueyKfsq(}L;qRHPtnNnj345)O@by+qKoT-L;2mAFO?`_Lp@^ z-O{>|x)XIz)LpDM)NiZ*oVUt*o%fLUe(z)6XT5JW)HiHuINmVZ@a=|QG@2UQ;itH_ z@topR)+po3rK*;-^A-qCkfSaMDEGiB=n>zt!{PG5=qBUY1($ z+Jn}{fS{Kndfq5iurKI&{Femw5;!R{kX3{*O3O27>3^f=IW+zMq3319g#Aj-8>A{W zq34ZKJ-b`anYtfRN21&(4IrLPpLi1QYF&e8SM;r_n_H3N0bUJC20p{IS6>{ z5sOzaGC@&;q_kt|;2nDo>{oiay0Li)O{UR&KNhiQZwIEQ_IKttsAHsb^&a{^sPFRg z52#}jXPn8*fdAfMf`zAqSy(A6lh#OsfY3T=NLtUVtQ_v}N@hbeNfmQ2Cv!13Y$?^O zhSjn+0Rz6m24FoV5`|0Hptepb!>>OXB+T86R%^}vrTL>sN)tk!nU$)Y&+Y* zZeS@k%5G#gv76Z~Y>eH?##x$8ut}z}DYldCV!PQMwwK+;ZfE=0es+LOv)==Ky@MTM zhuIN!l-_pUF zX*>Yxe42fh{UMuWf5aYS53$d&huP=ZAG0s8N7xzm-`H99D0_^3k)30I!p^fVNoUxX z*;m-(>`&Pf?5ixpE`YlK8T%T0iapK#oIS(-f<4RrlFhNdV$ZSX*$eEi*^BJ!p#Lwi zZ?bQ(Ec+YwZT21ZUG_42g?*2`%D&Hj!2UbC$o`i7ko^c;;_sw)0+si4b3|YFgn3Vd z_e6P5jQ7NOPlER(c~39zN%Niw-ZRO2RNgbidv@}0HxKu4c#pyn9***GjECbqoZ#Uk z5BKtLnujNNc#?-z9-iXiojlUbBR%k4@<@b7qC67gkvNYecqGXqy*!fUkqI7|M;1dmSgsLG>LJi3#|x_PXJ$HF`o zfj^YTVmub-u>_ALd90Vm(mXc7W0O3l^4JuQ?d0)p9`E7tFpo!gJj&xS9*^VSIq`Us z$9s7^&Epe1KFQ-Mk5BRVPM+xIi5{K^^F)LvqC64fi8xOrcp}LYy*!cTi3y&VTU4^M`9GQyKlo{aHioF@}JndHe{o=o%P1W!)#q{@?1Jh_wicJtmI-W%q< z5#Af+y)oV!=e-Huo8-N{yf@8zCwT89?^Sv46z|>1)7?DX!_#4&j_`Dpr(--F=jjAb zCwaP;r_($=!PApGt@89vKGDr5diX?`Pek}cluyL?M4V3~_(YOV^zw-`pP1kilYBzu z6H|O*C!g%*lRbPg%qJs!GRh}od@{}_6MQnsCwuv1nomyf$w@w`^2sSaxs$8iTL3* zyfBOs!(asDHDHzAllExB@ ztA|q=qkkY{@(GZZ$t|hz z;kxw5Xv#l|XDhd+@Su)XuTRyPF@!Sa)g4cQ?5-Xk=*$>V^bh!zjN~6kXYQWBWEn$y zXT}s#XhnQ*GQ$QZ#@C2Nn6*l&!+$|Cw2Ui*C;e#xn%JXMM{vj}b(k$bT}E#4r`Kqm zOF|cn#=#6ruj$NKLKsg`GM3dF2n5LZ2SzicR2o646s68gX-Ij-AWhKMBqqv~tsYlS zjw_imthX~$7TUNib-~Qmj5cS=r~G$zW~`x&TT&ahYL#_9)H_6ddFX;J1lkik(5oCI7kt)<=PN4I>wPJ2#Wc#C*C zifydJ;@6D>ehVPG0857-TVI`#`k!Qs32;|nEylrZDJf(14=Cdp_o?!72J7a)z{&9o z<;IT8zK*&kY`zi=D>^zew$KGesXcUoQ(6_eAXDlHT`*AU1XL+?g)W#Vb%!pPDfNUd zlu%k7x?rKSCX^}Z_<(cQV(uFBsl(iq)?;o;y_lQQ2Fy)qBj%=5!Q7PkFgK-5n43~R z=BBhcq%0Ho(-Oj#%g2?~0O&X!KpJVLx!u>934}5&9hnwjUJyvO4!Ds=J%2jsS59tE zU0aD0?##3n;K|&XV0(tSx&`>!inqJ?QF};QZLH*QIOKFUh&uL(l2rr)2u z(9T>~RS0{)3i7SSfk5eGXQngM3Wx^IQdDmSOVZl?iQs>Sx0van_hqN<|_K;z?%Uuk?UYMmjgt>ux_!CVsrooP>lU;sAS#}a*^(;JAy0kGe1|k%L9ZF`L z?$OFEsXyb2tknG({?k|O=m6d95>N=thZ+5Af!M2orMN{>heoFO>T%VdkyocxTwcC9 zU5EVmC~g9pr74j-O3g$2d^!@mkVVeSFA1n(O`VyTKI7^AAF$3uRli?+WO z^l8~>*M$Ic0<#l^Y5;$sI$5X|t@B+MwdoCIx;yeu77e;IliN(>`o&@s0V`2ci zD-*!{eF7qcFL?lFfD3-0Y8Nn9TjMg^Mo_Z?V&%8^yD?|oe+^j(I&@c;`IB|NqJ#5| z>ML1JTh4>7pLXdZ_|ii3)fP6k0vmH_H|9x+E{CHl6T$^q`5yJFKnIx9k?BO6fly`% zlGOy8K|oJg3o@RE#u^X?+?dq>-eBlSNm_=?T4Wey)`gyAqGkvgQL~=fEXSh_)P^z} zsSRbWqc)Vep4#*xvx(YJW;3;+%rLc~%ob|Xhs+4Iq0CllLz!*VhBDi!O+PX_s10Rq zpf;3AQ5(vPQk$j7+(>OGa}%|p%+1t>GPi^>;R2Y)sE~=H`c{!kAU7_s2GvOv(xFVG z(0YOjqV=T6QEOG?sOeNF6D>5|Nd?h#m&j4m-6BU#_k=RBLesre5KV6rIcj>l$WhaM zp^i++R7P$dzLUszCn)d6XQb>17%{tl^e;+aKAu!SCD&wR|8%BeP*L!>V#~&iY3q%t zOtdc3Iyw%KYdffye$6K`+`k6$k*WR3(wzP^`lO-NGB~p4f{CrU(9AxyC6!tEsni9N cyavdL5`+vYLY% diff --git a/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.woff b/lib/vendor/sabre/dav/lib/DAV/Browser/assets/openiconic/open-iconic.woff deleted file mode 100644 index 793176af47c13605a36275252d9ce11fda817f33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12404 zcmY*1BH0K$K@cJKf3|Jwh5k&sZ62LM2rzE#|B;M>TJA}XpfvV3cD-(2Dw zhHQ|^#wK<~j^A3+Hy8P?MF2<#;U+&_iN4#b-x~P;fD7_wVdV0kZ}Xc&|A((H0GNfX zr}?*b002;C0su0Wg*lh~mS#q#006cBw};^y93V=Tn3mt-w^sYj3BN%G83hhvY3J(k zt<8RO6951#G$RLqYwKY0?W1A)9&`9V%uIEO*%^6!AD8z1+eh>tK-d83_C|JQ0015S zx5pX)0QI{v2K91uaB&3y=)=DG#rJ8OTq3i6dSsax8XB4c0$H0Qr-M%JFB6XjECGs) zP!RyYe|<*(Mz{h3k^=(5gU0*=0`dVOtQ<_GtXWVIEVV4Gy#av0G323eB{~O29(A?h;2T}qOxfbLOyUzy`5`t(7G+5{}$ouOH zOgi-I3nML`1_yf$+fWWtf`X`T&>t2XCzKxm!1ILi{JyI1`TgF5e9tMUM^>^ok}KX) zdd*c7+kTzdM;#mP#;sI}scg#S>g`Fc3Ar;Wlaui%FcDn17oEpWM5`B$%xEFFzF4-y zSKcN|z;5j+IZLRa(Q!RVmCLsh=qa0OHhm5w>+O@Wl|>KN;d{xOzm-zGLpuV6bp3Xf z9WQ|h!f|VPm7V_f)v@#Z_Nj+;eCFDw*K=fwb&dK%RFJ6pFTzZO{fa{)5IVWQL5a@k#+fX31y>Ua=cf4lEkv0vPm@W7=*U~*SM(g07(2~c2$bhvoMK2UBkQzA{ zbjzp5Omajl3^|r?O73!0X^(wGm%fjwQN28tpkH+88bBSO2@$IN~hKpxxK8HT*tlpt&7vGy8bRnU)BkZ=gqzNZu(0L7H;j? z%V=f9ey2B3f?mC*f8V+5i;Mm`U|v{runCevRCRDWu+&54RnI{TF>-8s7FpVRPkgEG~VlMdSGX~3XgpT zJof6m{Zk1o+XPE{uj5DH1O{lo6|uG`=VvV_0c+P02~Oo4f{*A5p#~F?>mSgrz9O-N zKG}nH+0;p(K1mQ{Tpv-=06w4Zpx)q})pO|#_s{ozMqU9sd7`la*=)o#$=YVCaN_(_a#Lq-{oRUH_1J3yY z+$V&mw$BjpolQ_5)k24~eljGi{M0Nmmv;LTo^8X}IeAFFztktsba7$ol7Z8z4HZ*M zhcbP1RDt*!VtLmh4rD|naBYo$p28A*+T&)5V-?hB&?HCNL?xNc1O(=m*p*4VWyz%+ zlgE6K2zNL=Up6{=H2ACq{5+g@I+80WJ0MwqBo?1`nH2Lc6pvL;8e$bfuxJ)S(4%6a zmg!LyU<6s+jwVX(Dl%^B^>#00y&8xT-#eT@9uv48xKks_$QZgy%Miy`Li+k<+WNiO z-M_YsZQi;R9)uJ8nbiHc`STrrCmQMRA=WfOj~$e!@k6lZ1Qpqj$M)0hRK2QR?)p*Q zF!q+-vu*E0I*@!o^j=gym==cCInPeOFL6DBYW)@HsM~IVka>z> zE9*IAK)|_0fhQ12z@)UEp(0vvxx3-j1A3Xex=f1H8QUuf=_tvNkIHE$+4YCc8s(`} z{S+haF?o20#Jn;x`xV&NA^V~%Z^Zo1oi7Udg?$~kV&@Q4;7AA|k#i;}_)rO%CSCB| zSa6(N5uda+`rr#wTN~@3H=ilYNS<#oKl2ZcABU%6Z<=f*$lBxvoWWD);ZAb9-HXcz zXwLKRvEB2Io?h*pKTUvE{L%$y=|?l0w~8DaBvAV>#Q02ugnl7 zpvuE2tXY$ye(FPQlBSP60cvWA#?&y+%hl;lmS*7(Swbfb$#J@S$RCD4;*6?6NeucG zzWWmk+43MVgv9ol7*RS4ej0zC-LAE;BFOJZ`;g-9X>F@spxz)E$^H*Qiy$ z=+-FPbLszU(tALm%k4aLm3|+MOLtiS7VOWJOCL|ji9&*n9t0#-9|kB1b$xQd!Crv2 zLaS#B)W~2c&L`ZsaCsVK(8H;Cbw7P=3zye)%`cH+V4dK=5s0lXk0%Bf2T1{Tc$nA? zn!oUV@T?s~CfAS9vZK$~Boy%bFBla`M~l7} zRh)~PMDzR6={^1(DRSVdM&rrDN6(Rd$Sq->9%;pplv7wzI3{^uDLS0?dQxt$8tYF~ zOpInH)PWmu>%y=|;;{JI(mNyOWX$-sUi|1pwO{_Trs1^c3!-8=Xm_4KjgH_PySL^? zkM?##d#jWsp$T6jq-;d_)xWW&&b>Wt77ML3zuP@T#t#=U{e(0~KM4Yl`fB*la&A7h z0k2NFEv@7Q8r698`kLVq&0*!6>(o&cA578VR{|}t#X1Qq4-^Roj^5z0$B^3Ufj<7Z zKfRAs!WT{JAu?39e79iK5hXvylokK5U*lI!1XjR!K&Wuiy#rvpyn?K_iD^)P(#5Z) zfeGC1Z}!sb4uquPW<#uN2eQSPh!?3v$88W+hY;Z#Z}Zd(-htO197%{TB4kATi~;CP z&pvR;$gPpa)nteF&a)|~LNnk`ikOVZ5rnkSojVD5C8>KBUi%$RaMGQMB6jBS0#H(B ztJq!J6g#u!P3PJb#2x&t7f(t}eRV>S)64MfoMTw4q61};LU@g7Imhg*{I=( z+$_JXQMye!nIW$$ae7fYnxvuz*#-TfO@Xxtp)hE@3^uF$%f1LL10b~A+t>Sw zpwDb^nOGC?^IH0|=m1?pkSVD#4uK9KEFjpGB(463jsr#5%H#OYe+;&*y0-<>SAUs| z433>Q7xy>|wm3TD63V+ebd>p?kBw1#3?4}px*P}>>8g>b{Lru719!&ADBZ`W*jJXI zDIn=rYhZk}?;Nl|*a;>Bo$rY_2dP<05bCe4SS}G8Y)l(2?$dE}y4lV{YvPHc^Ql}^ zqdCbJc!gh6SqPWV{*|nNQJ%^uGGY`5kex61F>z(R~_6ego57uTa+%|L*b;WfiZElU7m)42Oav?YQ$ghxhr4`#uU0zQN*0Z@|&*P}9ugAm!V#C*DyB zm>ET%QC=EyqNn*-SRv79iZrwb02U)zbOW+>4%G8>_r2Hal#ht=-u;JUNsz(TbVqpa znDr7Ma;@KEmbi_y+EE#YpK6D+r}Ve`Ip2 zCeL}M?L7MJM%%oHsunYB4cY%3x2P~3VFiIc_!YnwKdie+S-1fXQ<9jL30aW^{ysD<2cx}b#s+W z!3YNxNR}Bs-eJ7aNyT_rV^p#9T^}3ba$Y%qiXr~SODzkN+9Hqe$rNsk3YRc&l`~cZ zL0>LZXr+>6mEBg-(3@bH93jD|%ck%gcSWH*av%o^v{tQ&E)hZ~KS_le51<@h=n_R2 zP+n7-n-_(-Ht9g-lnygbCYKwdsZGhnnaw~hT&Mq zY8$Qo)CvPlM5*vAyf}fgo|vYKP4>;=EYOOZRZS2QJVnRq4@};(qe$>Wfmt}r6;?<6>&vjS$J3g0(Ze;AG z^6)Cc{Y-qZ-_Gz)HyvBB%VvT{Q*Oi#_ArVdvQn2kbZX&(IIgg_RM#rV{n04%9Aeg0 zO?l3V7gHGh?EIPR``!zIpz6)T3bUD@G+K07d~3uD;qEkrwQG&YgnK!1*f)=E>b;Gf zcwsThP4rr&sk7o@R*%J+b}&vD=nEEtH{TVuJv{3ko06a0jdZAN#0VtFkal>{6|D&A zKNhl2BG)l(hEU5h*#AClccEq2D}J3s95R`z$UD%C{X^+KF?%X#%Ux>Vr* zf`NC}os(phAmO+o>C7PuS^+}N^NdXC zJVSikJWA1w%q*cIT+X)#y8bC_qL#)V>vI{&$GqT@H{7veU**rpYwnU={G2|Oznx@B(E6P78Z9M_cYNLE zp0~7FJ-#4mD45JrZ(`s$X|0e>u;5r}cOY&w>}V76>$t9))E3fd+DQQ+%VSsmB!fs6 zlhKV>^{k2EK~-xd0fH~sITsdUB}i*7d=JXWAk%B6?n7?-kv-4GfIgJ>J2zD!(EhKIlr% zA3J~eT}IGvX@9PASQ;BaW>1{6(?|`3_h5zkX%D%H9tjhF_Ya0XpEW3WH*(xsQw)3gE*5kIieWy#j3rmLL(H=MSJ%<(r8_`I<}#n0Z1%wC^sK zPv(6$bJ@1}jKL>B8qH-j@C>uv#gw{9nF0d~8i8t=d|5YR?_A@&h}X2-J1x&8?y!AXEm&~A4Az|M(OC%02Augl@EW>j5!@yDTsurgsyU&4*} zftmK!2URM@%Y>lxjgs+PfmeZboSAvT0w$N9qC$PER73cPzaC-@B=Ih^0U>q)$$p=; zF~#t3(o0r2M_XdrdIPxnURhX5SR$GPCr5^e0()~xik<;e$8a9$=>w?N>MmunBrl2O+Tzl9}do4~qOg+D0<|K4LMGG647RlDJ-d(%Yv~o&|o*YI5 z3j<;=nnfiR9w!rqLJnIW6-Lz+5rTd-X`HV3XSOsu5YIp^Ahc49jeI;dQEkhr%SM-M z9ycCxozK2|2#73l>15!iMPw(x(p(||R=EE3`=6(FbTyu~s1zNpt=(gA4Mng6ipcxF z)P!?>AL(84xgGq3^XluqI6>+*UzxlREC~0T@+!T0Zk^qb<8$%)PSulm=;#b_Ft}>EOl}wiMQupG7Us3p<$J3B9E_nJjZM_P9aI zhCfG7hqUG?P-S3xb6jWN#rq^o~W6!H#$=dCeztbmq`6wGaVEp#1n-ez@{|TY5$7UD<)Wm60v()Qo878fSO6D(HE*Xcf0zOZ*hakU)rwM*r zBk&xgpCf@`3j|qte~ZwHgq6wHPR0#eK(bb_@)-XDZIpacwlPRox<@pY z1`1aw2DqXOpKefQCXxb9Yy1%Fpc0 zfoAcK#=WS8*~UVSxB*)nnH!owf5#SEgs25T9O-%nN2l~RbawblWEiqi%Jc!ozwsX7Z7_U1aKxUuCO8wvv>vSoE&W~N_Xx%J zls;aNtSFJ9g8p~2q@`V#`i?dTg25va7m!5mBPI?Dy!+qlJOwN$VJIpe^xf>l+m}Wt z+-&|K-Z^cd6_bA_SVCD@$1CidlaSdjF40pg6e zn8(-p0593>8nl)|jS>-rJJdG8-u8GW*J@_DD?4q!f)SvhwsLq0Pc;UG#FB$Pl~(={ zpJN~{;aa(2)vTLrlHQ=qmK7MojYMk&6_|{F;8|J!O*=Or*^Il-=HEPH&|9WG+YQ57 z?SAH(M`xX!`|!s$Zf1_X0~2*k+sS4LDbe{LNhX067Y_Sted{h>s`-L#Mau%-HoX8$ zKEPaENjZJJ>kv(u_eH8tx*oEtVpXMf-D$p7;x!w6QtqA1%MEM?-nB(45(;~~yz!gl z-2>B0@@@XPZfNyXKlARn1;)%f>5kXdo7&sXU_;_7ETmz9l@|K_W68v6=m|fyt=?5m zV9#9JeEiL<_J+?5DmX$cO79rz^qytEXlu^i6D()f%$9@;t{O$8J6*ttZwIY}0Iy#` zf}ck`f3$a3pKs%clfpl1wq}cQRy@q(C^|@uUf8LnplTA1CEAxlHL*Es;bmmbl%+S5 zRO;E}05<%)@XFy1=8RIF1_!6i1qi8kp1NS78c=F3*6vuccRsv{HcnLV)!H`q!|JpE+k-U)>Av6iFg0#!Rc4v zcn5vPbeDIG4nrxzKt%Iy#|!~5+xzC~%Ko}HeBh5ntbwd@#t@b;1!yvDFJtIQcVEEh zt$x%~enqrnd;>Orvnih5i@k{d^skEX92%XyazgEoxBcX@?Ih&sM>jz`kmF>({Y__AJ#EY~<0JJ6%bT9i}-^ zbr0HkM`Am08YFM1Bawj{b53&4af-RZbStp)AMXUqkGJV&S=|rw_8h}CRw-nYtW^A_ zHvApsOu8yYydp~E6!;E-mjte(0B2^7-t|>GzQ|Shb5(Da41_R_zD%wIAC0XReR|9vyt1^J47SA*}J#UkC9m%rs}>f(F$XRbS(<-BhwY zn*xsdd~r@iFo06iiDr-2A4qS@=A^l+ck47=$5a-3Fi~a%27xC|Y{mlv|=AkrnM^kq-n1dt)gyqL%X`})To1| z7jGCa*DSn1yo`{Px^xQsZBmBnI=|?4CXKzq&76vK0BW+J@v;^x4wv4SE*6Zw*}B*} zK2Itmx$lR?4Y}S^`J^gWiQuJBbX3xwB%AXmY;p-W<|A|T-Z2W?ic7b%!eFI05b4Ee z!Cu?+%dCC%nb#$s24>N(eqWO^Z3D?rzd-QrNZep#Yd9V=pX;J^&Yr>*@}3z!Lcb>Had&qZS4iHx=r>5s|~WY#YxWFLQqF#KsE-4oBQ;qiJy$5a> zqb$Ou3{nzeBbv|VPZZCRU|lCs{GRkHW=7fsQnC#1{?X8HJ+fFKV=3Vra0fGj`UeTz z)SM%Bd%2+PyIowPPc#!~v_PVmDH+ClfSrpdHrKb1G%+Q`6r|gF>A-W}y5G)xzS;Vt z&+m4oe(xj{@_fDgxb?ijl{-wL`*|S|%|X}*b|-SMq%^uHk_UV*v+Jov*CoI~jAk)! zj%>g3Z=Q$#aZg0;Vaq1vg@Gc>pDqnPxgse3kI?I=zmU?N6y(0w;gh)qL?+`oelkGR zPVm>u99)O=?w?dl*4(xu)=4bUQ~oxZi0rH3yfnmhUDTn2DfEj%9Iz*W9U*qu*4bDKTm zG4t|oFDdl7`A!$2qeyrzchzKQ;eFA=Zk)K4wx+Jb#g}EcBRnjBLO>eIO3dmaGvA#$ zPh8YxShUaMKS@SC4_7aH(K101VY{Awp)#m66)uAcxqKz!78dzvYV$)_M~ymOrxN!h^@LC7{I@ z0-=e1D;5hUN5qTZrJr;T2p;7=_#JCjZK$qQuzI&kTpPrBdP==F4xvJ z7|y0hbt#;lWJB;^TM#RT{Zk80t^*8#jIo1XvH_c+DwgfK9{~WQ`ADQ% z@{H0wZ!F@u7`=guVS7!%xc-g93(nY4(Ij|GfCB{HmJI)#Q{rPB_p;VyQ>r$ODSM4` z;XKF^*kTjCl-5?G`jb429PR!3ol$vl^{ zh6FMD`cy2+{xQw)?b**)ABGqKq2bH0``3{)sz6mH zmI42*ui7l`fh}t^q-ab{TirY{A`RGl)Y~0GVMeN8DWkQeYkt}hWSv{D; zpD;})s5$D)rQ&vLdPQ7~<1vS(XIeqSVdazh=#5Kan7w#^$f&~160*JER%^RCtWyeY zR-D27KWknKg>I%sn20tia{YfRGhqCHdw1JWU&`gO-PQMcLa`YG$u*gV|2P+vt?HUc zgDT#|I@-bYCtYX@LXJ4}=3&~NMMH4-6Tz1#W-b;nkh^(sH`+#`3#cdn;ZHOiQn0 z$%JO`j`5I7gW=ik$ZmyhMiiSxX%3ZEx-!FoCZw=hdISVOO2KQo%p*%+zA&+1DW-w) z441WFU{Qs++G0=I2PGhN$slS!5gxDS zDnyyIkteXbUG6w1Oo$4qpvVZk+9P2(D>GyJrp4&O;up}#Gqy+mmVNY6%iaw3bjkpY z0+MUdn1Zp9K-EDm&INzm?<*mhXXloT3v$E8$s%gCdcG9-G!1X{+`s%V!}SN z?O;SafjvXG37UU)%4(S8ubTYT7lsaH4DGP>%71iM$p)AJ!Os?(CQXIXgcl>>&}|vT zMC|$<+2H5NSJwVUW?K9!%T;>=!%^do`-ukDeAF(0UY@JEH&^t z#nh6_FSDZXA07!B2nv_SQzr0yxnB3EdG#0tUOvk%RUz`^*O4vSXT&y$ek|(9m_S%q z9ndu-s*s+RyD4~ric{?70pw8XFKJIaEoG$+4v zd}0-k&G;v-`4gMoAiEjaO}hv4&#W!X^xCA!QnGlz_B?r-z zX1S*5R=4L>cZzw-jjoETsTpZVci#6jhg~GQ9seA_d3=tIdCzR_{V{o`tCiqMVtY*6 zN1lGph-imGZh3AtdI?InW*U?QuCB?w(A_lNS>_|Rp=irJA|36<+@tuam=)B`e5s4t zA17peEicz-jrfbzS3O+VIpl%Gp;9Dk5HseS6~ms;x#wi4OVs_WL~4{p?Q-E)n6)~y z2~sKzZ`BsRr-l~Fw{>35>#dG-2Tc;6XCc4Nfr$Ra%#E4OC$WwqxIW$<9}A^fPyO*B zG>CBb)l+e={!#0-dyweL@&$r7`|fyFZ*VM$B$|K5(cPgIOH#gh$Z6^;QLG~DbI$8S) zTn}yMcp&6UznC?}47~fy!nqg-PBNIygH@rHtJ!zdpjenOpaosWeFDbjAwaf&LLg2< zO>%Y^pFPrqSK)DS^*9gWvUW&p(!(s~YG( zk7p<${KJrT8XO2F)q9@#z!oc}4>!ZzM| zzMWv-^R)d{J#ypejXZH{2MZP{>k98V8x9hMN9BC7+1-DJdtDegnW2l^|5v(=ZW!?? zXne47^S{iXsi7fYFOW>P+T&Md4gBVJC=ey|zhEKh$yY;qa_=5Kyd04-0977l|NpXq z-+ql3!OXs(wh$2Lv}9~-9Hl-{fZR{8WX4V)y0*;1nKYnn<%;cN%6+K}L=O(bDI2YWV%P|e?!$p~9$gbp6JUS7 zigW@`vN4tV+aZ#tdI10~BpSN!SRsJsf14D*91sY|0dxbl0iPgjAQB*!AQ2$tAmbpL zAUB}kpqQXEpnRYTppKxmpwpo5V7OrBU}0bdU`ODv;7s7w;6C8x;O*ec5XcY`5D^gF z-)YC6khPF|P;^i{P*PADP^M6oP{U9sQ18%)&?L}o&}z^=(2dZ0FeET)Fs?8qFr%=r zuw<|Tuv)Oru-mW?a8z&-aE@>}aO3d!@Lcdp@UHMV@S_OW2uuhP2(}1u2!jZ#2p5Rp zi1>&?h#rUqh@FVbh&M>ENHjY%vQ`%%o8j~EE+5Yte;r5 zSgY8C*euvW*eclO*k0H%*ag_N*u&VnI7~PKILn75 zRgcZt_h7m)GH3TmjTgQTg)mvd-)?cbQPC*>>{A zW~HFp03DTedQto?dg&&+SEx_Gy|3%+7rTd$`&D*_W}I zTbiOdI^1rfInnM@iiL8cXu3@O(zZd7X2~)C_-1iFlTKbRGj)Q{C%Fs`^Dt~61uqyerhQm%v?856_F;6knp6Rwnft{gP3_(ZOBRj%X( zu54DW#0IWR7p~NMu3Wg*IBmVbA-#TEhC>#HW7z5gn(8Cm>O-FDV@Uf03i~5W`$G=< zW5lZihN~mOt3!dSW00d8BBWcU*c+rwTE-%89)~j_XUeNhYGamNnTk-a%rR!ZMzS%Xu|~l= z8e>N3oShZl;H)q`0ntX4dQh(ye|}i5mxy;T?2PuRusy2lNqK!3VjR&u0s zjb3u*T^^rCPN^%6#85dGMh&W3fsD!+jd-zU8I8P|5>AEOqWf92SH*VO^I6cpQh~CW zv&et?zUn)RNN1Gg+2zVjEJMe~y*{b<||7 ywW~@Wt<|f_5Ufp_!b25;<_y`n5cEZ7k=e-*v_93=5WMN&tpM*Mo6tJ&y1+Yn zgo9iR9c$ps0<0=RQh=ln;y#E2crSpp8h*V3&QfrYd++-F4d}fFgHuK@z*%x_KOE%4 ztO#lvY6=E5Bt=L{kVLR8fSEpgu~R&>4!pJd1I&}){RKJz*1)J79Pj=C^Xbd^6-p?OFxt+=7P6SKrDfi%b->Xze97ZRd7WF zhuVAk* z>{bvL4X2X`x)prI-n#?5TZi$^BB9wL=!ifU&E#t;rCOrR-$MZ;D$8kUre2P)c$7l&rm2x>+1|4jf(!CO8OHCq5*2w-tpg3pJlc2-WOz-oD+n}&yS zLW4&#Xl7Sc!D$899vQDxl>@}_Of_#9@_rzm58D9~ITQFBjO~US^YB4nj8__HV8K+C zP%VPa5*!ZjPzIRCQ%QcHEJ3d8Rcwz4r)tjTh^cx4L2Ci1W*I@OlKy3OFGL ztHfYcHwb`TJq1;%qgHo`XSy?J)&pO6B);Z1BuqDH%Gi^ZJLON?pKkD;l!^H8nE;-S zoP;J5aAPLcP$?Oq@HHGId7vqnQ{dPPqiYh7m~FfJ{Wgxjwue zIti^&aV(gEnZSGnhXDM;87~LkgWyeoF)QJBMHAS2(aU;809GSY!dwBsY&iIAIHFe! zm)ZpMoaBfQt}GZetF}Z6NM4Bfr${3>?F4n2k$9@a1C>Si7>lW;Sv1quwAJ%ul z4GZBIYj6vAD~AC!2Re4am;yXlbP}dtuQ;*gb!e2V(j`^x)+YA5U}6aWD%2<7y^2c( zLyv%z=(c{o0R7bDU7W)#zD9*6^YArd9CMP?x9 zUN|y@pqvpWerhw;u)7<+ih@GH48AijrA7eDd*Ji!Q0yj|z*4wcN{FVC?0^}P?ZCWl zr-WIS%KPXL?#q&4=h)qE>|Tq87p3~F`XEgFIk-`$b81YCdjej=;DE9Bdwh5^Op{yPPED%c8B3)cco;fnXMkA` zmq?)28dc1e8kS-bsGIww{J+4l>%(Ot5UteE2K-RToFBu7cLd#@1Y`#bWZM})s3f7y z25(LSm~Qz$fy27sDJ!44IUQm<38CW60Fxb?A$%zmujRxmE#hRbZ0zMw@UChA;wp_w zskX5PP8GGP1M|K5)x5r;N^Z59RgvR212|3=sY3$)%n<%lkeJE{cS5vY& z0le4?r(4fVtM`oETYOH#c9G+uCdFT!ij~ayPJm4k{0dHu;GeFI7Rhl)w&5jwcuVi? zkvdM>5?#Q&+ykco{J{ZoTPnq4BUmOIrQNzY5L?bvLr8kzjlW9yA`(0yg1;A9%XuS^ zUQ}9QRI{W`Xi|~g;-&zO&DhIa=WK`LVI;V())J+-+J{;!K%1MytXm~$A%!*o1M<#!5nhs;7miu%Bn~To&w}t%f9x(g;sc7ge z8H0nWH4XNngsj%A`QTYv-I~V9QF&M;fjE>wFYD=AKYXwlE)mr_DS|DnfH=ospRs)n z8m0`G$?eX#p|N&~1E`jv(hEPfJHUqpNDp`+%xqOJHLPr`CH^!lmV`Jlf>&AvyW`DR z!A>8(j1QOQO?*^Ti)ynGj9o?PI==10c_PCd&L-(+;{Mpru;Q;Q3u?3h{%&0b1c7~2irt>%n;10S7cvot#ES_6>)$)+^ zz?>CuMg+SWt7*T!@~s6B_rN#ztln(+Mkqh3wBy$CT8*AYVYg56=1qs-!IB6)$ z6Ae%I!Zjg$kZ*FYt)Qj8K z>4YD&Y@95Eb9>;ww)qycNinA`i_5UH6TT&-%FM97UDOu68oTn&Sd{`K{h+5xH>R#D zzaG5R^2N(=vlNFFDaG6MOl-ZPpi46RZ}!C_O(>V-pdzKrJGKIE`cU=?`EnZ^&;=_> zXwOKsEV6VsmBwOJQJHN+9@|0?d0n;Jxl6*3RInwn=axmnlans5}@xBDN^@6R2 zi?CxUeBaLNiG6u-UUk zetRcn1x)OOha#wz(!SG>1*PiWWN68Kw+|p&*-AbI@M<1@IuFJH%mQ!g{sOTMyftF% z1sJQ~`~V(}V0%g4A#t894$Au_Ls~kQa#Za1a!oCgdu3nqTnM-HOHUZ!PVgSy-){&F zG#FeChveX_5PlUvzk+x35D%ELJ}IV;tP|mTQk3qcv^gspUJGGy7hE|Tj$Pnv%w~O* z?`+xUiCxYh+PpRNv88Z&0N>FtS;1o(N&#%t@Vp%Bw5e)mYxsF5T(}*MSqTR>rhr%W b0mT0S5)@H#d7`>U00000NkvXXu0mjfEz&h@ diff --git a/lib/vendor/sabre/dav/lib/DAV/Client.php b/lib/vendor/sabre/dav/lib/DAV/Client.php deleted file mode 100644 index 1028a6b..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Client.php +++ /dev/null @@ -1,485 +0,0 @@ -xml->elementMap. - * It's deprecated as of version 3.0.0, and should no longer be used. - * - * @deprecated - * - * @var array - */ - public $propertyMap = []; - - /** - * Base URI. - * - * This URI will be used to resolve relative urls. - * - * @var string - */ - protected $baseUri; - - /** - * Basic authentication. - */ - const AUTH_BASIC = 1; - - /** - * Digest authentication. - */ - const AUTH_DIGEST = 2; - - /** - * NTLM authentication. - */ - const AUTH_NTLM = 4; - - /** - * Identity encoding, which basically does not nothing. - */ - const ENCODING_IDENTITY = 1; - - /** - * Deflate encoding. - */ - const ENCODING_DEFLATE = 2; - - /** - * Gzip encoding. - */ - const ENCODING_GZIP = 4; - - /** - * Sends all encoding headers. - */ - const ENCODING_ALL = 7; - - /** - * Content-encoding. - * - * @var int - */ - protected $encoding = self::ENCODING_IDENTITY; - - /** - * Constructor. - * - * Settings are provided through the 'settings' argument. The following - * settings are supported: - * - * * baseUri - * * userName (optional) - * * password (optional) - * * proxy (optional) - * * authType (optional) - * * encoding (optional) - * - * authType must be a bitmap, using self::AUTH_BASIC, self::AUTH_DIGEST - * and self::AUTH_NTLM. If you know which authentication method will be - * used, it's recommended to set it, as it will save a great deal of - * requests to 'discover' this information. - * - * Encoding is a bitmap with one of the ENCODING constants. - */ - public function __construct(array $settings) - { - if (!isset($settings['baseUri'])) { - throw new \InvalidArgumentException('A baseUri must be provided'); - } - - parent::__construct(); - - $this->baseUri = $settings['baseUri']; - - if (isset($settings['proxy'])) { - $this->addCurlSetting(CURLOPT_PROXY, $settings['proxy']); - } - - if (isset($settings['userName'])) { - $userName = $settings['userName']; - $password = isset($settings['password']) ? $settings['password'] : ''; - - if (isset($settings['authType'])) { - $curlType = 0; - if ($settings['authType'] & self::AUTH_BASIC) { - $curlType |= CURLAUTH_BASIC; - } - if ($settings['authType'] & self::AUTH_DIGEST) { - $curlType |= CURLAUTH_DIGEST; - } - if ($settings['authType'] & self::AUTH_NTLM) { - $curlType |= CURLAUTH_NTLM; - } - } else { - $curlType = CURLAUTH_BASIC | CURLAUTH_DIGEST; - } - - $this->addCurlSetting(CURLOPT_HTTPAUTH, $curlType); - $this->addCurlSetting(CURLOPT_USERPWD, $userName.':'.$password); - } - - if (isset($settings['encoding'])) { - $encoding = $settings['encoding']; - - $encodings = []; - if ($encoding & self::ENCODING_IDENTITY) { - $encodings[] = 'identity'; - } - if ($encoding & self::ENCODING_DEFLATE) { - $encodings[] = 'deflate'; - } - if ($encoding & self::ENCODING_GZIP) { - $encodings[] = 'gzip'; - } - $this->addCurlSetting(CURLOPT_ENCODING, implode(',', $encodings)); - } - - $this->addCurlSetting(CURLOPT_USERAGENT, 'sabre-dav/'.Version::VERSION.' (http://sabre.io/)'); - - $this->xml = new Xml\Service(); - // BC - $this->propertyMap = &$this->xml->elementMap; - } - - /** - * Does a PROPFIND request with filtered response returning only available properties. - * - * The list of requested properties must be specified as an array, in clark - * notation. - * - * 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. - * - * For depth 0, just the array of properties for the resource is returned. - * - * For depth 1, the returned array will contain a list of resource names as keys, - * and an array of properties as values. - * - * The array of properties will contain the properties as keys with their values as the value. - * Only properties that are actually returned from the server without error will be - * returned, anything else is discarded. - * - * @param 1|0 $depth - */ - public function propFind($url, array $properties, $depth = 0): array - { - $result = $this->doPropFind($url, $properties, $depth); - - // If depth was 0, we only return the top item - if (0 === $depth) { - reset($result); - $result = current($result); - - return isset($result[200]) ? $result[200] : []; - } - - $newResult = []; - foreach ($result as $href => $statusList) { - $newResult[$href] = isset($statusList[200]) ? $statusList[200] : []; - } - - return $newResult; - } - - /** - * Does a PROPFIND request with unfiltered response. - * - * The list of requested properties must be specified as an array, in clark - * notation. - * - * 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. - * - * For depth 0, just the multi-level array of status and properties for the resource is returned. - * - * For depth 1, the returned array will contain a list of resources as keys and - * a multi-level array containing status and properties as value. - * - * The multi-level array of status and properties is formatted the same as what is - * documented for parseMultiStatus. - * - * All properties that are actually returned from the server are returned by this method. - * - * @param 1|0 $depth - */ - public function propFindUnfiltered(string $url, array $properties, int $depth = 0): array - { - $result = $this->doPropFind($url, $properties, $depth); - - // If depth was 0, we only return the top item - if (0 === $depth) { - reset($result); - - return current($result); - } else { - return $result; - } - } - - /** - * Does a PROPFIND request. - * - * The list of requested properties must be specified as an array, in clark - * notation. - * - * 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. - * - * The returned array will contain a list of resources as keys and - * a multi-level array containing status and properties as value. - * - * The multi-level array of status and properties is formatted the same as what is - * documented for parseMultiStatus. - * - * @param 1|0 $depth - */ - private function doPropFind($url, array $properties, $depth = 0): array - { - $dom = new \DOMDocument('1.0', 'UTF-8'); - $dom->formatOutput = true; - $root = $dom->createElementNS('DAV:', 'd:propfind'); - $prop = $dom->createElement('d:prop'); - - foreach ($properties as $property) { - list( - $namespace, - $elementName - ) = \Sabre\Xml\Service::parseClarkNotation($property); - - if ('DAV:' === $namespace) { - $element = $dom->createElement('d:'.$elementName); - } else { - $element = $dom->createElementNS($namespace, 'x:'.$elementName); - } - - $prop->appendChild($element); - } - - $dom->appendChild($root)->appendChild($prop); - $body = $dom->saveXML(); - - $url = $this->getAbsoluteUrl($url); - - $request = new HTTP\Request('PROPFIND', $url, [ - 'Depth' => $depth, - 'Content-Type' => 'application/xml', - ], $body); - - $response = $this->send($request); - - if ((int) $response->getStatus() >= 400) { - throw new HTTP\ClientHttpException($response); - } - - return $this->parseMultiStatus($response->getBodyAsString()); - } - - /** - * 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. - * - * @param string $url - * - * @return bool - */ - public function propPatch($url, array $properties) - { - $propPatch = new Xml\Request\PropPatch(); - $propPatch->properties = $properties; - $xml = $this->xml->write( - '{DAV:}propertyupdate', - $propPatch - ); - - $url = $this->getAbsoluteUrl($url); - $request = new HTTP\Request('PROPPATCH', $url, [ - 'Content-Type' => 'application/xml', - ], $xml); - $response = $this->send($request); - - if ($response->getStatus() >= 400) { - throw new HTTP\ClientHttpException($response); - } - - if (207 === $response->getStatus()) { - // If it's a 207, the request could still have failed, but the - // information is hidden in the response body. - $result = $this->parseMultiStatus($response->getBodyAsString()); - - $errorProperties = []; - foreach ($result as $href => $statusList) { - foreach ($statusList as $status => $properties) { - if ($status >= 400) { - foreach ($properties as $propName => $propValue) { - $errorProperties[] = $propName.' ('.$status.')'; - } - } - } - } - if ($errorProperties) { - throw new HTTP\ClientException('PROPPATCH failed. The following properties errored: '.implode(', ', $errorProperties)); - } - } - - return true; - } - - /** - * 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 - */ - public function options() - { - $request = new HTTP\Request('OPTIONS', $this->getAbsoluteUrl('')); - $response = $this->send($request); - - $dav = $response->getHeader('Dav'); - if (!$dav) { - return []; - } - - $features = explode(',', $dav); - foreach ($features as &$v) { - $v = trim($v); - } - - return $features; - } - - /** - * Performs an actual HTTP request, and returns the result. - * - * 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 - * been lowercased. - * - * For large uploads, it's highly recommended to specify body as a stream - * resource. You can easily do this by simply passing the result of - * fopen(..., 'r'). - * - * This method will throw an exception if an HTTP error was received. Any - * HTTP status code above 399 is considered an error. - * - * Note that it is no longer recommended to use this method, use the send() - * method instead. - * - * @param string $method - * @param string $url - * @param string|resource|null $body - * - * @throws clientException, in case a curl error occurred - * - * @return array - */ - public function request($method, $url = '', $body = null, array $headers = []) - { - $url = $this->getAbsoluteUrl($url); - - $response = $this->send(new HTTP\Request($method, $url, $headers, $body)); - - return [ - 'body' => $response->getBodyAsString(), - 'statusCode' => (int) $response->getStatus(), - 'headers' => array_change_key_case($response->getHeaders()), - ]; - } - - /** - * 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 - */ - public function getAbsoluteUrl($url) - { - return Uri\resolve( - $this->baseUri, - (string) $url - ); - } - - /** - * Parses a WebDAV multistatus response body. - * - * This method returns an array with the following structure - * - * [ - * 'url/to/resource' => [ - * '200' => [ - * '{DAV:}property1' => 'value1', - * '{DAV:}property2' => 'value2', - * ], - * '404' => [ - * '{DAV:}property1' => null, - * '{DAV:}property2' => null, - * ], - * ], - * 'url/to/resource2' => [ - * .. etc .. - * ] - * ] - * - * @param string $body xml body - * - * @return array - */ - public function parseMultiStatus($body) - { - $multistatus = $this->xml->expect('{DAV:}multistatus', $body); - - $result = []; - - foreach ($multistatus->getResponses() as $response) { - $result[$response->getHref()] = $response->getResponseProperties(); - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Collection.php b/lib/vendor/sabre/dav/lib/DAV/Collection.php deleted file mode 100644 index 2728bb2..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Collection.php +++ /dev/null @@ -1,106 +0,0 @@ -getChildren() as $child) { - if ($child->getName() === $name) { - return $child; - } - } - throw new Exception\NotFound('File not found: '.$name); - } - - /** - * 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 - */ - public function childExists($name) - { - try { - $this->getChild($name); - - return true; - } catch (Exception\NotFound $e) { - return false; - } - } - - /** - * 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 successful 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 string|null - */ - public function createFile($name, $data = null) - { - throw new Exception\Forbidden('Permission denied to create file (filename '.$name.')'); - } - - /** - * Creates a new subdirectory. - * - * @param string $name - * - * @throws Exception\Forbidden - */ - public function createDirectory($name) - { - throw new Exception\Forbidden('Permission denied to create directory'); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/CorePlugin.php b/lib/vendor/sabre/dav/lib/DAV/CorePlugin.php deleted file mode 100644 index dbd8976..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/CorePlugin.php +++ /dev/null @@ -1,907 +0,0 @@ -server = $server; - $server->on('method:GET', [$this, 'httpGet']); - $server->on('method:OPTIONS', [$this, 'httpOptions']); - $server->on('method:HEAD', [$this, 'httpHead']); - $server->on('method:DELETE', [$this, 'httpDelete']); - $server->on('method:PROPFIND', [$this, 'httpPropFind']); - $server->on('method:PROPPATCH', [$this, 'httpPropPatch']); - $server->on('method:PUT', [$this, 'httpPut']); - $server->on('method:MKCOL', [$this, 'httpMkcol']); - $server->on('method:MOVE', [$this, 'httpMove']); - $server->on('method:COPY', [$this, 'httpCopy']); - $server->on('method:REPORT', [$this, 'httpReport']); - - $server->on('propPatch', [$this, 'propPatchProtectedPropertyCheck'], 90); - $server->on('propPatch', [$this, 'propPatchNodeUpdate'], 200); - $server->on('propFind', [$this, 'propFind']); - $server->on('propFind', [$this, 'propFindNode'], 120); - $server->on('propFind', [$this, 'propFindLate'], 200); - - $server->on('exception', [$this, 'exception']); - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'core'; - } - - /** - * This is the default implementation for the GET method. - * - * @return bool - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - $node = $this->server->tree->getNodeForPath($path); - - if (!$node instanceof IFile) { - return; - } - - if ('HEAD' === $request->getHeader('X-Sabre-Original-Method')) { - $body = ''; - } else { - $body = $node->get(); - - // Converting string into stream, if needed. - if (is_string($body)) { - $stream = fopen('php://temp', 'r+'); - fwrite($stream, $body); - rewind($stream); - $body = $stream; - } - } - - /* - * TODO: getetag, getlastmodified, getsize should also be used using - * this method - */ - $httpHeaders = $this->server->getHTTPHeaders($path); - - /* ContentType needs to get a default, because many webservers will otherwise - * default to text/html, and we don't want this for security reasons. - */ - if (!isset($httpHeaders['Content-Type'])) { - $httpHeaders['Content-Type'] = 'application/octet-stream'; - } - - if (isset($httpHeaders['Content-Length'])) { - $nodeSize = $httpHeaders['Content-Length']; - - // Need to unset Content-Length, because we'll handle that during figuring out the range - unset($httpHeaders['Content-Length']); - } else { - $nodeSize = null; - } - - $response->addHeaders($httpHeaders); - - $range = $this->server->getHTTPRange(); - $ifRange = $request->getHeader('If-Range'); - $ignoreRangeHeader = false; - - // 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; - } else { - $modified = new \DateTime($httpHeaders['Last-Modified']); - if ($modified > $ifRangeDate) { - $ignoreRangeHeader = true; - } - } - } catch (\Exception $e) { - // It's an entity. We can do a simple comparison. - if (!isset($httpHeaders['ETag'])) { - $ignoreRangeHeader = true; - } elseif ($httpHeaders['ETag'] !== $ifRange) { - $ignoreRangeHeader = true; - } - } - } - - // We're only going to support HTTP ranges if the backend provided a filesize - if (!$ignoreRangeHeader && $nodeSize && $range) { - // Determining the exact byte offsets - if (!is_null($range[0])) { - $start = $range[0]; - $end = $range[1] ? $range[1] : $nodeSize - 1; - if ($start >= $nodeSize) { - throw new Exception\RequestedRangeNotSatisfiable('The start offset ('.$range[0].') exceeded the size of the entity ('.$nodeSize.')'); - } - if ($end < $start) { - throw new Exception\RequestedRangeNotSatisfiable('The end offset ('.$range[1].') is lower than the start offset ('.$range[0].')'); - } - if ($end >= $nodeSize) { - $end = $nodeSize - 1; - } - } else { - $start = $nodeSize - $range[1]; - $end = $nodeSize - 1; - - if ($start < 0) { - $start = 0; - } - } - - // Streams may advertise themselves as seekable, but still not - // actually allow fseek. We'll manually go forward in the stream - // if fseek failed. - if (!stream_get_meta_data($body)['seekable'] || -1 === fseek($body, $start, SEEK_SET)) { - $consumeBlock = 8192; - for ($consumed = 0; $start - $consumed > 0;) { - if (feof($body)) { - throw new Exception\RequestedRangeNotSatisfiable('The start offset ('.$start.') exceeded the size of the entity ('.$consumed.')'); - } - $consumed += strlen(fread($body, min($start - $consumed, $consumeBlock))); - } - } - - $response->setHeader('Content-Length', $end - $start + 1); - $response->setHeader('Content-Range', 'bytes '.$start.'-'.$end.'/'.$nodeSize); - $response->setStatus(206); - $response->setBody($body); - } else { - if ($nodeSize) { - $response->setHeader('Content-Length', $nodeSize); - } - $response->setStatus(200); - $response->setBody($body); - } - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * HTTP OPTIONS. - * - * @return bool - */ - public function httpOptions(RequestInterface $request, ResponseInterface $response) - { - $methods = $this->server->getAllowedMethods($request->getPath()); - - $response->setHeader('Allow', strtoupper(implode(', ', $methods))); - $features = ['1', '3', 'extended-mkcol']; - - foreach ($this->server->getPlugins() as $plugin) { - $features = array_merge($features, $plugin->getFeatures()); - } - - $response->setHeader('DAV', implode(', ', $features)); - $response->setHeader('MS-Author-Via', 'DAV'); - $response->setHeader('Accept-Ranges', 'bytes'); - $response->setHeader('Content-Length', '0'); - $response->setStatus(200); - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * HTTP HEAD. - * - * This method is normally used to take a peak at a url, and only get the - * HTTP response headers, without the body. This is used by clients to - * determine if a remote file was changed, so they can use a local cached - * version, instead of downloading it again - * - * @return bool - */ - public function httpHead(RequestInterface $request, ResponseInterface $response) - { - // This is implemented by changing the HEAD request to a GET request, - // and telling the request handler that is doesn't need to create the body. - $subRequest = clone $request; - $subRequest->setMethod('GET'); - $subRequest->setHeader('X-Sabre-Original-Method', 'HEAD'); - - try { - $this->server->invokeMethod($subRequest, $response, false); - } catch (Exception\NotImplemented $e) { - // Some clients may do HEAD requests on collections, however, GET - // requests and HEAD requests _may_ not be defined on a collection, - // which would trigger a 501. - // This breaks some clients though, so we're transforming these - // 501s into 200s. - $response->setStatus(200); - $response->setBody(''); - $response->setHeader('Content-Type', 'text/plain'); - $response->setHeader('X-Sabre-Real-Status', $e->getHTTPCode()); - } - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * HTTP Delete. - * - * The HTTP delete method, deletes a given uri - */ - public function httpDelete(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - if (!$this->server->emit('beforeUnbind', [$path])) { - return false; - } - $this->server->tree->delete($path); - $this->server->emit('afterUnbind', [$path]); - - $response->setStatus(204); - $response->setHeader('Content-Length', '0'); - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * 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 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 - */ - public function httpPropFind(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - $requestBody = $request->getBodyAsString(); - if (strlen($requestBody)) { - try { - $propFindXml = $this->server->xml->expect('{DAV:}propfind', $requestBody); - } catch (ParseException $e) { - throw new BadRequest($e->getMessage(), 0, $e); - } - } else { - $propFindXml = new Xml\Request\PropFind(); - $propFindXml->allProp = true; - $propFindXml->properties = []; - } - - $depth = $this->server->getHTTPDepth(1); - // The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not enabled - if (!$this->server->enablePropfindDepthInfinity && 0 != $depth) { - $depth = 1; - } - - $newProperties = $this->server->getPropertiesIteratorForPath($path, $propFindXml->properties, $depth); - - // This is a multi-status response - $response->setStatus(207); - $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $response->setHeader('Vary', 'Brief,Prefer'); - - // 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 = ['1', '3', 'extended-mkcol']; - foreach ($this->server->getPlugins() as $plugin) { - $features = array_merge($features, $plugin->getFeatures()); - } - $response->setHeader('DAV', implode(', ', $features)); - - $prefer = $this->server->getHTTPPrefer(); - $minimal = 'minimal' === $prefer['return']; - - $data = $this->server->generateMultiStatus($newProperties, $minimal); - $response->setBody($data); - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * WebDAV PROPPATCH. - * - * This method is called to update properties on a Node. The request is an XML body with all the mutations. - * In this XML body it is specified which properties should be set/updated and/or deleted - * - * @return bool - */ - public function httpPropPatch(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - try { - $propPatch = $this->server->xml->expect('{DAV:}propertyupdate', $request->getBody()); - } catch (ParseException $e) { - throw new BadRequest($e->getMessage(), 0, $e); - } - $newProperties = $propPatch->properties; - - $result = $this->server->updateProperties($path, $newProperties); - - $prefer = $this->server->getHTTPPrefer(); - $response->setHeader('Vary', 'Brief,Prefer'); - - if ('minimal' === $prefer['return']) { - // If return-minimal is specified, we only have to check if the - // request was successful, and don't need to return the - // multi-status. - $ok = true; - foreach ($result as $prop => $code) { - if ((int) $code > 299) { - $ok = false; - } - } - - if ($ok) { - $response->setStatus(204); - - return false; - } - } - - $response->setStatus(207); - $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); - - // Reorganizing the result for generateMultiStatus - $multiStatus = []; - foreach ($result as $propertyName => $code) { - if (isset($multiStatus[$code])) { - $multiStatus[$code][$propertyName] = null; - } else { - $multiStatus[$code] = [$propertyName => null]; - } - } - $multiStatus['href'] = $path; - - $response->setBody( - $this->server->generateMultiStatus([$multiStatus]) - ); - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * 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 204 No Content - * - * @return bool - */ - public function httpPut(RequestInterface $request, ResponseInterface $response) - { - $body = $request->getBodyAsStream(); - $path = $request->getPath(); - - // Intercepting Content-Range - if ($request->getHeader('Content-Range')) { - /* - An origin server that allows PUT on a given target resource MUST send - a 400 (Bad Request) response to a PUT request that contains a - Content-Range header field. - - Reference: http://tools.ietf.org/html/rfc7231#section-4.3.4 - */ - throw new Exception\BadRequest('Content-Range on PUT requests are forbidden.'); - } - - // Intercepting the Finder problem - if (($expected = $request->getHeader('X-Expected-Entity-Length')) && $expected > 0) { - /* - 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-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, - we throw back an error if we detect this. - - The reason Finder uses Chunked, is because it thinks the files - might change as it's being uploaded, and therefore the - Content-Length can vary. - - Instead it sends the X-Expected-Entity-Length header with the size - of the file at the very start of the request. If this header is set, - but we don't get a request body we will fail the request to - protect the end-user. - */ - - // Only reading first byte - $firstByte = fread($body, 1); - if (1 !== strlen($firstByte)) { - throw new Exception\Forbidden('This server is not compatible with OS/X finder. Consider using a different WebDAV client or webserver.'); - } - - // The body needs to stay intact, so we copy everything to a - // temporary stream. - - $newBody = fopen('php://temp', 'r+'); - fwrite($newBody, $firstByte); - stream_copy_to_stream($body, $newBody); - rewind($newBody); - - $body = $newBody; - } - - if ($this->server->tree->nodeExists($path)) { - $node = $this->server->tree->getNodeForPath($path); - - // If the node is a collection, we'll deny it - if (!($node instanceof IFile)) { - throw new Exception\Conflict('PUT is not allowed on non-files.'); - } - if (!$this->server->updateFile($path, $body, $etag)) { - return false; - } - - $response->setHeader('Content-Length', '0'); - if ($etag) { - $response->setHeader('ETag', $etag); - } - $response->setStatus(204); - } else { - $etag = null; - // If we got here, the resource didn't exist yet. - if (!$this->server->createFile($path, $body, $etag)) { - // For one reason or another the file was not created. - return false; - } - - $response->setHeader('Content-Length', '0'); - if ($etag) { - $response->setHeader('ETag', $etag); - } - $response->setStatus(201); - } - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * WebDAV MKCOL. - * - * The MKCOL method is used to create a new collection (directory) on the server - * - * @return bool - */ - public function httpMkcol(RequestInterface $request, ResponseInterface $response) - { - $requestBody = $request->getBodyAsString(); - $path = $request->getPath(); - - if ($requestBody) { - $contentType = $request->getHeader('Content-Type'); - if (null === $contentType || (0 !== strpos($contentType, 'application/xml') && 0 !== strpos($contentType, 'text/xml'))) { - // We must throw 415 for unsupported mkcol bodies - throw new Exception\UnsupportedMediaType('The request body for the MKCOL request must have an xml Content-Type'); - } - - try { - $mkcol = $this->server->xml->expect('{DAV:}mkcol', $requestBody); - } catch (\Sabre\Xml\ParseException $e) { - throw new Exception\BadRequest($e->getMessage(), 0, $e); - } - - $properties = $mkcol->getProperties(); - - if (!isset($properties['{DAV:}resourcetype'])) { - throw new Exception\BadRequest('The mkcol request must include a {DAV:}resourcetype property'); - } - $resourceType = $properties['{DAV:}resourcetype']->getValue(); - unset($properties['{DAV:}resourcetype']); - } else { - $properties = []; - $resourceType = ['{DAV:}collection']; - } - - $mkcol = new MkCol($resourceType, $properties); - - $result = $this->server->createCollection($path, $mkcol); - - if (is_array($result)) { - $response->setStatus(207); - $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); - - $response->setBody( - $this->server->generateMultiStatus([$result]) - ); - } else { - $response->setHeader('Content-Length', '0'); - $response->setStatus(201); - } - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * WebDAV HTTP MOVE method. - * - * This method moves one uri to a different uri. A lot of the actual request processing is done in getCopyMoveInfo - * - * @return bool - */ - public function httpMove(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - $moveInfo = $this->server->getCopyAndMoveInfo($request); - - if ($moveInfo['destinationExists']) { - if (!$this->server->emit('beforeUnbind', [$moveInfo['destination']])) { - return false; - } - } - if (!$this->server->emit('beforeUnbind', [$path])) { - return false; - } - if (!$this->server->emit('beforeBind', [$moveInfo['destination']])) { - return false; - } - if (!$this->server->emit('beforeMove', [$path, $moveInfo['destination']])) { - return false; - } - - if ($moveInfo['destinationExists']) { - $this->server->tree->delete($moveInfo['destination']); - $this->server->emit('afterUnbind', [$moveInfo['destination']]); - } - - $this->server->tree->move($path, $moveInfo['destination']); - - // Its important afterMove is called before afterUnbind, because it - // allows systems to transfer data from one path to another. - // PropertyStorage uses this. If afterUnbind was first, it would clean - // up all the properties before it has a chance. - $this->server->emit('afterMove', [$path, $moveInfo['destination']]); - $this->server->emit('afterUnbind', [$path]); - $this->server->emit('afterBind', [$moveInfo['destination']]); - - // If a resource was overwritten we should send a 204, otherwise a 201 - $response->setHeader('Content-Length', '0'); - $response->setStatus($moveInfo['destinationExists'] ? 204 : 201); - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * WebDAV HTTP COPY method. - * - * This method copies one uri to a different uri, and works much like the MOVE request - * A lot of the actual request processing is done in getCopyMoveInfo - * - * @return bool - */ - public function httpCopy(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - $copyInfo = $this->server->getCopyAndMoveInfo($request); - - if (!$this->server->emit('beforeBind', [$copyInfo['destination']])) { - return false; - } - if (!$this->server->emit('beforeCopy', [$path, $copyInfo['destination']])) { - return false; - } - - if ($copyInfo['destinationExists']) { - if (!$this->server->emit('beforeUnbind', [$copyInfo['destination']])) { - return false; - } - $this->server->tree->delete($copyInfo['destination']); - } - - $this->server->tree->copy($path, $copyInfo['destination']); - $this->server->emit('afterCopy', [$path, $copyInfo['destination']]); - $this->server->emit('afterBind', [$copyInfo['destination']]); - - // If a resource was overwritten we should send a 204, otherwise a 201 - $response->setHeader('Content-Length', '0'); - $response->setStatus($copyInfo['destinationExists'] ? 204 : 201); - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * HTTP REPORT method implementation. - * - * Although the REPORT method is not part of the standard WebDAV spec (it's from rfc3253) - * It's used in a lot of extensions, so it made sense to implement it into the core. - * - * @return bool - */ - public function httpReport(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - $result = $this->server->xml->parse( - $request->getBody(), - $request->getUrl(), - $rootElementName - ); - - if ($this->server->emit('report', [$rootElementName, $result, $path])) { - // If emit returned true, it means the report was not supported - throw new Exception\ReportNotSupported(); - } - - // Sending back false will interrupt the event chain and tell the server - // we've handled this method. - return false; - } - - /** - * This method is called during property updates. - * - * Here we check if a user attempted to update a protected property and - * ensure that the process fails if this is the case. - * - * @param string $path - */ - public function propPatchProtectedPropertyCheck($path, PropPatch $propPatch) - { - // Comparing the mutation list to the list of protected properties. - $mutations = $propPatch->getMutations(); - - $protected = array_intersect( - $this->server->protectedProperties, - array_keys($mutations) - ); - - if ($protected) { - $propPatch->setResultCode($protected, 403); - } - } - - /** - * This method is called during property updates. - * - * Here we check if a node implements IProperties and let the node handle - * updating of (some) properties. - * - * @param string $path - */ - public function propPatchNodeUpdate($path, PropPatch $propPatch) - { - // This should trigger a 404 if the node doesn't exist. - $node = $this->server->tree->getNodeForPath($path); - - if ($node instanceof IProperties) { - $node->propPatch($propPatch); - } - } - - /** - * This method is called when properties are retrieved. - * - * Here we add all the default properties. - */ - public function propFind(PropFind $propFind, INode $node) - { - $propFind->handle('{DAV:}getlastmodified', function () use ($node) { - $lm = $node->getLastModified(); - if ($lm) { - return new Xml\Property\GetLastModified($lm); - } - }); - - if ($node instanceof IFile) { - $propFind->handle('{DAV:}getcontentlength', [$node, 'getSize']); - $propFind->handle('{DAV:}getetag', [$node, 'getETag']); - $propFind->handle('{DAV:}getcontenttype', [$node, 'getContentType']); - } - - if ($node instanceof IQuota) { - $quotaInfo = null; - $propFind->handle('{DAV:}quota-used-bytes', function () use (&$quotaInfo, $node) { - $quotaInfo = $node->getQuotaInfo(); - - return $quotaInfo[0]; - }); - $propFind->handle('{DAV:}quota-available-bytes', function () use (&$quotaInfo, $node) { - if (!$quotaInfo) { - $quotaInfo = $node->getQuotaInfo(); - } - - return $quotaInfo[1]; - }); - } - - $propFind->handle('{DAV:}supported-report-set', function () use ($propFind) { - $reports = []; - foreach ($this->server->getPlugins() as $plugin) { - $reports = array_merge($reports, $plugin->getSupportedReportSet($propFind->getPath())); - } - - return new Xml\Property\SupportedReportSet($reports); - }); - $propFind->handle('{DAV:}resourcetype', function () use ($node) { - return new Xml\Property\ResourceType($this->server->getResourceTypeForNode($node)); - }); - $propFind->handle('{DAV:}supported-method-set', function () use ($propFind) { - return new Xml\Property\SupportedMethodSet( - $this->server->getAllowedMethods($propFind->getPath()) - ); - }); - } - - /** - * Fetches properties for a node. - * - * This event is called a bit later, so plugins have a chance first to - * populate the result. - */ - public function propFindNode(PropFind $propFind, INode $node) - { - if ($node instanceof IProperties && $propertyNames = $propFind->get404Properties()) { - $nodeProperties = $node->getProperties($propertyNames); - foreach ($nodeProperties as $propertyName => $propertyValue) { - $propFind->set($propertyName, $propertyValue, 200); - } - } - } - - /** - * This method is called when properties are retrieved. - * - * This specific handler is called very late in the process, because we - * want other systems to first have a chance to handle the properties. - */ - public function propFindLate(PropFind $propFind, INode $node) - { - $propFind->handle('{http://calendarserver.org/ns/}getctag', function () use ($propFind) { - // If we already have a sync-token from the current propFind - // request, we can re-use that. - $val = $propFind->get('{http://sabredav.org/ns}sync-token'); - if ($val) { - return $val; - } - - $val = $propFind->get('{DAV:}sync-token'); - if ($val && is_scalar($val)) { - return $val; - } - if ($val && $val instanceof Xml\Property\Href) { - return substr($val->getHref(), strlen(Sync\Plugin::SYNCTOKEN_PREFIX)); - } - - // If we got here, the earlier two properties may simply not have - // been part of the earlier request. We're going to fetch them. - $result = $this->server->getProperties($propFind->getPath(), [ - '{http://sabredav.org/ns}sync-token', - '{DAV:}sync-token', - ]); - - if (isset($result['{http://sabredav.org/ns}sync-token'])) { - return $result['{http://sabredav.org/ns}sync-token']; - } - if (isset($result['{DAV:}sync-token'])) { - $val = $result['{DAV:}sync-token']; - if (is_scalar($val)) { - return $val; - } elseif ($val instanceof Xml\Property\Href) { - return substr($val->getHref(), strlen(Sync\Plugin::SYNCTOKEN_PREFIX)); - } - } - }); - } - - /** - * Listens for exception events, and automatically logs them. - * - * @param Exception $e - */ - public function exception($e) - { - $logLevel = \Psr\Log\LogLevel::CRITICAL; - if ($e instanceof \Sabre\DAV\Exception) { - // If it's a standard sabre/dav exception, it means we have a http - // status code available. - $code = $e->getHTTPCode(); - - if ($code >= 400 && $code < 500) { - // user error - $logLevel = \Psr\Log\LogLevel::INFO; - } else { - // Server-side error. We mark it's as an error, but it's not - // critical. - $logLevel = \Psr\Log\LogLevel::ERROR; - } - } - - $this->server->getLogger()->log( - $logLevel, - 'Uncaught exception', - [ - 'exception' => $e, - ] - ); - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'The Core plugin provides a lot of the basic functionality required by WebDAV, such as a default implementation for all HTTP and WebDAV methods.', - 'link' => null, - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception.php b/lib/vendor/sabre/dav/lib/DAV/Exception.php deleted file mode 100644 index 9fc1d16..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception.php +++ /dev/null @@ -1,50 +0,0 @@ -lock) { - $error = $errorNode->ownerDocument->createElementNS('DAV:', 'd:no-conflicting-lock'); - $errorNode->appendChild($error); - $error->appendChild($errorNode->ownerDocument->createElementNS('DAV:', 'd:href', $this->lock->uri)); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/Forbidden.php b/lib/vendor/sabre/dav/lib/DAV/Exception/Forbidden.php deleted file mode 100644 index 2f882c3..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/Forbidden.php +++ /dev/null @@ -1,29 +0,0 @@ -ownerDocument->createElementNS('DAV:', 'd:valid-resourcetype'); - $errorNode->appendChild($error); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php b/lib/vendor/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php deleted file mode 100644 index f28d20f..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/InvalidSyncToken.php +++ /dev/null @@ -1,34 +0,0 @@ -ownerDocument->createElementNS('DAV:', 'd:valid-sync-token'); - $errorNode->appendChild($error); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/LengthRequired.php b/lib/vendor/sabre/dav/lib/DAV/Exception/LengthRequired.php deleted file mode 100644 index 9d26fcb..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/LengthRequired.php +++ /dev/null @@ -1,30 +0,0 @@ -ownerDocument->createElementNS('DAV:', 'd:lock-token-matches-request-uri'); - $errorNode->appendChild($error); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/Locked.php b/lib/vendor/sabre/dav/lib/DAV/Exception/Locked.php deleted file mode 100644 index 24fad70..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/Locked.php +++ /dev/null @@ -1,68 +0,0 @@ -lock = $lock; - } - - /** - * Returns the HTTP statuscode for this exception. - * - * @return int - */ - public function getHTTPCode() - { - return 423; - } - - /** - * This method allows the exception to include additional information into the WebDAV error response. - */ - public function serialize(DAV\Server $server, \DOMElement $errorNode) - { - if ($this->lock) { - $error = $errorNode->ownerDocument->createElementNS('DAV:', 'd:lock-token-submitted'); - $errorNode->appendChild($error); - - $href = $errorNode->ownerDocument->createElementNS('DAV:', 'd:href'); - $href->appendChild($errorNode->ownerDocument->createTextNode($this->lock->uri)); - $error->appendChild( - $href - ); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php b/lib/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php deleted file mode 100644 index dbf42ed..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/MethodNotAllowed.php +++ /dev/null @@ -1,46 +0,0 @@ -getAllowedMethods($server->getRequestUri()); - - return [ - 'Allow' => strtoupper(implode(', ', $methods)), - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/NotAuthenticated.php b/lib/vendor/sabre/dav/lib/DAV/Exception/NotAuthenticated.php deleted file mode 100644 index 0a5ba9b..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/NotAuthenticated.php +++ /dev/null @@ -1,30 +0,0 @@ -header = $header; - } - - /** - * Returns the HTTP statuscode for this exception. - * - * @return int - */ - public function getHTTPCode() - { - return 412; - } - - /** - * This method allows the exception to include additional information into the WebDAV error response. - */ - public function serialize(DAV\Server $server, \DOMElement $errorNode) - { - if ($this->header) { - $prop = $errorNode->ownerDocument->createElement('s:header'); - $prop->nodeValue = $this->header; - $errorNode->appendChild($prop); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/ReportNotSupported.php b/lib/vendor/sabre/dav/lib/DAV/Exception/ReportNotSupported.php deleted file mode 100644 index a483838..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/ReportNotSupported.php +++ /dev/null @@ -1,28 +0,0 @@ -ownerDocument->createElementNS('DAV:', 'd:supported-report'); - $errorNode->appendChild($error); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php b/lib/vendor/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php deleted file mode 100644 index 6ccb5b8..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/RequestedRangeNotSatisfiable.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class ServiceUnavailable extends DAV\Exception -{ - /** - * Returns the HTTP statuscode for this exception. - * - * @return int - */ - public function getHTTPCode() - { - return 503; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/TooManyMatches.php b/lib/vendor/sabre/dav/lib/DAV/Exception/TooManyMatches.php deleted file mode 100644 index ef6f502..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/TooManyMatches.php +++ /dev/null @@ -1,34 +0,0 @@ -ownerDocument->createElementNS('DAV:', 'd:number-of-matches-within-limits'); - $errorNode->appendChild($error); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php b/lib/vendor/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php deleted file mode 100644 index bc9da30..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Exception/UnsupportedMediaType.php +++ /dev/null @@ -1,30 +0,0 @@ -path.'/'.$name; - file_put_contents($newPath, $data); - clearstatcache(true, $newPath); - } - - /** - * Creates a new subdirectory. - * - * @param string $name - */ - public function createDirectory($name) - { - $newPath = $this->path.'/'.$name; - mkdir($newPath); - clearstatcache(true, $newPath); - } - - /** - * Returns a specific child node, referenced by its name. - * - * This method must throw DAV\Exception\NotFound if the node does not - * exist. - * - * @param string $name - * - * @throws DAV\Exception\NotFound - * - * @return DAV\INode - */ - public function getChild($name) - { - $path = $this->path.'/'.$name; - - if (!file_exists($path)) { - throw new DAV\Exception\NotFound('File with name '.$path.' could not be located'); - } - if (is_dir($path)) { - return new self($path); - } else { - return new File($path); - } - } - - /** - * Returns an array with all the child nodes. - * - * @return DAV\INode[] - */ - public function getChildren() - { - $nodes = []; - $iterator = new \FilesystemIterator( - $this->path, - \FilesystemIterator::CURRENT_AS_SELF - | \FilesystemIterator::SKIP_DOTS - ); - foreach ($iterator as $entry) { - $nodes[] = $this->getChild($entry->getFilename()); - } - - return $nodes; - } - - /** - * Checks if a child exists. - * - * @param string $name - * - * @return bool - */ - public function childExists($name) - { - $path = $this->path.'/'.$name; - - return file_exists($path); - } - - /** - * Deletes all files in this directory, and then itself. - */ - public function delete() - { - foreach ($this->getChildren() as $child) { - $child->delete(); - } - rmdir($this->path); - } - - /** - * Returns available diskspace information. - * - * @return array - */ - public function getQuotaInfo() - { - $absolute = realpath($this->path); - - return [ - disk_total_space($absolute) - disk_free_space($absolute), - disk_free_space($absolute), - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/FS/File.php b/lib/vendor/sabre/dav/lib/DAV/FS/File.php deleted file mode 100644 index b78a801..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/FS/File.php +++ /dev/null @@ -1,87 +0,0 @@ -path, $data); - clearstatcache(true, $this->path); - } - - /** - * Returns the data. - * - * @return resource - */ - public function get() - { - return fopen($this->path, 'r'); - } - - /** - * Delete the current file. - */ - public function delete() - { - unlink($this->path); - } - - /** - * Returns the size of the node, in bytes. - * - * @return int - */ - public function getSize() - { - return filesize($this->path); - } - - /** - * 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 arbitrary string, but MUST be surrounded by double-quotes. - * - * Return null if the ETag can not effectively be determined - * - * @return mixed - */ - public function getETag() - { - return '"'.sha1( - fileinode($this->path). - filesize($this->path). - filemtime($this->path) - ).'"'; - } - - /** - * Returns the mime-type for a file. - * - * If null is returned, we'll assume application/octet-stream - * - * @return mixed - */ - public function getContentType() - { - return null; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/FS/Node.php b/lib/vendor/sabre/dav/lib/DAV/FS/Node.php deleted file mode 100644 index 32aa747..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/FS/Node.php +++ /dev/null @@ -1,96 +0,0 @@ -path = $path; - $this->overrideName = $overrideName; - } - - /** - * Returns the name of the node. - * - * @return string - */ - public function getName() - { - if ($this->overrideName) { - return $this->overrideName; - } - - list(, $name) = Uri\split($this->path); - - return $name; - } - - /** - * Renames the node. - * - * @param string $name The new name - */ - public function setName($name) - { - if ($this->overrideName) { - throw new Forbidden('This node cannot be renamed'); - } - - list($parentPath) = Uri\split($this->path); - list(, $newName) = Uri\split($name); - - $newPath = $parentPath.'/'.$newName; - rename($this->path, $newPath); - - $this->path = $newPath; - } - - /** - * Returns the last modification time, as a unix timestamp. - * - * @return int - */ - public function getLastModified() - { - return filemtime($this->path); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/FSExt/Directory.php b/lib/vendor/sabre/dav/lib/DAV/FSExt/Directory.php deleted file mode 100644 index d6aea00..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/FSExt/Directory.php +++ /dev/null @@ -1,212 +0,0 @@ -path.'/'.$name; - file_put_contents($newPath, $data); - clearstatcache(true, $newPath); - - return '"'.sha1( - fileinode($newPath). - filesize($newPath). - filemtime($newPath) - ).'"'; - } - - /** - * Creates a new subdirectory. - * - * @param string $name - */ - public function createDirectory($name) - { - // We're not allowing dots - if ('.' == $name || '..' == $name) { - throw new DAV\Exception\Forbidden('Permission denied to . and ..'); - } - $newPath = $this->path.'/'.$name; - mkdir($newPath); - clearstatcache(true, $newPath); - } - - /** - * Returns a specific child node, referenced by its name. - * - * This method must throw Sabre\DAV\Exception\NotFound if the node does not - * exist. - * - * @param string $name - * - * @throws DAV\Exception\NotFound - * - * @return DAV\INode - */ - public function getChild($name) - { - $path = $this->path.'/'.$name; - - if (!file_exists($path)) { - throw new DAV\Exception\NotFound('File could not be located'); - } - if ('.' == $name || '..' == $name) { - throw new DAV\Exception\Forbidden('Permission denied to . and ..'); - } - if (is_dir($path)) { - return new self($path); - } else { - return new File($path); - } - } - - /** - * Checks if a child exists. - * - * @param string $name - * - * @return bool - */ - public function childExists($name) - { - if ('.' == $name || '..' == $name) { - throw new DAV\Exception\Forbidden('Permission denied to . and ..'); - } - $path = $this->path.'/'.$name; - - return file_exists($path); - } - - /** - * Returns an array with all the child nodes. - * - * @return DAV\INode[] - */ - public function getChildren() - { - $nodes = []; - $iterator = new \FilesystemIterator( - $this->path, - \FilesystemIterator::CURRENT_AS_SELF - | \FilesystemIterator::SKIP_DOTS - ); - - foreach ($iterator as $entry) { - $nodes[] = $this->getChild($entry->getFilename()); - } - - return $nodes; - } - - /** - * Deletes all files in this directory, and then itself. - * - * @return bool - */ - public function delete() - { - // Deleting all children - foreach ($this->getChildren() as $child) { - $child->delete(); - } - - // Removing the directory itself - rmdir($this->path); - - return true; - } - - /** - * Returns available diskspace information. - * - * @return array - */ - public function getQuotaInfo() - { - $total = disk_total_space(realpath($this->path)); - $free = disk_free_space(realpath($this->path)); - - return [ - $total - $free, - $free, - ]; - } - - /** - * Moves a node into this collection. - * - * It is up to the implementors to: - * 1. Create the new resource. - * 2. Remove the old resource. - * 3. Transfer any properties or other data. - * - * Generally you should make very sure that your collection can easily move - * the move. - * - * If you don't, just return false, which will trigger sabre/dav to handle - * the move itself. If you return true from this function, the assumption - * is that the move was successful. - * - * @param string $targetName new local file/collection name - * @param string $sourcePath Full path to source node - * @param DAV\INode $sourceNode Source node itself - * - * @return bool - */ - public function moveInto($targetName, $sourcePath, DAV\INode $sourceNode) - { - // We only support FSExt\Directory or FSExt\File objects, so - // anything else we want to quickly reject. - if (!$sourceNode instanceof self && !$sourceNode instanceof File) { - return false; - } - - // PHP allows us to access protected properties from other objects, as - // long as they are defined in a class that has a shared inheritance - // with the current class. - return rename($sourceNode->path, $this->path.'/'.$targetName); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/FSExt/File.php b/lib/vendor/sabre/dav/lib/DAV/FSExt/File.php deleted file mode 100644 index 74849b5..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/FSExt/File.php +++ /dev/null @@ -1,153 +0,0 @@ -path, $data); - clearstatcache(true, $this->path); - - return $this->getETag(); - } - - /** - * Updates the file based on a range specification. - * - * The first argument is the data, which is either a readable stream - * resource or a string. - * - * The second argument is the type of update we're doing. - * This is either: - * * 1. append (default) - * * 2. update based on a start byte - * * 3. update based on an end byte - *; - * The third argument is the start or end byte. - * - * After a successful 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. - * - * @param resource|string $data - * @param int $rangeType - * @param int $offset - * - * @return string|null - */ - public function patch($data, $rangeType, $offset = null) - { - switch ($rangeType) { - case 1: - $f = fopen($this->path, 'a'); - break; - case 2: - $f = fopen($this->path, 'c'); - fseek($f, $offset); - break; - case 3: - $f = fopen($this->path, 'c'); - fseek($f, $offset, SEEK_END); - break; - default: - $f = fopen($this->path, 'a'); - break; - } - if (is_string($data)) { - fwrite($f, $data); - } else { - stream_copy_to_stream($data, $f); - } - fclose($f); - clearstatcache(true, $this->path); - - return $this->getETag(); - } - - /** - * Returns the data. - * - * @return resource - */ - public function get() - { - return fopen($this->path, 'r'); - } - - /** - * Delete the current file. - * - * @return bool - */ - public function delete() - { - return unlink($this->path); - } - - /** - * 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 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() - { - return '"'.sha1( - fileinode($this->path). - filesize($this->path). - filemtime($this->path) - ).'"'; - } - - /** - * 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; - } - - /** - * Returns the size of the file, in bytes. - * - * @return int - */ - public function getSize() - { - return filesize($this->path); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/File.php b/lib/vendor/sabre/dav/lib/DAV/File.php deleted file mode 100644 index daf83aa..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/File.php +++ /dev/null @@ -1,93 +0,0 @@ -locksFile = $locksFile; - } - - /** - * 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 bool $returnChildLocks - * - * @return array - */ - public function getLocks($uri, $returnChildLocks) - { - $newLocks = []; - - $locks = $this->getData(); - - foreach ($locks as $lock) { - if ($lock->uri === $uri || - //deep locks on parents - (0 != $lock->depth && 0 === strpos($uri, $lock->uri.'/')) || - - // locks on children - ($returnChildLocks && (0 === strpos($lock->uri, $uri.'/')))) { - $newLocks[] = $lock; - } - } - - // Checking if we can remove any of these locks - foreach ($newLocks as $k => $lock) { - if (time() > $lock->timeout + $lock->created) { - unset($newLocks[$k]); - } - } - - return $newLocks; - } - - /** - * Locks a uri. - * - * @param string $uri - * - * @return bool - */ - public function lock($uri, LockInfo $lockInfo) - { - // We're making the lock timeout 30 minutes - $lockInfo->timeout = 1800; - $lockInfo->created = time(); - $lockInfo->uri = $uri; - - $locks = $this->getData(); - - foreach ($locks as $k => $lock) { - if ( - ($lock->token == $lockInfo->token) || - (time() > $lock->timeout + $lock->created) - ) { - unset($locks[$k]); - } - } - $locks[] = $lockInfo; - $this->putData($locks); - - return true; - } - - /** - * Removes a lock from a uri. - * - * @param string $uri - * - * @return bool - */ - public function unlock($uri, LockInfo $lockInfo) - { - $locks = $this->getData(); - foreach ($locks as $k => $lock) { - if ($lock->token == $lockInfo->token) { - unset($locks[$k]); - $this->putData($locks); - - return true; - } - } - - return false; - } - - /** - * Loads the lockdata from the filesystem. - * - * @return array - */ - protected function getData() - { - if (!file_exists($this->locksFile)) { - return []; - } - - // opening up the file, and creating a shared lock - $handle = fopen($this->locksFile, 'r'); - flock($handle, LOCK_SH); - - // Reading data until the eof - $data = stream_get_contents($handle); - - // We're all good - flock($handle, LOCK_UN); - fclose($handle); - - // Unserializing and checking if the resource file contains data for this file - $data = unserialize($data); - if (!$data) { - return []; - } - - return $data; - } - - /** - * Saves the lockdata. - */ - protected function putData(array $newData) - { - // opening up the file, and creating an exclusive lock - $handle = fopen($this->locksFile, 'a+'); - flock($handle, LOCK_EX); - - // We can only truncate and rewind once the lock is acquired. - ftruncate($handle, 0); - rewind($handle); - - fwrite($handle, serialize($newData)); - flock($handle, LOCK_UN); - fclose($handle); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php b/lib/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php deleted file mode 100644 index 3f425f9..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Locks/Backend/PDO.php +++ /dev/null @@ -1,172 +0,0 @@ -pdo = $pdo; - } - - /** - * 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 bool $returnChildLocks - * - * @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 concatenation prevents us - // from doing this though. - $query = 'SELECT owner, token, timeout, created, scope, depth, uri FROM '.$this->tableName.' WHERE (created > (? - timeout)) AND ((uri = ?)'; - $params = [time(), $uri]; - - // We need to check locks for every part in the uri. - $uriParts = explode('/', $uri); - - // We already covered the last part of the uri - array_pop($uriParts); - - $currentPath = ''; - - foreach ($uriParts as $part) { - if ($currentPath) { - $currentPath .= '/'; - } - $currentPath .= $part; - - $query .= ' OR (depth!=0 AND uri = ?)'; - $params[] = $currentPath; - } - - if ($returnChildLocks) { - $query .= ' OR (uri LIKE ?)'; - $params[] = $uri.'/%'; - } - $query .= ')'; - - $stmt = $this->pdo->prepare($query); - $stmt->execute($params); - $result = $stmt->fetchAll(); - - $lockList = []; - foreach ($result as $row) { - $lockInfo = new LockInfo(); - $lockInfo->owner = $row['owner']; - $lockInfo->token = $row['token']; - $lockInfo->timeout = $row['timeout']; - $lockInfo->created = $row['created']; - $lockInfo->scope = $row['scope']; - $lockInfo->depth = $row['depth']; - $lockInfo->uri = $row['uri']; - $lockList[] = $lockInfo; - } - - return $lockList; - } - - /** - * Locks a uri. - * - * @param string $uri - * - * @return bool - */ - public function lock($uri, LockInfo $lockInfo) - { - // We're making the lock timeout 30 minutes - $lockInfo->timeout = 30 * 60; - $lockInfo->created = time(); - $lockInfo->uri = $uri; - - $locks = $this->getLocks($uri, false); - $exists = false; - 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->execute([ - $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->execute([ - $lockInfo->owner, - $lockInfo->timeout, - $lockInfo->scope, - $lockInfo->depth, - $uri, - $lockInfo->created, - $lockInfo->token, - ]); - } - - return true; - } - - /** - * Removes a lock from a uri. - * - * @param string $uri - * - * @return bool - */ - public function unlock($uri, LockInfo $lockInfo) - { - $stmt = $this->pdo->prepare('DELETE FROM '.$this->tableName.' WHERE uri = ? AND token = ?'); - $stmt->execute([$uri, $lockInfo->token]); - - return 1 === $stmt->rowCount(); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Locks/LockInfo.php b/lib/vendor/sabre/dav/lib/DAV/Locks/LockInfo.php deleted file mode 100644 index df82275..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Locks/LockInfo.php +++ /dev/null @@ -1,82 +0,0 @@ -addPlugin($lockPlugin); - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class Plugin extends DAV\ServerPlugin -{ - /** - * locksBackend. - * - * @var Backend\BackendInterface - */ - protected $locksBackend; - - /** - * server. - * - * @var DAV\Server - */ - protected $server; - - /** - * __construct. - */ - public function __construct(Backend\BackendInterface $locksBackend) - { - $this->locksBackend = $locksBackend; - } - - /** - * Initializes the plugin. - * - * This method is automatically called by the Server class after addPlugin. - */ - public function initialize(DAV\Server $server) - { - $this->server = $server; - - $this->server->xml->elementMap['{DAV:}lockinfo'] = 'Sabre\\DAV\\Xml\\Request\\Lock'; - - $server->on('method:LOCK', [$this, 'httpLock']); - $server->on('method:UNLOCK', [$this, 'httpUnlock']); - $server->on('validateTokens', [$this, 'validateTokens']); - $server->on('propFind', [$this, 'propFind']); - $server->on('afterUnbind', [$this, 'afterUnbind']); - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'locks'; - } - - /** - * This method is called after most properties have been found - * it allows us to add in any Lock-related properties. - */ - public function propFind(DAV\PropFind $propFind, DAV\INode $node) - { - $propFind->handle('{DAV:}supportedlock', function () { - return new DAV\Xml\Property\SupportedLock(); - }); - $propFind->handle('{DAV:}lockdiscovery', function () use ($propFind) { - return new DAV\Xml\Property\LockDiscovery( - $this->getLocks($propFind->getPath()) - ); - }); - } - - /** - * 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 - * available for the specified uri. - * - * @param string $uri - * - * @return array - */ - public function getHTTPMethods($uri) - { - return ['LOCK', 'UNLOCK']; - } - - /** - * Returns a list of features for the HTTP OPTIONS Dav: header. - * - * In this case this is only the number 2. The 2 in the Dav: header - * indicates the server supports locks. - * - * @return array - */ - public function getFeatures() - { - return [2]; - } - - /** - * 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 - * 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 bool $returnChildLocks - * - * @return array - */ - public function getLocks($uri, $returnChildLocks = false) - { - return $this->locksBackend->getLocks($uri, $returnChildLocks); - } - - /** - * 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 - * 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-existent file. In these case we're obligated to create an empty file as per RFC4918:S7.3 - * - * @return bool - */ - public function httpLock(RequestInterface $request, ResponseInterface $response) - { - $uri = $request->getPath(); - - $existingLocks = $this->getLocks($uri); - - if ($body = $request->getBodyAsString()) { - // This is a new lock request - - $existingLock = null; - // Checking if there's already non-shared locks on the uri. - foreach ($existingLocks as $existingLock) { - if (LockInfo::EXCLUSIVE === $existingLock->scope) { - throw new DAV\Exception\ConflictingLock($existingLock); - } - } - - $lockInfo = $this->parseLockRequest($body); - $lockInfo->depth = $this->server->getHTTPDepth(); - $lockInfo->uri = $uri; - if ($existingLock && LockInfo::SHARED != $lockInfo->scope) { - throw new DAV\Exception\ConflictingLock($existingLock); - } - } else { - // Gonna check if this was a lock refresh. - $existingLocks = $this->getLocks($uri); - $conditions = $this->server->getIfConditions($request); - $found = null; - - foreach ($existingLocks as $existingLock) { - foreach ($conditions as $condition) { - foreach ($condition['tokens'] as $token) { - if ($token['token'] === 'opaquelocktoken:'.$existingLock->token) { - $found = $existingLock; - break 3; - } - } - } - } - - // If none were found, this request is in error. - if (is_null($found)) { - if ($existingLocks) { - throw new DAV\Exception\Locked(reset($existingLocks)); - } else { - throw new DAV\Exception\BadRequest('An xml body is required for lock requests'); - } - } - - // This must have been a lock refresh - $lockInfo = $found; - - // The resource could have been locked through another uri. - if ($uri != $lockInfo->uri) { - $uri = $lockInfo->uri; - } - } - - if ($timeout = $this->getTimeoutHeader()) { - $lockInfo->timeout = $timeout; - } - - $newFile = false; - - // 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 { - $this->server->tree->getNodeForPath($uri); - - // We need to call the beforeWriteContent event for RFC3744 - // Edit: looks like this is not used, and causing problems now. - // - // See Issue 222 - // $this->server->emit('beforeWriteContent',array($uri)); - } catch (DAV\Exception\NotFound $e) { - // It didn't, lets create it - $this->server->createFile($uri, fopen('php://memory', 'r')); - $newFile = true; - } - - $this->lockNode($uri, $lockInfo); - - $response->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $response->setHeader('Lock-Token', 'token.'>'); - $response->setStatus($newFile ? 201 : 200); - $response->setBody($this->generateLockResponse($lockInfo)); - - // Returning false will interrupt the event chain and mark this method - // as 'handled'. - return false; - } - - /** - * Unlocks a uri. - * - * This WebDAV method allows you to remove a lock from a node. The client should provide a valid locktoken through the Lock-token http header - * The server should return 204 (No content) on success - */ - public function httpUnlock(RequestInterface $request, ResponseInterface $response) - { - $lockToken = $request->getHeader('Lock-Token'); - - // If the locktoken header is not supplied, we need to throw a bad request exception - if (!$lockToken) { - throw new DAV\Exception\BadRequest('No lock token was supplied'); - } - $path = $request->getPath(); - $locks = $this->getLocks($path); - - // Windows sometimes forgets to include < and > in the Lock-Token - // header - if ('<' !== $lockToken[0]) { - $lockToken = '<'.$lockToken.'>'; - } - - foreach ($locks as $lock) { - if ('token.'>' == $lockToken) { - $this->unlockNode($path, $lock); - $response->setHeader('Content-Length', '0'); - $response->setStatus(204); - - // Returning false will break the method chain, and mark the - // method as 'handled'. - return false; - } - } - - // If we got here, it means the locktoken was invalid - throw new DAV\Exception\LockTokenMatchesRequestUri(); - } - - /** - * This method is called after a node is deleted. - * - * We use this event to clean up any locks that still exist on the node. - * - * @param string $path - */ - public function afterUnbind($path) - { - $locks = $this->getLocks($path, $includeChildren = true); - foreach ($locks as $lock) { - // don't delete a lock on a parent dir - if (0 !== strpos($lock->uri, $path)) { - continue; - } - $this->unlockNode($path, $lock); - } - } - - /** - * Locks a uri. - * - * 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 - * - * @return bool - */ - public function lockNode($uri, LockInfo $lockInfo) - { - if (!$this->server->emit('beforeLock', [$uri, $lockInfo])) { - return; - } - - return $this->locksBackend->lock($uri, $lockInfo); - } - - /** - * 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 - * - * @return bool - */ - public function unlockNode($uri, LockInfo $lockInfo) - { - if (!$this->server->emit('beforeUnlock', [$uri, $lockInfo])) { - return; - } - - return $this->locksBackend->unlock($uri, $lockInfo); - } - - /** - * Returns the contents of the HTTP Timeout header. - * - * The method formats the header into an integer. - * - * @return int - */ - public function getTimeoutHeader() - { - $header = $this->server->httpRequest->getHeader('Timeout'); - - if ($header) { - if (0 === stripos($header, 'second-')) { - $header = (int) (substr($header, 7)); - } elseif (0 === stripos($header, 'infinite')) { - $header = LockInfo::TIMEOUT_INFINITE; - } else { - throw new DAV\Exception\BadRequest('Invalid HTTP timeout header'); - } - } else { - $header = 0; - } - - return $header; - } - - /** - * Generates the response for successful LOCK requests. - * - * @return string - */ - protected function generateLockResponse(LockInfo $lockInfo) - { - return $this->server->xml->write('{DAV:}prop', [ - '{DAV:}lockdiscovery' => new DAV\Xml\Property\LockDiscovery([$lockInfo]), - ], $this->server->getBaseUri()); - } - - /** - * The validateTokens event is triggered before every request. - * - * It's a moment where this plugin can check all the supplied lock tokens - * in the If: header, and check if they are valid. - * - * In addition, it will also ensure that it checks any missing lokens that - * must be present in the request, and reject requests without the proper - * tokens. - * - * @param mixed $conditions - */ - public function validateTokens(RequestInterface $request, &$conditions) - { - // First we need to gather a list of locks that must be satisfied. - $mustLocks = []; - $method = $request->getMethod(); - - // Methods not in that list are operations that doesn't alter any - // resources, and we don't need to check the lock-states for. - switch ($method) { - case 'DELETE': - $mustLocks = array_merge($mustLocks, $this->getLocks( - $request->getPath(), - true - )); - break; - case 'MKCOL': - case 'MKCALENDAR': - case 'PROPPATCH': - case 'PUT': - case 'PATCH': - $mustLocks = array_merge($mustLocks, $this->getLocks( - $request->getPath(), - false - )); - break; - case 'MOVE': - $mustLocks = array_merge($mustLocks, $this->getLocks( - $request->getPath(), - true - )); - $mustLocks = array_merge($mustLocks, $this->getLocks( - $this->server->calculateUri($request->getHeader('Destination')), - false - )); - break; - case 'COPY': - $mustLocks = array_merge($mustLocks, $this->getLocks( - $this->server->calculateUri($request->getHeader('Destination')), - false - )); - break; - case 'LOCK': - //Temporary measure.. figure out later why this is needed - // Here we basically ignore all incoming tokens... - foreach ($conditions as $ii => $condition) { - foreach ($condition['tokens'] as $jj => $token) { - $conditions[$ii]['tokens'][$jj]['validToken'] = true; - } - } - - return; - } - - // It's possible that there's identical locks, because of shared - // parents. We're removing the duplicates here. - $tmp = []; - foreach ($mustLocks as $lock) { - $tmp[$lock->token] = $lock; - } - $mustLocks = array_values($tmp); - - foreach ($conditions as $kk => $condition) { - foreach ($condition['tokens'] as $ii => $token) { - // Lock tokens always start with opaquelocktoken: - if ('opaquelocktoken:' !== substr($token['token'], 0, 16)) { - continue; - } - - $checkToken = substr($token['token'], 16); - // Looping through our list with locks. - foreach ($mustLocks as $jj => $mustLock) { - if ($mustLock->token == $checkToken) { - // We have a match! - // Removing this one from mustlocks - unset($mustLocks[$jj]); - - // Marking the condition as valid. - $conditions[$kk]['tokens'][$ii]['validToken'] = true; - - // Advancing to the next token - continue 2; - } - } - - // If we got here, it means that there was a - // lock-token, but it was not in 'mustLocks'. - // - // This is an edge-case, as it could mean that token - // was specified with a url that was not 'required' to - // check. So we're doing one extra lookup to make sure - // we really don't know this token. - // - // This also gets triggered when the user specified a - // lock-token that was expired. - $oddLocks = $this->getLocks($condition['uri']); - foreach ($oddLocks as $oddLock) { - if ($oddLock->token === $checkToken) { - // We have a hit! - $conditions[$kk]['tokens'][$ii]['validToken'] = true; - continue 2; - } - } - - // If we get all the way here, the lock-token was - // really unknown. - } - } - - // If there's any locks left in the 'mustLocks' array, it means that - // the resource was locked and we must block it. - if ($mustLocks) { - throw new DAV\Exception\Locked(reset($mustLocks)); - } - } - - /** - * Parses a webdav lock xml body, and returns a new Sabre\DAV\Locks\LockInfo object. - * - * @param string $body - * - * @return LockInfo - */ - protected function parseLockRequest($body) - { - $result = $this->server->xml->expect( - '{DAV:}lockinfo', - $body - ); - - $lockInfo = new LockInfo(); - - $lockInfo->owner = $result->owner; - $lockInfo->token = DAV\UUIDUtil::getUUID(); - $lockInfo->scope = $result->scope; - - return $lockInfo; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'The locks plugin turns this server into a class-2 WebDAV server and adds support for LOCK and UNLOCK', - 'link' => 'http://sabre.io/dav/locks/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/MkCol.php b/lib/vendor/sabre/dav/lib/DAV/MkCol.php deleted file mode 100644 index f3c5ea5..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/MkCol.php +++ /dev/null @@ -1,71 +0,0 @@ -resourceType = $resourceType; - parent::__construct($mutations); - } - - /** - * Returns the resourcetype of the new collection. - * - * @return string[] - */ - public function getResourceType() - { - return $this->resourceType; - } - - /** - * Returns true or false if the MKCOL operation has at least the specified - * resource type. - * - * If the resourcetype is specified as an array, all resourcetypes are - * checked. - * - * @param string|string[] $resourceType - * - * @return bool - */ - public function hasResourceType($resourceType) - { - return 0 === count(array_diff((array) $resourceType, $this->resourceType)); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Mount/Plugin.php b/lib/vendor/sabre/dav/lib/DAV/Mount/Plugin.php deleted file mode 100644 index b7f4851..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Mount/Plugin.php +++ /dev/null @@ -1,78 +0,0 @@ -server = $server; - $this->server->on('method:GET', [$this, 'httpGet'], 90); - } - - /** - * 'beforeMethod' event handles. This event handles intercepts GET requests ending - * with ?mount. - * - * @return bool - */ - public function httpGet(RequestInterface $request, ResponseInterface $response) - { - $queryParams = $request->getQueryParameters(); - if (!array_key_exists('mount', $queryParams)) { - return; - } - - $currentUri = $request->getAbsoluteUrl(); - - // Stripping off everything after the ? - list($currentUri) = explode('?', $currentUri); - - $this->davMount($response, $currentUri); - - // Returning false to break the event chain - return false; - } - - /** - * Generates the davmount response. - * - * @param string $uri absolute uri - */ - public function davMount(ResponseInterface $response, $uri) - { - $response->setStatus(200); - $response->setHeader('Content-Type', 'application/davmount+xml'); - ob_start(); - echo '', "\n"; - echo "\n"; - echo ' ', htmlspecialchars($uri, ENT_NOQUOTES, 'UTF-8'), "\n"; - echo ''; - $response->setBody(ob_get_clean()); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Node.php b/lib/vendor/sabre/dav/lib/DAV/Node.php deleted file mode 100644 index 948060d..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Node.php +++ /dev/null @@ -1,51 +0,0 @@ -addPlugin($patchPlugin); - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Jean-Tiare LE BIGOT (http://www.jtlebi.fr/) - * @license http://sabre.io/license/ Modified BSD License - */ -class Plugin extends DAV\ServerPlugin -{ - const RANGE_APPEND = 1; - const RANGE_START = 2; - const RANGE_END = 3; - - /** - * Reference to server. - * - * @var DAV\Server - */ - protected $server; - - /** - * Initializes the plugin. - * - * This method is automatically called by the Server class after addPlugin. - */ - public function initialize(DAV\Server $server) - { - $this->server = $server; - $server->on('method:PATCH', [$this, 'httpPatch']); - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'partialupdate'; - } - - /** - * 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 - * available for the specified uri. - * - * We claim to support PATCH method (partirl update) if and only if - * - the node exist - * - the node implements our partial update interface - * - * @param string $uri - * - * @return array - */ - public function getHTTPMethods($uri) - { - $tree = $this->server->tree; - - if ($tree->nodeExists($uri)) { - $node = $tree->getNodeForPath($uri); - if ($node instanceof IPatchSupport) { - return ['PATCH']; - } - } - - return []; - } - - /** - * Returns a list of features for the HTTP OPTIONS Dav: header. - * - * @return array - */ - public function getFeatures() - { - return ['sabredav-partialupdate']; - } - - /** - * Patch an uri. - * - * The WebDAV patch request can be used to modify only a part of an - * existing resource. If the resource does not exist yet and the first - * offset is not 0, the request fails - */ - public function httpPatch(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - - // Get the node. Will throw a 404 if not found - $node = $this->server->tree->getNodeForPath($path); - if (!$node instanceof IPatchSupport) { - throw new DAV\Exception\MethodNotAllowed('The target resource does not support the PATCH method.'); - } - - $range = $this->getHTTPUpdateRange($request); - - if (!$range) { - throw new DAV\Exception\BadRequest('No valid "X-Update-Range" found in the headers'); - } - - $contentType = strtolower( - (string) $request->getHeader('Content-Type') - ); - - if ('application/x-sabredav-partialupdate' != $contentType) { - throw new DAV\Exception\UnsupportedMediaType('Unknown Content-Type header "'.$contentType.'"'); - } - - $len = $this->server->httpRequest->getHeader('Content-Length'); - if (!$len) { - throw new DAV\Exception\LengthRequired('A Content-Length header is required'); - } - switch ($range[0]) { - case self::RANGE_START: - // Calculate the end-range if it doesn't exist. - if (!$range[2]) { - $range[2] = $range[1] + $len - 1; - } else { - if ($range[2] < $range[1]) { - throw new DAV\Exception\RequestedRangeNotSatisfiable('The end offset ('.$range[2].') is lower than the start offset ('.$range[1].')'); - } - if ($range[2] - $range[1] + 1 != $len) { - throw new DAV\Exception\RequestedRangeNotSatisfiable('Actual data length ('.$len.') is not consistent with begin ('.$range[1].') and end ('.$range[2].') offsets'); - } - } - break; - } - - if (!$this->server->emit('beforeWriteContent', [$path, $node, null])) { - return; - } - - $body = $this->server->httpRequest->getBody(); - - $etag = $node->patch($body, $range[0], isset($range[1]) ? $range[1] : null); - - $this->server->emit('afterWriteContent', [$path, $node]); - - $response->setHeader('Content-Length', '0'); - if ($etag) { - $response->setHeader('ETag', $etag); - } - $response->setStatus(204); - - // Breaks the event chain - return false; - } - - /** - * Returns the HTTP custom range update header. - * - * This method returns null if there is no well-formed HTTP range request - * header. It returns array(1) if it was an append request, array(2, - * $start, $end) if it's a start and end range, lastly it's array(3, - * $endoffset) if the offset was negative, and should be calculated from - * the end of the file. - * - * Examples: - * - * null - invalid - * [1] - append - * [2,10,15] - update bytes 10, 11, 12, 13, 14, 15 - * [2,10,null] - update bytes 10 until the end of the patch body - * [3,-5] - update from 5 bytes from the end of the file. - * - * @return array|null - */ - public function getHTTPUpdateRange(RequestInterface $request) - { - $range = $request->getHeader('X-Update-Range'); - if (is_null($range)) { - return null; - } - - // Matching "Range: bytes=1234-5678: both numbers are optional - - if (!preg_match('/^(append)|(?:bytes=([0-9]+)-([0-9]*))|(?:bytes=(-[0-9]+))$/i', $range, $matches)) { - return null; - } - - if ('append' === $matches[1]) { - return [self::RANGE_APPEND]; - } elseif (strlen($matches[2]) > 0) { - return [self::RANGE_START, (int) $matches[2], (int) $matches[3] ?: null]; - } else { - return [self::RANGE_END, (int) $matches[4]]; - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/PropFind.php b/lib/vendor/sabre/dav/lib/DAV/PropFind.php deleted file mode 100644 index e9ffb07..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/PropFind.php +++ /dev/null @@ -1,335 +0,0 @@ -path = $path; - $this->properties = $properties; - $this->depth = $depth; - $this->requestType = $requestType; - - if (self::ALLPROPS === $requestType) { - $this->properties = [ - '{DAV:}getlastmodified', - '{DAV:}getcontentlength', - '{DAV:}resourcetype', - '{DAV:}quota-used-bytes', - '{DAV:}quota-available-bytes', - '{DAV:}getetag', - '{DAV:}getcontenttype', - ]; - } - - foreach ($this->properties as $propertyName) { - // Seeding properties with 404's. - $this->result[$propertyName] = [404, null]; - } - $this->itemsLeft = count($this->result); - } - - /** - * Handles a specific property. - * - * This method checks whether the specified property was requested in this - * PROPFIND request, and if so, it will call the callback and use the - * return value for it's value. - * - * Example: - * - * $propFind->handle('{DAV:}displayname', function() { - * return 'hello'; - * }); - * - * Note that handle will only work the first time. If null is returned, the - * value is ignored. - * - * It's also possible to not pass a callback, but immediately pass a value - * - * @param string $propertyName - * @param mixed $valueOrCallBack - */ - public function handle($propertyName, $valueOrCallBack) - { - if ($this->itemsLeft && isset($this->result[$propertyName]) && 404 === $this->result[$propertyName][0]) { - if (is_callable($valueOrCallBack)) { - $value = $valueOrCallBack(); - } else { - $value = $valueOrCallBack; - } - if (!is_null($value)) { - --$this->itemsLeft; - $this->result[$propertyName] = [200, $value]; - } - } - } - - /** - * Sets the value of the property. - * - * If status is not supplied, the status will default to 200 for non-null - * properties, and 404 for null properties. - * - * @param string $propertyName - * @param mixed $value - * @param int $status - */ - public function set($propertyName, $value, $status = null) - { - if (is_null($status)) { - $status = is_null($value) ? 404 : 200; - } - // If this is an ALLPROPS request and the property is - // unknown, add it to the result; else ignore it: - if (!isset($this->result[$propertyName])) { - if (self::ALLPROPS === $this->requestType) { - $this->result[$propertyName] = [$status, $value]; - } - - return; - } - if (404 !== $status && 404 === $this->result[$propertyName][0]) { - --$this->itemsLeft; - } elseif (404 === $status && 404 !== $this->result[$propertyName][0]) { - ++$this->itemsLeft; - } - $this->result[$propertyName] = [$status, $value]; - } - - /** - * Returns the current value for a property. - * - * @param string $propertyName - * - * @return mixed - */ - public function get($propertyName) - { - return isset($this->result[$propertyName]) ? $this->result[$propertyName][1] : null; - } - - /** - * Returns the current status code for a property name. - * - * If the property does not appear in the list of requested properties, - * null will be returned. - * - * @param string $propertyName - * - * @return int|null - */ - public function getStatus($propertyName) - { - return isset($this->result[$propertyName]) ? $this->result[$propertyName][0] : null; - } - - /** - * Updates the path for this PROPFIND. - * - * @param string $path - */ - public function setPath($path) - { - $this->path = $path; - } - - /** - * Returns the path this PROPFIND request is for. - * - * @return string - */ - public function getPath() - { - return $this->path; - } - - /** - * Returns the depth of this propfind request. - * - * @return int - */ - public function getDepth() - { - return $this->depth; - } - - /** - * Updates the depth of this propfind request. - * - * @param int $depth - */ - public function setDepth($depth) - { - $this->depth = $depth; - } - - /** - * Returns all propertynames that have a 404 status, and thus don't have a - * value yet. - * - * @return array - */ - public function get404Properties() - { - if (0 === $this->itemsLeft) { - return []; - } - $result = []; - foreach ($this->result as $propertyName => $stuff) { - if (404 === $stuff[0]) { - $result[] = $propertyName; - } - } - - return $result; - } - - /** - * Returns the full list of requested properties. - * - * This returns just their names, not a status or value. - * - * @return array - */ - public function getRequestedProperties() - { - return $this->properties; - } - - /** - * Returns true if this was an '{DAV:}allprops' request. - * - * @return bool - */ - public function isAllProps() - { - return self::ALLPROPS === $this->requestType; - } - - /** - * Returns a result array that's often used in multistatus responses. - * - * The array uses status codes as keys, and property names and value pairs - * as the value of the top array.. such as : - * - * [ - * 200 => [ '{DAV:}displayname' => 'foo' ], - * ] - * - * @return array - */ - public function getResultForMultiStatus() - { - $r = [ - 200 => [], - 404 => [], - ]; - foreach ($this->result as $propertyName => $info) { - if (!isset($r[$info[0]])) { - $r[$info[0]] = [$propertyName => $info[1]]; - } else { - $r[$info[0]][$propertyName] = $info[1]; - } - } - // Removing the 404's for multi-status requests. - if (self::ALLPROPS === $this->requestType) { - unset($r[404]); - } - - return $r; - } - - /** - * The path that we're fetching properties for. - * - * @var string - */ - protected $path; - - /** - * The Depth of the request. - * - * 0 means only the current item. 1 means the current item + its children. - * It can also be DEPTH_INFINITY if this is enabled in the server. - * - * @var int - */ - protected $depth = 0; - - /** - * The type of request. See the TYPE constants. - */ - protected $requestType; - - /** - * A list of requested properties. - * - * @var array - */ - protected $properties = []; - - /** - * The result of the operation. - * - * The keys in this array are property names. - * The values are an array with two elements: the http status code and then - * optionally a value. - * - * Example: - * - * [ - * "{DAV:}owner" : [404], - * "{DAV:}displayname" : [200, "Admin"] - * ] - * - * @var array - */ - protected $result = []; - - /** - * This is used as an internal counter for the number of properties that do - * not yet have a value. - * - * @var int - */ - protected $itemsLeft; -} diff --git a/lib/vendor/sabre/dav/lib/DAV/PropPatch.php b/lib/vendor/sabre/dav/lib/DAV/PropPatch.php deleted file mode 100644 index 092909d..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/PropPatch.php +++ /dev/null @@ -1,337 +0,0 @@ -mutations = $mutations; - } - - /** - * Call this function if you wish to handle updating certain properties. - * For instance, your class may be responsible for handling updates for the - * {DAV:}displayname property. - * - * In that case, call this method with the first argument - * "{DAV:}displayname" and a second argument that's a method that does the - * actual updating. - * - * It's possible to specify more than one property as an array. - * - * The callback must return a boolean or an it. If the result is true, the - * operation was considered successful. If it's false, it's consided - * failed. - * - * If the result is an integer, we'll use that integer as the http status - * code associated with the operation. - * - * @param string|string[] $properties - */ - public function handle($properties, callable $callback) - { - $usedProperties = []; - foreach ((array) $properties as $propertyName) { - if (array_key_exists($propertyName, $this->mutations) && !isset($this->result[$propertyName])) { - $usedProperties[] = $propertyName; - // HTTP Accepted - $this->result[$propertyName] = 202; - } - } - - // Only registering if there's any unhandled properties. - if (!$usedProperties) { - return; - } - $this->propertyUpdateCallbacks[] = [ - // If the original argument to this method was a string, we need - // to also make sure that it stays that way, so the commit function - // knows how to format the arguments to the callback. - is_string($properties) ? $properties : $usedProperties, - $callback, - ]; - } - - /** - * Call this function if you wish to handle _all_ properties that haven't - * been handled by anything else yet. Note that you effectively claim with - * this that you promise to process _all_ properties that are coming in. - */ - public function handleRemaining(callable $callback) - { - $properties = $this->getRemainingMutations(); - if (!$properties) { - // Nothing to do, don't register callback - return; - } - - foreach ($properties as $propertyName) { - // HTTP Accepted - $this->result[$propertyName] = 202; - - $this->propertyUpdateCallbacks[] = [ - $properties, - $callback, - ]; - } - } - - /** - * Sets the result code for one or more properties. - * - * @param string|string[] $properties - * @param int $resultCode - */ - public function setResultCode($properties, $resultCode) - { - foreach ((array) $properties as $propertyName) { - $this->result[$propertyName] = $resultCode; - } - - if ($resultCode >= 400) { - $this->failed = true; - } - } - - /** - * Sets the result code for all properties that did not have a result yet. - * - * @param int $resultCode - */ - public function setRemainingResultCode($resultCode) - { - $this->setResultCode( - $this->getRemainingMutations(), - $resultCode - ); - } - - /** - * Returns the list of properties that don't have a result code yet. - * - * This method returns a list of property names, but not its values. - * - * @return string[] - */ - public function getRemainingMutations() - { - $remaining = []; - foreach ($this->mutations as $propertyName => $propValue) { - if (!isset($this->result[$propertyName])) { - $remaining[] = $propertyName; - } - } - - return $remaining; - } - - /** - * Returns the list of properties that don't have a result code yet. - * - * This method returns list of properties and their values. - * - * @return array - */ - public function getRemainingValues() - { - $remaining = []; - foreach ($this->mutations as $propertyName => $propValue) { - if (!isset($this->result[$propertyName])) { - $remaining[$propertyName] = $propValue; - } - } - - return $remaining; - } - - /** - * Performs the actual update, and calls all callbacks. - * - * This method returns true or false depending on if the operation was - * successful. - * - * @return bool - */ - public function commit() - { - // First we validate if every property has a handler - foreach ($this->mutations as $propertyName => $value) { - if (!isset($this->result[$propertyName])) { - $this->failed = true; - $this->result[$propertyName] = 403; - } - } - - foreach ($this->propertyUpdateCallbacks as $callbackInfo) { - if ($this->failed) { - break; - } - if (is_string($callbackInfo[0])) { - $this->doCallbackSingleProp($callbackInfo[0], $callbackInfo[1]); - } else { - $this->doCallbackMultiProp($callbackInfo[0], $callbackInfo[1]); - } - } - - /* - * If anywhere in this operation updating a property failed, we must - * update all other properties accordingly. - */ - if ($this->failed) { - foreach ($this->result as $propertyName => $status) { - if (202 === $status) { - // Failed dependency - $this->result[$propertyName] = 424; - } - } - } - - return !$this->failed; - } - - /** - * Executes a property callback with the single-property syntax. - * - * @param string $propertyName - */ - private function doCallBackSingleProp($propertyName, callable $callback) - { - $result = $callback($this->mutations[$propertyName]); - if (is_bool($result)) { - if ($result) { - if (is_null($this->mutations[$propertyName])) { - // Delete - $result = 204; - } else { - // Update - $result = 200; - } - } else { - // Fail - $result = 403; - } - } - if (!is_int($result)) { - throw new UnexpectedValueException('A callback sent to handle() did not return an int or a bool'); - } - $this->result[$propertyName] = $result; - if ($result >= 400) { - $this->failed = true; - } - } - - /** - * Executes a property callback with the multi-property syntax. - */ - private function doCallBackMultiProp(array $propertyList, callable $callback) - { - $argument = []; - foreach ($propertyList as $propertyName) { - $argument[$propertyName] = $this->mutations[$propertyName]; - } - - $result = $callback($argument); - - if (is_array($result)) { - foreach ($propertyList as $propertyName) { - if (!isset($result[$propertyName])) { - $resultCode = 500; - } else { - $resultCode = $result[$propertyName]; - } - if ($resultCode >= 400) { - $this->failed = true; - } - $this->result[$propertyName] = $resultCode; - } - } elseif (true === $result) { - // Success - foreach ($argument as $propertyName => $propertyValue) { - $this->result[$propertyName] = is_null($propertyValue) ? 204 : 200; - } - } elseif (false === $result) { - // Fail :( - $this->failed = true; - foreach ($propertyList as $propertyName) { - $this->result[$propertyName] = 403; - } - } else { - throw new UnexpectedValueException('A callback sent to handle() did not return an array or a bool'); - } - } - - /** - * Returns the result of the operation. - * - * @return array - */ - public function getResult() - { - return $this->result; - } - - /** - * Returns the full list of mutations. - * - * @return array - */ - public function getMutations() - { - return $this->mutations; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php b/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php deleted file mode 100644 index 64a8825..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/BackendInterface.php +++ /dev/null @@ -1,75 +0,0 @@ -isAllProps(). - * - * @param string $path - */ - public function propFind($path, PropFind $propFind); - - /** - * Updates properties for a path. - * - * This method received a PropPatch object, which contains all the - * information about the update. - * - * Usually you would want to call 'handleRemaining' on this object, to get; - * a list of all properties that need to be stored. - * - * @param string $path - */ - public function propPatch($path, PropPatch $propPatch); - - /** - * This method is called after a node is deleted. - * - * This allows a backend to clean up all associated properties. - * - * The delete method will get called once for the deletion of an entire - * tree. - * - * @param string $path - */ - public function delete($path); - - /** - * This method is called after a successful MOVE. - * - * This should be used to migrate all properties from one path to another. - * Note that entire collections may be moved, so ensure that all properties - * for children are also moved along. - * - * @param string $source - * @param string $destination - */ - public function move($source, $destination); -} diff --git a/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php b/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php deleted file mode 100644 index 8960331..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php +++ /dev/null @@ -1,224 +0,0 @@ -pdo = $pdo; - } - - /** - * Fetches properties for a path. - * - * This method received a PropFind object, which contains all the - * information about the properties that need to be fetched. - * - * Usually you would just want to call 'get404Properties' on this object, - * as this will give you the _exact_ list of properties that need to be - * fetched, and haven't yet. - * - * However, you can also support the 'allprops' property here. In that - * case, you should check for $propFind->isAllProps(). - * - * @param string $path - */ - public function propFind($path, PropFind $propFind) - { - if (!$propFind->isAllProps() && 0 === count($propFind->get404Properties())) { - return; - } - - $query = 'SELECT name, value, valuetype FROM '.$this->tableName.' WHERE path = ?'; - $stmt = $this->pdo->prepare($query); - $stmt->execute([$path]); - - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - if ('resource' === gettype($row['value'])) { - $row['value'] = stream_get_contents($row['value']); - } - switch ($row['valuetype']) { - case null: - case self::VT_STRING: - $propFind->set($row['name'], $row['value']); - break; - case self::VT_XML: - $propFind->set($row['name'], new Complex($row['value'])); - break; - case self::VT_OBJECT: - $propFind->set($row['name'], unserialize($row['value'])); - break; - } - } - } - - /** - * Updates properties for a path. - * - * This method received a PropPatch object, which contains all the - * information about the update. - * - * Usually you would want to call 'handleRemaining' on this object, to get; - * a list of all properties that need to be stored. - * - * @param string $path - */ - public function propPatch($path, PropPatch $propPatch) - { - $propPatch->handleRemaining(function ($properties) use ($path) { - if ('pgsql' === $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME)) { - $updateSql = <<tableName} (path, name, valuetype, value) -VALUES (:path, :name, :valuetype, :value) -ON CONFLICT (path, name) -DO UPDATE SET valuetype = :valuetype, value = :value -SQL; - } else { - $updateSql = <<tableName} (path, name, valuetype, value) -VALUES (:path, :name, :valuetype, :value) -SQL; - } - - $updateStmt = $this->pdo->prepare($updateSql); - $deleteStmt = $this->pdo->prepare('DELETE FROM '.$this->tableName.' WHERE path = ? AND name = ?'); - - foreach ($properties as $name => $value) { - if (!is_null($value)) { - if (is_scalar($value)) { - $valueType = self::VT_STRING; - } elseif ($value instanceof Complex) { - $valueType = self::VT_XML; - $value = $value->getXml(); - } else { - $valueType = self::VT_OBJECT; - $value = serialize($value); - } - - $updateStmt->bindParam('path', $path, \PDO::PARAM_STR); - $updateStmt->bindParam('name', $name, \PDO::PARAM_STR); - $updateStmt->bindParam('valuetype', $valueType, \PDO::PARAM_INT); - $updateStmt->bindParam('value', $value, \PDO::PARAM_LOB); - - $updateStmt->execute(); - } else { - $deleteStmt->execute([$path, $name]); - } - } - - return true; - }); - } - - /** - * This method is called after a node is deleted. - * - * This allows a backend to clean up all associated properties. - * - * The delete method will get called once for the deletion of an entire - * tree. - * - * @param string $path - */ - public function delete($path) - { - $stmt = $this->pdo->prepare('DELETE FROM '.$this->tableName." WHERE path = ? OR path LIKE ? ESCAPE '='"); - $childPath = strtr( - $path, - [ - '=' => '==', - '%' => '=%', - '_' => '=_', - ] - ).'/%'; - - $stmt->execute([$path, $childPath]); - } - - /** - * This method is called after a successful MOVE. - * - * This should be used to migrate all properties from one path to another. - * Note that entire collections may be moved, so ensure that all properties - * for children are also moved along. - * - * @param string $source - * @param string $destination - */ - public function move($source, $destination) - { - // I don't know a way to write this all in a single sql query that's - // also compatible across db engines, so we're letting PHP do all the - // updates. Much slower, but it should still be pretty fast in most - // cases. - $select = $this->pdo->prepare('SELECT id, path FROM '.$this->tableName.' WHERE path = ? OR path LIKE ?'); - $select->execute([$source, $source.'/%']); - - $update = $this->pdo->prepare('UPDATE '.$this->tableName.' SET path = ? WHERE id = ?'); - while ($row = $select->fetch(\PDO::FETCH_ASSOC)) { - // Sanity check. SQL may select too many records, such as records - // with different cases. - if ($row['path'] !== $source && 0 !== strpos($row['path'], $source.'/')) { - continue; - } - - $trailingPart = substr($row['path'], strlen($source) + 1); - $newPath = $destination; - if ($trailingPart) { - $newPath .= '/'.$trailingPart; - } - $update->execute([$newPath, $row['id']]); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php b/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php deleted file mode 100644 index da47ec9..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/PropertyStorage/Plugin.php +++ /dev/null @@ -1,176 +0,0 @@ -backend = $backend; - } - - /** - * This initializes the plugin. - * - * This function is called by Sabre\DAV\Server, after - * addPlugin is called. - * - * This method should set up the required event subscriptions. - */ - public function initialize(Server $server) - { - $server->on('propFind', [$this, 'propFind'], 130); - $server->on('propPatch', [$this, 'propPatch'], 300); - $server->on('afterMove', [$this, 'afterMove']); - $server->on('afterUnbind', [$this, 'afterUnbind']); - } - - /** - * Called during PROPFIND operations. - * - * If there's any requested properties that don't have a value yet, this - * plugin will look in the property storage backend to find them. - */ - public function propFind(PropFind $propFind, INode $node) - { - $path = $propFind->getPath(); - $pathFilter = $this->pathFilter; - if ($pathFilter && !$pathFilter($path)) { - return; - } - $this->backend->propFind($propFind->getPath(), $propFind); - } - - /** - * Called during PROPPATCH operations. - * - * If there's any updated properties that haven't been stored, the - * propertystorage backend can handle it. - * - * @param string $path - */ - public function propPatch($path, PropPatch $propPatch) - { - $pathFilter = $this->pathFilter; - if ($pathFilter && !$pathFilter($path)) { - return; - } - $this->backend->propPatch($path, $propPatch); - } - - /** - * Called after a node is deleted. - * - * This allows the backend to clean up any properties still in the - * database. - * - * @param string $path - */ - public function afterUnbind($path) - { - $pathFilter = $this->pathFilter; - if ($pathFilter && !$pathFilter($path)) { - return; - } - $this->backend->delete($path); - } - - /** - * Called after a node is moved. - * - * This allows the backend to move all the associated properties. - * - * @param string $source - * @param string $destination - */ - public function afterMove($source, $destination) - { - $pathFilter = $this->pathFilter; - if ($pathFilter && !$pathFilter($source)) { - return; - } - // If the destination is filtered, afterUnbind will handle cleaning up - // the properties. - if ($pathFilter && !$pathFilter($destination)) { - return; - } - - $this->backend->move($source, $destination); - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using \Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'property-storage'; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'This plugin allows any arbitrary WebDAV property to be set on any resource.', - 'link' => 'http://sabre.io/dav/property-storage/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Server.php b/lib/vendor/sabre/dav/lib/DAV/Server.php deleted file mode 100644 index 3133e54..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Server.php +++ /dev/null @@ -1,1682 +0,0 @@ - '{DAV:}collection', - ]; - - /** - * This property allows the usage of Depth: infinity on PROPFIND requests. - * - * By default Depth: infinity is treated as Depth: 1. Allowing Depth: - * infinity is potentially risky, as it allows a single client to do a full - * index of the webdav server, which is an easy DoS attack vector. - * - * Only turn this on if you know what you're doing. - * - * @var bool - */ - public $enablePropfindDepthInfinity = false; - - /** - * Reference to the XML utility object. - * - * @var Xml\Service - */ - public $xml; - - /** - * 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 - */ - public static $exposeVersion = true; - - /** - * If this setting is turned on, any multi status response on any PROPFIND will be streamed to the output buffer. - * This will be beneficial for large result sets which will no longer consume a large amount of memory as well as - * send back data to the client earlier. - * - * @var bool - */ - public static $streamMultiStatus = false; - - /** - * Sets up the server. - * - * If a Sabre\DAV\Tree object is passed as an argument, it will - * use it as the directory tree. If a Sabre\DAV\INode is passed, it - * will create a Sabre\DAV\Tree and use the node as the root. - * - * If nothing is passed, a Sabre\DAV\SimpleCollection is created in - * a Sabre\DAV\Tree. - * - * If an array is passed, we automatically create a root node, and use - * the nodes in the array as top-level children. - * - * @param Tree|INode|array|null $treeOrNode The tree object - * - * @throws Exception - */ - public function __construct($treeOrNode = null, ?HTTP\Sapi $sapi = null) - { - if ($treeOrNode instanceof Tree) { - $this->tree = $treeOrNode; - } elseif ($treeOrNode instanceof INode) { - $this->tree = new Tree($treeOrNode); - } elseif (is_array($treeOrNode)) { - $root = new SimpleCollection('root', $treeOrNode); - $this->tree = new Tree($root); - } elseif (is_null($treeOrNode)) { - $root = new SimpleCollection('root'); - $this->tree = new Tree($root); - } else { - throw new Exception('Invalid argument passed to constructor. Argument must either be an instance of Sabre\\DAV\\Tree, Sabre\\DAV\\INode, an array or null'); - } - - $this->xml = new Xml\Service(); - $this->sapi = $sapi ?? new HTTP\Sapi(); - $this->httpResponse = new HTTP\Response(); - $this->httpRequest = $this->sapi->getRequest(); - $this->addPlugin(new CorePlugin()); - } - - /** - * Starts the DAV Server. - */ - public function start() - { - try { - // If nginx (pre-1.2) is used as a proxy server, and SabreDAV as an - // origin, we must make sure we send back HTTP/1.0 if this was - // requested. - // This is mainly because nginx doesn't support Chunked Transfer - // Encoding, and this forces the webserver SabreDAV is running on, - // to buffer entire responses to calculate Content-Length. - $this->httpResponse->setHTTPVersion($this->httpRequest->getHTTPVersion()); - - // Setting the base url - $this->httpRequest->setBaseUrl($this->getBaseUri()); - $this->invokeMethod($this->httpRequest, $this->httpResponse); - } catch (\Throwable $e) { - try { - $this->emit('exception', [$e]); - } catch (\Exception $ignore) { - } - $DOM = new \DOMDocument('1.0', 'utf-8'); - $DOM->formatOutput = true; - - $error = $DOM->createElementNS('DAV:', 'd:error'); - $error->setAttribute('xmlns:s', self::NS_SABREDAV); - $DOM->appendChild($error); - - $h = function ($v) { - return htmlspecialchars((string) $v, ENT_NOQUOTES, 'UTF-8'); - }; - - if (self::$exposeVersion) { - $error->appendChild($DOM->createElement('s:sabredav-version', $h(Version::VERSION))); - } - - $error->appendChild($DOM->createElement('s:exception', $h(get_class($e)))); - $error->appendChild($DOM->createElement('s:message', $h($e->getMessage()))); - if ($this->debugExceptions) { - $error->appendChild($DOM->createElement('s:file', $h($e->getFile()))); - $error->appendChild($DOM->createElement('s:line', $h($e->getLine()))); - $error->appendChild($DOM->createElement('s:code', $h($e->getCode()))); - $error->appendChild($DOM->createElement('s:stacktrace', $h($e->getTraceAsString()))); - } - - if ($this->debugExceptions) { - $previous = $e; - while ($previous = $previous->getPrevious()) { - $xPrevious = $DOM->createElement('s:previous-exception'); - $xPrevious->appendChild($DOM->createElement('s:exception', $h(get_class($previous)))); - $xPrevious->appendChild($DOM->createElement('s:message', $h($previous->getMessage()))); - $xPrevious->appendChild($DOM->createElement('s:file', $h($previous->getFile()))); - $xPrevious->appendChild($DOM->createElement('s:line', $h($previous->getLine()))); - $xPrevious->appendChild($DOM->createElement('s:code', $h($previous->getCode()))); - $xPrevious->appendChild($DOM->createElement('s:stacktrace', $h($previous->getTraceAsString()))); - $error->appendChild($xPrevious); - } - } - - if ($e instanceof Exception) { - $httpCode = $e->getHTTPCode(); - $e->serialize($this, $error); - $headers = $e->getHTTPHeaders($this); - } else { - $httpCode = 500; - $headers = []; - } - $headers['Content-Type'] = 'application/xml; charset=utf-8'; - - $this->httpResponse->setStatus($httpCode); - $this->httpResponse->setHeaders($headers); - $this->httpResponse->setBody($DOM->saveXML()); - $this->sapi->sendResponse($this->httpResponse); - } - } - - /** - * Alias of start(). - * - * @deprecated - */ - public function exec() - { - $this->start(); - } - - /** - * Sets the base server uri. - * - * @param string $uri - */ - public function setBaseUri($uri) - { - // If the baseUri does not end with a slash, we must add it - if ('/' !== $uri[strlen($uri) - 1]) { - $uri .= '/'; - } - - $this->baseUri = $uri; - } - - /** - * Returns the base responding uri. - * - * @return string - */ - public function getBaseUri() - { - if (is_null($this->baseUri)) { - $this->baseUri = $this->guessBaseUri(); - } - - return $this->baseUri; - } - - /** - * 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. - * - * @return string - */ - public function guessBaseUri() - { - $pathInfo = $this->httpRequest->getRawServerValue('PATH_INFO'); - $uri = $this->httpRequest->getRawServerValue('REQUEST_URI'); - - // If PATH_INFO is found, we can assume it's accurate. - if (!empty($pathInfo)) { - // We need to make sure we ignore the QUERY_STRING part - if ($pos = strpos($uri, '?')) { - $uri = substr($uri, 0, $pos); - } - - // PATH_INFO is only set for urls, such as: /example.php/path - // in that case PATH_INFO contains '/path'. - // Note that REQUEST_URI is percent encoded, while PATH_INFO is - // not, Therefore they are only comparable if we first decode - // REQUEST_INFO as well. - $decodedUri = HTTP\decodePath($uri); - - // A simple sanity check: - if (substr($decodedUri, strlen($decodedUri) - strlen($pathInfo)) === $pathInfo) { - $baseUri = substr($decodedUri, 0, strlen($decodedUri) - strlen($pathInfo)); - - return rtrim($baseUri, '/').'/'; - } - - throw new 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. - return '/'; - } - - /** - * Adds a plugin to the server. - * - * For more information, console the documentation of Sabre\DAV\ServerPlugin - */ - public function addPlugin(ServerPlugin $plugin) - { - $this->plugins[$plugin->getPluginName()] = $plugin; - $plugin->initialize($this); - } - - /** - * Returns an initialized plugin by it's name. - * - * This function returns null if the plugin was not found. - * - * @param string $name - * - * @return ServerPlugin - */ - public function getPlugin($name) - { - if (isset($this->plugins[$name])) { - return $this->plugins[$name]; - } - - return null; - } - - /** - * Returns all plugins. - * - * @return array - */ - public function getPlugins() - { - return $this->plugins; - } - - /** - * Returns the PSR-3 logger object. - * - * @return LoggerInterface - */ - public function getLogger() - { - if (!$this->logger) { - $this->logger = new NullLogger(); - } - - return $this->logger; - } - - /** - * Handles a http request, and execute a method based on its name. - * - * @param bool $sendResponse whether to send the HTTP response to the DAV client - */ - public function invokeMethod(RequestInterface $request, ResponseInterface $response, $sendResponse = true) - { - $method = $request->getMethod(); - - if (!$this->emit('beforeMethod:'.$method, [$request, $response])) { - return; - } - - if (self::$exposeVersion) { - $response->setHeader('X-Sabre-Version', Version::VERSION); - } - - $this->transactionType = strtolower($method); - - if (!$this->checkPreconditions($request, $response)) { - $this->sapi->sendResponse($response); - - return; - } - - if ($this->emit('method:'.$method, [$request, $response])) { - $exMessage = 'There was no plugin in the system that was willing to handle this '.$method.' method.'; - if ('GET' === $method) { - $exMessage .= ' Enable the Browser plugin to get a better result here.'; - } - - // Unsupported method - throw new Exception\NotImplemented($exMessage); - } - - if (!$this->emit('afterMethod:'.$method, [$request, $response])) { - return; - } - - if (null === $response->getStatus()) { - throw new Exception('No subsystem set a valid HTTP status code. Something must have interrupted the request without providing further detail.'); - } - if ($sendResponse) { - $this->sapi->sendResponse($response); - $this->emit('afterResponse', [$request, $response]); - } - } - - // {{{ HTTP/WebDAV protocol helpers - - /** - * Returns an array with all the supported HTTP methods for a specific uri. - * - * @param string $path - * - * @return array - */ - public function getAllowedMethods($path) - { - $methods = [ - 'OPTIONS', - 'GET', - 'HEAD', - 'DELETE', - 'PROPFIND', - 'PUT', - 'PROPPATCH', - 'COPY', - 'MOVE', - 'REPORT', - ]; - - // The MKCOL is only allowed on an unmapped uri - try { - $this->tree->getNodeForPath($path); - } catch (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($path)); - } - array_unique($methods); - - return $methods; - } - - /** - * Gets the uri for the request, keeping the base uri into consideration. - * - * @return string - */ - public function getRequestUri() - { - return $this->calculateUri($this->httpRequest->getUrl()); - } - - /** - * Turns a URI such as the REQUEST_URI into a local path. - * - * This method: - * * strips off the base path - * * normalizes the path - * * uri-decodes the path - * - * @param string $uri - * - * @throws Exception\Forbidden A permission denied exception is thrown whenever there was an attempt to supply a uri outside of the base uri - * - * @return string - */ - public function calculateUri($uri) - { - if ('' != $uri && '/' != $uri[0] && strpos($uri, '://')) { - $uri = parse_url($uri, PHP_URL_PATH); - } - - $uri = Uri\normalize(preg_replace('|/+|', '/', $uri)); - $baseUri = Uri\normalize($this->getBaseUri()); - - if (0 === strpos($uri, $baseUri)) { - return trim(HTTP\decodePath(substr($uri, strlen($baseUri))), '/'); - - // A special case, if the baseUri was accessed without a trailing - // slash, we'll accept it as well. - } elseif ($uri.'/' === $baseUri) { - return ''; - } else { - throw new Exception\Forbidden('Requested uri ('.$uri.') is out of base uri ('.$this->getBaseUri().')'); - } - } - - /** - * 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-existent - * - * @param mixed $default - * - * @return int - */ - public function getHTTPDepth($default = self::DEPTH_INFINITY) - { - // If its not set, we'll grab the default - $depth = $this->httpRequest->getHeader('Depth'); - - if (is_null($depth)) { - return $default; - } - - if ('infinity' == $depth) { - return self::DEPTH_INFINITY; - } - - // If its an unknown value. we'll grab the default - if (!ctype_digit($depth)) { - return $default; - } - - return (int) $depth; - } - - /** - * Returns the HTTP range header. - * - * This method returns null if there is no well-formed HTTP range request - * header or array($start, $end). - * - * The first number is the offset of the first byte in the range. - * 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 - * - * @return int[]|null - */ - public function getHTTPRange() - { - $range = $this->httpRequest->getHeader('range'); - if (is_null($range)) { - return null; - } - - // Matching "Range: bytes=1234-5678: both numbers are optional - - if (!preg_match('/^bytes=([0-9]*)-([0-9]*)$/i', $range, $matches)) { - return null; - } - - if ('' === $matches[1] && '' === $matches[2]) { - return null; - } - - return [ - '' !== $matches[1] ? (int) $matches[1] : null, - '' !== $matches[2] ? (int) $matches[2] : null, - ]; - } - - /** - * Returns the HTTP Prefer header information. - * - * The prefer header is defined in: - * http://tools.ietf.org/html/draft-snell-http-prefer-14 - * - * This method will return an array with options. - * - * Currently, the following options may be returned: - * [ - * 'return-asynch' => true, - * 'return-minimal' => true, - * 'return-representation' => true, - * 'wait' => 30, - * 'strict' => true, - * 'lenient' => true, - * ] - * - * This method also supports the Brief header, and will also return - * 'return-minimal' if the brief header was set to 't'. - * - * For the boolean options, false will be returned if the headers are not - * specified. For the integer options it will be 'null'. - * - * @return array - */ - public function getHTTPPrefer() - { - $result = [ - // can be true or false - 'respond-async' => false, - // Could be set to 'representation' or 'minimal'. - 'return' => null, - // Used as a timeout, is usually a number. - 'wait' => null, - // can be 'strict' or 'lenient'. - 'handling' => false, - ]; - - if ($prefer = $this->httpRequest->getHeader('Prefer')) { - $result = array_merge( - $result, - HTTP\parsePrefer($prefer) - ); - } elseif ('t' == $this->httpRequest->getHeader('Brief')) { - $result['return'] = 'minimal'; - } - - return $result; - } - - /** - * 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 - * - * The returned value is an array with the following keys: - * * destination - Destination path - * * destinationExists - Whether or not the destination is an existing url (and should therefore be overwritten) - * - * @throws Exception\BadRequest upon missing or broken request headers - * @throws Exception\UnsupportedMediaType when trying to copy into a - * non-collection - * @throws Exception\PreconditionFailed if overwrite is set to false, but - * the destination exists - * @throws Exception\Forbidden when source and destination paths are - * identical - * @throws Exception\Conflict when trying to copy a node into its own - * subtree - * - * @return array - */ - public function getCopyAndMoveInfo(RequestInterface $request) - { - // Collecting the relevant HTTP headers - if (!$request->getHeader('Destination')) { - throw new Exception\BadRequest('The destination header was not supplied'); - } - $destination = $this->calculateUri($request->getHeader('Destination')); - $overwrite = $request->getHeader('Overwrite'); - if (!$overwrite) { - $overwrite = 'T'; - } - if ('T' == strtoupper($overwrite)) { - $overwrite = true; - } elseif ('F' == strtoupper($overwrite)) { - $overwrite = false; - } - // We need to throw a bad request exception, if the header was invalid - else { - throw new Exception\BadRequest('The HTTP Overwrite header should be either T or F'); - } - list($destinationDir) = Uri\split($destination); - - try { - $destinationParent = $this->tree->getNodeForPath($destinationDir); - if (!($destinationParent instanceof ICollection)) { - throw new Exception\UnsupportedMediaType('The destination node is not a collection'); - } - } catch (Exception\NotFound $e) { - // If the destination parent node is not found, we throw a 409 - throw new Exception\Conflict('The destination node is not found'); - } - - 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 Exception\PreconditionFailed('The destination node already exists, and the overwrite header is set to false', 'Overwrite'); - } - } catch (Exception\NotFound $e) { - // Destination didn't exist, we're all good - $destinationNode = false; - } - - $requestPath = $request->getPath(); - if ($destination === $requestPath) { - throw new Exception\Forbidden('Source and destination uri are identical.'); - } - if (substr($destination, 0, strlen($requestPath) + 1) === $requestPath.'/') { - throw new Exception\Conflict('The destination may not be part of the same subtree as the source path.'); - } - - // These are the three relevant properties we need to return - return [ - 'destination' => $destination, - 'destinationExists' => (bool) $destinationNode, - 'destinationNode' => $destinationNode, - ]; - } - - /** - * Returns a list of properties for a path. - * - * This is a simplified version getPropertiesForPath. If you aren't - * interested in status codes, but you just want to have a flat list of - * properties, use this method. - * - * Please note though that any problems related to retrieving properties, - * such as permission issues will just result in an empty array being - * returned. - * - * @param string $path - * @param array $propertyNames - * - * @return array - */ - public function getProperties($path, $propertyNames) - { - $result = $this->getPropertiesForPath($path, $propertyNames, 0); - if (isset($result[0][200])) { - return $result[0][200]; - } else { - return []; - } - } - - /** - * 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 = []; - foreach ($this->getPropertiesForPath($path, $propertyNames, 1) as $k => $row) { - // Skipping the parent path - if (0 === $k) { - 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 - * 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 = [ - '{DAV:}getcontenttype' => 'Content-Type', - '{DAV:}getcontentlength' => 'Content-Length', - '{DAV:}getlastmodified' => 'Last-Modified', - '{DAV:}getetag' => 'ETag', - ]; - - $properties = $this->getProperties($path, array_keys($propertyMap)); - - $headers = []; - foreach ($propertyMap as $property => $header) { - if (!isset($properties[$property])) { - continue; - } - - if (is_scalar($properties[$property])) { - $headers[$header] = $properties[$property]; - - // GetLastModified gets special cased - } elseif ($properties[$property] instanceof Xml\Property\GetLastModified) { - $headers[$header] = HTTP\toDate($properties[$property]->getTime()); - } - } - - return $headers; - } - - /** - * Small helper to support PROPFIND with DEPTH_INFINITY. - * - * @param array $yieldFirst - * - * @return \Traversable - */ - private function generatePathNodes(PropFind $propFind, ?array $yieldFirst = null) - { - if (null !== $yieldFirst) { - yield $yieldFirst; - } - $newDepth = $propFind->getDepth(); - $path = $propFind->getPath(); - - if (self::DEPTH_INFINITY !== $newDepth) { - --$newDepth; - } - - $propertyNames = $propFind->getRequestedProperties(); - $propFindType = !$propFind->isAllProps() ? PropFind::NORMAL : PropFind::ALLPROPS; - - foreach ($this->tree->getChildren($path) as $childNode) { - if ('' !== $path) { - $subPath = $path.'/'.$childNode->getName(); - } else { - $subPath = $childNode->getName(); - } - $subPropFind = new PropFind($subPath, $propertyNames, $newDepth, $propFindType); - - yield [ - $subPropFind, - $childNode, - ]; - - if ((self::DEPTH_INFINITY === $newDepth || $newDepth >= 1) && $childNode instanceof ICollection) { - foreach ($this->generatePathNodes($subPropFind) as $subItem) { - yield $subItem; - } - } - } - } - - /** - * 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 array $propertyNames - * @param int $depth - * - * @return array - * - * @deprecated Use getPropertiesIteratorForPath() instead (as it's more memory efficient) - * @see getPropertiesIteratorForPath() - */ - public function getPropertiesForPath($path, $propertyNames = [], $depth = 0) - { - return iterator_to_array($this->getPropertiesIteratorForPath($path, $propertyNames, $depth)); - } - - /** - * 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 array $propertyNames - * @param int $depth - * - * @return \Iterator - */ - public function getPropertiesIteratorForPath($path, $propertyNames = [], $depth = 0) - { - // The only two options for the depth of a propfind is 0 or 1 - as long as depth infinity is not enabled - if (!$this->enablePropfindDepthInfinity && 0 != $depth) { - $depth = 1; - } - - $path = trim($path, '/'); - - $propFindType = $propertyNames ? PropFind::NORMAL : PropFind::ALLPROPS; - $propFind = new PropFind($path, (array) $propertyNames, $depth, $propFindType); - - $parentNode = $this->tree->getNodeForPath($path); - - $propFindRequests = [[ - $propFind, - $parentNode, - ]]; - - if (($depth > 0 || self::DEPTH_INFINITY === $depth) && $parentNode instanceof ICollection) { - $propFindRequests = $this->generatePathNodes(clone $propFind, current($propFindRequests)); - } - - foreach ($propFindRequests as $propFindRequest) { - list($propFind, $node) = $propFindRequest; - $r = $this->getPropertiesByNode($propFind, $node); - if ($r) { - $result = $propFind->getResultForMultiStatus(); - $result['href'] = $propFind->getPath(); - - // WebDAV recommends adding a slash to the path, if the path is - // a collection. - // Furthermore, iCal also demands this to be the case for - // principals. This is non-standard, but we support it. - $resourceType = $this->getResourceTypeForNode($node); - if (in_array('{DAV:}collection', $resourceType) || in_array('{DAV:}principal', $resourceType)) { - $result['href'] .= '/'; - } - yield $result; - } - } - } - - /** - * Returns a list of properties for a list of paths. - * - * 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. - * - * The result is returned as an array, with paths for it's keys. - * The result may be returned out of order. - * - * @return array - */ - public function getPropertiesForMultiplePaths(array $paths, array $propertyNames = []) - { - $result = [ - ]; - - $nodes = $this->tree->getMultipleNodes($paths); - - foreach ($nodes as $path => $node) { - $propFind = new PropFind($path, $propertyNames); - $r = $this->getPropertiesByNode($propFind, $node); - if ($r) { - $result[$path] = $propFind->getResultForMultiStatus(); - $result[$path]['href'] = $path; - - $resourceType = $this->getResourceTypeForNode($node); - if (in_array('{DAV:}collection', $resourceType) || in_array('{DAV:}principal', $resourceType)) { - $result[$path]['href'] .= '/'; - } - } - } - - return $result; - } - - /** - * Determines all properties for a node. - * - * This method tries to grab all properties for a node. This method is used - * internally getPropertiesForPath and a few others. - * - * It could be useful to call this, if you already have an instance of your - * target node and simply want to run through the system to get a correct - * list of properties. - * - * @return bool - */ - public function getPropertiesByNode(PropFind $propFind, INode $node) - { - return $this->emit('propFind', [$propFind, $node]); - } - - /** - * 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, - * 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 - * @param string $etag - * - * @return bool - */ - public function createFile($uri, $data, &$etag = null) - { - list($dir, $name) = Uri\split($uri); - - if (!$this->emit('beforeBind', [$uri])) { - return false; - } - - try { - $parent = $this->tree->getNodeForPath($dir); - } catch (Exception\NotFound $e) { - throw new Exception\Conflict('Files cannot be created in non-existent collections'); - } - - if (!$parent instanceof ICollection) { - throw new Exception\Conflict('Files can only be created as children of collections'); - } - - // It is possible for an event handler to modify the content of the - // body, before it gets written. If this is the case, $modified - // should be set to true. - // - // If $modified is true, we must not send back an ETag. - $modified = false; - if (!$this->emit('beforeCreateFile', [$uri, &$data, $parent, &$modified])) { - return false; - } - - $etag = $parent->createFile($name, $data); - - if ($modified) { - $etag = null; - } - - $this->tree->markDirty($dir.'/'.$name); - - $this->emit('afterBind', [$uri]); - $this->emit('afterCreateFile', [$uri, $parent]); - - return true; - } - - /** - * This method is invoked by sub-systems updating a file. - * - * This method will return true if the file was actually updated - * - * @param string $uri - * @param resource $data - * @param string $etag - * - * @return bool - */ - public function updateFile($uri, $data, &$etag = null) - { - $node = $this->tree->getNodeForPath($uri); - - // It is possible for an event handler to modify the content of the - // body, before it gets written. If this is the case, $modified - // should be set to true. - // - // If $modified is true, we must not send back an ETag. - $modified = false; - if (!$this->emit('beforeWriteContent', [$uri, $node, &$data, &$modified])) { - return false; - } - - $etag = $node->put($data); - if ($modified) { - $etag = null; - } - $this->emit('afterWriteContent', [$uri, $node]); - - return true; - } - - /** - * This method is invoked by sub-systems creating a new directory. - * - * @param string $uri - */ - public function createDirectory($uri) - { - $this->createCollection($uri, new MkCol(['{DAV:}collection'], [])); - } - - /** - * Use this method to create a new collection. - * - * @param string $uri The new uri - * - * @return array|null - */ - public function createCollection($uri, MkCol $mkCol) - { - list($parentUri, $newName) = Uri\split($uri); - - // Making sure the parent exists - try { - $parent = $this->tree->getNodeForPath($parentUri); - } catch (Exception\NotFound $e) { - throw new Exception\Conflict('Parent node does not exist'); - } - - // Making sure the parent is a collection - if (!$parent instanceof ICollection) { - throw new Exception\Conflict('Parent node is not a collection'); - } - - // Making sure the child does not already exist - try { - $parent->getChild($newName); - - // If we got here.. it means there's already a node on that url, and we need to throw a 405 - throw new Exception\MethodNotAllowed('The resource you tried to create already exists'); - } catch (Exception\NotFound $e) { - // NotFound is the expected behavior. - } - - if (!$this->emit('beforeBind', [$uri])) { - return; - } - - if ($parent instanceof IExtendedCollection) { - /* - * If the parent is an instance of IExtendedCollection, it means that - * we can pass the MkCol object directly as it may be able to store - * properties immediately. - */ - $parent->createExtendedCollection($newName, $mkCol); - } else { - /* - * If the parent is a standard ICollection, it means only - * 'standard' collections can be created, so we should fail any - * MKCOL operation that carries extra resourcetypes. - */ - if (count($mkCol->getResourceType()) > 1) { - throw new Exception\InvalidResourceType('The {DAV:}resourcetype you specified is not supported here.'); - } - - $parent->createDirectory($newName); - } - - // If there are any properties that have not been handled/stored, - // we ask the 'propPatch' event to handle them. This will allow for - // example the propertyStorage system to store properties upon MKCOL. - if ($mkCol->getRemainingMutations()) { - $this->emit('propPatch', [$uri, $mkCol]); - } - $success = $mkCol->commit(); - - if (!$success) { - $result = $mkCol->getResult(); - - $formattedResult = [ - 'href' => $uri, - ]; - - foreach ($result as $propertyName => $status) { - if (!isset($formattedResult[$status])) { - $formattedResult[$status] = []; - } - $formattedResult[$status][$propertyName] = null; - } - - return $formattedResult; - } - - $this->tree->markDirty($parentUri); - $this->emit('afterBind', [$uri]); - $this->emit('afterCreateCollection', [$uri]); - } - - /** - * This method updates a resource's properties. - * - * 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 - * completely fail. - * - * The response is an array with properties for keys, and http status codes - * as their values. - * - * @param string $path - * - * @return array - */ - public function updateProperties($path, array $properties) - { - $propPatch = new PropPatch($properties); - $this->emit('propPatch', [$path, $propPatch]); - $propPatch->commit(); - - return $propPatch->getResult(); - } - - /** - * This method checks the main HTTP preconditions. - * - * Currently these are: - * * If-Match - * * If-None-Match - * * If-Modified-Since - * * If-Unmodified-Since - * - * The method will return true if all preconditions are met - * The method will return false, or throw an exception if preconditions - * failed. If false is returned the operation should be aborted, and - * 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 - * set the status to 304 Not Modified for If-Modified_since. - * - * @return bool - */ - public function checkPreconditions(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - $node = null; - $lastMod = null; - $etag = null; - - if ($ifMatch = $request->getHeader('If-Match')) { - // If-Match contains an entity tag. Only if the entity-tag - // matches we are allowed to make the request succeed. - // If the entity-tag is '*' we are only allowed to make the - // request succeed if a resource exists at that url. - try { - $node = $this->tree->getNodeForPath($path); - } catch (Exception\NotFound $e) { - throw new Exception\PreconditionFailed('An If-Match header was specified and the resource did not exist', 'If-Match'); - } - - // Only need to check entity tags if they are not * - if ('*' !== $ifMatch) { - // There can be multiple ETags - $ifMatch = explode(',', $ifMatch); - $haveMatch = false; - foreach ($ifMatch as $ifMatchItem) { - // Stripping any extra spaces - $ifMatchItem = trim($ifMatchItem, ' '); - - $etag = $node instanceof IFile ? $node->getETag() : null; - if ($etag === $ifMatchItem) { - $haveMatch = true; - } else { - // Evolution has a bug where it sometimes prepends the " - // with a \. This is our workaround. - if (str_replace('\\"', '"', $ifMatchItem) === $etag) { - $haveMatch = true; - } - } - } - if (!$haveMatch) { - if ($etag) { - $response->setHeader('ETag', $etag); - } - throw new Exception\PreconditionFailed('An If-Match header was specified, but none of the specified ETags matched.', 'If-Match'); - } - } - } - - if ($ifNoneMatch = $request->getHeader('If-None-Match')) { - // The If-None-Match header contains an ETag. - // Only if the ETag does not match the current ETag, the request will succeed - // The header can also contain *, in which case the request - // will only succeed if the entity does not exist at all. - $nodeExists = true; - if (!$node) { - try { - $node = $this->tree->getNodeForPath($path); - } catch (Exception\NotFound $e) { - $nodeExists = false; - } - } - if ($nodeExists) { - $haveMatch = false; - if ('*' === $ifNoneMatch) { - $haveMatch = true; - } else { - // There might be multiple ETags - $ifNoneMatch = explode(',', $ifNoneMatch); - $etag = $node instanceof IFile ? $node->getETag() : null; - - foreach ($ifNoneMatch as $ifNoneMatchItem) { - // Stripping any extra spaces - $ifNoneMatchItem = trim($ifNoneMatchItem, ' '); - - if ($etag === $ifNoneMatchItem) { - $haveMatch = true; - } - } - } - - if ($haveMatch) { - if ($etag) { - $response->setHeader('ETag', $etag); - } - if ('GET' === $request->getMethod()) { - $response->setStatus(304); - - return false; - } else { - throw new Exception\PreconditionFailed('An If-None-Match header was specified, but the ETag matched (or * was specified).', 'If-None-Match'); - } - } - } - } - - if (!$ifNoneMatch && ($ifModifiedSince = $request->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 - // header - // Note that this header only has to be checked if there was no If-None-Match header - // as per the HTTP spec. - $date = HTTP\parseDate($ifModifiedSince); - - if ($date) { - if (is_null($node)) { - $node = $this->tree->getNodeForPath($path); - } - $lastMod = $node->getLastModified(); - if ($lastMod) { - $lastMod = new \DateTime('@'.$lastMod); - if ($lastMod <= $date) { - $response->setStatus(304); - $response->setHeader('Last-Modified', HTTP\toDate($lastMod)); - - return false; - } - } - } - } - - if ($ifUnmodifiedSince = $request->getHeader('If-Unmodified-Since')) { - // The If-Unmodified-Since will allow allow the request if the - // entity has not changed since the specified date. - $date = HTTP\parseDate($ifUnmodifiedSince); - - // We must only check the date if it's valid - if ($date) { - if (is_null($node)) { - $node = $this->tree->getNodeForPath($path); - } - $lastMod = $node->getLastModified(); - if ($lastMod) { - $lastMod = new \DateTime('@'.$lastMod); - if ($lastMod > $date) { - throw new Exception\PreconditionFailed('An If-Unmodified-Since header was specified, but the entity has been changed since the specified date.', 'If-Unmodified-Since'); - } - } - } - } - - // Now the hardest, the If: header. The If: header can contain multiple - // urls, ETags and so-called 'state tokens'. - // - // Examples of state tokens include lock-tokens (as defined in rfc4918) - // and sync-tokens (as defined in rfc6578). - // - // The only proper way to deal with these, is to emit events, that a - // Sync and Lock plugin can pick up. - $ifConditions = $this->getIfConditions($request); - - foreach ($ifConditions as $kk => $ifCondition) { - foreach ($ifCondition['tokens'] as $ii => $token) { - $ifConditions[$kk]['tokens'][$ii]['validToken'] = false; - } - } - - // Plugins are responsible for validating all the tokens. - // If a plugin deemed a token 'valid', it will set 'validToken' to - // true. - $this->emit('validateTokens', [$request, &$ifConditions]); - - // Now we're going to analyze the result. - - // Every ifCondition needs to validate to true, so we exit as soon as - // we have an invalid condition. - foreach ($ifConditions as $ifCondition) { - $uri = $ifCondition['uri']; - $tokens = $ifCondition['tokens']; - - // We only need 1 valid token for the condition to succeed. - foreach ($tokens as $token) { - $tokenValid = $token['validToken'] || !$token['token']; - - $etagValid = false; - if (!$token['etag']) { - $etagValid = true; - } - // Checking the ETag, only if the token was already deemed - // valid and there is one. - if ($token['etag'] && $tokenValid) { - // The token was valid, and there was an ETag. We must - // grab the current ETag and check it. - $node = $this->tree->getNodeForPath($uri); - $etagValid = $node instanceof IFile && $node->getETag() == $token['etag']; - } - - if (($tokenValid && $etagValid) ^ $token['negate']) { - // Both were valid, so we can go to the next condition. - continue 2; - } - } - - // If we ended here, it means there was no valid ETag + token - // combination found for the current condition. This means we fail! - throw new Exception\PreconditionFailed('Failed to find a valid token/etag combination for '.$uri, 'If'); - } - - return true; - } - - /** - * 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, containing structs with the following keys - * - * * uri - the uri the condition applies to. - * * tokens - The lock token. another 2 dimensional array containing 3 elements - * - * Example 1: - * - * If: () - * - * Would result in: - * - * [ - * [ - * 'uri' => '/request/uri', - * 'tokens' => [ - * [ - * [ - * 'negate' => false, - * 'token' => 'opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2', - * 'etag' => "" - * ] - * ] - * ], - * ] - * ] - * - * Example 2: - * - * If: (Not ["Im An ETag"]) (["Another ETag"]) (Not ["Path2 ETag"]) - * - * Would result in: - * - * [ - * [ - * 'uri' => 'path', - * 'tokens' => [ - * [ - * [ - * 'negate' => true, - * 'token' => 'opaquelocktoken:181d4fae-7d8c-11d0-a765-00a0c91e6bf2', - * 'etag' => '"Im An ETag"' - * ], - * [ - * 'negate' => false, - * 'token' => '', - * 'etag' => '"Another ETag"' - * ] - * ] - * ], - * ], - * [ - * 'uri' => 'path2', - * 'tokens' => [ - * [ - * [ - * 'negate' => true, - * 'token' => '', - * 'etag' => '"Path2 ETag"' - * ] - * ] - * ], - * ], - * ] - * - * @return array - */ - public function getIfConditions(RequestInterface $request) - { - $header = $request->getHeader('If'); - if (!$header) { - return []; - } - - $matches = []; - - $regex = '/(?:\<(?P.*?)\>\s)?\((?PNot\s)?(?:\<(?P[^\>]*)\>)?(?:\s?)(?:\[(?P[^\]]*)\])?\)/im'; - preg_match_all($regex, $header, $matches, PREG_SET_ORDER); - - $conditions = []; - - foreach ($matches as $match) { - // If there was no uri specified in this match, and there were - // already conditions parsed, we add the condition to the list of - // conditions for the previous uri. - if (!$match['uri'] && count($conditions)) { - $conditions[count($conditions) - 1]['tokens'][] = [ - 'negate' => $match['not'] ? true : false, - 'token' => $match['token'], - 'etag' => isset($match['etag']) ? $match['etag'] : '', - ]; - } else { - if (!$match['uri']) { - $realUri = $request->getPath(); - } else { - $realUri = $this->calculateUri($match['uri']); - } - - $conditions[] = [ - 'uri' => $realUri, - 'tokens' => [ - [ - 'negate' => $match['not'] ? true : false, - 'token' => $match['token'], - 'etag' => isset($match['etag']) ? $match['etag'] : '', - ], - ], - ]; - } - } - - return $conditions; - } - - /** - * Returns an array with resourcetypes for a node. - * - * @return array - */ - public function getResourceTypeForNode(INode $node) - { - $result = []; - foreach ($this->resourceTypeMapping as $className => $resourceType) { - if ($node instanceof $className) { - $result[] = $resourceType; - } - } - - return $result; - } - - // }}} - // {{{ XML Readers & Writers - - /** - * Returns a callback generating a WebDAV propfind response body based on a list of nodes. - * - * If 'strip404s' is set to true, all 404 responses will be removed. - * - * @param array|\Traversable $fileProperties The list with nodes - * @param bool $strip404s - * - * @return callable|string - */ - public function generateMultiStatus($fileProperties, $strip404s = false) - { - $this->emit('beforeMultiStatus', [&$fileProperties]); - - $w = $this->xml->getWriter(); - if (self::$streamMultiStatus) { - return function () use ($fileProperties, $strip404s, $w) { - $w->openUri('php://output'); - $this->writeMultiStatus($w, $fileProperties, $strip404s); - $w->flush(); - }; - } - $w->openMemory(); - $this->writeMultiStatus($w, $fileProperties, $strip404s); - - return $w->outputMemory(); - } - - /** - * @param $fileProperties - */ - private function writeMultiStatus(Writer $w, $fileProperties, bool $strip404s) - { - $w->contextUri = $this->baseUri; - $w->startDocument(); - - $w->startElement('{DAV:}multistatus'); - - foreach ($fileProperties as $entry) { - $href = $entry['href']; - unset($entry['href']); - if ($strip404s) { - unset($entry[404]); - } - $response = new Xml\Element\Response( - ltrim($href, '/'), - $entry - ); - $w->write([ - 'name' => '{DAV:}response', - 'value' => $response, - ]); - } - $w->endElement(); - $w->endDocument(); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/ServerPlugin.php b/lib/vendor/sabre/dav/lib/DAV/ServerPlugin.php deleted file mode 100644 index 70acb01..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/ServerPlugin.php +++ /dev/null @@ -1,105 +0,0 @@ - $this->getPluginName(), - 'description' => null, - 'link' => null, - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php b/lib/vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php deleted file mode 100644 index a746ac7..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php +++ /dev/null @@ -1,69 +0,0 @@ -server = $server; - - $server->xml->elementMap['{DAV:}share-resource'] = 'Sabre\\DAV\\Xml\\Request\\ShareResource'; - - array_push( - $server->protectedProperties, - '{DAV:}share-mode' - ); - - $server->on('method:POST', [$this, 'httpPost']); - $server->on('propFind', [$this, 'propFind']); - $server->on('getSupportedPrivilegeSet', [$this, 'getSupportedPrivilegeSet']); - $server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']); - $server->on('onBrowserPostAction', [$this, 'browserPostAction']); - } - - /** - * Updates the list of sharees on a shared resource. - * - * The sharees array is a list of people that are to be added modified - * or removed in the list of shares. - * - * @param string $path - * @param Sharee[] $sharees - */ - public function shareResource($path, array $sharees) - { - $node = $this->server->tree->getNodeForPath($path); - - if (!$node instanceof ISharedNode) { - throw new Forbidden('Sharing is not allowed on this node'); - } - - // Getting ACL info - $acl = $this->server->getPlugin('acl'); - - // If there's no ACL support, we allow everything - if ($acl) { - $acl->checkPrivileges($path, '{DAV:}share'); - } - - foreach ($sharees as $sharee) { - // We're going to attempt to get a local principal uri for a share - // href by emitting the getPrincipalByUri event. - $principal = null; - $this->server->emit('getPrincipalByUri', [$sharee->href, &$principal]); - $sharee->principal = $principal; - } - $node->updateInvites($sharees); - } - - /** - * This event is triggered when properties are requested for nodes. - * - * This allows us to inject any sharings-specific properties. - */ - public function propFind(PropFind $propFind, INode $node) - { - if ($node instanceof ISharedNode) { - $propFind->handle('{DAV:}share-access', function () use ($node) { - return new Property\ShareAccess($node->getShareAccess()); - }); - $propFind->handle('{DAV:}invite', function () use ($node) { - return new Property\Invite($node->getInvites()); - }); - $propFind->handle('{DAV:}share-resource-uri', function () use ($node) { - return new Property\Href($node->getShareResourceUri()); - }); - } - } - - /** - * We intercept this to handle POST requests on shared resources. - * - * @return bool|null - */ - public function httpPost(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - $contentType = $request->getHeader('Content-Type'); - if (null === $contentType) { - return; - } - - // We're only interested in the davsharing content type. - if (false === strpos($contentType, 'application/davsharing+xml')) { - return; - } - - $message = $this->server->xml->parse( - $request->getBody(), - $request->getUrl(), - $documentType - ); - - switch ($documentType) { - case '{DAV:}share-resource': - $this->shareResource($path, $message->sharees); - $response->setStatus(200); - // Adding this because sending a response body may cause issues, - // and I wanted some type of indicator the response was handled. - $response->setHeader('X-Sabre-Status', 'everything-went-well'); - - // Breaking the event chain - return false; - - default: - throw new BadRequest('Unexpected document type: '.$documentType.' for this Content-Type'); - } - } - - /** - * This method is triggered whenever a subsystem requests the privileges - * hat are supported on a particular node. - * - * We need to add a number of privileges for scheduling purposes. - */ - public function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilegeSet) - { - if ($node instanceof ISharedNode) { - $supportedPrivilegeSet['{DAV:}share'] = [ - 'abstract' => false, - 'aggregates' => [], - ]; - } - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'This plugin implements WebDAV resource sharing', - 'link' => 'https://github.com/evert/webdav-sharing', - ]; - } - - /** - * This method is used to generate HTML output for the - * DAV\Browser\Plugin. - * - * @param string $output - * @param string $path - * - * @return bool|null - */ - public function htmlActionsPanel(INode $node, &$output, $path) - { - if (!$node instanceof ISharedNode) { - return; - } - - $aclPlugin = $this->server->getPlugin('acl'); - if ($aclPlugin) { - if (!$aclPlugin->checkPrivileges($path, '{DAV:}share', \Sabre\DAVACL\Plugin::R_PARENT, false)) { - // Sharing is not permitted, we will not draw this interface. - return; - } - } - - $output .= '

-

Share this resource

- -
- -
- - - '; - } - - /** - * This method is triggered for POST actions generated by the browser - * plugin. - * - * @param string $path - * @param string $action - * @param array $postVars - */ - public function browserPostAction($path, $action, $postVars) - { - if ('share' !== $action) { - return; - } - - if (empty($postVars['href'])) { - throw new BadRequest('The "href" POST parameter is required'); - } - if (empty($postVars['access'])) { - throw new BadRequest('The "access" POST parameter is required'); - } - - $accessMap = [ - 'readwrite' => self::ACCESS_READWRITE, - 'read' => self::ACCESS_READ, - 'no-access' => self::ACCESS_NOACCESS, - ]; - - if (!isset($accessMap[$postVars['access']])) { - throw new BadRequest('The "access" POST must be readwrite, read or no-access'); - } - $sharee = new Sharee([ - 'href' => $postVars['href'], - 'access' => $accessMap[$postVars['access']], - ]); - - $this->shareResource( - $path, - [$sharee] - ); - - return false; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/SimpleCollection.php b/lib/vendor/sabre/dav/lib/DAV/SimpleCollection.php deleted file mode 100644 index 3cd14d9..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/SimpleCollection.php +++ /dev/null @@ -1,109 +0,0 @@ -name = $name; - foreach ($children as $key => $child) { - if (is_string($child)) { - $child = new SimpleFile($key, $child); - } elseif (is_array($child)) { - $child = new self($key, $child); - } elseif (!$child instanceof INode) { - throw new InvalidArgumentException('Children must be specified as strings, arrays or instances of Sabre\DAV\INode'); - } - $this->addChild($child); - } - } - - /** - * Adds a new childnode to this collection. - */ - public function addChild(INode $child) - { - $this->children[$child->getName()] = $child; - } - - /** - * Returns the name of the collection. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * 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. - * Generally its wise to override this, as this can usually be optimized - * - * This method must throw Sabre\DAV\Exception\NotFound if the node does not - * exist. - * - * @param string $name - * - * @throws Exception\NotFound - * - * @return INode - */ - public function getChild($name) - { - if (isset($this->children[$name])) { - return $this->children[$name]; - } - throw new Exception\NotFound('File not found: '.$name.' in \''.$this->getName().'\''); - } - - /** - * Returns a list of children for this collection. - * - * @return INode[] - */ - public function getChildren() - { - return array_values($this->children); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/SimpleFile.php b/lib/vendor/sabre/dav/lib/DAV/SimpleFile.php deleted file mode 100644 index ca808b6..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/SimpleFile.php +++ /dev/null @@ -1,118 +0,0 @@ -name = $name; - $this->contents = $contents; - $this->mimeType = $mimeType; - } - - /** - * Returns the node name for this file. - * - * This name is used to construct the url. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Returns the data. - * - * This method may either return a string or a readable stream resource - * - * @return mixed - */ - public function get() - { - return $this->contents; - } - - /** - * Returns the size of the file, in bytes. - * - * @return int - */ - public function getSize() - { - return strlen($this->contents); - } - - /** - * 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 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 '"'.sha1($this->contents).'"'; - } - - /** - * 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; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/StringUtil.php b/lib/vendor/sabre/dav/lib/DAV/StringUtil.php deleted file mode 100644 index edfb7fa..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/StringUtil.php +++ /dev/null @@ -1,86 +0,0 @@ - 'The current synctoken', - * 'added' => [ - * 'new.txt', - * ], - * 'modified' => [ - * 'modified.txt', - * ], - * 'deleted' => array( - * 'foo.php.bak', - * 'old.txt' - * ) - * ]; - * - * The syncToken property should reflect the *current* syncToken of the - * collection, as reported getSyncToken(). This is needed here too, to - * ensure the operation is atomic. - * - * If the syncToken is specified as null, this is an initial sync, and all - * members should be reported. - * - * The modified property is an array of nodenames that have changed since - * the last token. - * - * The deleted property is an array with nodenames, that have been deleted - * from collection. - * - * The second argument is basically the 'depth' of the report. If it's 1, - * you only have to report changes that happened only directly in immediate - * descendants. If it's 2, it should also include changes from the nodes - * below the child collections. (grandchildren) - * - * The third (optional) argument allows a client to specify how many - * results should be returned at most. If the limit is not specified, it - * should be treated as infinite. - * - * If the limit (infinite or not) is higher than you're willing to return, - * you should throw a Sabre\DAV\Exception\TooMuchMatches() exception. - * - * If the syncToken is expired (due to data cleanup) or unknown, you must - * return null. - * - * The limit is 'suggestive'. You are free to ignore it. - * - * @param string $syncToken - * @param int $syncLevel - * @param int $limit - * - * @return array|null - */ - public function getChanges($syncToken, $syncLevel, $limit = null); -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Sync/Plugin.php b/lib/vendor/sabre/dav/lib/DAV/Sync/Plugin.php deleted file mode 100644 index 8609f75..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Sync/Plugin.php +++ /dev/null @@ -1,249 +0,0 @@ -server = $server; - $server->xml->elementMap['{DAV:}sync-collection'] = 'Sabre\\DAV\\Xml\\Request\\SyncCollectionReport'; - - $self = $this; - - $server->on('report', function ($reportName, $dom, $uri) use ($self) { - if ('{DAV:}sync-collection' === $reportName) { - $this->server->transactionType = 'report-sync-collection'; - $self->syncCollection($uri, $dom); - - return false; - } - }); - - $server->on('propFind', [$this, 'propFind']); - $server->on('validateTokens', [$this, 'validateTokens']); - } - - /** - * 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 - * - * @param string $uri - * - * @return array - */ - public function getSupportedReportSet($uri) - { - $node = $this->server->tree->getNodeForPath($uri); - if ($node instanceof ISyncCollection && $node->getSyncToken()) { - return [ - '{DAV:}sync-collection', - ]; - } - - return []; - } - - /** - * This method handles the {DAV:}sync-collection HTTP REPORT. - * - * @param string $uri - */ - public function syncCollection($uri, SyncCollectionReport $report) - { - // Getting the data - $node = $this->server->tree->getNodeForPath($uri); - if (!$node instanceof ISyncCollection) { - throw new DAV\Exception\ReportNotSupported('The {DAV:}sync-collection REPORT is not supported on this url.'); - } - $token = $node->getSyncToken(); - if (!$token) { - throw new DAV\Exception\ReportNotSupported('No sync information is available at this node'); - } - - $syncToken = $report->syncToken; - if (!is_null($syncToken)) { - // Sync-token must start with our prefix - if (self::SYNCTOKEN_PREFIX !== substr($syncToken, 0, strlen(self::SYNCTOKEN_PREFIX))) { - throw new DAV\Exception\InvalidSyncToken('Invalid or unknown sync token'); - } - - $syncToken = substr($syncToken, strlen(self::SYNCTOKEN_PREFIX)); - } - $changeInfo = $node->getChanges($syncToken, $report->syncLevel, $report->limit); - - if (is_null($changeInfo)) { - throw new DAV\Exception\InvalidSyncToken('Invalid or unknown sync token'); - } - - if (!array_key_exists('result_truncated', $changeInfo)) { - $changeInfo['result_truncated'] = false; - } - - // Encoding the response - $this->sendSyncCollectionResponse( - $changeInfo['syncToken'], - $uri, - $changeInfo['added'], - $changeInfo['modified'], - $changeInfo['deleted'], - $report->properties, - $changeInfo['result_truncated'] - ); - } - - /** - * Sends the response to a sync-collection request. - * - * @param string $syncToken - * @param string $collectionUrl - */ - protected function sendSyncCollectionResponse($syncToken, $collectionUrl, array $added, array $modified, array $deleted, array $properties, bool $resultTruncated = false) - { - $fullPaths = []; - - // Pre-fetching children, if this is possible. - foreach (array_merge($added, $modified) as $item) { - $fullPath = $collectionUrl.'/'.$item; - $fullPaths[] = $fullPath; - } - - $responses = []; - foreach ($this->server->getPropertiesForMultiplePaths($fullPaths, $properties) as $fullPath => $props) { - // The 'Property_Response' class is responsible for generating a - // single {DAV:}response xml element. - $responses[] = new DAV\Xml\Element\Response($fullPath, $props); - } - - // Deleted items also show up as 'responses'. They have no properties, - // and a single {DAV:}status element set as 'HTTP/1.1 404 Not Found'. - foreach ($deleted as $item) { - $fullPath = $collectionUrl.'/'.$item; - $responses[] = new DAV\Xml\Element\Response($fullPath, [], 404); - } - if ($resultTruncated) { - $responses[] = new DAV\Xml\Element\Response($collectionUrl.'/', [], 507); - } - - $multiStatus = new DAV\Xml\Response\MultiStatus($responses, self::SYNCTOKEN_PREFIX.$syncToken); - - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setBody( - $this->server->xml->write('{DAV:}multistatus', $multiStatus, $this->server->getBaseUri()) - ); - } - - /** - * This method is triggered whenever properties are requested for a node. - * We intercept this to see if we must return a {DAV:}sync-token. - */ - public function propFind(DAV\PropFind $propFind, DAV\INode $node) - { - $propFind->handle('{DAV:}sync-token', function () use ($node) { - if (!$node instanceof ISyncCollection || !$token = $node->getSyncToken()) { - return; - } - - return self::SYNCTOKEN_PREFIX.$token; - }); - } - - /** - * The validateTokens event is triggered before every request. - * - * It's a moment where this plugin can check all the supplied lock tokens - * in the If: header, and check if they are valid. - * - * @param array $conditions - */ - public function validateTokens(RequestInterface $request, &$conditions) - { - foreach ($conditions as $kk => $condition) { - foreach ($condition['tokens'] as $ii => $token) { - // Sync-tokens must always start with our designated prefix. - if (self::SYNCTOKEN_PREFIX !== substr($token['token'], 0, strlen(self::SYNCTOKEN_PREFIX))) { - continue; - } - - // Checking if the token is a match. - $node = $this->server->tree->getNodeForPath($condition['uri']); - - if ( - $node instanceof ISyncCollection && - $node->getSyncToken() == substr($token['token'], strlen(self::SYNCTOKEN_PREFIX)) - ) { - $conditions[$kk]['tokens'][$ii]['validToken'] = true; - } - } - } - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds support for WebDAV Collection Sync (rfc6578)', - 'link' => 'http://sabre.io/dav/sync/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php b/lib/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php deleted file mode 100644 index 9f8ec5b..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/TemporaryFileFilterPlugin.php +++ /dev/null @@ -1,298 +0,0 @@ -dataDir = $dataDir; - } - - /** - * Initialize the plugin. - * - * This is called automatically be the Server class after this plugin is - * added with Sabre\DAV\Server::addPlugin() - */ - public function initialize(Server $server) - { - $this->server = $server; - $server->on('beforeMethod:*', [$this, 'beforeMethod']); - $server->on('beforeCreateFile', [$this, 'beforeCreateFile']); - } - - /** - * This method is called before any HTTP method handler. - * - * This method intercepts any GET, DELETE, PUT and PROPFIND calls to - * filenames that are known to match the 'temporary file' regex. - * - * @return bool - */ - public function beforeMethod(RequestInterface $request, ResponseInterface $response) - { - if (!$tempLocation = $this->isTempFile($request->getPath())) { - return; - } - - switch ($request->getMethod()) { - case 'GET': - return $this->httpGet($request, $response, $tempLocation); - case 'PUT': - return $this->httpPut($request, $response, $tempLocation); - case 'PROPFIND': - return $this->httpPropfind($request, $response, $tempLocation); - case 'DELETE': - return $this->httpDelete($request, $response, $tempLocation); - } - - return; - } - - /** - * This method is invoked if some subsystem creates a new file. - * - * This is used to deal with HTTP LOCK requests which create a new - * file. - * - * @param string $uri - * @param resource $data - * @param bool $modified should be set to true, if this event handler - * changed &$data - * - * @return bool - */ - public function beforeCreateFile($uri, $data, ICollection $parent, $modified) - { - if ($tempPath = $this->isTempFile($uri)) { - $hR = $this->server->httpResponse; - $hR->setHeader('X-Sabre-Temp', 'true'); - file_put_contents($tempPath, $data); - - return false; - } - - return; - } - - /** - * 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 - * temporary file storage. - * - * @param string $path - * - * @return bool|string - */ - protected function isTempFile($path) - { - // We're only interested in the basename. - list(, $tempPath) = Uri\split($path); - - if (null === $tempPath) { - return false; - } - - foreach ($this->temporaryFilePatterns as $tempFile) { - if (preg_match($tempFile, $tempPath)) { - return $this->getDataDir().'/sabredav_'.md5($path).'.tempfile'; - } - } - - return false; - } - - /** - * 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 - */ - public function httpGet(RequestInterface $request, ResponseInterface $hR, $tempLocation) - { - if (!file_exists($tempLocation)) { - return; - } - - $hR->setHeader('Content-Type', 'application/octet-stream'); - $hR->setHeader('Content-Length', filesize($tempLocation)); - $hR->setHeader('X-Sabre-Temp', 'true'); - $hR->setStatus(200); - $hR->setBody(fopen($tempLocation, 'r')); - - return false; - } - - /** - * This method handles the PUT method. - * - * @param string $tempLocation - * - * @return bool - */ - public function httpPut(RequestInterface $request, ResponseInterface $hR, $tempLocation) - { - $hR->setHeader('X-Sabre-Temp', 'true'); - - $newFile = !file_exists($tempLocation); - - if (!$newFile && ($this->server->httpRequest->getHeader('If-None-Match'))) { - throw new Exception\PreconditionFailed('The resource already exists, and an If-None-Match header was supplied'); - } - - file_put_contents($tempLocation, $this->server->httpRequest->getBody()); - $hR->setStatus($newFile ? 201 : 200); - - return false; - } - - /** - * This method handles the DELETE method. - * - * 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 - */ - public function httpDelete(RequestInterface $request, ResponseInterface $hR, $tempLocation) - { - if (!file_exists($tempLocation)) { - return; - } - - unlink($tempLocation); - $hR->setHeader('X-Sabre-Temp', 'true'); - $hR->setStatus(204); - - return false; - } - - /** - * 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 bool - */ - public function httpPropfind(RequestInterface $request, ResponseInterface $hR, $tempLocation) - { - if (!file_exists($tempLocation)) { - return; - } - - $hR->setHeader('X-Sabre-Temp', 'true'); - $hR->setStatus(207); - $hR->setHeader('Content-Type', 'application/xml; charset=utf-8'); - - $properties = [ - 'href' => $request->getPath(), - 200 => [ - '{DAV:}getlastmodified' => new Xml\Property\GetLastModified(filemtime($tempLocation)), - '{DAV:}getcontentlength' => filesize($tempLocation), - '{DAV:}resourcetype' => new Xml\Property\ResourceType(null), - '{'.Server::NS_SABREDAV.'}tempFile' => true, - ], - ]; - - $data = $this->server->generateMultiStatus([$properties]); - $hR->setBody($data); - - return false; - } - - /** - * This method returns the directory where the temporary files should be stored. - * - * @return string - */ - protected function getDataDir() - { - return $this->dataDir; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Tree.php b/lib/vendor/sabre/dav/lib/DAV/Tree.php deleted file mode 100644 index 1483e1b..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Tree.php +++ /dev/null @@ -1,342 +0,0 @@ -rootNode = $rootNode; - } - - /** - * Returns the INode object for the requested path. - * - * @param string $path - * - * @return INode - */ - public function getNodeForPath($path) - { - $path = trim($path, '/'); - if (isset($this->cache[$path])) { - return $this->cache[$path]; - } - - // Is it the root node? - if (!strlen($path)) { - return $this->rootNode; - } - - $node = $this->rootNode; - - // look for any cached parent and collect the parts below the parent - $parts = []; - $remainingPath = $path; - do { - list($remainingPath, $baseName) = Uri\split($remainingPath); - array_unshift($parts, $baseName); - - if (isset($this->cache[$remainingPath])) { - $node = $this->cache[$remainingPath]; - break; - } - } while ('' !== $remainingPath); - - while (count($parts)) { - if (!($node instanceof ICollection)) { - throw new Exception\NotFound('Could not find node at path: '.$path); - } - - if ($node instanceof INodeByPath) { - $targetNode = $node->getNodeForPath(implode('/', $parts)); - if ($targetNode instanceof Node) { - $node = $targetNode; - break; - } - } - - $part = array_shift($parts); - if ('' !== $part) { - $node = $node->getChild($part); - } - } - - $this->cache[$path] = $node; - - return $node; - } - - /** - * This function allows you to check if a node exists. - * - * Implementors of this class should override this method to make - * it cheaper. - * - * @param string $path - * - * @return bool - */ - public function nodeExists($path) - { - try { - // The root always exists - if ('' === $path) { - return true; - } - - list($parent, $base) = Uri\split($path); - - $parentNode = $this->getNodeForPath($parent); - if (!$parentNode instanceof ICollection) { - return false; - } - - return $parentNode->childExists($base); - } catch (Exception\NotFound $e) { - return false; - } - } - - /** - * Copies a file from path to another. - * - * @param string $sourcePath The source location - * @param string $destinationPath The full destination path - */ - public function copy($sourcePath, $destinationPath) - { - $sourceNode = $this->getNodeForPath($sourcePath); - - // grab the dirname and basename components - list($destinationDir, $destinationName) = Uri\split($destinationPath); - - $destinationParent = $this->getNodeForPath($destinationDir); - // Check if the target can handle the copy itself. If not, we do it ourselves. - if (!$destinationParent instanceof ICopyTarget || !$destinationParent->copyInto($destinationName, $sourcePath, $sourceNode)) { - $this->copyNode($sourceNode, $destinationParent, $destinationName); - } - - $this->markDirty($destinationDir); - } - - /** - * 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 - */ - public function move($sourcePath, $destinationPath) - { - list($sourceDir) = Uri\split($sourcePath); - list($destinationDir, $destinationName) = Uri\split($destinationPath); - - if ($sourceDir === $destinationDir) { - // If this is a 'local' rename, it means we can just trigger a rename. - $sourceNode = $this->getNodeForPath($sourcePath); - $sourceNode->setName($destinationName); - } else { - $newParentNode = $this->getNodeForPath($destinationDir); - $moveSuccess = false; - if ($newParentNode instanceof IMoveTarget) { - // The target collection may be able to handle the move - $sourceNode = $this->getNodeForPath($sourcePath); - $moveSuccess = $newParentNode->moveInto($destinationName, $sourcePath, $sourceNode); - } - if (!$moveSuccess) { - $this->copy($sourcePath, $destinationPath); - $this->getNodeForPath($sourcePath)->delete(); - } - } - $this->markDirty($sourceDir); - $this->markDirty($destinationDir); - } - - /** - * Deletes a node from the tree. - * - * @param string $path - */ - public function delete($path) - { - $node = $this->getNodeForPath($path); - $node->delete(); - - list($parent) = Uri\split($path); - $this->markDirty($parent); - } - - /** - * Returns a list of childnodes for a given path. - * - * @param string $path - * - * @return \Traversable - */ - public function getChildren($path) - { - $node = $this->getNodeForPath($path); - $basePath = trim($path, '/'); - if ('' !== $basePath) { - $basePath .= '/'; - } - - foreach ($node->getChildren() as $child) { - $this->cache[$basePath.$child->getName()] = $child; - yield $child; - } - } - - /** - * This method is called with every tree update. - * - * Examples of tree updates are: - * * node deletions - * * node creations - * * copy - * * move - * * 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 - */ - public function markDirty($path) - { - // We don't care enough about sub-paths - // flushing the entire cache - $path = trim($path, '/'); - foreach ($this->cache as $nodePath => $node) { - if ('' === $path || $nodePath == $path || 0 === strpos((string) $nodePath, $path.'/')) { - unset($this->cache[$nodePath]); - } - } - } - - /** - * This method tells the tree system to pre-fetch and cache a list of - * children of a single parent. - * - * There are a bunch of operations in the WebDAV stack that request many - * children (based on uris), and sometimes fetching many at once can - * optimize this. - * - * This method returns an array with the found nodes. It's keys are the - * original paths. The result may be out of order. - * - * @param array $paths list of nodes that must be fetched - * - * @return array - */ - public function getMultipleNodes($paths) - { - // Finding common parents - $parents = []; - foreach ($paths as $path) { - list($parent, $node) = Uri\split($path); - if (!isset($parents[$parent])) { - $parents[$parent] = [$node]; - } else { - $parents[$parent][] = $node; - } - } - - $result = []; - - foreach ($parents as $parent => $children) { - $parentNode = $this->getNodeForPath($parent); - if ($parentNode instanceof IMultiGet) { - foreach ($parentNode->getMultipleChildren($children) as $childNode) { - $fullPath = $parent.'/'.$childNode->getName(); - $result[$fullPath] = $childNode; - $this->cache[$fullPath] = $childNode; - } - } else { - foreach ($children as $child) { - $fullPath = $parent.'/'.$child; - $result[$fullPath] = $this->getNodeForPath($fullPath); - } - } - } - - return $result; - } - - /** - * copyNode. - * - * @param string $destinationName - */ - protected function copyNode(INode $source, ICollection $destinationParent, $destinationName = null) - { - if ('' === (string) $destinationName) { - $destinationName = $source->getName(); - } - - $destination = null; - - if ($source instanceof IFile) { - $data = $source->get(); - - // If the body was a string, we need to convert it to a stream - if (is_string($data)) { - $stream = fopen('php://temp', 'r+'); - fwrite($stream, $data); - rewind($stream); - $data = $stream; - } - $destinationParent->createFile($destinationName, $data); - $destination = $destinationParent->getChild($destinationName); - } elseif ($source instanceof ICollection) { - $destinationParent->createDirectory($destinationName); - - $destination = $destinationParent->getChild($destinationName); - foreach ($source->getChildren() as $child) { - $this->copyNode($child, $destination); - } - } - if ($source instanceof IProperties && $destination instanceof IProperties) { - $props = $source->getProperties([]); - $propPatch = new PropPatch($props); - $destination->propPatch($propPatch); - $propPatch->commit(); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/UUIDUtil.php b/lib/vendor/sabre/dav/lib/DAV/UUIDUtil.php deleted file mode 100644 index 8c36e1b..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/UUIDUtil.php +++ /dev/null @@ -1,66 +0,0 @@ -value array. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class Prop implements XmlDeserializable -{ - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - // If there's no children, we don't do anything. - if ($reader->isEmptyElement) { - $reader->next(); - - return []; - } - - $values = []; - - $reader->read(); - do { - if (Reader::ELEMENT === $reader->nodeType) { - $clark = $reader->getClark(); - $values[$clark] = self::parseCurrentElement($reader)['value']; - } else { - $reader->read(); - } - } while (Reader::END_ELEMENT !== $reader->nodeType); - - $reader->read(); - - return $values; - } - - /** - * This function behaves similar to Sabre\Xml\Reader::parseCurrentElement, - * but instead of creating deep xml array structures, it will turn any - * top-level element it doesn't recognize into either a string, or an - * XmlFragment class. - * - * This method returns arn array with 2 properties: - * * name - A clark-notation XML element name. - * * value - The parsed value. - * - * @return array - */ - private static function parseCurrentElement(Reader $reader) - { - $name = $reader->getClark(); - - if (array_key_exists($name, $reader->elementMap)) { - $deserializer = $reader->elementMap[$name]; - if (is_subclass_of($deserializer, 'Sabre\\Xml\\XmlDeserializable')) { - $value = call_user_func([$deserializer, 'xmlDeserialize'], $reader); - } elseif (is_callable($deserializer)) { - $value = call_user_func($deserializer, $reader); - } else { - $type = gettype($deserializer); - if ('string' === $type) { - $type .= ' ('.$deserializer.')'; - } elseif ('object' === $type) { - $type .= ' ('.get_class($deserializer).')'; - } - throw new \LogicException('Could not use this type as a deserializer: '.$type); - } - } else { - $value = Complex::xmlDeserialize($reader); - } - - return [ - 'name' => $name, - 'value' => $value, - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php deleted file mode 100644 index df92914..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Element/Response.php +++ /dev/null @@ -1,267 +0,0 @@ -href = $href; - $this->responseProperties = $responseProperties; - $this->httpStatus = $httpStatus; - } - - /** - * Returns the url. - * - * @return string - */ - public function getHref() - { - return $this->href; - } - - /** - * Returns the httpStatus value. - * - * @return string - */ - public function getHttpStatus() - { - return $this->httpStatus; - } - - /** - * Returns the property list. - * - * @return array - */ - public function getResponseProperties() - { - return $this->responseProperties; - } - - /** - * The serialize method is called during xml writing. - * - * It should use the $writer argument to encode this object into XML. - * - * Important note: it is not needed to create the parent element. The - * parent element is already created, and we only have to worry about - * attributes, child elements and text (if any). - * - * Important note 2: If you are writing any new elements, you are also - * responsible for closing them. - */ - public function xmlSerialize(Writer $writer) - { - /* - * Accordingly to the RFC the element looks like: - * - * - * So the response - * - MUST contain a href and - * - EITHER a status and additional href(s) - * OR one or more propstat(s) - */ - $writer->writeElement('{DAV:}href', $writer->contextUri.\Sabre\HTTP\encodePath($this->getHref())); - - $empty = true; - $httpStatus = $this->getHTTPStatus(); - - // Add propstat elements - foreach ($this->getResponseProperties() as $status => $properties) { - // Skipping empty lists - if (!$properties || (!is_int($status) && !ctype_digit($status))) { - continue; - } - $empty = false; - $writer->startElement('{DAV:}propstat'); - $writer->writeElement('{DAV:}prop', $properties); - $writer->writeElement('{DAV:}status', 'HTTP/1.1 '.$status.' '.\Sabre\HTTP\Response::$statusCodes[$status]); - $writer->endElement(); // {DAV:}propstat - } - - // The WebDAV spec only allows the status element on responses _without_ a propstat - if ($empty) { - if (null !== $httpStatus) { - $writer->writeElement('{DAV:}status', 'HTTP/1.1 '.$httpStatus.' '.\Sabre\HTTP\Response::$statusCodes[$httpStatus]); - } else { - /* - * The WebDAV spec _requires_ at least one DAV:propstat to appear for - * every DAV:response if there is no status. - * In some circumstances however, there are no properties to encode. - * - * In those cases we MUST specify at least one DAV:propstat anyway, with - * no properties. - */ - $writer->writeElement('{DAV:}propstat', [ - '{DAV:}prop' => [], - '{DAV:}status' => 'HTTP/1.1 418 '.\Sabre\HTTP\Response::$statusCodes[418], - ]); - } - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $reader->pushContext(); - - $reader->elementMap['{DAV:}propstat'] = 'Sabre\\Xml\\Element\\KeyValue'; - - // We are overriding the parser for {DAV:}prop. This deserializer is - // almost identical to the one for Sabre\Xml\Element\KeyValue. - // - // The difference is that if there are any child-elements inside of - // {DAV:}prop, that have no value, normally any deserializers are - // called. But we don't want this, because a singular element without - // child-elements implies 'no value' in {DAV:}prop, so we want to skip - // deserializers and just set null for those. - $reader->elementMap['{DAV:}prop'] = function (Reader $reader) { - if ($reader->isEmptyElement) { - $reader->next(); - - return []; - } - - if (!$reader->read()) { - $reader->next(); - - return []; - } - - if (Reader::END_ELEMENT === $reader->nodeType) { - $reader->next(); - - return []; - } - - $values = []; - - do { - if (Reader::ELEMENT === $reader->nodeType) { - $clark = $reader->getClark(); - - if ($reader->isEmptyElement) { - $values[$clark] = null; - $reader->next(); - } else { - $values[$clark] = $reader->parseCurrentElement()['value']; - } - } else { - if (!$reader->read()) { - break; - } - } - } while (Reader::END_ELEMENT !== $reader->nodeType); - - $reader->read(); - - return $values; - }; - $elems = $reader->parseInnerTree(); - $reader->popContext(); - - $href = null; - $propertyLists = []; - $statusCode = null; - - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{DAV:}href': - $href = $elem['value']; - break; - case '{DAV:}propstat': - $status = $elem['value']['{DAV:}status']; - list(, $status) = explode(' ', $status, 3); - $properties = isset($elem['value']['{DAV:}prop']) ? $elem['value']['{DAV:}prop'] : []; - if ($properties) { - $propertyLists[$status] = $properties; - } - break; - case '{DAV:}status': - list(, $statusCode) = explode(' ', $elem['value'], 3); - break; - } - } - - return new self($href, $propertyLists, $statusCode); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php deleted file mode 100644 index 33564d8..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php +++ /dev/null @@ -1,189 +0,0 @@ - $v) { - if (property_exists($this, $k)) { - $this->$k = $v; - } else { - throw new \InvalidArgumentException('Unknown property: '.$k); - } - } - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - $writer->write([ - new Href($this->href), - '{DAV:}prop' => $this->properties, - '{DAV:}share-access' => new ShareAccess($this->access), - ]); - switch ($this->inviteStatus) { - case Plugin::INVITE_NORESPONSE: - $writer->writeElement('{DAV:}invite-noresponse'); - break; - case Plugin::INVITE_ACCEPTED: - $writer->writeElement('{DAV:}invite-accepted'); - break; - case Plugin::INVITE_DECLINED: - $writer->writeElement('{DAV:}invite-declined'); - break; - case Plugin::INVITE_INVALID: - $writer->writeElement('{DAV:}invite-invalid'); - break; - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - // Temporarily override configuration - $reader->pushContext(); - $reader->elementMap['{DAV:}share-access'] = 'Sabre\DAV\Xml\Property\ShareAccess'; - $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Deserializer\keyValue'; - - $elems = Deserializer\keyValue($reader, 'DAV:'); - - // Restore previous configuration - $reader->popContext(); - - $sharee = new self(); - if (!isset($elems['href'])) { - throw new BadRequest('Every {DAV:}sharee must have a {DAV:}href child-element'); - } - $sharee->href = $elems['href']; - - if (isset($elems['prop'])) { - $sharee->properties = $elems['prop']; - } - if (isset($elems['comment'])) { - $sharee->comment = $elems['comment']; - } - if (!isset($elems['share-access'])) { - throw new BadRequest('Every {DAV:}sharee must have a {DAV:}share-access child element'); - } - $sharee->access = $elems['share-access']->getValue(); - - return $sharee; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php deleted file mode 100644 index 787d30d..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Complex.php +++ /dev/null @@ -1,87 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $xml = $reader->readInnerXml(); - - if (Reader::ELEMENT === $reader->nodeType && $reader->isEmptyElement) { - // Easy! - $reader->next(); - - return null; - } - // Now we have a copy of the inner xml, we need to traverse it to get - // all the strings. If there's no non-string data, we just return the - // string, otherwise we return an instance of this class. - $reader->read(); - - $nonText = false; - $text = ''; - - while (true) { - switch ($reader->nodeType) { - case Reader::ELEMENT: - $nonText = true; - $reader->next(); - continue 2; - case Reader::TEXT: - case Reader::CDATA: - $text .= $reader->value; - break; - case Reader::END_ELEMENT: - break 2; - } - $reader->read(); - } - - // Make sure we advance the cursor one step further. - $reader->read(); - - if ($nonText) { - $new = new self($xml); - - return $new; - } else { - return $text; - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php deleted file mode 100644 index efc15c2..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/GetLastModified.php +++ /dev/null @@ -1,103 +0,0 @@ -time = clone $time; - } else { - $this->time = new DateTime('@'.$time); - } - - // Setting timezone to UTC - $this->time->setTimezone(new DateTimeZone('UTC')); - } - - /** - * getTime. - * - * @return DateTime - */ - public function getTime() - { - return $this->time; - } - - /** - * The serialize method is called during xml writing. - * - * It should use the $writer argument to encode this object into XML. - * - * Important note: it is not needed to create the parent element. The - * parent element is already created, and we only have to worry about - * attributes, child elements and text (if any). - * - * Important note 2: If you are writing any new elements, you are also - * responsible for closing them. - */ - public function xmlSerialize(Writer $writer) - { - $writer->write( - HTTP\toDate($this->time) - ); - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - return new self(new DateTime($reader->parseInnerTree())); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php deleted file mode 100644 index d4e43da..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php +++ /dev/null @@ -1,166 +0,0 @@ -hrefs = $hrefs; - } - - /** - * Returns the first Href. - * - * @return string|null - */ - public function getHref() - { - return $this->hrefs[0] ?? null; - } - - /** - * Returns the hrefs as an array. - * - * @return array - */ - public function getHrefs() - { - return $this->hrefs; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->getHrefs() as $href) { - $href = Uri\resolve($writer->contextUri, $href); - $writer->writeElement('{DAV:}href', $href); - } - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - $links = []; - foreach ($this->getHrefs() as $href) { - $links[] = $html->link($href); - } - - return implode('
', $links); - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $hrefs = []; - foreach ((array) $reader->parseInnerTree() as $elem) { - if ('{DAV:}href' !== $elem['name']) { - continue; - } - - $hrefs[] = $elem['value']; - } - if ($hrefs) { - return new self($hrefs); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php deleted file mode 100644 index e3f0a61..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php +++ /dev/null @@ -1,66 +0,0 @@ -sharees = $sharees; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->sharees as $sharee) { - $writer->writeElement('{DAV:}sharee', $sharee); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php deleted file mode 100644 index cb79497..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php +++ /dev/null @@ -1,48 +0,0 @@ -locks = $locks; - } - - /** - * The serialize method is called during xml writing. - * - * It should use the $writer argument to encode this object into XML. - * - * Important note: it is not needed to create the parent element. The - * parent element is already created, and we only have to worry about - * attributes, child elements and text (if any). - * - * Important note 2: If you are writing any new elements, you are also - * responsible for closing them. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->locks as $lock) { - $writer->startElement('{DAV:}activelock'); - - $writer->startElement('{DAV:}lockscope'); - if (LockInfo::SHARED === $lock->scope) { - $writer->writeElement('{DAV:}shared'); - } else { - $writer->writeElement('{DAV:}exclusive'); - } - - $writer->endElement(); // {DAV:}lockscope - - $writer->startElement('{DAV:}locktype'); - $writer->writeElement('{DAV:}write'); - $writer->endElement(); // {DAV:}locktype - - if (!self::$hideLockRoot) { - $writer->startElement('{DAV:}lockroot'); - $writer->writeElement('{DAV:}href', $writer->contextUri.$lock->uri); - $writer->endElement(); // {DAV:}lockroot - } - $writer->writeElement('{DAV:}depth', (DAV\Server::DEPTH_INFINITY == $lock->depth ? 'infinity' : $lock->depth)); - $writer->writeElement('{DAV:}timeout', (LockInfo::TIMEOUT_INFINITE === $lock->timeout ? 'Infinite' : 'Second-'.$lock->timeout)); - - // optional according to https://tools.ietf.org/html/rfc4918#section-6.5 - if (null !== $lock->token && '' !== $lock->token) { - $writer->startElement('{DAV:}locktoken'); - $writer->writeElement('{DAV:}href', 'opaquelocktoken:'.$lock->token); - $writer->endElement(); // {DAV:}locktoken - } - - if ($lock->owner) { - $writer->writeElement('{DAV:}owner', new XmlFragment($lock->owner)); - } - $writer->endElement(); // {DAV:}activelock - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php deleted file mode 100644 index 75ddcba..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/ResourceType.php +++ /dev/null @@ -1,120 +0,0 @@ -value; - } - - /** - * Checks if the principal contains a certain value. - * - * @param string $type - * - * @return bool - */ - public function is($type) - { - return in_array($type, $this->value); - } - - /** - * Adds a resourcetype value to this property. - * - * @param string $type - */ - public function add($type) - { - $this->value[] = $type; - $this->value = array_unique($this->value); - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - return new self(parent::xmlDeserialize($reader)); - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - return implode( - ', ', - array_map([$html, 'xmlName'], $this->getValue()) - ); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php deleted file mode 100644 index fdd5555..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php +++ /dev/null @@ -1,135 +0,0 @@ -value = $shareAccess; - } - - /** - * Returns the current value. - * - * @return int - */ - public function getValue() - { - return $this->value; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - switch ($this->value) { - case SharingPlugin::ACCESS_NOTSHARED: - $writer->writeElement('{DAV:}not-shared'); - break; - case SharingPlugin::ACCESS_SHAREDOWNER: - $writer->writeElement('{DAV:}shared-owner'); - break; - case SharingPlugin::ACCESS_READ: - $writer->writeElement('{DAV:}read'); - break; - case SharingPlugin::ACCESS_READWRITE: - $writer->writeElement('{DAV:}read-write'); - break; - case SharingPlugin::ACCESS_NOACCESS: - $writer->writeElement('{DAV:}no-access'); - break; - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseInnerTree(); - foreach ($elems as $elem) { - switch ($elem['name']) { - case '{DAV:}not-shared': - return new self(SharingPlugin::ACCESS_NOTSHARED); - case '{DAV:}shared-owner': - return new self(SharingPlugin::ACCESS_SHAREDOWNER); - case '{DAV:}read': - return new self(SharingPlugin::ACCESS_READ); - case '{DAV:}read-write': - return new self(SharingPlugin::ACCESS_READWRITE); - case '{DAV:}no-access': - return new self(SharingPlugin::ACCESS_NOACCESS); - } - } - throw new BadRequest('Invalid value for {DAV:}share-access element'); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php deleted file mode 100644 index 100829c..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedLock.php +++ /dev/null @@ -1,52 +0,0 @@ -writeElement('{DAV:}lockentry', [ - '{DAV:}lockscope' => ['{DAV:}exclusive' => null], - '{DAV:}locktype' => ['{DAV:}write' => null], - ]); - $writer->writeElement('{DAV:}lockentry', [ - '{DAV:}lockscope' => ['{DAV:}shared' => null], - '{DAV:}locktype' => ['{DAV:}write' => null], - ]); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php deleted file mode 100644 index 6344010..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php +++ /dev/null @@ -1,114 +0,0 @@ -methods = $methods; - } - - /** - * Returns the list of supported http methods. - * - * @return string[] - */ - public function getValue() - { - return $this->methods; - } - - /** - * Returns true or false if the property contains a specific method. - * - * @param string $methodName - * - * @return bool - */ - public function has($methodName) - { - return in_array( - $methodName, - $this->methods - ); - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->getValue() as $val) { - $writer->startElement('{DAV:}supported-method'); - $writer->writeAttribute('name', $val); - $writer->endElement(); - } - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - return implode( - ', ', - array_map([$html, 'h'], $this->getValue()) - ); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php deleted file mode 100644 index 0b4990e..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedReportSet.php +++ /dev/null @@ -1,144 +0,0 @@ -addReport($reports); - } - } - - /** - * Adds a report to this property. - * - * The report must be a string in clark-notation. - * Multiple reports can be specified as an array. - * - * @param mixed $report - */ - public function addReport($report) - { - $report = (array) $report; - - foreach ($report as $r) { - if (!preg_match('/^{([^}]*)}(.*)$/', $r)) { - throw new DAV\Exception('Reportname must be in clark-notation'); - } - $this->reports[] = $r; - } - } - - /** - * Returns the list of supported reports. - * - * @return string[] - */ - public function getValue() - { - return $this->reports; - } - - /** - * Returns true or false if the property contains a specific report. - * - * @param string $reportName - * - * @return bool - */ - public function has($reportName) - { - return in_array( - $reportName, - $this->reports - ); - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->getValue() as $val) { - $writer->startElement('{DAV:}supported-report'); - $writer->startElement('{DAV:}report'); - $writer->writeElement($val); - $writer->endElement(); - $writer->endElement(); - } - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - return implode( - ', ', - array_map([$html, 'xmlName'], $this->getValue()) - ); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php deleted file mode 100644 index 57d12ef..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/Lock.php +++ /dev/null @@ -1,84 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $reader->pushContext(); - $reader->elementMap['{DAV:}owner'] = 'Sabre\\Xml\\Element\\XmlFragment'; - - $values = KeyValue::xmlDeserialize($reader); - - $reader->popContext(); - - $new = new self(); - $new->owner = !empty($values['{DAV:}owner']) ? $values['{DAV:}owner']->getXml() : null; - $new->scope = LockInfo::SHARED; - - if (isset($values['{DAV:}lockscope'])) { - foreach ($values['{DAV:}lockscope'] as $elem) { - if ('{DAV:}exclusive' === $elem['name']) { - $new->scope = LockInfo::EXCLUSIVE; - } - } - } - - return $new; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php deleted file mode 100644 index e0d7e90..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/MkCol.php +++ /dev/null @@ -1,80 +0,0 @@ -value array with properties that are supposed to get set - * during creation of the new collection. - * - * @return array - */ - public function getProperties() - { - return $this->properties; - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $self = new self(); - - $elementMap = $reader->elementMap; - $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop'; - $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue'; - $elementMap['{DAV:}remove'] = 'Sabre\Xml\Element\KeyValue'; - - $elems = $reader->parseInnerTree($elementMap); - - foreach ($elems as $elem) { - if ('{DAV:}set' === $elem['name']) { - $self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']); - } - } - - return $self; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php deleted file mode 100644 index 505e7c7..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropFind.php +++ /dev/null @@ -1,79 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $self = new self(); - - $reader->pushContext(); - $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Element\Elements'; - - foreach (KeyValue::xmlDeserialize($reader) as $k => $v) { - switch ($k) { - case '{DAV:}prop': - $self->properties = $v; - break; - case '{DAV:}allprop': - $self->allProp = true; - } - } - - $reader->popContext(); - - return $self; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php deleted file mode 100644 index 4a27095..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/PropPatch.php +++ /dev/null @@ -1,109 +0,0 @@ -properties as $propertyName => $propertyValue) { - if (is_null($propertyValue)) { - $writer->startElement('{DAV:}remove'); - $writer->write(['{DAV:}prop' => [$propertyName => $propertyValue]]); - $writer->endElement(); - } else { - $writer->startElement('{DAV:}set'); - $writer->write(['{DAV:}prop' => [$propertyName => $propertyValue]]); - $writer->endElement(); - } - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $self = new self(); - - $elementMap = $reader->elementMap; - $elementMap['{DAV:}prop'] = 'Sabre\DAV\Xml\Element\Prop'; - $elementMap['{DAV:}set'] = 'Sabre\Xml\Element\KeyValue'; - $elementMap['{DAV:}remove'] = 'Sabre\Xml\Element\KeyValue'; - - $elems = $reader->parseInnerTree($elementMap); - - foreach ($elems as $elem) { - if ('{DAV:}set' === $elem['name']) { - $self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']); - } - if ('{DAV:}remove' === $elem['name']) { - // Ensuring there are no values. - foreach ($elem['value']['{DAV:}prop'] as $remove => $value) { - $self->properties[$remove] = null; - } - } - } - - return $self; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php deleted file mode 100644 index 79d7dc8..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php +++ /dev/null @@ -1,80 +0,0 @@ -sharees = $sharees; - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseInnerTree([ - '{DAV:}sharee' => 'Sabre\DAV\Xml\Element\Sharee', - '{DAV:}share-access' => 'Sabre\DAV\Xml\Property\ShareAccess', - '{DAV:}prop' => 'Sabre\Xml\Deserializer\keyValue', - ]); - - $sharees = []; - - foreach ($elems as $elem) { - if ('{DAV:}sharee' !== $elem['name']) { - continue; - } - $sharees[] = $elem['value']; - } - - return new self($sharees); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php deleted file mode 100644 index 8dd9576..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Request/SyncCollectionReport.php +++ /dev/null @@ -1,118 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $self = new self(); - - $reader->pushContext(); - - $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Element\Elements'; - $elems = KeyValue::xmlDeserialize($reader); - - $reader->popContext(); - - $required = [ - '{DAV:}sync-token', - '{DAV:}prop', - ]; - - foreach ($required as $elem) { - if (!array_key_exists($elem, $elems)) { - throw new BadRequest('The '.$elem.' element in the {DAV:}sync-collection report is required'); - } - } - - $self->properties = $elems['{DAV:}prop']; - $self->syncToken = $elems['{DAV:}sync-token']; - - if (isset($elems['{DAV:}limit'])) { - $nresults = null; - foreach ($elems['{DAV:}limit'] as $child) { - if ('{DAV:}nresults' === $child['name']) { - $nresults = (int) $child['value']; - } - } - $self->limit = $nresults; - } - - if (isset($elems['{DAV:}sync-level'])) { - $value = $elems['{DAV:}sync-level']; - if ('infinity' === $value) { - $value = \Sabre\DAV\Server::DEPTH_INFINITY; - } - $self->syncLevel = $value; - } - - return $self; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php deleted file mode 100644 index e824cda..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Response/MultiStatus.php +++ /dev/null @@ -1,136 +0,0 @@ -responses = $responses; - $this->syncToken = $syncToken; - } - - /** - * Returns the response list. - * - * @return \Sabre\DAV\Xml\Element\Response[] - */ - public function getResponses() - { - return $this->responses; - } - - /** - * Returns the sync-token, if available. - * - * @return string|null - */ - public function getSyncToken() - { - return $this->syncToken; - } - - /** - * The serialize method is called during xml writing. - * - * It should use the $writer argument to encode this object into XML. - * - * Important note: it is not needed to create the parent element. The - * parent element is already created, and we only have to worry about - * attributes, child elements and text (if any). - * - * Important note 2: If you are writing any new elements, you are also - * responsible for closing them. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->getResponses() as $response) { - $writer->writeElement('{DAV:}response', $response); - } - if ($syncToken = $this->getSyncToken()) { - $writer->writeElement('{DAV:}sync-token', $syncToken); - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elementMap = $reader->elementMap; - $elementMap['{DAV:}prop'] = 'Sabre\\DAV\\Xml\\Element\\Prop'; - $elements = $reader->parseInnerTree($elementMap); - - $responses = []; - $syncToken = null; - - if ($elements) { - foreach ($elements as $elem) { - if ('{DAV:}response' === $elem['name']) { - $responses[] = $elem['value']; - } - if ('{DAV:}sync-token' === $elem['name']) { - $syncToken = $elem['value']; - } - } - } - - return new self($responses, $syncToken); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAV/Xml/Service.php b/lib/vendor/sabre/dav/lib/DAV/Xml/Service.php deleted file mode 100644 index 4406b02..0000000 --- a/lib/vendor/sabre/dav/lib/DAV/Xml/Service.php +++ /dev/null @@ -1,47 +0,0 @@ - 'Sabre\\DAV\\Xml\\Response\\MultiStatus', - '{DAV:}response' => 'Sabre\\DAV\\Xml\\Element\\Response', - - // Requests - '{DAV:}propfind' => 'Sabre\\DAV\\Xml\\Request\\PropFind', - '{DAV:}propertyupdate' => 'Sabre\\DAV\\Xml\\Request\\PropPatch', - '{DAV:}mkcol' => 'Sabre\\DAV\\Xml\\Request\\MkCol', - - // Properties - '{DAV:}resourcetype' => 'Sabre\\DAV\\Xml\\Property\\ResourceType', - ]; - - /** - * This is a default list of namespaces. - * - * If you are defining your own custom namespace, add it here to reduce - * bandwidth and improve legibility of xml bodies. - * - * @var array - */ - public $namespaceMap = [ - 'DAV:' => 'd', - 'http://sabredav.org/ns' => 's', - ]; -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/ACLTrait.php b/lib/vendor/sabre/dav/lib/DAVACL/ACLTrait.php deleted file mode 100644 index 98c1ce3..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/ACLTrait.php +++ /dev/null @@ -1,94 +0,0 @@ - '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - ]; - } - - /** - * Updates the ACL. - * - * This method will receive a list of new ACE's as an array argument. - */ - public function setACL(array $acl) - { - throw new \Sabre\DAV\Exception\Forbidden('Setting ACL is not supported on this node'); - } - - /** - * 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/lib/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php b/lib/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php deleted file mode 100644 index d26f7d2..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php +++ /dev/null @@ -1,178 +0,0 @@ -principalPrefix = $principalPrefix; - $this->principalBackend = $principalBackend; - } - - /** - * This method returns a node for a principal. - * - * 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. - * - * @return DAV\INode - */ - abstract public function getChildForPrincipal(array $principalInfo); - - /** - * Returns the name of this collection. - * - * @return string - */ - public function getName() - { - list(, $name) = Uri\split($this->principalPrefix); - - return $name; - } - - /** - * Return the list of users. - * - * @return array - */ - public function getChildren() - { - if ($this->disableListing) { - throw new DAV\Exception\MethodNotAllowed('Listing members of this collection is disabled'); - } - $children = []; - foreach ($this->principalBackend->getPrincipalsByPrefix($this->principalPrefix) as $principalInfo) { - $children[] = $this->getChildForPrincipal($principalInfo); - } - - return $children; - } - - /** - * Returns a child object, by its name. - * - * @param string $name - * - * @throws DAV\Exception\NotFound - * - * @return DAV\INode - */ - public function getChild($name) - { - $principalInfo = $this->principalBackend->getPrincipalByPath($this->principalPrefix.'/'.$name); - if (!$principalInfo) { - throw new 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. - * - * By default, if multiple properties are submitted to this method, the - * various properties should be combined with 'AND'. If $test is set to - * 'anyof', it should be combined using 'OR'. - * - * This method should simply return a list of 'child names', which may be - * used to call $this->getChild in the future. - * - * @param string $test - * - * @return array - */ - public function searchPrincipals(array $searchProperties, $test = 'allof') - { - $result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties, $test); - $r = []; - - foreach ($result as $row) { - list(, $r[]) = Uri\split($row); - } - - return $r; - } - - /** - * Finds a principal by its URI. - * - * This method may receive any type of uri, but mailto: addresses will be - * the most common. - * - * Implementation of this API is optional. It is currently used by the - * CalDAV system to find principals based on their email addresses. If this - * API is not implemented, some features may not work correctly. - * - * This method must return a relative principal path, or null, if the - * principal was not found or you refuse to find it. - * - * @param string $uri - * - * @return string - */ - public function findByUri($uri) - { - return $this->principalBackend->findByUri($uri, $this->principalPrefix); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Exception/AceConflict.php b/lib/vendor/sabre/dav/lib/DAVACL/Exception/AceConflict.php deleted file mode 100644 index 0fc3f77..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Exception/AceConflict.php +++ /dev/null @@ -1,31 +0,0 @@ -ownerDocument; - - $np = $doc->createElementNS('DAV:', 'd:no-ace-conflict'); - $errorNode->appendChild($np); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php b/lib/vendor/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php deleted file mode 100644 index af1f01c..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NeedPrivileges.php +++ /dev/null @@ -1,73 +0,0 @@ -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 - */ - public function serialize(DAV\Server $server, \DOMElement $errorNode) - { - $doc = $errorNode->ownerDocument; - - $np = $doc->createElementNS('DAV:', 'd:need-privileges'); - $errorNode->appendChild($np); - - foreach ($this->privileges as $privilege) { - $resource = $doc->createElementNS('DAV:', 'd:resource'); - $np->appendChild($resource); - - $resource->appendChild($doc->createElementNS('DAV:', 'd:href', $server->getBaseUri().$this->uri)); - - $priv = $doc->createElementNS('DAV:', 'd:privilege'); - $resource->appendChild($priv); - - preg_match('/^{([^}]*)}(.*)$/', $privilege, $privilegeParts); - $priv->appendChild($doc->createElementNS($privilegeParts[1], 'd:'.$privilegeParts[2])); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NoAbstract.php b/lib/vendor/sabre/dav/lib/DAVACL/Exception/NoAbstract.php deleted file mode 100644 index b9c6616..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NoAbstract.php +++ /dev/null @@ -1,31 +0,0 @@ -ownerDocument; - - $np = $doc->createElementNS('DAV:', 'd:no-abstract'); - $errorNode->appendChild($np); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php b/lib/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php deleted file mode 100644 index d4e7284..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NotRecognizedPrincipal.php +++ /dev/null @@ -1,31 +0,0 @@ -ownerDocument; - - $np = $doc->createElementNS('DAV:', 'd:recognized-principal'); - $errorNode->appendChild($np); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php b/lib/vendor/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php deleted file mode 100644 index c04c5fa..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Exception/NotSupportedPrivilege.php +++ /dev/null @@ -1,31 +0,0 @@ -ownerDocument; - - $np = $doc->createElementNS('DAV:', 'd:not-supported-privilege'); - $errorNode->appendChild($np); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/FS/Collection.php b/lib/vendor/sabre/dav/lib/DAVACL/FS/Collection.php deleted file mode 100644 index 85b04e2..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/FS/Collection.php +++ /dev/null @@ -1,109 +0,0 @@ -acl = $acl; - $this->owner = $owner; - } - - /** - * Returns a specific child node, referenced by its name. - * - * This method must throw Sabre\DAV\Exception\NotFound if the node does not - * exist. - * - * @param string $name - * - * @throws NotFound - * - * @return \Sabre\DAV\INode - */ - public function getChild($name) - { - $path = $this->path.'/'.$name; - - if (!file_exists($path)) { - throw new NotFound('File could not be located'); - } - if ('.' == $name || '..' == $name) { - throw new Forbidden('Permission denied to . and ..'); - } - if (is_dir($path)) { - return new self($path, $this->acl, $this->owner); - } else { - return new File($path, $this->acl, $this->owner); - } - } - - /** - * 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->owner; - } - - /** - * 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 $this->acl; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/FS/File.php b/lib/vendor/sabre/dav/lib/DAVACL/FS/File.php deleted file mode 100644 index 5506aa2..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/FS/File.php +++ /dev/null @@ -1,78 +0,0 @@ -acl = $acl; - $this->owner = $owner; - } - - /** - * 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->owner; - } - - /** - * 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 $this->acl; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php b/lib/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php deleted file mode 100644 index fa476e0..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php +++ /dev/null @@ -1,123 +0,0 @@ -storagePath = $storagePath; - } - - /** - * Returns the name of the node. - * - * This is used to generate the url. - * - * @return string - */ - public function getName() - { - return $this->collectionName; - } - - /** - * Returns a principals' collection of files. - * - * 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. - * - * @return \Sabre\DAV\INode - */ - public function getChildForPrincipal(array $principalInfo) - { - $owner = $principalInfo['uri']; - $acl = [ - [ - 'privilege' => '{DAV:}all', - 'principal' => '{DAV:}owner', - 'protected' => true, - ], - ]; - - list(, $principalBaseName) = Uri\split($owner); - - $path = $this->storagePath.'/'.$principalBaseName; - - if (!is_dir($path)) { - mkdir($path, 0777, true); - } - - return new Collection( - $path, - $acl, - $owner - ); - } - - /** - * 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 [ - [ - 'principal' => '{DAV:}authenticated', - 'privilege' => '{DAV:}read', - 'protected' => true, - ], - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/IACL.php b/lib/vendor/sabre/dav/lib/DAVACL/IACL.php deleted file mode 100644 index 291fb24..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/IACL.php +++ /dev/null @@ -1,72 +0,0 @@ -getChild in the future. - * - * @param string $test - * - * @return array - */ - public function searchPrincipals(array $searchProperties, $test = 'allof'); - - /** - * Finds a principal by its URI. - * - * This method may receive any type of uri, but mailto: addresses will be - * the most common. - * - * Implementation of this API is optional. It is currently used by the - * CalDAV system to find principals based on their email addresses. If this - * API is not implemented, some features may not work correctly. - * - * This method must return a relative principal path, or null, if the - * principal was not found or you refuse to find it. - * - * @param string $uri - * - * @return string - */ - public function findByUri($uri); -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Plugin.php b/lib/vendor/sabre/dav/lib/DAVACL/Plugin.php deleted file mode 100644 index f049784..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Plugin.php +++ /dev/null @@ -1,1545 +0,0 @@ - '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 = []; - - /** - * The ACL plugin allows privileges to be assigned to users that are not - * logged in. To facilitate that, it modifies the auth plugin's behavior - * to only require login when a privileged operation was denied. - * - * Unauthenticated access can be considered a security concern, so it's - * possible to turn this feature off to harden the server's security. - * - * @var bool - */ - public $allowUnauthenticatedAccess = true; - - /** - * Returns a list of features added by this plugin. - * - * This list is used in the response of a HTTP OPTIONS request. - * - * @return array - */ - public function getFeatures() - { - return ['access-control', 'calendarserver-principal-property-search']; - } - - /** - * Returns a list of available methods for a given url. - * - * @param string $uri - * - * @return array - */ - public function getMethods($uri) - { - return ['ACL']; - } - - /** - * Returns a plugin name. - * - * Using this name other plugins will be able to access other plugins - * using Sabre\DAV\Server::getPlugin - * - * @return string - */ - public function getPluginName() - { - return 'acl'; - } - - /** - * 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 - * - * @param string $uri - * - * @return array - */ - public function getSupportedReportSet($uri) - { - return [ - '{DAV:}expand-property', - '{DAV:}principal-match', - '{DAV:}principal-property-search', - '{DAV:}principal-search-property-set', - ]; - } - - /** - * 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 int $recursion - * @param bool $throwExceptions if set to false, this method won't throw exceptions - * - * @throws NeedPrivileges - * @throws NotAuthenticated - * - * @return bool - */ - public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) - { - if (!is_array($privileges)) { - $privileges = [$privileges]; - } - - $acl = $this->getCurrentUserPrivilegeSet($uri); - - $failed = []; - foreach ($privileges as $priv) { - if (!in_array($priv, $acl)) { - $failed[] = $priv; - } - } - - if ($failed) { - if ($this->allowUnauthenticatedAccess && is_null($this->getCurrentUserPrincipal())) { - // We are not authenticated. Kicking in the Auth plugin. - $authPlugin = $this->server->getPlugin('auth'); - $reasons = $authPlugin->getLoginFailedReasons(); - $authPlugin->challenge( - $this->server->httpRequest, - $this->server->httpResponse - ); - throw new NotAuthenticated(implode(', ', $reasons).'. Login was needed for privilege: '.implode(', ', $failed).' on '.$uri); - } - if ($throwExceptions) { - throw new NeedPrivileges($uri, $failed); - } else { - return false; - } - } - - return true; - } - - /** - * Returns the standard users' principal. - * - * This is one authoritative principal url for the current user. - * This method will return null if the user wasn't logged in. - * - * @return string|null - */ - public function getCurrentUserPrincipal() - { - /** @var $authPlugin \Sabre\DAV\Auth\Plugin */ - $authPlugin = $this->server->getPlugin('auth'); - if (!$authPlugin) { - return null; - } - - return $authPlugin->getCurrentPrincipal(); - } - - /** - * Returns a list of principals that's associated to the current - * user, either directly or through group membership. - * - * @return array - */ - public function getCurrentUserPrincipals() - { - $currentUser = $this->getCurrentUserPrincipal(); - - if (is_null($currentUser)) { - return []; - } - - return array_merge( - [$currentUser], - $this->getPrincipalMembership($currentUser) - ); - } - - /** - * Sets the default ACL rules. - * - * These rules are used for all nodes that don't implement the IACL interface. - */ - public function setDefaultAcl(array $acl) - { - $this->defaultAcl = $acl; - } - - /** - * Returns the default ACL rules. - * - * These rules are used for all nodes that don't implement the IACL interface. - * - * @return array - */ - public function getDefaultAcl() - { - return $this->defaultAcl; - } - - /** - * The default ACL rules. - * - * These rules are used for nodes that don't implement IACL. These default - * set of rules allow anyone to do anything, as long as they are - * authenticated. - * - * @var array - */ - protected $defaultAcl = [ - [ - 'principal' => '{DAV:}authenticated', - 'protected' => true, - 'privilege' => '{DAV:}all', - ], - ]; - - /** - * This array holds a cache for all the principals that are associated with - * a single principal. - * - * @var array - */ - protected $principalMembershipCache = []; - - /** - * Returns all the principal groups the specified principal is a member of. - * - * @param string $mainPrincipal - * - * @return array - */ - public function getPrincipalMembership($mainPrincipal) - { - // First check our cache - if (isset($this->principalMembershipCache[$mainPrincipal])) { - return $this->principalMembershipCache[$mainPrincipal]; - } - - $check = [$mainPrincipal]; - $principals = []; - - while (count($check)) { - $principal = array_shift($check); - - $node = $this->server->tree->getNodeForPath($principal); - if ($node instanceof IPrincipal) { - foreach ($node->getGroupMembership() as $groupMember) { - if (!in_array($groupMember, $principals)) { - $check[] = $groupMember; - $principals[] = $groupMember; - } - } - } - } - - // Store the result in the cache - $this->principalMembershipCache[$mainPrincipal] = $principals; - - return $principals; - } - - /** - * Find out of a principal equals another principal. - * - * This is a quick way to find out whether a principal URI is part of a - * group, or any subgroups. - * - * The first argument is the principal URI you want to check against. For - * example the principal group, and the second argument is the principal of - * which you want to find out of it is the same as the first principal, or - * in a member of the first principal's group or subgroups. - * - * So the arguments are not interchangeable. If principal A is in group B, - * passing 'B', 'A' will yield true, but 'A', 'B' is false. - * - * If the second argument is not passed, we will use the current user - * principal. - * - * @param string $checkPrincipal - * @param string $currentPrincipal - * - * @return bool - */ - public function principalMatchesPrincipal($checkPrincipal, $currentPrincipal = null) - { - if (is_null($currentPrincipal)) { - $currentPrincipal = $this->getCurrentUserPrincipal(); - } - if ($currentPrincipal === $checkPrincipal) { - return true; - } - if (is_null($currentPrincipal)) { - return false; - } - - return in_array( - $checkPrincipal, - $this->getPrincipalMembership($currentPrincipal) - ); - } - - /** - * Returns a tree of supported privileges for a resource. - * - * The returned array structure should be in this form: - * - * [ - * [ - * 'privilege' => '{DAV:}read', - * 'abstract' => false, - * 'aggregates' => [] - * ] - * ] - * - * Privileges can be nested using "aggregates". Doing so means that - * if you assign someone the aggregating privilege, all the - * sub-privileges will automatically be granted. - * - * Marking a privilege as abstract means that the privilege cannot be - * directly assigned, but must be assigned via the parent privilege. - * - * So a more complex version might look like this: - * - * [ - * [ - * 'privilege' => '{DAV:}read', - * 'abstract' => false, - * 'aggregates' => [ - * [ - * 'privilege' => '{DAV:}read-acl', - * 'abstract' => false, - * 'aggregates' => [], - * ] - * ] - * ] - * ] - * - * @param string|INode $node - * - * @return array - */ - public function getSupportedPrivilegeSet($node) - { - if (is_string($node)) { - $node = $this->server->tree->getNodeForPath($node); - } - - $supportedPrivileges = null; - if ($node instanceof IACL) { - $supportedPrivileges = $node->getSupportedPrivilegeSet(); - } - - if (is_null($supportedPrivileges)) { - // Default - $supportedPrivileges = [ - '{DAV:}read' => [ - 'abstract' => false, - 'aggregates' => [ - '{DAV:}read-acl' => [ - 'abstract' => false, - 'aggregates' => [], - ], - '{DAV:}read-current-user-privilege-set' => [ - 'abstract' => false, - 'aggregates' => [], - ], - ], - ], - '{DAV:}write' => [ - 'abstract' => false, - 'aggregates' => [ - '{DAV:}write-properties' => [ - 'abstract' => false, - 'aggregates' => [], - ], - '{DAV:}write-content' => [ - 'abstract' => false, - 'aggregates' => [], - ], - '{DAV:}unlock' => [ - 'abstract' => false, - 'aggregates' => [], - ], - ], - ], - ]; - if ($node instanceof DAV\ICollection) { - $supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}bind'] = [ - 'abstract' => false, - 'aggregates' => [], - ]; - $supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}unbind'] = [ - 'abstract' => false, - 'aggregates' => [], - ]; - } - if ($node instanceof IACL) { - $supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}write-acl'] = [ - 'abstract' => false, - 'aggregates' => [], - ]; - } - } - - $this->server->emit( - 'getSupportedPrivilegeSet', - [$node, &$supportedPrivileges] - ); - - return $supportedPrivileges; - } - - /** - * Returns the supported privilege set as a flat list. - * - * This is much easier to parse. - * - * The returned list will be index by privilege name. - * The value is a struct containing the following properties: - * - aggregates - * - abstract - * - concrete - * - * @param string|INode $node - * - * @return array - */ - final public function getFlatPrivilegeSet($node) - { - $privs = [ - 'abstract' => false, - 'aggregates' => $this->getSupportedPrivilegeSet($node), - ]; - - $fpsTraverse = null; - $fpsTraverse = function ($privName, $privInfo, $concrete, &$flat) use (&$fpsTraverse) { - $myPriv = [ - 'privilege' => $privName, - 'abstract' => isset($privInfo['abstract']) && $privInfo['abstract'], - 'aggregates' => [], - 'concrete' => isset($privInfo['abstract']) && $privInfo['abstract'] ? $concrete : $privName, - ]; - - if (isset($privInfo['aggregates'])) { - foreach ($privInfo['aggregates'] as $subPrivName => $subPrivInfo) { - $myPriv['aggregates'][] = $subPrivName; - } - } - - $flat[$privName] = $myPriv; - - if (isset($privInfo['aggregates'])) { - foreach ($privInfo['aggregates'] as $subPrivName => $subPrivInfo) { - $fpsTraverse($subPrivName, $subPrivInfo, $myPriv['concrete'], $flat); - } - } - }; - - $flat = []; - $fpsTraverse('{DAV:}all', $privs, null, $flat); - - return $flat; - } - - /** - * Returns the full ACL list. - * - * Either a uri or a INode may be passed. - * - * null will be returned if the node doesn't support ACLs. - * - * @param string|DAV\INode $node - * - * @return array - */ - public function getAcl($node) - { - if (is_string($node)) { - $node = $this->server->tree->getNodeForPath($node); - } - if (!$node instanceof IACL) { - return $this->getDefaultAcl(); - } - $acl = $node->getACL(); - foreach ($this->adminPrincipals as $adminPrincipal) { - $acl[] = [ - 'principal' => $adminPrincipal, - 'privilege' => '{DAV:}all', - 'protected' => true, - ]; - } - - return $acl; - } - - /** - * Returns a list of privileges the current user has - * on a particular node. - * - * Either a uri or a DAV\INode may be passed. - * - * null will be returned if the node doesn't support ACLs. - * - * @param string|DAV\INode $node - * - * @return array - */ - public function getCurrentUserPrivilegeSet($node) - { - if (is_string($node)) { - $node = $this->server->tree->getNodeForPath($node); - } - - $acl = $this->getACL($node); - - $collected = []; - - $isAuthenticated = null !== $this->getCurrentUserPrincipal(); - - foreach ($acl as $ace) { - $principal = $ace['principal']; - - switch ($principal) { - case '{DAV:}owner': - $owner = $node->getOwner(); - if ($owner && $this->principalMatchesPrincipal($owner)) { - $collected[] = $ace; - } - break; - - // 'all' matches for every user - case '{DAV:}all': - $collected[] = $ace; - break; - - case '{DAV:}authenticated': - // Authenticated users only - if ($isAuthenticated) { - $collected[] = $ace; - } - break; - - case '{DAV:}unauthenticated': - // Unauthenticated users only - if (!$isAuthenticated) { - $collected[] = $ace; - } - break; - - default: - if ($this->principalMatchesPrincipal($ace['principal'])) { - $collected[] = $ace; - } - break; - } - } - - // Now we deduct all aggregated privileges. - $flat = $this->getFlatPrivilegeSet($node); - - $collected2 = []; - while (count($collected)) { - $current = array_pop($collected); - $collected2[] = $current['privilege']; - - if (!isset($flat[$current['privilege']])) { - // Ignoring privileges that are not in the supported-privileges list. - $this->server->getLogger()->debug('A node has the "'.$current['privilege'].'" in its ACL list, but this privilege was not reported in the supportedPrivilegeSet list. This will be ignored.'); - continue; - } - foreach ($flat[$current['privilege']]['aggregates'] as $subPriv) { - $collected2[] = $subPriv; - $collected[] = $flat[$subPriv]; - } - } - - return array_values(array_unique($collected2)); - } - - /** - * Returns a principal based on its uri. - * - * Returns null if the principal could not be found. - * - * @param string $uri - * - * @return string|null - */ - public function getPrincipalByUri($uri) - { - $result = null; - $collections = $this->principalCollectionSet; - foreach ($collections as $collection) { - try { - $principalCollection = $this->server->tree->getNodeForPath($collection); - } catch (NotFound $e) { - // Ignore and move on - continue; - } - - if (!$principalCollection instanceof IPrincipalCollection) { - // Not a principal collection, we're simply going to ignore - // this. - continue; - } - - $result = $principalCollection->findByUri($uri); - if ($result) { - return $result; - } - } - } - - /** - * 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 omitted, the standard - * principal collection-set will be used - * @param string $test "allof" to use AND to search the - * properties. 'anyof' for OR. - * - * @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, $test = 'allof') - { - if (!is_null($collectionUri)) { - $uris = [$collectionUri]; - } else { - $uris = $this->principalCollectionSet; - } - - $lookupResults = []; - foreach ($uris as $uri) { - $principalCollection = $this->server->tree->getNodeForPath($uri); - if (!$principalCollection instanceof IPrincipalCollection) { - // Not a principal collection, we're simply going to ignore - // this. - continue; - } - - $results = $principalCollection->searchPrincipals($searchProperties, $test); - foreach ($results as $result) { - $lookupResults[] = rtrim($uri, '/').'/'.$result; - } - } - - $matches = []; - - foreach ($lookupResults as $lookupResult) { - list($matches[]) = $this->server->getPropertiesForPath($lookupResult, $requestedProperties, 0); - } - - return $matches; - } - - /** - * Sets up the plugin. - * - * This method is automatically called by the server class. - */ - public function initialize(DAV\Server $server) - { - if ($this->allowUnauthenticatedAccess) { - $authPlugin = $server->getPlugin('auth'); - if (!$authPlugin) { - throw new \Exception('The Auth plugin must be loaded before the ACL plugin if you want to allow unauthenticated access.'); - } - $authPlugin->autoRequireLogin = false; - } - - $this->server = $server; - $server->on('propFind', [$this, 'propFind'], 20); - $server->on('beforeMethod:*', [$this, 'beforeMethod'], 20); - $server->on('beforeBind', [$this, 'beforeBind'], 20); - $server->on('beforeUnbind', [$this, 'beforeUnbind'], 20); - $server->on('propPatch', [$this, 'propPatch']); - $server->on('beforeUnlock', [$this, 'beforeUnlock'], 20); - $server->on('report', [$this, 'report']); - $server->on('method:ACL', [$this, 'httpAcl']); - $server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']); - $server->on('getPrincipalByUri', function ($principal, &$uri) { - $uri = $this->getPrincipalByUri($principal); - - // Break event chain - if ($uri) { - return false; - } - }); - - array_push($server->protectedProperties, - '{DAV:}alternate-URI-set', - '{DAV:}principal-URL', - '{DAV:}group-membership', - '{DAV:}principal-collection-set', - '{DAV:}current-user-principal', - '{DAV:}supported-privilege-set', - '{DAV:}current-user-privilege-set', - '{DAV:}acl', - '{DAV:}acl-restrictions', - '{DAV:}inherited-acl-set', - '{DAV:}owner', - '{DAV:}group' - ); - - // 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 - // class. - $server->xml->elementMap['{DAV:}group-member-set'] = 'Sabre\\DAV\\Xml\\Property\\Href'; - $server->xml->elementMap['{DAV:}acl'] = 'Sabre\\DAVACL\\Xml\\Property\\Acl'; - $server->xml->elementMap['{DAV:}acl-principal-prop-set'] = 'Sabre\\DAVACL\\Xml\\Request\\AclPrincipalPropSetReport'; - $server->xml->elementMap['{DAV:}expand-property'] = 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport'; - $server->xml->elementMap['{DAV:}principal-property-search'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport'; - $server->xml->elementMap['{DAV:}principal-search-property-set'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport'; - $server->xml->elementMap['{DAV:}principal-match'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalMatchReport'; - } - - /* {{{ Event handlers */ - - /** - * Triggered before any method is handled. - */ - public function beforeMethod(RequestInterface $request, ResponseInterface $response) - { - $method = $request->getMethod(); - $path = $request->getPath(); - - $exists = $this->server->tree->nodeExists($path); - - // If the node doesn't exists, none of these checks apply - if (!$exists) { - return; - } - - switch ($method) { - case 'GET': - case 'HEAD': - case 'OPTIONS': - // For these 3 we only need to know if the node is readable. - $this->checkPrivileges($path, '{DAV:}read'); - break; - - case 'PUT': - case 'LOCK': - // 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($path, '{DAV:}write-content'); - break; - - case 'UNLOCK': - // Unlock is always allowed at the moment. - break; - - case 'PROPPATCH': - $this->checkPrivileges($path, '{DAV:}write-properties'); - break; - - case 'ACL': - $this->checkPrivileges($path, '{DAV:}write-acl'); - break; - - 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 - // beforeUnbind event. - // - // 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. - $this->checkPrivileges($path, '{DAV:}read', self::R_RECURSIVE); - break; - } - } - - /** - * 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 - */ - public function beforeBind($uri) - { - list($parentUri) = Uri\split($uri); - $this->checkPrivileges($parentUri, '{DAV:}bind'); - } - - /** - * Triggered before a node is deleted. - * - * This allows us to check permissions for any operation that will delete - * an existing node. - * - * @param string $uri - */ - public function beforeUnbind($uri) - { - list($parentUri) = Uri\split($uri); - $this->checkPrivileges($parentUri, '{DAV:}unbind', self::R_RECURSIVEPARENTS); - } - - /** - * Triggered before a node is unlocked. - * - * @param string $uri - * @TODO: not yet implemented - */ - public function beforeUnlock($uri, DAV\Locks\LockInfo $lock) - { - } - - /** - * Triggered before properties are looked up in specific nodes. - * - * @TODO really should be broken into multiple methods, or even a class. - */ - public function propFind(DAV\PropFind $propFind, DAV\INode $node) - { - $path = $propFind->getPath(); - - // Checking the read permission - if (!$this->checkPrivileges($path, '{DAV:}read', self::R_PARENT, false)) { - // User is not allowed to read properties - - // Returning false causes the property-fetching system to pretend - // that the node does not exist, and will cause it to be hidden - // from listings such as PROPFIND or the browser plugin. - if ($this->hideNodesFromListings) { - return false; - } - - // Otherwise we simply mark every property as 403. - foreach ($propFind->getRequestedProperties() as $requestedProperty) { - $propFind->set($requestedProperty, null, 403); - } - - return; - } - - /* Adding principal properties */ - if ($node instanceof IPrincipal) { - $propFind->handle('{DAV:}alternate-URI-set', function () use ($node) { - return new Href($node->getAlternateUriSet()); - }); - $propFind->handle('{DAV:}principal-URL', function () use ($node) { - return new Href($node->getPrincipalUrl().'/'); - }); - $propFind->handle('{DAV:}group-member-set', function () use ($node) { - $members = $node->getGroupMemberSet(); - foreach ($members as $k => $member) { - $members[$k] = rtrim($member, '/').'/'; - } - - return new Href($members); - }); - $propFind->handle('{DAV:}group-membership', function () use ($node) { - $members = $node->getGroupMembership(); - foreach ($members as $k => $member) { - $members[$k] = rtrim($member, '/').'/'; - } - - return new Href($members); - }); - $propFind->handle('{DAV:}displayname', [$node, 'getDisplayName']); - } - - $propFind->handle('{DAV:}principal-collection-set', function () { - $val = $this->principalCollectionSet; - // Ensuring all collections end with a slash - foreach ($val as $k => $v) { - $val[$k] = $v.'/'; - } - - return new Href($val); - }); - $propFind->handle('{DAV:}current-user-principal', function () { - if ($url = $this->getCurrentUserPrincipal()) { - return new Xml\Property\Principal(Xml\Property\Principal::HREF, $url.'/'); - } else { - return new Xml\Property\Principal(Xml\Property\Principal::UNAUTHENTICATED); - } - }); - $propFind->handle('{DAV:}supported-privilege-set', function () use ($node) { - return new Xml\Property\SupportedPrivilegeSet($this->getSupportedPrivilegeSet($node)); - }); - $propFind->handle('{DAV:}current-user-privilege-set', function () use ($node, $propFind, $path) { - if (!$this->checkPrivileges($path, '{DAV:}read-current-user-privilege-set', self::R_PARENT, false)) { - $propFind->set('{DAV:}current-user-privilege-set', null, 403); - } else { - $val = $this->getCurrentUserPrivilegeSet($node); - - return new Xml\Property\CurrentUserPrivilegeSet($val); - } - }); - $propFind->handle('{DAV:}acl', function () use ($node, $propFind, $path) { - /* The ACL property contains all the permissions */ - if (!$this->checkPrivileges($path, '{DAV:}read-acl', self::R_PARENT, false)) { - $propFind->set('{DAV:}acl', null, 403); - } else { - $acl = $this->getACL($node); - - return new Xml\Property\Acl($this->getACL($node)); - } - }); - $propFind->handle('{DAV:}acl-restrictions', function () { - return new Xml\Property\AclRestrictions(); - }); - - /* Adding ACL properties */ - if ($node instanceof IACL) { - $propFind->handle('{DAV:}owner', function () use ($node) { - return new Href($node->getOwner().'/'); - }); - } - } - - /** - * This method intercepts PROPPATCH methods and make sure the - * group-member-set is updated correctly. - * - * @param string $path - */ - public function propPatch($path, DAV\PropPatch $propPatch) - { - $propPatch->handle('{DAV:}group-member-set', function ($value) use ($path) { - if (is_null($value)) { - $memberSet = []; - } elseif ($value instanceof Href) { - $memberSet = array_map( - [$this->server, 'calculateUri'], - $value->getHrefs() - ); - } else { - throw new DAV\Exception('The group-member-set property MUST be an instance of Sabre\DAV\Property\HrefList or null'); - } - $node = $this->server->tree->getNodeForPath($path); - if (!($node instanceof IPrincipal)) { - // Fail - return false; - } - - $node->setGroupMemberSet($memberSet); - // We must also clear our cache, just in case - - $this->principalMembershipCache = []; - - return true; - }); - } - - /** - * This method handles HTTP REPORT requests. - * - * @param string $reportName - * @param mixed $report - * @param mixed $path - */ - public function report($reportName, $report, $path) - { - switch ($reportName) { - case '{DAV:}principal-property-search': - $this->server->transactionType = 'report-principal-property-search'; - $this->principalPropertySearchReport($path, $report); - - return false; - case '{DAV:}principal-search-property-set': - $this->server->transactionType = 'report-principal-search-property-set'; - $this->principalSearchPropertySetReport($path, $report); - - return false; - case '{DAV:}expand-property': - $this->server->transactionType = 'report-expand-property'; - $this->expandPropertyReport($path, $report); - - return false; - case '{DAV:}principal-match': - $this->server->transactionType = 'report-principal-match'; - $this->principalMatchReport($path, $report); - - return false; - case '{DAV:}acl-principal-prop-set': - $this->server->transactionType = 'acl-principal-prop-set'; - $this->aclPrincipalPropSetReport($path, $report); - - return false; - } - } - - /** - * This method is responsible for handling the 'ACL' event. - * - * @return bool - */ - public function httpAcl(RequestInterface $request, ResponseInterface $response) - { - $path = $request->getPath(); - $body = $request->getBodyAsString(); - - if (!$body) { - throw new DAV\Exception\BadRequest('XML body expected in ACL request'); - } - - $acl = $this->server->xml->expect('{DAV:}acl', $body); - $newAcl = $acl->getPrivileges(); - - // Normalizing urls - foreach ($newAcl as $k => $newAce) { - $newAcl[$k]['principal'] = $this->server->calculateUri($newAce['principal']); - } - $node = $this->server->tree->getNodeForPath($path); - - if (!$node instanceof IACL) { - throw new DAV\Exception\MethodNotAllowed('This node does not support the ACL method'); - } - - $oldAcl = $this->getACL($node); - - $supportedPrivileges = $this->getFlatPrivilegeSet($node); - - /* Checking if protected principals from the existing principal set are - not overwritten. */ - foreach ($oldAcl as $oldAce) { - if (!isset($oldAce['protected']) || !$oldAce['protected']) { - continue; - } - - $found = false; - foreach ($newAcl as $newAce) { - if ( - $newAce['privilege'] === $oldAce['privilege'] && - $newAce['principal'] === $oldAce['principal'] && - $newAce['protected'] - ) { - $found = true; - } - } - - if (!$found) { - throw new Exception\AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request'); - } - } - - foreach ($newAcl as $newAce) { - // Do we recognize the privilege - if (!isset($supportedPrivileges[$newAce['privilege']])) { - throw new Exception\NotSupportedPrivilege('The privilege you specified ('.$newAce['privilege'].') is not recognized by this server'); - } - - if ($supportedPrivileges[$newAce['privilege']]['abstract']) { - throw new Exception\NoAbstract('The privilege you specified ('.$newAce['privilege'].') is an abstract privilege'); - } - - // Looking up the principal - try { - $principal = $this->server->tree->getNodeForPath($newAce['principal']); - } catch (NotFound $e) { - throw new Exception\NotRecognizedPrincipal('The specified principal ('.$newAce['principal'].') does not exist'); - } - if (!($principal instanceof IPrincipal)) { - throw new Exception\NotRecognizedPrincipal('The specified uri ('.$newAce['principal'].') is not a principal'); - } - } - $node->setACL($newAcl); - - $response->setStatus(200); - - // Breaking the event chain, because we handled this method. - return false; - } - - /* }}} */ - - /* Reports {{{ */ - - /** - * The principal-match report is defined in RFC3744, section 9.3. - * - * This report allows a client to figure out based on the current user, - * or a principal URL, the principal URL and principal URLs of groups that - * principal belongs to. - * - * @param string $path - */ - protected function principalMatchReport($path, Xml\Request\PrincipalMatchReport $report) - { - $depth = $this->server->getHTTPDepth(0); - if (0 !== $depth) { - throw new BadRequest('The principal-match report is only defined on Depth: 0'); - } - - $currentPrincipals = $this->getCurrentUserPrincipals(); - - $result = []; - - if (Xml\Request\PrincipalMatchReport::SELF === $report->type) { - // Finding all principals under the request uri that match the - // current principal. - foreach ($currentPrincipals as $currentPrincipal) { - if ($currentPrincipal === $path || 0 === strpos($currentPrincipal, $path.'/')) { - $result[] = $currentPrincipal; - } - } - } else { - // We need to find all resources that have a property that matches - // one of the current principals. - $candidates = $this->server->getPropertiesForPath( - $path, - [$report->principalProperty], - 1 - ); - - foreach ($candidates as $candidate) { - if (!isset($candidate[200][$report->principalProperty])) { - continue; - } - - $hrefs = $candidate[200][$report->principalProperty]; - - if (!$hrefs instanceof Href) { - continue; - } - - foreach ($hrefs->getHrefs() as $href) { - if (in_array(trim($href, '/'), $currentPrincipals)) { - $result[] = $candidate['href']; - continue 2; - } - } - } - } - - $responses = []; - - foreach ($result as $item) { - $properties = []; - - if ($report->properties) { - $foo = $this->server->getPropertiesForPath($item, $report->properties); - $foo = $foo[0]; - $item = $foo['href']; - unset($foo['href']); - $properties = $foo; - } - - $responses[] = new DAV\Xml\Element\Response( - $item, - $properties, - '200' - ); - } - - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setBody( - $this->server->xml->write( - '{DAV:}multistatus', - $responses, - $this->server->getBaseUri() - ) - ); - } - - /** - * 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 - * {DAV:}href element, follow that property and grab additional elements - * there. - * - * Other rfc's, such as ACL rely on this report, so it made sense to put - * it in this plugin. - * - * @param string $path - * @param Xml\Request\ExpandPropertyReport $report - */ - protected function expandPropertyReport($path, $report) - { - $depth = $this->server->getHTTPDepth(0); - - $result = $this->expandProperties($path, $report->properties, $depth); - - $xml = $this->server->xml->write( - '{DAV:}multistatus', - new DAV\Xml\Response\MultiStatus($result), - $this->server->getBaseUri() - ); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setBody($xml); - } - - /** - * This method expands all the properties and returns - * a list with property values. - * - * @param array $path - * @param array $requestedProperties the list of required properties - * @param int $depth - * - * @return array - */ - protected function expandProperties($path, array $requestedProperties, $depth) - { - $foundProperties = $this->server->getPropertiesForPath($path, array_keys($requestedProperties), $depth); - - $result = []; - - foreach ($foundProperties as $node) { - foreach ($requestedProperties as $propertyName => $childRequestedProperties) { - // We're only traversing if sub-properties were requested - if (!is_array($childRequestedProperties) || 0 === count($childRequestedProperties)) { - 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; - } - - if (!$node[200][$propertyName] instanceof DAV\Xml\Property\Href) { - continue; - } - - $childHrefs = $node[200][$propertyName]->getHrefs(); - $childProps = []; - - foreach ($childHrefs as $href) { - // Gathering the result of the children - $childProps[] = [ - 'name' => '{DAV:}response', - 'value' => $this->expandProperties($href, $childRequestedProperties, 0)[0], - ]; - } - - // Replacing the property with its expanded form. - $node[200][$propertyName] = $childProps; - } - $result[] = new DAV\Xml\Element\Response($node['href'], $node); - } - - return $result; - } - - /** - * principalSearchPropertySetReport. - * - * 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 string $path - * @param Xml\Request\PrincipalSearchPropertySetReport $report - */ - protected function principalSearchPropertySetReport($path, $report) - { - $httpDepth = $this->server->getHTTPDepth(0); - if (0 !== $httpDepth) { - throw new DAV\Exception\BadRequest('This report is only defined when Depth: 0'); - } - - $writer = $this->server->xml->getWriter(); - $writer->openMemory(); - $writer->startDocument(); - - $writer->startElement('{DAV:}principal-search-property-set'); - - foreach ($this->principalSearchPropertySet as $propertyName => $description) { - $writer->startElement('{DAV:}principal-search-property'); - $writer->startElement('{DAV:}prop'); - - $writer->writeElement($propertyName); - - $writer->endElement(); // prop - - if ($description) { - $writer->write([[ - 'name' => '{DAV:}description', - 'value' => $description, - 'attributes' => ['xml:lang' => 'en'], - ]]); - } - - $writer->endElement(); // principal-search-property - } - - $writer->endElement(); // principal-search-property-set - - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setStatus(200); - $this->server->httpResponse->setBody($writer->outputMemory()); - } - - /** - * principalPropertySearchReport. - * - * 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 string $path - */ - protected function principalPropertySearchReport($path, Xml\Request\PrincipalPropertySearchReport $report) - { - if ($report->applyToPrincipalCollectionSet) { - $path = null; - } - if (0 !== $this->server->getHttpDepth('0')) { - throw new BadRequest('Depth must be 0'); - } - $result = $this->principalSearch( - $report->searchProperties, - $report->properties, - $path, - $report->test - ); - - $prefer = $this->server->getHTTPPrefer(); - - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); - $this->server->httpResponse->setBody($this->server->generateMultiStatus($result, 'minimal' === $prefer['return'])); - } - - /** - * aclPrincipalPropSet REPORT. - * - * This method is responsible for handling the {DAV:}acl-principal-prop-set - * REPORT, as defined in: - * - * https://tools.ietf.org/html/rfc3744#section-9.2 - * - * This REPORT allows a user to quickly fetch information about all - * principals specified in the access control list. Most commonly this - * is used to for example generate a UI with ACL rules, allowing you - * to show names for principals for every entry. - * - * @param string $path - */ - protected function aclPrincipalPropSetReport($path, Xml\Request\AclPrincipalPropSetReport $report) - { - if (0 !== $this->server->getHTTPDepth(0)) { - throw new BadRequest('The {DAV:}acl-principal-prop-set REPORT only supports Depth 0'); - } - - // Fetching ACL rules for the given path. We're using the property - // API and not the local getACL, because it will ensure that all - // business rules and restrictions are applied. - $acl = $this->server->getProperties($path, '{DAV:}acl'); - - if (!$acl || !isset($acl['{DAV:}acl'])) { - throw new Forbidden('Could not fetch ACL rules for this path'); - } - - $principals = []; - foreach ($acl['{DAV:}acl']->getPrivileges() as $ace) { - if ('{' === $ace['principal'][0]) { - // It's not a principal, it's one of the special rules such as {DAV:}authenticated - continue; - } - - $principals[] = $ace['principal']; - } - - $properties = $this->server->getPropertiesForMultiplePaths( - $principals, - $report->properties - ); - - $this->server->httpResponse->setStatus(207); - $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); - $this->server->httpResponse->setBody( - $this->server->generateMultiStatus($properties) - ); - } - - /* }}} */ - - /** - * This method is used to generate HTML output for the - * DAV\Browser\Plugin. This allows us to generate an interface users - * can use to create new calendars. - * - * @param string $output - * - * @return bool - */ - public function htmlActionsPanel(DAV\INode $node, &$output) - { - if (!$node instanceof PrincipalCollection) { - return; - } - - $output .= '
-

Create new principal

- - -
-
-
- -
- '; - - return false; - } - - /** - * Returns a bunch of meta-data about the plugin. - * - * Providing this information is optional, and is mainly displayed by the - * Browser plugin. - * - * The description key in the returned array may contain html and will not - * be sanitized. - * - * @return array - */ - public function getPluginInfo() - { - return [ - 'name' => $this->getPluginName(), - 'description' => 'Adds support for WebDAV ACL (rfc3744)', - 'link' => 'http://sabre.io/dav/acl/', - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Principal.php b/lib/vendor/sabre/dav/lib/DAVACL/Principal.php deleted file mode 100644 index ada38ab..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Principal.php +++ /dev/null @@ -1,199 +0,0 @@ -principalBackend = $principalBackend; - $this->principalProperties = $principalProperties; - } - - /** - * Returns the full principal url. - * - * @return string - */ - public function getPrincipalUrl() - { - return $this->principalProperties['uri']; - } - - /** - * Returns a list of alternative urls for a principal. - * - * This can for example be an email address, or ldap url. - * - * @return array - */ - public function getAlternateUriSet() - { - $uris = []; - if (isset($this->principalProperties['{DAV:}alternate-URI-set'])) { - $uris = $this->principalProperties['{DAV:}alternate-URI-set']; - } - - if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) { - $uris[] = 'mailto:'.$this->principalProperties['{http://sabredav.org/ns}email-address']; - } - - 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. - * - * @return array - */ - public function getGroupMemberSet() - { - return $this->principalBackend->getGroupMemberSet($this->principalProperties['uri']); - } - - /** - * 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 - */ - public function getGroupMembership() - { - return $this->principalBackend->getGroupMemberShip($this->principalProperties['uri']); - } - - /** - * Sets a list of group members. - * - * 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. - */ - public function setGroupMemberSet(array $groupMembers) - { - $this->principalBackend->setGroupMemberSet($this->principalProperties['uri'], $groupMembers); - } - - /** - * Returns this principals name. - * - * @return string - */ - public function getName() - { - $uri = $this->principalProperties['uri']; - list(, $name) = Uri\split($uri); - - return $name; - } - - /** - * Returns the name of the user. - * - * @return string - */ - public function getDisplayName() - { - if (isset($this->principalProperties['{DAV:}displayname'])) { - return $this->principalProperties['{DAV:}displayname']; - } else { - return $this->getName(); - } - } - - /** - * Returns a list of properties. - * - * @param array $requestedProperties - * - * @return array - */ - public function getProperties($requestedProperties) - { - $newProperties = []; - foreach ($requestedProperties as $propName) { - if (isset($this->principalProperties[$propName])) { - $newProperties[$propName] = $this->principalProperties[$propName]; - } - } - - return $newProperties; - } - - /** - * Updates properties on this node. - * - * This method received a PropPatch object, which contains all the - * information about the update. - * - * To update specific properties, call the 'handle' method on this object. - * Read the PropPatch documentation for more information. - */ - public function propPatch(DAV\PropPatch $propPatch) - { - return $this->principalBackend->updatePrincipal( - $this->principalProperties['uri'], - $propPatch - ); - } - - /** - * 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->principalProperties['uri']; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php b/lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php deleted file mode 100644 index f61a0c9..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/AbstractBackend.php +++ /dev/null @@ -1,54 +0,0 @@ -searchPrincipals( - $principalPrefix, - ['{http://sabredav.org/ns}email-address' => substr($uri, 7)] - ); - - if ($result) { - return $result[0]; - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php b/lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php deleted file mode 100644 index 2fd3191..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/BackendInterface.php +++ /dev/null @@ -1,143 +0,0 @@ - [ - 'dbField' => 'displayname', - ], - - /* - * This is the users' primary email-address. - */ - '{http://sabredav.org/ns}email-address' => [ - 'dbField' => 'email', - ], - ]; - - /** - * Sets up the backend. - */ - public function __construct(\PDO $pdo) - { - $this->pdo = $pdo; - } - - /** - * Returns a list of principals based on a prefix. - * - * 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 - * 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 actually injected in a number of other properties. If - * you have an email address, use this property. - * - * @param string $prefixPath - * - * @return array - */ - public function getPrincipalsByPrefix($prefixPath) - { - $fields = [ - 'uri', - ]; - - foreach ($this->fieldMap as $key => $value) { - $fields[] = $value['dbField']; - } - $result = $this->pdo->query('SELECT '.implode(',', $fields).' FROM '.$this->tableName); - - $principals = []; - - while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { - // Checking if the principal is in the prefix - list($rowPrefix) = Uri\split($row['uri']); - if ($rowPrefix !== $prefixPath) { - continue; - } - - $principal = [ - 'uri' => $row['uri'], - ]; - foreach ($this->fieldMap as $key => $value) { - if ($row[$value['dbField']]) { - $principal[$key] = $row[$value['dbField']]; - } - } - $principals[] = $principal; - } - - return $principals; - } - - /** - * 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 - */ - public function getPrincipalByPath($path) - { - $fields = [ - 'id', - 'uri', - ]; - - foreach ($this->fieldMap as $key => $value) { - $fields[] = $value['dbField']; - } - $stmt = $this->pdo->prepare('SELECT '.implode(',', $fields).' FROM '.$this->tableName.' WHERE uri = ?'); - $stmt->execute([$path]); - - $row = $stmt->fetch(\PDO::FETCH_ASSOC); - if (!$row) { - return; - } - - $principal = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - ]; - 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 stored in a Sabre\DAV\PropPatch object. - * To do the actual updates, you must tell this object which properties - * you're going to process with the handle() method. - * - * Calling the handle method is like telling the PropPatch object "I - * promise I can handle updating this property". - * - * Read the PropPatch documentation for more info and examples. - * - * @param string $path - */ - public function updatePrincipal($path, DAV\PropPatch $propPatch) - { - $propPatch->handle(array_keys($this->fieldMap), function ($properties) use ($path) { - $query = 'UPDATE '.$this->tableName.' SET '; - $first = true; - - $values = []; - - foreach ($properties as $key => $value) { - $dbField = $this->fieldMap[$key]['dbField']; - - if (!$first) { - $query .= ', '; - } - $first = false; - $query .= $dbField.' = :'.$dbField; - $values[$dbField] = $value; - } - - $query .= ' WHERE uri = :uri'; - $values['uri'] = $path; - - $stmt = $this->pdo->prepare($query); - $stmt->execute($values); - - return true; - }); - } - - /** - * 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. - * - * 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. - * - * By default, if multiple properties are submitted to this method, the - * various properties should be combined with 'AND'. If $test is set to - * 'anyof', it should be combined using 'OR'. - * - * 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 string $test - * - * @return array - */ - public function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') - { - if (0 == count($searchProperties)) { - return []; - } //No criteria - - $query = 'SELECT uri FROM '.$this->tableName.' WHERE '; - $values = []; - foreach ($searchProperties as $property => $value) { - switch ($property) { - case '{DAV:}displayname': - $column = 'displayname'; - break; - case '{http://sabredav.org/ns}email-address': - $column = 'email'; - break; - default: - // Unsupported property - return []; - } - if (count($values) > 0) { - $query .= (0 == strcmp($test, 'anyof') ? ' OR ' : ' AND '); - } - $query .= 'lower('.$column.') LIKE lower(?)'; - $values[] = '%'.$value.'%'; - } - $stmt = $this->pdo->prepare($query); - $stmt->execute($values); - - $principals = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - // Checking if the principal is in the prefix - list($rowPrefix) = Uri\split($row['uri']); - if ($rowPrefix !== $prefixPath) { - continue; - } - - $principals[] = $row['uri']; - } - - return $principals; - } - - /** - * Finds a principal by its URI. - * - * This method may receive any type of uri, but mailto: addresses will be - * the most common. - * - * Implementation of this API is optional. It is currently used by the - * CalDAV system to find principals based on their email addresses. If this - * API is not implemented, some features may not work correctly. - * - * This method must return a relative principal path, or null, if the - * principal was not found or you refuse to find it. - * - * @param string $uri - * @param string $principalPrefix - * - * @return string - */ - public function findByUri($uri, $principalPrefix) - { - $uriParts = Uri\parse($uri); - - // Only two types of uri are supported : - // - the "mailto:" scheme with some non-empty address - // - a principals uri, in the form "principals/NAME" - // In both cases, `path` must not be empty. - if (empty($uriParts['path'])) { - return null; - } - - $uri = null; - if ('mailto' === $uriParts['scheme']) { - $query = 'SELECT uri FROM '.$this->tableName.' WHERE lower(email)=lower(?)'; - $stmt = $this->pdo->prepare($query); - $stmt->execute([$uriParts['path']]); - - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - // Checking if the principal is in the prefix - list($rowPrefix) = Uri\split($row['uri']); - if ($rowPrefix !== $principalPrefix) { - continue; - } - - $uri = $row['uri']; - break; //Stop on first match - } - } else { - $pathParts = Uri\split($uriParts['path']); // We can do this since $uriParts['path'] is not null - - if (2 === count($pathParts) && $pathParts[0] === $principalPrefix) { - // Checking that this uri exists - $query = 'SELECT * FROM '.$this->tableName.' WHERE uri = ?'; - $stmt = $this->pdo->prepare($query); - $stmt->execute([$uriParts['path']]); - $rows = $stmt->fetchAll(); - - if (count($rows) > 0) { - $uri = $uriParts['path']; - } - } - } - - return $uri; - } - - /** - * 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 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->execute([$principal['id']]); - - $result = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $result[] = $row['uri']; - } - - return $result; - } - - /** - * 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 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->execute([$principal['id']]); - - $result = []; - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $result[] = $row['uri']; - } - - return $result; - } - - /** - * Updates the list of group members for a group principal. - * - * The principals should be passed as a list of uri's. - * - * @param string $principal - */ - 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->execute(array_merge([$principal], $members)); - - $memberIds = []; - $principalId = null; - - while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - if ($row['uri'] == $principal) { - $principalId = $row['id']; - } else { - $memberIds[] = $row['id']; - } - } - if (!$principalId) { - throw new DAV\Exception('Principal not found'); - } - // Wiping out old members - $stmt = $this->pdo->prepare('DELETE FROM '.$this->groupMembersTableName.' WHERE principal_id = ?;'); - $stmt->execute([$principalId]); - - foreach ($memberIds as $memberId) { - $stmt = $this->pdo->prepare('INSERT INTO '.$this->groupMembersTableName.' (principal_id, member_id) VALUES (?, ?);'); - $stmt->execute([$principalId, $memberId]); - } - } - - /** - * Creates a new principal. - * - * This method receives a full path for the new principal. The mkCol object - * contains any additional webdav properties specified during the creation - * of the principal. - * - * @param string $path - */ - public function createPrincipal($path, MkCol $mkCol) - { - $stmt = $this->pdo->prepare('INSERT INTO '.$this->tableName.' (uri) VALUES (?)'); - $stmt->execute([$path]); - $this->updatePrincipal($path, $mkCol); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php b/lib/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php deleted file mode 100644 index b823b6c..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php +++ /dev/null @@ -1,96 +0,0 @@ -principalBackend, $principal); - } - - /** - * Creates a new collection. - * - * This method will receive a MkCol object with all the information about - * the new collection that's being created. - * - * The MkCol object contains information about the resourceType of the new - * collection. If you don't support the specified resourceType, you should - * throw Exception\InvalidResourceType. - * - * The object also contains a list of WebDAV properties for the new - * collection. - * - * You should call the handle() method on this object to specify exactly - * which properties you are storing. This allows the system to figure out - * exactly which properties you didn't store, which in turn allows other - * plugins (such as the propertystorage plugin) to handle storing the - * property for you. - * - * @param string $name - * - * @throws InvalidResourceType - */ - public function createExtendedCollection($name, MkCol $mkCol) - { - if (!$mkCol->hasResourceType('{DAV:}principal')) { - throw new InvalidResourceType('Only resources of type {DAV:}principal may be created here'); - } - - $this->principalBackend->createPrincipal( - $this->principalPrefix.'/'.$name, - $mkCol - ); - } - - /** - * 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 [ - [ - 'principal' => '{DAV:}authenticated', - 'privilege' => '{DAV:}read', - 'protected' => true, - ], - ]; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php deleted file mode 100644 index c6e236d..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Acl.php +++ /dev/null @@ -1,257 +0,0 @@ -privileges = $privileges; - $this->prefixBaseUrl = $prefixBaseUrl; - } - - /** - * Returns the list of privileges for this property. - * - * @return array - */ - public function getPrivileges() - { - return $this->privileges; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->privileges as $ace) { - $this->serializeAce($writer, $ace); - } - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - ob_start(); - echo ''; - echo ''; - foreach ($this->privileges as $privilege) { - echo ''; - // if it starts with a {, it's a special principal - if ('{' === $privilege['principal'][0]) { - echo ''; - } else { - echo ''; - } - echo ''; - echo ''; - echo ''; - } - echo '
PrincipalPrivilege
', $html->xmlName($privilege['principal']), '', $html->link($privilege['principal']), '', $html->xmlName($privilege['privilege']), ''; - if (!empty($privilege['protected'])) { - echo '(protected)'; - } - echo '
'; - - return ob_get_clean(); - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elementMap = [ - '{DAV:}ace' => 'Sabre\Xml\Element\KeyValue', - '{DAV:}privilege' => 'Sabre\Xml\Element\Elements', - '{DAV:}principal' => 'Sabre\DAVACL\Xml\Property\Principal', - ]; - - $privileges = []; - - foreach ((array) $reader->parseInnerTree($elementMap) as $element) { - if ('{DAV:}ace' !== $element['name']) { - continue; - } - $ace = $element['value']; - - if (empty($ace['{DAV:}principal'])) { - throw new DAV\Exception\BadRequest('Each {DAV:}ace element must have one {DAV:}principal element'); - } - $principal = $ace['{DAV:}principal']; - - switch ($principal->getType()) { - case Principal::HREF: - $principal = $principal->getHref(); - break; - case Principal::AUTHENTICATED: - $principal = '{DAV:}authenticated'; - break; - case Principal::UNAUTHENTICATED: - $principal = '{DAV:}unauthenticated'; - break; - case Principal::ALL: - $principal = '{DAV:}all'; - break; - } - - $protected = array_key_exists('{DAV:}protected', $ace); - - if (!isset($ace['{DAV:}grant'])) { - throw new DAV\Exception\NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported'); - } - foreach ($ace['{DAV:}grant'] as $elem) { - if ('{DAV:}privilege' !== $elem['name']) { - continue; - } - - foreach ($elem['value'] as $priv) { - $privileges[] = [ - 'principal' => $principal, - 'protected' => $protected, - 'privilege' => $priv, - ]; - } - } - } - - return new self($privileges); - } - - /** - * Serializes a single access control entry. - */ - private function serializeAce(Writer $writer, array $ace) - { - $writer->startElement('{DAV:}ace'); - - switch ($ace['principal']) { - case '{DAV:}authenticated': - $principal = new Principal(Principal::AUTHENTICATED); - break; - case '{DAV:}unauthenticated': - $principal = new Principal(Principal::UNAUTHENTICATED); - break; - case '{DAV:}all': - $principal = new Principal(Principal::ALL); - break; - default: - $principal = new Principal(Principal::HREF, $ace['principal']); - break; - } - - $writer->writeElement('{DAV:}principal', $principal); - $writer->startElement('{DAV:}grant'); - $writer->startElement('{DAV:}privilege'); - - $writer->writeElement($ace['privilege']); - - $writer->endElement(); // privilege - $writer->endElement(); // grant - - if (!empty($ace['protected'])) { - $writer->writeElement('{DAV:}protected'); - } - - $writer->endElement(); // ace - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php deleted file mode 100644 index b5629c8..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/AclRestrictions.php +++ /dev/null @@ -1,42 +0,0 @@ -writeElement('{DAV:}grant-only'); - $writer->writeElement('{DAV:}no-invert'); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php deleted file mode 100644 index e38a45c..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/CurrentUserPrivilegeSet.php +++ /dev/null @@ -1,145 +0,0 @@ -privileges = $privileges; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - foreach ($this->privileges as $privName) { - $writer->startElement('{DAV:}privilege'); - $writer->writeElement($privName); - $writer->endElement(); - } - } - - /** - * Returns true or false, whether the specified principal appears in the - * list. - * - * @param string $privilegeName - * - * @return bool - */ - public function has($privilegeName) - { - return in_array($privilegeName, $this->privileges); - } - - /** - * Returns the list of privileges. - * - * @return array - */ - public function getValue() - { - return $this->privileges; - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $result = []; - - $tree = $reader->parseInnerTree(['{DAV:}privilege' => 'Sabre\\Xml\\Element\\Elements']); - foreach ($tree as $element) { - if ('{DAV:}privilege' !== $element['name']) { - continue; - } - $result[] = $element['value'][0]; - } - - return new self($result); - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - return implode( - ', ', - array_map([$html, 'xmlName'], $this->getValue()) - ); - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php deleted file mode 100644 index 5b9ee45..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/Principal.php +++ /dev/null @@ -1,186 +0,0 @@ -type = $type; - if (self::HREF === $type && is_null($href)) { - throw new DAV\Exception('The href argument must be specified for the HREF principal type.'); - } - if ($href) { - $href = rtrim($href, '/').'/'; - parent::__construct($href); - } - } - - /** - * Returns the principal type. - * - * @return int - */ - public function getType() - { - return $this->type; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - switch ($this->type) { - case self::UNAUTHENTICATED: - $writer->writeElement('{DAV:}unauthenticated'); - break; - case self::AUTHENTICATED: - $writer->writeElement('{DAV:}authenticated'); - break; - case self::HREF: - parent::xmlSerialize($writer); - break; - case self::ALL: - $writer->writeElement('{DAV:}all'); - break; - } - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - switch ($this->type) { - case self::UNAUTHENTICATED: - return 'unauthenticated'; - case self::AUTHENTICATED: - return 'authenticated'; - case self::HREF: - return parent::toHtml($html); - case self::ALL: - return 'all'; - } - - return 'unknown'; - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $tree = $reader->parseInnerTree()[0]; - - switch ($tree['name']) { - case '{DAV:}unauthenticated': - return new self(self::UNAUTHENTICATED); - case '{DAV:}authenticated': - return new self(self::AUTHENTICATED); - case '{DAV:}href': - return new self(self::HREF, $tree['value']); - case '{DAV:}all': - return new self(self::ALL); - default: - throw new BadRequest('Unknown or unsupported principal type: '.$tree['name']); - } - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php deleted file mode 100644 index 6e7514b..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php +++ /dev/null @@ -1,146 +0,0 @@ -privileges = $privileges; - } - - /** - * Returns the privilege value. - * - * @return array - */ - public function getValue() - { - return $this->privileges; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - $this->serializePriv($writer, '{DAV:}all', ['aggregates' => $this->privileges]); - } - - /** - * Generate html representation for this value. - * - * The html output is 100% trusted, and no effort is being made to sanitize - * it. It's up to the implementor to sanitize user provided values. - * - * The output must be in UTF-8. - * - * The baseUri parameter is a url to the root of the application, and can - * be used to construct local links. - * - * @return string - */ - public function toHtml(HtmlOutputHelper $html) - { - $traverse = function ($privName, $priv) use (&$traverse, $html) { - echo '
  • '; - echo $html->xmlName($privName); - if (isset($priv['abstract']) && $priv['abstract']) { - echo ' (abstract)'; - } - if (isset($priv['description'])) { - echo ' '.$html->h($priv['description']); - } - if (isset($priv['aggregates'])) { - echo "\n
      \n"; - foreach ($priv['aggregates'] as $subPrivName => $subPriv) { - $traverse($subPrivName, $subPriv); - } - echo '
    '; - } - echo "
  • \n"; - }; - - ob_start(); - echo '
      '; - $traverse('{DAV:}all', ['aggregates' => $this->getValue()]); - echo "
    \n"; - - return ob_get_clean(); - } - - /** - * Serializes a property. - * - * This is a recursive function. - * - * @param string $privName - * @param array $privilege - */ - private function serializePriv(Writer $writer, $privName, $privilege) - { - $writer->startElement('{DAV:}supported-privilege'); - - $writer->startElement('{DAV:}privilege'); - $writer->writeElement($privName); - $writer->endElement(); // privilege - - if (!empty($privilege['abstract'])) { - $writer->writeElement('{DAV:}abstract'); - } - if (!empty($privilege['description'])) { - $writer->writeElement('{DAV:}description', $privilege['description']); - } - if (isset($privilege['aggregates'])) { - foreach ($privilege['aggregates'] as $subPrivName => $subPrivilege) { - $this->serializePriv($writer, $subPrivName, $subPrivilege); - } - } - - $writer->endElement(); // supported-privilege - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php deleted file mode 100644 index 4fc6127..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php +++ /dev/null @@ -1,66 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $reader->pushContext(); - $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Deserializer\enum'; - - $elems = Deserializer\keyValue( - $reader, - 'DAV:' - ); - - $reader->popContext(); - - $report = new self(); - - if (!empty($elems['prop'])) { - $report->properties = $elems['prop']; - } - - return $report; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php deleted file mode 100644 index 70a7e22..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/ExpandPropertyReport.php +++ /dev/null @@ -1,100 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $elems = $reader->parseInnerTree(); - - $obj = new self(); - $obj->properties = self::traverse($elems); - - return $obj; - } - - /** - * This method is used by deserializeXml, to recursively parse the - * {DAV:}property elements. - * - * @param array $elems - * - * @return array - */ - private static function traverse($elems) - { - $result = []; - - foreach ($elems as $elem) { - if ('{DAV:}property' !== $elem['name']) { - continue; - } - - $namespace = isset($elem['attributes']['namespace']) ? - $elem['attributes']['namespace'] : - 'DAV:'; - - $propName = '{'.$namespace.'}'.$elem['attributes']['name']; - - $value = null; - if (is_array($elem['value'])) { - $value = self::traverse($elem['value']); - } - - $result[$propName] = $value; - } - - return $result; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php deleted file mode 100644 index b495824..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php +++ /dev/null @@ -1,106 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $reader->pushContext(); - $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Deserializer\enum'; - - $elems = Deserializer\keyValue( - $reader, - 'DAV:' - ); - - $reader->popContext(); - - $principalMatch = new self(); - - if (array_key_exists('self', $elems)) { - $principalMatch->type = self::SELF; - } - - if (array_key_exists('principal-property', $elems)) { - $principalMatch->type = self::PRINCIPAL_PROPERTY; - $principalMatch->principalProperty = $elems['principal-property'][0]['name']; - } - - if (!empty($elems['prop'])) { - $principalMatch->properties = $elems['prop']; - } - - return $principalMatch; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php deleted file mode 100644 index bddceca..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalPropertySearchReport.php +++ /dev/null @@ -1,122 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - $self = new self(); - - $foundSearchProp = false; - $self->test = 'allof'; - if ('anyof' === $reader->getAttribute('test')) { - $self->test = 'anyof'; - } - - $elemMap = [ - '{DAV:}property-search' => 'Sabre\\Xml\\Element\\KeyValue', - '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', - ]; - - foreach ($reader->parseInnerTree($elemMap) as $elem) { - switch ($elem['name']) { - case '{DAV:}prop': - $self->properties = array_keys($elem['value']); - break; - case '{DAV:}property-search': - $foundSearchProp = true; - // This property has two sub-elements: - // {DAV:}prop - The property to be searched on. This may - // also be more than one - // {DAV:}match - The value to match with - if (!isset($elem['value']['{DAV:}prop']) || !isset($elem['value']['{DAV:}match'])) { - throw new BadRequest('The {DAV:}property-search element must contain one {DAV:}match and one {DAV:}prop element'); - } - foreach ($elem['value']['{DAV:}prop'] as $propName => $discard) { - $self->searchProperties[$propName] = $elem['value']['{DAV:}match']; - } - break; - case '{DAV:}apply-to-principal-collection-set': - $self->applyToPrincipalCollectionSet = true; - break; - } - } - if (!$foundSearchProp) { - throw new BadRequest('The {DAV:}principal-property-search report must contain at least 1 {DAV:}property-search element'); - } - - return $self; - } -} diff --git a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php b/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php deleted file mode 100644 index 7f15d8a..0000000 --- a/lib/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalSearchPropertySetReport.php +++ /dev/null @@ -1,58 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @return mixed - */ - public static function xmlDeserialize(Reader $reader) - { - if (!$reader->isEmptyElement) { - throw new BadRequest('The {DAV:}principal-search-property-set element must be empty'); - } - - // The element is actually empty, so there's not much to do. - $reader->next(); - - $self = new self(); - - return $self; - } -} diff --git a/lib/vendor/sabre/event/.php-cs-fixer.dist.php b/lib/vendor/sabre/event/.php-cs-fixer.dist.php deleted file mode 100644 index 319886c..0000000 --- a/lib/vendor/sabre/event/.php-cs-fixer.dist.php +++ /dev/null @@ -1,18 +0,0 @@ -exclude('vendor') - ->in(__DIR__); - -$config = new PhpCsFixer\Config(); -$config->setRules([ - '@PSR1' => true, - '@Symfony' => true, - 'blank_line_between_import_groups' => false, - 'nullable_type_declaration' => [ - 'syntax' => 'question_mark', - ], - 'nullable_type_declaration_for_default_null_value' => true, -]); -$config->setFinder($finder); -return $config; \ No newline at end of file diff --git a/lib/vendor/sabre/event/LICENSE b/lib/vendor/sabre/event/LICENSE deleted file mode 100644 index 962a492..0000000 --- a/lib/vendor/sabre/event/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (C) 2013-2016 fruux GmbH (https://fruux.com/) - -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 Sabre 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/lib/vendor/sabre/event/composer.json b/lib/vendor/sabre/event/composer.json deleted file mode 100644 index 0d3ec06..0000000 --- a/lib/vendor/sabre/event/composer.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "sabre/event", - "description": "sabre/event is a library for lightweight event-based programming", - "keywords": [ - "Events", - "EventEmitter", - "Promise", - "Hooks", - "Plugin", - "Signal", - "Async", - "EventLoop", - "Reactor", - "Coroutine" - ], - "homepage": "http://sabre.io/event/", - "license": "BSD-3-Clause", - "require": { - "php": "^7.1 || ^8.0" - }, - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "source": "https://github.com/fruux/sabre-event" - }, - "autoload": { - "psr-4": { - "Sabre\\Event\\": "lib/" - }, - "files" : [ - "lib/coroutine.php", - "lib/Loop/functions.php", - "lib/Promise/functions.php" - ] - }, - "autoload-dev": { - "psr-4" : { - "Sabre\\Event\\" : "tests/Event" - } - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1||^3.63", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.6" - }, - "scripts": { - "phpstan": [ - "phpstan analyse lib tests" - ], - "cs-fixer": [ - "PHP_CS_FIXER_IGNORE_ENV=true php-cs-fixer fix" - ], - "phpunit": [ - "phpunit --configuration tests/phpunit.xml" - ], - "test": [ - "composer phpstan", - "composer cs-fixer", - "composer phpunit" - ] - } -} diff --git a/lib/vendor/sabre/event/lib/Emitter.php b/lib/vendor/sabre/event/lib/Emitter.php deleted file mode 100644 index e1f23fc..0000000 --- a/lib/vendor/sabre/event/lib/Emitter.php +++ /dev/null @@ -1,19 +0,0 @@ -listeners[$eventName])) { - $this->listeners[$eventName] = [ - true, // If there's only one item, it's sorted - [$priority], - [$callBack], - ]; - } else { - $this->listeners[$eventName][0] = false; // marked as unsorted - $this->listeners[$eventName][1][] = $priority; - $this->listeners[$eventName][2][] = $callBack; - } - } - - /** - * Subscribe to an event exactly once. - */ - public function once(string $eventName, callable $callBack, int $priority = 100) - { - $wrapper = null; - $wrapper = function () use ($eventName, $callBack, &$wrapper) { - $this->removeListener($eventName, $wrapper); - - return \call_user_func_array($callBack, \func_get_args()); - }; - - $this->on($eventName, $wrapper, $priority); - } - - /** - * Emits an event. - * - * This method will return true if 0 or more listeners were successfully - * handled. false is returned if one of the events broke the event chain. - * - * If the continueCallBack is specified, this callback will be called every - * time before the next event handler is called. - * - * If the continueCallback returns false, event propagation stops. This - * allows you to use the eventEmitter as a means for listeners to implement - * functionality in your application, and break the event loop as soon as - * some condition is fulfilled. - * - * Note that returning false from an event subscriber breaks propagation - * and returns false, but if the continue-callback stops propagation, this - * is still considered a 'successful' operation and returns true. - * - * Lastly, if there are 5 event handlers for an event. The continueCallback - * will be called at most 4 times. - */ - public function emit(string $eventName, array $arguments = [], ?callable $continueCallBack = null): bool - { - if (\is_null($continueCallBack)) { - foreach ($this->listeners($eventName) as $listener) { - $result = \call_user_func_array($listener, $arguments); - if (false === $result) { - return false; - } - } - } else { - $listeners = $this->listeners($eventName); - $counter = \count($listeners); - - foreach ($listeners as $listener) { - --$counter; - $result = \call_user_func_array($listener, $arguments); - if (false === $result) { - return false; - } - - if ($counter > 0) { - if (!$continueCallBack()) { - break; - } - } - } - } - - return true; - } - - /** - * Returns the list of listeners for an event. - * - * The list is returned as an array, and the list of events are sorted by - * their priority. - * - * @return callable[] - */ - public function listeners(string $eventName): array - { - if (!isset($this->listeners[$eventName])) { - return []; - } - - // The list is not sorted - if (!$this->listeners[$eventName][0]) { - // Sorting - \array_multisort($this->listeners[$eventName][1], SORT_NUMERIC, $this->listeners[$eventName][2]); - - // Marking the listeners as sorted - $this->listeners[$eventName][0] = true; - } - - return $this->listeners[$eventName][2]; - } - - /** - * Removes a specific listener from an event. - * - * If the listener could not be found, this method will return false. If it - * was removed it will return true. - */ - public function removeListener(string $eventName, callable $listener): bool - { - if (!isset($this->listeners[$eventName])) { - return false; - } - foreach ($this->listeners[$eventName][2] as $index => $check) { - if ($check === $listener) { - unset($this->listeners[$eventName][1][$index]); - unset($this->listeners[$eventName][2][$index]); - - return true; - } - } - - return false; - } - - /** - * Removes all listeners. - * - * If the eventName argument is specified, all listeners for that event are - * removed. If it is not specified, every listener for every event is - * removed. - */ - public function removeAllListeners(?string $eventName = null) - { - if (!\is_null($eventName)) { - unset($this->listeners[$eventName]); - } else { - $this->listeners = []; - } - } - - /** - * The list of listeners. - * - * @var array - */ - protected $listeners = []; -} diff --git a/lib/vendor/sabre/event/lib/EventEmitter.php b/lib/vendor/sabre/event/lib/EventEmitter.php deleted file mode 100644 index 865c99b..0000000 --- a/lib/vendor/sabre/event/lib/EventEmitter.php +++ /dev/null @@ -1,20 +0,0 @@ -timers) { - // Special case when the timers array was empty. - $this->timers[] = [$triggerTime, $cb]; - - return; - } - - // We need to insert these values in the timers array, but the timers - // array must be in reverse-order of trigger times. - // - // So here we search the array for the insertion point. - $index = count($this->timers) - 1; - while (true) { - if ($triggerTime < $this->timers[$index][0]) { - array_splice( - $this->timers, - $index + 1, - 0, - [[$triggerTime, $cb]] - ); - break; - } elseif (0 === $index) { - array_unshift($this->timers, [$triggerTime, $cb]); - break; - } - --$index; - } - } - - /** - * Executes a function every x seconds. - * - * The value this function returns can be used to stop the interval with - * clearInterval. - */ - public function setInterval(callable $cb, float $timeout): array - { - $keepGoing = true; - $f = null; - - $f = function () use ($cb, &$f, $timeout, &$keepGoing) { - if ($keepGoing) { - $cb(); - $this->setTimeout($f, $timeout); - } - }; - $this->setTimeout($f, $timeout); - - // Really the only thing that matters is returning the $keepGoing - // boolean value. - // - // We need to pack it in an array to allow returning by reference. - // Because I'm worried people will be confused by using a boolean as a - // sort of identifier, I added an extra string. - return ['I\'m an implementation detail', &$keepGoing]; - } - - /** - * Stops a running interval. - */ - public function clearInterval(array $intervalId) - { - $intervalId[1] = false; - } - - /** - * Runs a function immediately at the next iteration of the loop. - */ - public function nextTick(callable $cb) - { - $this->nextTick[] = $cb; - } - - /** - * Adds a read stream. - * - * The callback will be called as soon as there is something to read from - * the stream. - * - * You MUST call removeReadStream after you are done with the stream, to - * prevent the eventloop from never stopping. - * - * @param resource $stream - */ - public function addReadStream($stream, callable $cb) - { - $this->readStreams[(int) $stream] = $stream; - $this->readCallbacks[(int) $stream] = $cb; - } - - /** - * Adds a write stream. - * - * The callback will be called as soon as the system reports it's ready to - * receive writes on the stream. - * - * You MUST call removeWriteStream after you are done with the stream, to - * prevent the eventloop from never stopping. - * - * @param resource $stream - */ - public function addWriteStream($stream, callable $cb) - { - $this->writeStreams[(int) $stream] = $stream; - $this->writeCallbacks[(int) $stream] = $cb; - } - - /** - * Stop watching a stream for reads. - * - * @param resource $stream - */ - public function removeReadStream($stream) - { - unset( - $this->readStreams[(int) $stream], - $this->readCallbacks[(int) $stream] - ); - } - - /** - * Stop watching a stream for writes. - * - * @param resource $stream - */ - public function removeWriteStream($stream) - { - unset( - $this->writeStreams[(int) $stream], - $this->writeCallbacks[(int) $stream] - ); - } - - /** - * Runs the loop. - * - * This function will run continuously, until there's no more events to - * handle. - */ - public function run() - { - $this->running = true; - - do { - $hasEvents = $this->tick(true); - } while ($this->running && $hasEvents); - $this->running = false; - } - - /** - * Executes all pending events. - * - * If $block is turned true, this function will block until any event is - * triggered. - * - * If there are now timeouts, nextTick callbacks or events in the loop at - * all, this function will exit immediately. - * - * This function will return true if there are _any_ events left in the - * loop after the tick. - */ - public function tick(bool $block = false): bool - { - $this->runNextTicks(); - $nextTimeout = $this->runTimers(); - - // Calculating how long runStreams should at most wait. - if (!$block) { - // Don't wait - $streamWait = 0; - } elseif ($this->nextTick) { - // There's a pending 'nextTick'. Don't wait. - $streamWait = 0; - } elseif (is_numeric($nextTimeout)) { - // Wait until the next Timeout should trigger. - $streamWait = $nextTimeout; - } else { - // Wait indefinitely - $streamWait = null; - } - - $this->runStreams($streamWait); - - return $this->readStreams || $this->writeStreams || $this->nextTick || $this->timers; - } - - /** - * Stops a running eventloop. - */ - public function stop() - { - $this->running = false; - } - - /** - * Executes all 'nextTick' callbacks. - * - * return void - */ - protected function runNextTicks() - { - $nextTick = $this->nextTick; - $this->nextTick = []; - - foreach ($nextTick as $cb) { - $cb(); - } - } - - /** - * Runs all pending timers. - * - * After running the timer callbacks, this function returns the number of - * seconds until the next timer should be executed. - * - * If there's no more pending timers, this function returns null. - * - * @return float|null - */ - protected function runTimers() - { - $now = microtime(true); - while (($timer = array_pop($this->timers)) && $timer[0] < $now) { - $timer[1](); - } - // Add the last timer back to the array. - if ($timer) { - $this->timers[] = $timer; - - return max(0, $timer[0] - microtime(true)); - } - } - - /** - * Runs all pending stream events. - * - * If $timeout is 0, it will return immediately. If $timeout is null, it - * will wait indefinitely. - * - * @param float|null $timeout - */ - protected function runStreams($timeout) - { - if ($this->readStreams || $this->writeStreams) { - $read = $this->readStreams; - $write = $this->writeStreams; - $except = null; - // stream_select changes behavior in 8.1 to forbid passing non-null microseconds when the seconds are null. - // Older versions of php don't allow passing null to microseconds. - if (null !== $timeout ? stream_select($read, $write, $except, 0, (int) ($timeout * 1000000)) : stream_select($read, $write, $except, null)) { - // See PHP Bug https://bugs.php.net/bug.php?id=62452 - // Fixed in PHP7 - foreach ($read as $readStream) { - $readCb = $this->readCallbacks[(int) $readStream]; - $readCb(); - } - foreach ($write as $writeStream) { - $writeCb = $this->writeCallbacks[(int) $writeStream]; - $writeCb(); - } - } - } elseif ($this->running && ($this->nextTick || $this->timers)) { - usleep(null !== $timeout ? intval($timeout * 1000000) : 200000); - } - } - - /** - * Is the main loop active. - * - * @var bool - */ - protected $running = false; - - /** - * A list of timers, added by setTimeout. - * - * @var array - */ - protected $timers = []; - - /** - * A list of 'nextTick' callbacks. - * - * @var callable[] - */ - protected $nextTick = []; - - /** - * List of readable streams for stream_select, indexed by stream id. - * - * @var resource[] - */ - protected $readStreams = []; - - /** - * List of writable streams for stream_select, indexed by stream id. - * - * @var resource[] - */ - protected $writeStreams = []; - - /** - * List of read callbacks, indexed by stream id. - * - * @var callable[] - */ - protected $readCallbacks = []; - - /** - * List of write callbacks, indexed by stream id. - * - * @var callable[] - */ - protected $writeCallbacks = []; -} diff --git a/lib/vendor/sabre/event/lib/Loop/functions.php b/lib/vendor/sabre/event/lib/Loop/functions.php deleted file mode 100644 index 9412a77..0000000 --- a/lib/vendor/sabre/event/lib/Loop/functions.php +++ /dev/null @@ -1,143 +0,0 @@ -setTimeout($cb, $timeout); -} - -/** - * Executes a function every x seconds. - * - * The value this function returns can be used to stop the interval with - * clearInterval. - */ -function setInterval(callable $cb, float $timeout): array -{ - return instance()->setInterval($cb, $timeout); -} - -/** - * Stops a running interval. - */ -function clearInterval(array $intervalId) -{ - instance()->clearInterval($intervalId); -} - -/** - * Runs a function immediately at the next iteration of the loop. - */ -function nextTick(callable $cb) -{ - instance()->nextTick($cb); -} - -/** - * Adds a read stream. - * - * The callback will be called as soon as there is something to read from - * the stream. - * - * You MUST call removeReadStream after you are done with the stream, to - * prevent the eventloop from never stopping. - * - * @param resource $stream - */ -function addReadStream($stream, callable $cb) -{ - instance()->addReadStream($stream, $cb); -} - -/** - * Adds a write stream. - * - * The callback will be called as soon as the system reports it's ready to - * receive writes on the stream. - * - * You MUST call removeWriteStream after you are done with the stream, to - * prevent the eventloop from never stopping. - * - * @param resource $stream - */ -function addWriteStream($stream, callable $cb) -{ - instance()->addWriteStream($stream, $cb); -} - -/** - * Stop watching a stream for reads. - * - * @param resource $stream - */ -function removeReadStream($stream) -{ - instance()->removeReadStream($stream); -} - -/** - * Stop watching a stream for writes. - * - * @param resource $stream - */ -function removeWriteStream($stream) -{ - instance()->removeWriteStream($stream); -} - -/** - * Runs the loop. - * - * This function will run continuously, until there's no more events to - * handle. - */ -function run() -{ - instance()->run(); -} - -/** - * Executes all pending events. - * - * If $block is turned true, this function will block until any event is - * triggered. - * - * If there are now timeouts, nextTick callbacks or events in the loop at - * all, this function will exit immediately. - * - * This function will return true if there are _any_ events left in the - * loop after the tick. - */ -function tick(bool $block = false): bool -{ - return instance()->tick($block); -} - -/** - * Stops a running eventloop. - */ -function stop() -{ - instance()->stop(); -} - -/** - * Retrieves or sets the global Loop object. - */ -function instance(?Loop $newLoop = null): Loop -{ - static $loop; - if ($newLoop) { - $loop = $newLoop; - } elseif (!$loop) { - $loop = new Loop(); - } - - return $loop; -} diff --git a/lib/vendor/sabre/event/lib/Promise.php b/lib/vendor/sabre/event/lib/Promise.php deleted file mode 100644 index 66903fb..0000000 --- a/lib/vendor/sabre/event/lib/Promise.php +++ /dev/null @@ -1,253 +0,0 @@ -fulfill and $this->reject. - * Using the executor is optional. - */ - public function __construct(?callable $executor = null) - { - if ($executor) { - $executor( - [$this, 'fulfill'], - [$this, 'reject'] - ); - } - } - - /** - * This method allows you to specify the callback that will be called after - * the promise has been fulfilled or rejected. - * - * Both arguments are optional. - * - * This method returns a new promise, which can be used for chaining. - * If either the onFulfilled or onRejected callback is called, you may - * return a result from this callback. - * - * If the result of this callback is yet another promise, the result of - * _that_ promise will be used to set the result of the returned promise. - * - * If either of the callbacks return any other value, the returned promise - * is automatically fulfilled with that value. - * - * If either of the callbacks throw an exception, the returned promise will - * be rejected and the exception will be passed back. - */ - public function then(?callable $onFulfilled = null, ?callable $onRejected = null): Promise - { - // This new subPromise will be returned from this function, and will - // be fulfilled with the result of the onFulfilled or onRejected event - // handlers. - $subPromise = new self(); - - switch ($this->state) { - case self::PENDING: - // The operation is pending, so we keep a reference to the - // event handlers so we can call them later. - $this->subscribers[] = [$subPromise, $onFulfilled, $onRejected]; - break; - case self::FULFILLED: - // The async operation is already fulfilled, so we trigger the - // onFulfilled callback asap. - $this->invokeCallback($subPromise, $onFulfilled); - break; - case self::REJECTED: - // The async operation failed, so we call the onRejected - // callback asap. - $this->invokeCallback($subPromise, $onRejected); - break; - } - - return $subPromise; - } - - /** - * Add a callback for when this promise is rejected. - * - * Its usage is identical to then(). However, the otherwise() function is - * preferred. - */ - public function otherwise(callable $onRejected): Promise - { - return $this->then(null, $onRejected); - } - - /** - * Marks this promise as fulfilled and sets its return value. - */ - public function fulfill($value = null) - { - if (self::PENDING !== $this->state) { - throw new PromiseAlreadyResolvedException('This promise is already resolved, and you\'re not allowed to resolve a promise more than once'); - } - $this->state = self::FULFILLED; - $this->value = $value; - foreach ($this->subscribers as $subscriber) { - $this->invokeCallback($subscriber[0], $subscriber[1]); - } - } - - /** - * Marks this promise as rejected, and set its rejection reason. - */ - public function reject(\Throwable $reason) - { - if (self::PENDING !== $this->state) { - throw new PromiseAlreadyResolvedException('This promise is already resolved, and you\'re not allowed to resolve a promise more than once'); - } - $this->state = self::REJECTED; - $this->value = $reason; - foreach ($this->subscribers as $subscriber) { - $this->invokeCallback($subscriber[0], $subscriber[2]); - } - } - - /** - * Stops execution until this promise is resolved. - * - * This method stops execution completely. If the promise is successful with - * a value, this method will return this value. If the promise was - * rejected, this method will throw an exception. - * - * This effectively turns the asynchronous operation into a synchronous - * one. In PHP it might be useful to call this on the last promise in a - * chain. - * - * @psalm-return TReturn - */ - public function wait() - { - $hasEvents = true; - while (self::PENDING === $this->state) { - if (!$hasEvents) { - throw new \LogicException('There were no more events in the loop. This promise will never be fulfilled.'); - } - - // As long as the promise is not fulfilled, we tell the event loop - // to handle events, and to block. - $hasEvents = Loop\tick(true); - } - - if (self::FULFILLED === $this->state) { - // If the state of this promise is fulfilled, we can return the value. - return $this->value; - } else { - // If we got here, it means that the asynchronous operation - // errored. Therefore we need to throw an exception. - throw $this->value; - } - } - - /** - * A list of subscribers. Subscribers are the callbacks that want us to let - * them know if the callback was fulfilled or rejected. - * - * @var array - */ - protected $subscribers = []; - - /** - * The result of the promise. - * - * If the promise was fulfilled, this will be the result value. If the - * promise was rejected, this property hold the rejection reason. - */ - protected $value; - - /** - * This method is used to call either an onFulfilled or onRejected callback. - * - * This method makes sure that the result of these callbacks are handled - * correctly, and any chained promises are also correctly fulfilled or - * rejected. - */ - private function invokeCallback(Promise $subPromise, ?callable $callBack = null) - { - // We use 'nextTick' to ensure that the event handlers are always - // triggered outside of the calling stack in which they were originally - // passed to 'then'. - // - // This makes the order of execution more predictable. - Loop\nextTick(function () use ($callBack, $subPromise) { - if (is_callable($callBack)) { - try { - $result = $callBack($this->value); - if ($result instanceof self) { - // If the callback (onRejected or onFulfilled) - // returned a promise, we only fulfill or reject the - // chained promise once that promise has also been - // resolved. - $result->then([$subPromise, 'fulfill'], [$subPromise, 'reject']); - } else { - // If the callback returned any other value, we - // immediately fulfill the chained promise. - $subPromise->fulfill($result); - } - } catch (\Throwable $e) { - // If the event handler threw an exception, we need to make sure that - // the chained promise is rejected as well. - $subPromise->reject($e); - } - } else { - if (self::FULFILLED === $this->state) { - $subPromise->fulfill($this->value); - } else { - $subPromise->reject($this->value); - } - } - }); - } -} diff --git a/lib/vendor/sabre/event/lib/Promise/functions.php b/lib/vendor/sabre/event/lib/Promise/functions.php deleted file mode 100644 index 67e80cb..0000000 --- a/lib/vendor/sabre/event/lib/Promise/functions.php +++ /dev/null @@ -1,125 +0,0 @@ - $subPromise) { - $subPromise->then( - function ($result) use ($promiseIndex, &$completeResult, &$successCount, $success, $promises) { - $completeResult[$promiseIndex] = $result; - ++$successCount; - if ($successCount === count($promises)) { - $success($completeResult); - } - - return $result; - } - )->otherwise( - function ($reason) use ($fail) { - $fail($reason); - } - ); - } - }); -} - -/** - * The race function returns a promise that resolves or rejects as soon as - * one of the promises in the argument resolves or rejects. - * - * The returned promise will resolve or reject with the value or reason of - * that first promise. - * - * @param Promise[] $promises - */ -function race(array $promises): Promise -{ - return new Promise(function ($success, $fail) use ($promises) { - $alreadyDone = false; - foreach ($promises as $promise) { - $promise->then( - function ($result) use ($success, &$alreadyDone) { - if ($alreadyDone) { - return; - } - $alreadyDone = true; - $success($result); - }, - function ($reason) use ($fail, &$alreadyDone) { - if ($alreadyDone) { - return; - } - $alreadyDone = true; - $fail($reason); - } - ); - } - }); -} - -/** - * Returns a Promise that resolves with the given value. - * - * If the value is a promise, the returned promise will attach itself to that - * promise and eventually get the same state as the followed promise. - */ -function resolve($value): Promise -{ - if ($value instanceof Promise) { - return $value->then(); - } else { - $promise = new Promise(); - $promise->fulfill($value); - - return $promise; - } -} - -/** - * Returns a Promise that will reject with the given reason. - */ -function reject(\Throwable $reason): Promise -{ - $promise = new Promise(); - $promise->reject($reason); - - return $promise; -} diff --git a/lib/vendor/sabre/event/lib/PromiseAlreadyResolvedException.php b/lib/vendor/sabre/event/lib/PromiseAlreadyResolvedException.php deleted file mode 100644 index abb6c10..0000000 --- a/lib/vendor/sabre/event/lib/PromiseAlreadyResolvedException.php +++ /dev/null @@ -1,17 +0,0 @@ -wildcardListeners; - } else { - $listeners = &$this->listeners; - } - - // Always fully reset the listener index. This is fairly sane for most - // applications, because there's a clear "event registering" and "event - // emitting" phase, but can be slow if there's a lot adding and removing - // of listeners during emitting of events. - $this->listenerIndex = []; - - if (!isset($listeners[$eventName])) { - $listeners[$eventName] = []; - } - $listeners[$eventName][] = [$priority, $callBack]; - } - - /** - * Subscribe to an event exactly once. - */ - public function once(string $eventName, callable $callBack, int $priority = 100) - { - $wrapper = null; - $wrapper = function () use ($eventName, $callBack, &$wrapper) { - $this->removeListener($eventName, $wrapper); - - return \call_user_func_array($callBack, \func_get_args()); - }; - - $this->on($eventName, $wrapper, $priority); - } - - /** - * Emits an event. - * - * This method will return true if 0 or more listeners were successfully - * handled. false is returned if one of the events broke the event chain. - * - * If the continueCallBack is specified, this callback will be called every - * time before the next event handler is called. - * - * If the continueCallback returns false, event propagation stops. This - * allows you to use the eventEmitter as a means for listeners to implement - * functionality in your application, and break the event loop as soon as - * some condition is fulfilled. - * - * Note that returning false from an event subscriber breaks propagation - * and returns false, but if the continue-callback stops propagation, this - * is still considered a 'successful' operation and returns true. - * - * Lastly, if there are 5 event handlers for an event. The continueCallback - * will be called at most 4 times. - */ - public function emit(string $eventName, array $arguments = [], ?callable $continueCallBack = null): bool - { - if (\is_null($continueCallBack)) { - foreach ($this->listeners($eventName) as $listener) { - $result = \call_user_func_array($listener, $arguments); - if (false === $result) { - return false; - } - } - } else { - $listeners = $this->listeners($eventName); - $counter = \count($listeners); - - foreach ($listeners as $listener) { - --$counter; - $result = \call_user_func_array($listener, $arguments); - if (false === $result) { - return false; - } - - if ($counter > 0) { - if (!$continueCallBack()) { - break; - } - } - } - } - - return true; - } - - /** - * Returns the list of listeners for an event. - * - * The list is returned as an array, and the list of events are sorted by - * their priority. - * - * @return callable[] - */ - public function listeners(string $eventName): array - { - if (!\array_key_exists($eventName, $this->listenerIndex)) { - // Create a new index. - $listeners = []; - $listenersPriority = []; - if (isset($this->listeners[$eventName])) { - foreach ($this->listeners[$eventName] as $listener) { - $listenersPriority[] = $listener[0]; - $listeners[] = $listener[1]; - } - } - - foreach ($this->wildcardListeners as $wcEvent => $wcListeners) { - // Wildcard match - if (\substr($eventName, 0, \strlen($wcEvent)) === $wcEvent) { - foreach ($wcListeners as $listener) { - $listenersPriority[] = $listener[0]; - $listeners[] = $listener[1]; - } - } - } - - // Sorting by priority - \array_multisort($listenersPriority, SORT_NUMERIC, $listeners); - - // Creating index - $this->listenerIndex[$eventName] = $listeners; - } - - return $this->listenerIndex[$eventName]; - } - - /** - * Removes a specific listener from an event. - * - * If the listener could not be found, this method will return false. If it - * was removed it will return true. - */ - public function removeListener(string $eventName, callable $listener): bool - { - // If it ends with a wildcard, we use the wildcardListeners array - if ('*' === $eventName[\strlen($eventName) - 1]) { - $eventName = \substr($eventName, 0, -1); - $listeners = &$this->wildcardListeners; - } else { - $listeners = &$this->listeners; - } - - if (!isset($listeners[$eventName])) { - return false; - } - - foreach ($listeners[$eventName] as $index => $check) { - if ($check[1] === $listener) { - // Remove listener - unset($listeners[$eventName][$index]); - // Reset index - $this->listenerIndex = []; - - return true; - } - } - - return false; - } - - /** - * Removes all listeners. - * - * If the eventName argument is specified, all listeners for that event are - * removed. If it is not specified, every listener for every event is - * removed. - */ - public function removeAllListeners(?string $eventName = null) - { - if (\is_null($eventName)) { - $this->listeners = []; - $this->wildcardListeners = []; - } else { - if ('*' === $eventName[\strlen($eventName) - 1]) { - // Wildcard event - unset($this->wildcardListeners[\substr($eventName, 0, -1)]); - } else { - unset($this->listeners[$eventName]); - } - } - - // Reset index - $this->listenerIndex = []; - } - - /** - * The list of listeners. - */ - protected $listeners = []; - - /** - * The list of "wildcard listeners". - */ - protected $wildcardListeners = []; - - /** - * An index of listeners for a specific event name. This helps speeding - * up emitting events after all listeners have been set. - * - * If the list of listeners changes though, the index clears. - */ - protected $listenerIndex = []; -} diff --git a/lib/vendor/sabre/event/lib/coroutine.php b/lib/vendor/sabre/event/lib/coroutine.php deleted file mode 100644 index f664efa..0000000 --- a/lib/vendor/sabre/event/lib/coroutine.php +++ /dev/null @@ -1,122 +0,0 @@ -request('GET', '/foo'); - * $promise->then(function($value) { - * - * return $httpClient->request('DELETE','/foo'); - * - * })->then(function($value) { - * - * return $httpClient->request('PUT', '/foo'); - * - * })->error(function($reason) { - * - * echo "Failed because: $reason\n"; - * - * }); - * - * Example with coroutines: - * - * coroutine(function() { - * - * try { - * yield $httpClient->request('GET', '/foo'); - * yield $httpClient->request('DELETE', /foo'); - * yield $httpClient->request('PUT', '/foo'); - * } catch(\Throwable $reason) { - * echo "Failed because: $reason\n"; - * } - * - * }); - * - * @psalm-template TReturn - * - * @psalm-param callable():\Generator $gen - * - * @psalm-return Promise - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -function coroutine(callable $gen): Promise -{ - $generator = $gen(); - if (!$generator instanceof \Generator) { - throw new \InvalidArgumentException('You must pass a generator function'); - } - - // This is the value we're returning. - $promise = new Promise(); - - /** - * So tempted to use the mythical y-combinator here, but it's not needed in - * PHP. - */ - $advanceGenerator = function () use (&$advanceGenerator, $generator, $promise) { - while ($generator->valid()) { - $yieldedValue = $generator->current(); - if ($yieldedValue instanceof Promise) { - $yieldedValue->then( - function ($value) use ($generator, &$advanceGenerator) { - $generator->send($value); - $advanceGenerator(); - }, - function (\Throwable $reason) use ($generator, $advanceGenerator) { - $generator->throw($reason); - $advanceGenerator(); - } - )->otherwise(function (\Throwable $reason) use ($promise) { - // This error handler would be called, if something in the - // generator throws an exception, and it's not caught - // locally. - $promise->reject($reason); - }); - // We need to break out of the loop, because $advanceGenerator - // will be called asynchronously when the promise has a result. - break; - } else { - // If the value was not a promise, we'll just let it pass through. - $generator->send($yieldedValue); - } - } - - // If the generator is at the end, and we didn't run into an exception, - // We're grabbing the "return" value and fulfilling our top-level - // promise with its value. - if (!$generator->valid() && Promise::PENDING === $promise->state) { - $returnValue = $generator->getReturn(); - - // The return value is a promise. - if ($returnValue instanceof Promise) { - $returnValue->then(function ($value) use ($promise) { - $promise->fulfill($value); - }, function (\Throwable $reason) use ($promise) { - $promise->reject($reason); - }); - } else { - $promise->fulfill($returnValue); - } - } - }; - - try { - $advanceGenerator(); - } catch (\Throwable $e) { - $promise->reject($e); - } - - return $promise; -} diff --git a/lib/vendor/sabre/http/.github/workflows/ci.yml b/lib/vendor/sabre/http/.github/workflows/ci.yml deleted file mode 100644 index 1ec92b8..0000000 --- a/lib/vendor/sabre/http/.github/workflows/ci.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: continuous-integration -on: - push: - branches: - - master - - release/* - pull_request: -jobs: - unit-testing: - name: PHPUnit (PHP ${{ matrix.php-versions }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] - coverage: ['xdebug'] - code-style: ['yes'] - code-analysis: ['no'] - include: - - php-versions: '7.1' - code-style: 'yes' - code-analysis: 'yes' - - php-versions: '8.4' - code-style: 'yes' - code-analysis: 'yes' - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php - with: - php-version: ${{ matrix.php-versions }} - extensions: ctype, curl, mbstring, xdebug - coverage: ${{ matrix.coverage }} - tools: composer - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache composer dependencies - uses: actions/cache@v4 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install composer dependencies - run: composer install --no-progress --prefer-dist --optimize-autoloader - - - name: Code Analysis (PHP CS-Fixer) - if: matrix.code-style == 'yes' - run: PHP_CS_FIXER_IGNORE_ENV=true php vendor/bin/php-cs-fixer fix --dry-run --diff - - - name: Code Analysis (PHPStan) - if: matrix.code-analysis == 'yes' - run: composer phpstan - - - name: Run application server - run: php -S localhost:8000 -t tests/www 2>/dev/null & - - - name: Test with phpunit - run: vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-clover clover.xml - - - name: Code Coverage - uses: codecov/codecov-action@v5 - if: matrix.coverage != 'none' diff --git a/lib/vendor/sabre/http/.gitignore b/lib/vendor/sabre/http/.gitignore deleted file mode 100644 index a5356dd..0000000 --- a/lib/vendor/sabre/http/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Composer -vendor/ -composer.lock - -# Tests -tests/cov/ -.phpunit.result.cache -.php_cs.cache -.php-cs-fixer.cache diff --git a/lib/vendor/sabre/http/.php-cs-fixer.dist.php b/lib/vendor/sabre/http/.php-cs-fixer.dist.php deleted file mode 100644 index f9d4b7a..0000000 --- a/lib/vendor/sabre/http/.php-cs-fixer.dist.php +++ /dev/null @@ -1,17 +0,0 @@ -exclude('vendor') - ->in(__DIR__); - -$config = new PhpCsFixer\Config(); -$config->setRules([ - '@PSR1' => true, - '@Symfony' => true, - 'nullable_type_declaration' => [ - 'syntax' => 'question_mark', - ], - 'nullable_type_declaration_for_default_null_value' => true, -]); -$config->setFinder($finder); -return $config; \ No newline at end of file diff --git a/lib/vendor/sabre/http/.php_cs.dist b/lib/vendor/sabre/http/.php_cs.dist deleted file mode 100644 index c5c78a9..0000000 --- a/lib/vendor/sabre/http/.php_cs.dist +++ /dev/null @@ -1,12 +0,0 @@ -getFinder() - ->exclude('vendor') - ->in(__DIR__); -$config->setRules([ - '@PSR1' => true, - '@Symfony' => true -]); - -return $config; \ No newline at end of file diff --git a/lib/vendor/sabre/http/CHANGELOG.md b/lib/vendor/sabre/http/CHANGELOG.md deleted file mode 100644 index 6a2458c..0000000 --- a/lib/vendor/sabre/http/CHANGELOG.md +++ /dev/null @@ -1,403 +0,0 @@ -ChangeLog -========= - -5.1.13 (2025-09-09) ------------------- - -* #262 properly compute absolute URL (@skjnldsv) - -5.1.12 (2024-08-27) ------------------- - -* #243 add cs-fixer v3 (@phil-davis) - -5.1.11 (2024-07-26) ------------------- - -* #241 PHP 8.4 compliance (@phil-davis) - -5.1.10 (2023-08-18) ------------------- - -* #225 Enhance tests/bootstrap.php to find autoloader in more environments (@phil-davis) - -5.1.9 (2023-08-17) ------------------- - -* #223 skip testParseMimeTypeOnInvalidMimeType (@phil-davis) - -5.1.8 (2023-08-17) ------------------- - -* #215 Improve CURLOPT_HTTPHEADER Setting Assignment (@amrita-shrestha) - -5.1.7 (2023-06-26) ------------------- - -* #98 and #176 Add more tests (@peter279k) -* #207 fix: handle client disconnect properly with ignore_user_abort true (@kesselb) - -5.1.6 (2022-07-15) ------------------- - -* #187 Allow testSendToGetLargeContent peak memory usage to be specified externally (@phil-davis) -* #188 Fix various small typos and grammar (@phil-davis) -* #189 Fix typo in text of status code 203 'Non-Authoritative Information' (@phil-davis) - -5.1.5 (2022-07-09) ------------------- - -* #184 Remove 4GB file size workaround for 32bit OS / Stream Videos on IOS (@schoetju) - -5.1.4 (2022-06-24) ------------------- - -* #182 Fix encoding detection on PHP 8.1 (@come-nc) - -5.1.3 (2021-11-04) ------------------- - -* #179 version bump that was missed in 5.1.2 (@phil-davis) - -5.1.2 (2021-11-04) -------------------------- - -* #169 Ensure $_SERVER keys are read as strings (@fredrik-eriksson) -* #170 Fix deprecated usages on PHP 8.1 (@cedric-anne) -* #175 Add resource size to CURL options in client (from #172 ) (@Dartui) - -5.1.1 (2020-10-03) -------------------------- - -* #160: Added support for PHP 8.0 (@phil-davis) - -5.1.0 (2020-01-31) -------------------------- - -* Added support for PHP 7.4, dropped support for PHP 7.0 (@phil-davis) -* Updated testsuite for phpunit8, added phpstan coverage (@phil-davis) -* Added autoload-dev for test classes (@C0pyR1ght) - -5.0.5 (2019-11-28) -------------------------- - -* #138: Fixed possible infinite loop (@dpakach, @vfreex, @phil-davis) -* #136: Improvement regex content-range (@ho4ho) - -5.0.4 (2019-10-08) -------------------------- - -* #133: Fix short Content-Range download - Regression from 5.0.3 (@phil-davis) - -5.0.3 (2019-10-08) -------------------------- - -* #119: Significantly improve file download speed by enabling mmap based stream_copy_to_stream (@vfreex) - -5.0.2 (2019-09-12) -------------------------- - -* #125: Fix Strict Error if Response Body Empty (@WorksDev, @phil-davis) - -5.0.1 (2019-09-11) -------------------------- - -* #121: fix "Trying to access array offset on value of type bool" in 7.4 (@remicollet) -* #115: Reduce memory footprint when parsing HTTP result (@Gasol) -* #114: Misc code improvements (@mrcnpdlk) -* #111, #118: Added phpstan analysis (@DeepDiver1975, @staabm) -* #107: Tested with php 7.3 (@DeepDiver1975) - - -5.0.0 (2018-06-04) -------------------------- - -* #99: Previous CURL opts are not persisted anymore (@christiaan) -* Final release - -5.0.0-alpha1 (2018-02-16) -------------------------- - -* Now requires PHP 7.0+. -* Supports sabre/event 4.x and 5.x -* Depends on sabre/uri 2. -* hhvm is no longer supported starting this release. -* #65: It's now possible to supply request/response bodies using a callback - functions. This allows very high-speed/low-memory responses to be created. - (@petrkotek). -* Strict typing is used everywhere this is applicable. -* Removed `URLUtil` class. It was deprecated a long time ago, and most of - its functions moved to the `sabre/uri` package. -* Removed `Util` class. Most of its functions moved to the `functions.php` - file. -* #68: The `$method` and `$uri` arguments when constructing a Request object - are now required. -* When `Sapi::getRequest()` is called, we default to setting the HTTP Method - to `CLI`. -* The HTTP response is now initialized with HTTP code `500` instead of `null`, - so if it's not changed, it will be emitted as 500. -* #69: Sending `charset="UTF-8"` on Basic authentication challenges per - [rfc7617][rfc7617]. -* #84: Added support for `SERVER_PROTOCOL HTTP/2.0` (@jens1o) - - -4.2.3 (2017-06-12) ------------------- - -* #74, #77: Work around 4GB file size limit at 32-Bit systems - - -4.2.2 (2017-01-02) ------------------- - -* #72: Handling clients that send invalid `Content-Length` headers. - - -4.2.1 (2016-01-06) ------------------- - -* #56: `getBodyAsString` now returns at most as many bytes as the contents of - the `Content-Length` header. This allows users to pass much larger strings - without having to copy and truncate them. -* The client now sets a default `User-Agent` header identifying this library. - - -4.2.0 (2016-01-04) ------------------- - -* This package now supports sabre/event 3.0. - - -4.1.0 (2015-09-04) ------------------- - -* The async client wouldn't `wait()` for new http requests being started - after the (previous) last request in the queue was resolved. -* Added `Sabre\HTTP\Auth\Bearer`, to easily extract a OAuth2 bearer token. - - -4.0.0 (2015-05-20) ------------------- - -* Deprecated: All static functions from `Sabre\HTTP\URLUtil` and - `Sabre\HTTP\Util` moved to a separate `functions.php`, which is also - autoloaded. The old functions are still there, but will be removed in a - future version. (#49) - - -4.0.0-alpha3 (2015-05-19) -------------------------- - -* Added a parser for the HTTP `Prefer` header, as defined in [RFC7240][rfc7240]. -* Deprecated `Sabre\HTTP\Util::parseHTTPDate`, use `Sabre\HTTP\parseDate()`. -* Deprecated `Sabre\HTTP\Util::toHTTPDate` use `Sabre\HTTP\toDate()`. - - -4.0.0-alpha2 (2015-05-18) -------------------------- - -* #45: Don't send more data than what is promised in the HTTP content-length. - (@dratini0). -* #43: `getCredentials` returns null if incomplete. (@Hywan) -* #48: Now using php-cs-fixer to make our CS consistent (yay!) -* This includes fixes released in version 3.0.5. - - -4.0.0-alpha1 (2015-02-25) -------------------------- - -* #41: Fixing bugs related to comparing URLs in `Request::getPath()`. -* #41: This library now uses the `sabre/uri` package for uri handling. -* Added `421 Misdirected Request` from the HTTP/2.0 spec. - - -3.0.5 (2015-05-11) ------------------- - -* #47 #35: When re-using the client and doing any request after a `HEAD` - request, the client discards the body. - - -3.0.4 (2014-12-10) ------------------- - -* #38: The Authentication helpers no longer overwrite any existing - `WWW-Authenticate` headers, but instead append new headers. This ensures - that multiple authentication systems can exist in the same environment. - - -3.0.3 (2014-12-03) ------------------- - -* Hiding `Authorization` header value from `Request::__toString`. - - -3.0.2 (2014-10-09) ------------------- - -* When parsing `Accept:` headers, we're ignoring invalid parts. Before we - would throw a PHP E_NOTICE. - - -3.0.1 (2014-09-29) ------------------- - -* Minor change in unittests. - - -3.0.0 (2014-09-23) ------------------- - -* `getHeaders()` now returns header values as an array, just like psr/http. -* Added `hasHeader()`. - - -2.1.0-alpha1 (2014-09-15) -------------------------- - -* Changed: Copied most of the header-semantics for the PSR draft for - representing HTTP messages. [Reference here][psr-http]. -* This means that `setHeaders()` does not wipe out every existing header - anymore. -* We also support multiple headers with the same name. -* Use `Request::getHeaderAsArray()` and `Response::getHeaderAsArray()` to - get a hold off multiple headers with the same name. -* If you use `getHeader()`, and there's more than 1 header with that name, we - concatenate all these with a comma. -* `addHeader()` will now preserve an existing header with that name, and add a - second header with the same name. -* The message class should be a lot faster now for looking up headers. No more - array traversal, because we maintain a tiny index. -* Added: `URLUtil::resolve()` to make resolving relative urls super easy. -* Switched to PSR-4. -* #12: Circumventing CURL's FOLLOW_LOCATION and doing it in PHP instead. This - fixes compatibility issues with people that have open_basedir turned on. -* Added: Content negotiation now correctly support mime-type parameters such as - charset. -* Changed: `Util::negotiate()` is now deprecated. Use - `Util::negotiateContentType()` instead. -* #14: The client now only follows http and https urls. - - -2.0.4 (2014-07-14) ------------------- - -* Changed: No longer escaping @ in urls when it's not needed. -* Fixed: #7: Client now correctly deals with responses without a body. - - -2.0.3 (2014-04-17) ------------------- - -* Now works on hhvm! -* Fixed: Now throwing an error when a Request object is being created with - arguments that were valid for sabre/http 1.0. Hopefully this will aid with - debugging for upgraders. - - -2.0.2 (2014-02-09) ------------------- - -* Fixed: Potential security problem in the client. - - -2.0.1 (2014-01-09) ------------------- - -* Fixed: getBodyAsString on an empty body now works. -* Fixed: Version string - - -2.0.0 (2014-01-08) ------------------- - -* Removed: Request::createFromPHPRequest. This is now handled by - Sapi::getRequest. - - -2.0.0alpha6 (2014-01-03) ------------------------- - -* Added: Asynchronous HTTP client. See examples/asyncclient.php. -* Fixed: Issue #4: Don't escape colon (:) when it's not needed. -* Fixed: Fixed a bug in the content negotation script. -* Fixed: Fallback for when CURLOPT_POSTREDIR is not defined (mainly for hhvm). -* Added: The Request and Response object now have a `__toString()` method that - serializes the objects into a standard HTTP message. This is mainly for - debugging purposes. -* Changed: Added Response::getStatusText(). This method returns the - human-readable HTTP status message. This part has been removed from - Response::getStatus(), which now always returns just the status code as an - int. -* Changed: Response::send() is now Sapi::sendResponse($response). -* Changed: Request::createFromPHPRequest is now Sapi::getRequest(). -* Changed: Message::getBodyAsStream and Message::getBodyAsString were added. The - existing Message::getBody changed its behavior, so be careful. - - -2.0.0alpha5 (2013-11-07) ------------------------- - -* Added: HTTP Status 451 Unavailable For Legal Reasons. Fight government - censorship! -* Added: Ability to catch and retry http requests in the client when a curl - error occurs. -* Changed: Request::getPath does not return the query part of the url, so - everything after the ? is stripped. -* Added: a reverse proxy example. - - -2.0.0alpha4 (2013-08-07) ------------------------- - -* Fixed: Doing a GET request with the client uses the last used HTTP method - instead. -* Added: HttpException -* Added: The Client class can now automatically emit exceptions when HTTP errors - occurred. - - -2.0.0alpha3 (2013-07-24) ------------------------- - -* Changed: Now depends on sabre/event package. -* Changed: setHeaders() now overwrites any existing http headers. -* Added: getQueryParameters to RequestInterface. -* Added: Util::negotiate. -* Added: RequestDecorator, ResponseDecorator. -* Added: A very simple HTTP client. -* Added: addHeaders() to append a list of new headers. -* Fixed: Not erroring on unknown HTTP status codes. -* Fixed: Throwing exceptions on invalid HTTP status codes (not 3 digits). -* Fixed: Much better README.md -* Changed: getBody() now uses a bitfield to specify what type to return. - - -2.0.0alpha2 (2013-07-02) ------------------------- - -* Added: Digest & AWS Authentication. -* Added: Message::getHttpVersion and Message::setHttpVersion. -* Added: Request::setRawServerArray, getRawServerValue. -* Added: Request::createFromPHPRequest -* Added: Response::send -* Added: Request::getQueryParameters -* Added: Utility for dealing with HTTP dates. -* Added: Request::setPostData and Request::getPostData. -* Added: Request::setAbsoluteUrl and Request::getAbsoluteUrl. -* Added: URLUtil, methods for calculation relative and base urls. -* Removed: Response::sendBody - - -2.0.0alpha1 (2012-10-07) ------------------------- - -* Fixed: Lots of small naming improvements -* Added: Introduction of Message, MessageInterface, Response, ResponseInterface. - -Before 2.0.0, this package was built-into SabreDAV, where it first appeared in -January 2009. - -[psr-http]: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md -[rfc7240]: http://tools.ietf.org/html/rfc7240 -[rfc7617]: https://tools.ietf.org/html/rfc7617 diff --git a/lib/vendor/sabre/http/LICENSE b/lib/vendor/sabre/http/LICENSE deleted file mode 100644 index 864041b..0000000 --- a/lib/vendor/sabre/http/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (C) 2009-2017 fruux GmbH (https://fruux.com/) - -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 Sabre 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/lib/vendor/sabre/http/README.md b/lib/vendor/sabre/http/README.md deleted file mode 100644 index 2f01c14..0000000 --- a/lib/vendor/sabre/http/README.md +++ /dev/null @@ -1,747 +0,0 @@ -sabre/http -========== - -This library provides a toolkit to make working with the [HTTP protocol](https://tools.ietf.org/html/rfc2616) easier. - -Most PHP scripts run within a HTTP request but accessing information about the -HTTP request is cumbersome at least. - -There's bad practices, inconsistencies and confusion. This library is -effectively a wrapper around the following PHP constructs: - -For Input: - -* `$_GET`, -* `$_POST`, -* `$_SERVER`, -* `php://input` or `$HTTP_RAW_POST_DATA`. - -For output: - -* `php://output` or `echo`, -* `header()`. - -What this library provides, is a `Request` object, and a `Response` object. - -The objects are extendable and easily mockable. - -Build status ------------- - -| branch | status | -|--------|---------------------------------------------------------------------------------------------------------------| -| master | [![Build Status](https://travis-ci.org/sabre-io/http.svg?branch=master)](https://travis-ci.org/sabre-io/http) | -| 4.2 | [![Build Status](https://travis-ci.org/sabre-io/http.svg?branch=4.2)](https://travis-ci.org/sabre-io/http) | -| 3.0 | [![Build Status](https://travis-ci.org/sabre-io/http.svg?branch=3.0)](https://travis-ci.org/sabre-io/http) | - -Installation ------------- - -Make sure you have [composer][1] installed. In your project directory, create, -or edit a `composer.json` file, and make sure it contains something like this: - -```json -{ - "require" : { - "sabre/http" : "~5.0.0" - } -} -``` - -After that, just hit `composer install` and you should be rolling. - -Quick history -------------- - -This library came to existence in 2009, as a part of the [`sabre/dav`][2] -project, which uses it heavily. - -It got split off into a separate library to make it easier to manage -releases and hopefully giving it use outside of the scope of just `sabre/dav`. - -Although completely independently developed, this library has a LOT of -overlap with [Symfony's `HttpFoundation`][3]. - -Said library does a lot more stuff and is significantly more popular, -so if you are looking for something to fulfill this particular requirement, -I'd recommend also considering [`HttpFoundation`][3]. - - -Getting started ---------------- - -First and foremost, this library wraps the superglobals. The easiest way to -instantiate a request object is as follows: - -```php -use Sabre\HTTP; - -include 'vendor/autoload.php'; - -$request = HTTP\Sapi::getRequest(); -``` - -This line should only happen once in your entire application. Everywhere else -you should pass this request object around using dependency injection. - -You should always typehint on its interface: - -```php -function handleRequest(HTTP\RequestInterface $request) { - - // Do something with this request :) - -} -``` - -A response object you can just create as such: - -```php -use Sabre\HTTP; - -include 'vendor/autoload.php'; - -$response = new HTTP\Response(); -$response->setStatus(201); // created ! -$response->setHeader('X-Foo', 'bar'); -$response->setBody( - 'success!' -); - -``` - -After you fully constructed your response, you must call: - -```php -HTTP\Sapi::sendResponse($response); -``` - -This line should generally also appear once in your application (at the very -end). - -Decorators ----------- - -It may be useful to extend the `Request` and `Response` objects in your -application, if you for example would like them to carry a bit more -information about the current request. - -For instance, you may want to add an `isLoggedIn` method to the Request -object. - -Simply extending Request and Response may pose some problems: - -1. You may want to extend the objects with new behaviors differently, in - different subsystems of your application, -2. The `Sapi::getRequest` factory always returns an instance of - `Request` so you would have to override the factory method as well, -3. By controlling the instantiation and depend on specific `Request` and - `Response` instances in your library or application, you make it harder to - work with other applications which also use `sabre/http`. - -In short: it would be bad design. Instead, it's recommended to use the -[decorator pattern][6] to add new behavior where you need it. `sabre/http` -provides helper classes to quickly do this. - -Example: - -```php -use Sabre\HTTP; - -class MyRequest extends HTTP\RequestDecorator { - - function isLoggedIn() { - - return true; - - } - -} -``` - -Our application assumes that the true `Request` object was instantiated -somewhere else, by some other subsystem. This could simply be a call like -`$request = Sapi::getRequest()` at the top of your application, -but could also be somewhere in a unit test. - -All we know in the current subsystem, is that we received a `$request` and -that it implements `Sabre\HTTP\RequestInterface`. To decorate this object, -all we need to do is: - -```php -$request = new MyRequest($request); -``` - -And that's it, we now have an `isLoggedIn` method, without having to mess -with the core instances. - - -Client ------- - -This package also contains a simple wrapper around [cURL][4], which will allow -you to write simple clients, using the `Request` and `Response` objects you're -already familiar with. - -It's by no means a replacement for something like [Guzzle][7], but it provides -a simple and lightweight API for making the occasional API call. - -### Usage - -```php -use Sabre\HTTP; - -$request = new HTTP\Request('GET', 'http://example.org/'); -$request->setHeader('X-Foo', 'Bar'); - -$client = new HTTP\Client(); -$response = $client->send($request); - -echo $response->getBodyAsString(); -``` - -The client emits 3 event using [`sabre/event`][5]. `beforeRequest`, -`afterRequest` and `error`. - -```php -$client = new HTTP\Client(); -$client->on('beforeRequest', function($request) { - - // You could use beforeRequest to for example inject a few extra headers. - // into the Request object. - -}); - -$client->on('afterRequest', function($request, $response) { - - // The afterRequest event could be a good time to do some logging, or - // do some rewriting in the response. - -}); - -$client->on('error', function($request, $response, &$retry, $retryCount) { - - // The error event is triggered for every response with a HTTP code higher - // than 399. - -}); - -$client->on('error:401', function($request, $response, &$retry, $retryCount) { - - // You can also listen for specific error codes. This example shows how - // to inject HTTP authentication headers if a 401 was returned. - - if ($retryCount > 1) { - // We're only going to retry exactly once. - } - - $request->setHeader('Authorization', 'Basic xxxxxxxxxx'); - $retry = true; - -}); -``` - -### Asynchronous requests - -The `Client` also supports doing asynchronous requests. This is especially handy -if you need to perform a number of requests, that are allowed to be executed -in parallel. - -The underlying system for this is simply [cURL's multi request handler][8], -but this provides a much nicer API to handle this. - -Sample usage: - -```php - -use Sabre\HTTP; - -$request = new Request('GET', 'http://localhost/'); -$client = new Client(); - -// Executing 1000 requests -for ($i = 0; $i < 1000; $i++) { - $client->sendAsync( - $request, - function(ResponseInterface $response) { - // Success handler - }, - function($error) { - // Error handler - } - ); -} - -// Wait for all requests to get a result. -$client->wait(); - -``` - -Check out `examples/asyncclient.php` for more information. - -Writing a reverse proxy ------------------------ - -With all these tools combined, it becomes very easy to write a simple reverse -http proxy. - -```php -use - Sabre\HTTP\Sapi, - Sabre\HTTP\Client; - -// The url we're proxying to. -$remoteUrl = 'http://example.org/'; - -// The url we're proxying from. Please note that this must be a relative url, -// and basically acts as the base url. -// -// If your $remoteUrl doesn't end with a slash, this one probably shouldn't -// either. -$myBaseUrl = '/reverseproxy.php'; -// $myBaseUrl = '/~evert/sabre/http/examples/reverseproxy.php/'; - -$request = Sapi::getRequest(); -$request->setBaseUrl($myBaseUrl); - -$subRequest = clone $request; - -// Removing the Host header. -$subRequest->removeHeader('Host'); - -// Rewriting the url. -$subRequest->setUrl($remoteUrl . $request->getPath()); - -$client = new Client(); - -// Sends the HTTP request to the server -$response = $client->send($subRequest); - -// Sends the response back to the client that connected to the proxy. -Sapi::sendResponse($response); -``` - -The Request and Response API's ------------------------------- - -### Request - -```php - -/** - * Creates the request object - * - * @param string $method - * @param string $url - * @param array $headers - * @param resource $body - */ -public function __construct($method = null, $url = null, array $headers = null, $body = null); - -/** - * Returns the current HTTP method - * - * @return string - */ -function getMethod(); - -/** - * Sets the HTTP method - * - * @param string $method - * @return void - */ -function setMethod($method); - -/** - * Returns the request url. - * - * @return string - */ -function getUrl(); - -/** - * Sets the request url. - * - * @param string $url - * @return void - */ -function setUrl($url); - -/** - * Returns the absolute url. - * - * @return string - */ -function getAbsoluteUrl(); - -/** - * Sets the absolute url. - * - * @param string $url - * @return void - */ -function setAbsoluteUrl($url); - -/** - * Returns the current base url. - * - * @return string - */ -function getBaseUrl(); - -/** - * Sets a base url. - * - * This url is used for relative path calculations. - * - * The base url should default to / - * - * @param string $url - * @return void - */ -function setBaseUrl($url); - -/** - * Returns the relative path. - * - * This is being calculated using the base url. This path will not start - * with a slash, so it will always return something like - * 'example/path.html'. - * - * If the full path is equal to the base url, this method will return an - * empty string. - * - * This method will also urldecode the path, and if the url was encoded as - * ISO-8859-1, it will convert it to UTF-8. - * - * If the path is outside the base url, a LogicException will be thrown. - * - * @return string - */ -function getPath(); - -/** - * Returns the list of query parameters. - * - * This is equivalent to PHP's $_GET superglobal. - * - * @return array - */ -function getQueryParameters(); - -/** - * Returns the POST data. - * - * This is equivalent to PHP's $_POST superglobal. - * - * @return array - */ -function getPostData(); - -/** - * Sets the post data. - * - * This is equivalent to PHP's $_POST superglobal. - * - * This would not have been needed, if POST data was accessible as - * php://input, but unfortunately we need to special case it. - * - * @param array $postData - * @return void - */ -function setPostData(array $postData); - -/** - * Returns an item from the _SERVER array. - * - * If the value does not exist in the array, null is returned. - * - * @param string $valueName - * @return string|null - */ -function getRawServerValue($valueName); - -/** - * Sets the _SERVER array. - * - * @param array $data - * @return void - */ -function setRawServerData(array $data); - -/** - * Returns the body as a readable stream resource. - * - * Note that the stream may not be rewindable, and therefore may only be - * read once. - * - * @return resource - */ -function getBodyAsStream(); - -/** - * Returns the body as a string. - * - * Note that because the underlying data may be based on a stream, this - * method could only work correctly the first time. - * - * @return string - */ -function getBodyAsString(); - -/** - * Returns the message body, as its internal representation. - * - * This could be either a string or a stream. - * - * @return resource|string - */ -function getBody(); - -/** - * Updates the body resource with a new stream. - * - * @param resource $body - * @return void - */ -function setBody($body); - -/** - * Returns all the HTTP headers as an array. - * - * @return array - */ -function getHeaders(); - -/** - * Returns a specific HTTP header, based on its name. - * - * The name must be treated as case-insensitive. - * - * If the header does not exist, this method must return null. - * - * @param string $name - * @return string|null - */ -function getHeader($name); - -/** - * Updates a HTTP header. - * - * The case-sensitivity of the name value must be retained as-is. - * - * @param string $name - * @param string $value - * @return void - */ -function setHeader($name, $value); - -/** - * Resets HTTP headers - * - * This method overwrites all existing HTTP headers - * - * @param array $headers - * @return void - */ -function setHeaders(array $headers); - -/** - * Adds a new set of HTTP headers. - * - * Any header specified in the array that already exists will be - * overwritten, but any other existing headers will be retained. - * - * @param array $headers - * @return void - */ -function addHeaders(array $headers); - -/** - * Removes a HTTP header. - * - * The specified header name must be treated as case-insensitive. - * This method should return true if the header was successfully deleted, - * and false if the header did not exist. - * - * @return bool - */ -function removeHeader($name); - -/** - * Sets the HTTP version. - * - * Should be 1.0, 1.1 or 2.0. - * - * @param string $version - * @return void - */ -function setHttpVersion($version); - -/** - * Returns the HTTP version. - * - * @return string - */ -function getHttpVersion(); -``` - -### Response - -```php -/** - * Returns the current HTTP status. - * - * This is the status-code as well as the human-readable string. - * - * @return string - */ -function getStatus(); - -/** - * Sets the HTTP status code. - * - * This can be either the full HTTP status code with human-readable string, - * for example: "403 I can't let you do that, Dave". - * - * Or just the code, in which case the appropriate default message will be - * added. - * - * @param string|int $status - * @throws \InvalidArgumentExeption - * @return void - */ -function setStatus($status); - -/** - * Returns the body as a readable stream resource. - * - * Note that the stream may not be rewindable, and therefore may only be - * read once. - * - * @return resource - */ -function getBodyAsStream(); - -/** - * Returns the body as a string. - * - * Note that because the underlying data may be based on a stream, this - * method could only work correctly the first time. - * - * @return string - */ -function getBodyAsString(); - -/** - * Returns the message body, as its internal representation. - * - * This could be either a string or a stream. - * - * @return resource|string - */ -function getBody(); - - -/** - * Updates the body resource with a new stream. - * - * @param resource $body - * @return void - */ -function setBody($body); - -/** - * Returns all the HTTP headers as an array. - * - * @return array - */ -function getHeaders(); - -/** - * Returns a specific HTTP header, based on its name. - * - * The name must be treated as case-insensitive. - * - * If the header does not exist, this method must return null. - * - * @param string $name - * @return string|null - */ -function getHeader($name); - -/** - * Updates a HTTP header. - * - * The case-sensitivity of the name value must be retained as-is. - * - * @param string $name - * @param string $value - * @return void - */ -function setHeader($name, $value); - -/** - * Resets HTTP headers - * - * This method overwrites all existing HTTP headers - * - * @param array $headers - * @return void - */ -function setHeaders(array $headers); - -/** - * Adds a new set of HTTP headers. - * - * Any header specified in the array that already exists will be - * overwritten, but any other existing headers will be retained. - * - * @param array $headers - * @return void - */ -function addHeaders(array $headers); - -/** - * Removes a HTTP header. - * - * The specified header name must be treated as case-insensitive. - * This method should return true if the header was successfully deleted, - * and false if the header did not exist. - * - * @return bool - */ -function removeHeader($name); - -/** - * Sets the HTTP version. - * - * Should be 1.0, 1.1 or 2.0. - * - * @param string $version - * @return void - */ -function setHttpVersion($version); - -/** - * Returns the HTTP version. - * - * @return string - */ -function getHttpVersion(); -``` - -Made at fruux -------------- - -This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support. - -[1]: http://getcomposer.org/ -[2]: http://sabre.io/ -[3]: https://github.com/symfony/HttpFoundation -[4]: http://php.net/curl -[5]: https://github.com/fruux/sabre-event -[6]: http://en.wikipedia.org/wiki/Decorator_pattern -[7]: http://guzzlephp.org/ -[8]: http://php.net/curl_multi_init diff --git a/lib/vendor/sabre/http/bin/.empty b/lib/vendor/sabre/http/bin/.empty deleted file mode 100644 index e69de29..0000000 diff --git a/lib/vendor/sabre/http/composer.json b/lib/vendor/sabre/http/composer.json deleted file mode 100644 index 567dd0d..0000000 --- a/lib/vendor/sabre/http/composer.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "name": "sabre/http", - "description" : "The sabre/http library provides utilities for dealing with http requests and responses. ", - "keywords" : [ "HTTP" ], - "homepage" : "https://github.com/fruux/sabre-http", - "license" : "BSD-3-Clause", - "require" : { - "php" : "^7.1 || ^8.0", - "ext-mbstring" : "*", - "ext-ctype" : "*", - "ext-curl" : "*", - "sabre/event" : ">=4.0 <6.0", - "sabre/uri" : "^2.0" - }, - "require-dev" : { - "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.6" - }, - "suggest" : { - "ext-curl" : " to make http requests with the Client class" - }, - "authors" : [ - { - "name" : "Evert Pot", - "email" : "me@evertpot.com", - "homepage" : "http://evertpot.com/", - "role" : "Developer" - } - ], - "support" : { - "forum" : "https://groups.google.com/group/sabredav-discuss", - "source" : "https://github.com/fruux/sabre-http" - }, - "autoload" : { - "files" : [ - "lib/functions.php" - ], - "psr-4" : { - "Sabre\\HTTP\\" : "lib/" - } - }, - "autoload-dev" : { - "psr-4" : { - "Sabre\\HTTP\\" : "tests/HTTP" - } - }, - "scripts": { - "phpstan": [ - "phpstan analyse lib tests" - ], - "cs-fixer": [ - "PHP_CS_FIXER_IGNORE_ENV=true php-cs-fixer fix" - ], - "phpunit": [ - "phpunit --configuration tests/phpunit.xml" - ], - "test": [ - "composer phpstan", - "composer cs-fixer", - "composer phpunit" - ] - } -} diff --git a/lib/vendor/sabre/http/examples/asyncclient.php b/lib/vendor/sabre/http/examples/asyncclient.php deleted file mode 100644 index 5bcc844..0000000 --- a/lib/vendor/sabre/http/examples/asyncclient.php +++ /dev/null @@ -1,62 +0,0 @@ -sendAsync( - $request, - - // This is the 'success' callback - function ($response) use ($i) { - echo "$i -> ".$response->getStatus()."\n"; - }, - - // This is the 'error' callback. It is called for general connection - // problems (such as not being able to connect to a host, dns errors, - // etc.) and also cases where a response was returned, but it had a - // status code of 400 or higher. - function ($error) use ($i) { - if (Client::STATUS_CURLERROR === $error['status']) { - // Curl errors - echo "$i -> curl error: ".$error['curl_errmsg']."\n"; - } else { - // HTTP errors - echo "$i -> ".$error['response']->getStatus()."\n"; - } - } - ); -} - -// After everything is done, we call 'wait'. This causes the client to wait for -// all outstanding http requests to complete. -$client->wait(); diff --git a/lib/vendor/sabre/http/examples/basicauth.php b/lib/vendor/sabre/http/examples/basicauth.php deleted file mode 100644 index 9c13da8..0000000 --- a/lib/vendor/sabre/http/examples/basicauth.php +++ /dev/null @@ -1,50 +0,0 @@ - 'password', - 'user2' => 'password', -]; - -use Sabre\HTTP\Auth; -use Sabre\HTTP\Response; -use Sabre\HTTP\Sapi; - -// Find the autoloader -$paths = [ - __DIR__.'/../vendor/autoload.php', - __DIR__.'/../../../autoload.php', - __DIR__.'/vendor/autoload.php', -]; - -foreach ($paths as $path) { - if (file_exists($path)) { - include $path; - break; - } -} - -$request = Sapi::getRequest(); -$response = new Response(); - -$basicAuth = new Auth\Basic('Locked down area', $request, $response); -if (!$userPass = $basicAuth->getCredentials()) { - // No username or password given - $basicAuth->requireLogin(); -} elseif (!isset($userList[$userPass[0]]) || $userList[$userPass[0]] !== $userPass[1]) { - // Username or password are incorrect - $basicAuth->requireLogin(); -} else { - // Success ! - $response->setBody('You are logged in!'); -} - -// Sending the response -Sapi::sendResponse($response); diff --git a/lib/vendor/sabre/http/examples/client.php b/lib/vendor/sabre/http/examples/client.php deleted file mode 100644 index fd169a4..0000000 --- a/lib/vendor/sabre/http/examples/client.php +++ /dev/null @@ -1,37 +0,0 @@ -addCurlSetting(CURLOPT_PROXY,'localhost:8888'); -$response = $client->send($request); - -echo "Response:\n"; - -echo (string) $response; diff --git a/lib/vendor/sabre/http/examples/digestauth.php b/lib/vendor/sabre/http/examples/digestauth.php deleted file mode 100644 index 5594306..0000000 --- a/lib/vendor/sabre/http/examples/digestauth.php +++ /dev/null @@ -1,51 +0,0 @@ - 'password', - 'user2' => 'password', -]; - -use Sabre\HTTP\Auth; -use Sabre\HTTP\Response; -use Sabre\HTTP\Sapi; - -// Find the autoloader -$paths = [ - __DIR__.'/../vendor/autoload.php', - __DIR__.'/../../../autoload.php', - __DIR__.'/vendor/autoload.php', -]; - -foreach ($paths as $path) { - if (file_exists($path)) { - include $path; - break; - } -} - -$request = Sapi::getRequest(); -$response = new Response(); - -$digestAuth = new Auth\Digest('Locked down area', $request, $response); -$digestAuth->init(); -if (!$userName = $digestAuth->getUsername()) { - // No username given - $digestAuth->requireLogin(); -} elseif (!isset($userList[$userName]) || !$digestAuth->validatePassword($userList[$userName])) { - // Username or password are incorrect - $digestAuth->requireLogin(); -} else { - // Success ! - $response->setBody('You are logged in!'); -} - -// Sending the response -Sapi::sendResponse($response); diff --git a/lib/vendor/sabre/http/examples/reverseproxy.php b/lib/vendor/sabre/http/examples/reverseproxy.php deleted file mode 100644 index ce51ad4..0000000 --- a/lib/vendor/sabre/http/examples/reverseproxy.php +++ /dev/null @@ -1,48 +0,0 @@ -setBaseUrl($myBaseUrl); - -$subRequest = clone $request; - -// Removing the Host header. -$subRequest->removeHeader('Host'); - -// Rewriting the url. -$subRequest->setUrl($remoteUrl.$request->getPath()); - -$client = new Client(); - -// Sends the HTTP request to the server -$response = $client->send($subRequest); - -// Sends the response back to the client that connected to the proxy. -Sapi::sendResponse($response); diff --git a/lib/vendor/sabre/http/examples/stringify.php b/lib/vendor/sabre/http/examples/stringify.php deleted file mode 100644 index 8ceefe2..0000000 --- a/lib/vendor/sabre/http/examples/stringify.php +++ /dev/null @@ -1,50 +0,0 @@ -setHeaders([ - 'Host' => 'example.org', - 'Content-Type' => 'application/json', -]); - -$request->setBody(json_encode(['foo' => 'bar'])); - -echo $request; -echo "\r\n\r\n"; - -$response = new Response(424); -$response->setHeaders([ - 'Content-Type' => 'text/plain', - 'Connection' => 'close', -]); - -$response->setBody('ABORT! ABORT!'); - -echo $response; - -echo "\r\n"; diff --git a/lib/vendor/sabre/http/lib/Auth/AWS.php b/lib/vendor/sabre/http/lib/Auth/AWS.php deleted file mode 100644 index 2690c63..0000000 --- a/lib/vendor/sabre/http/lib/Auth/AWS.php +++ /dev/null @@ -1,220 +0,0 @@ -request->getHeader('Authorization'); - - if (null === $authHeader) { - $this->errorCode = self::ERR_NOAWSHEADER; - - return false; - } - $authHeader = explode(' ', $authHeader); - - if ('AWS' !== $authHeader[0] || !isset($authHeader[1])) { - $this->errorCode = self::ERR_NOAWSHEADER; - - return false; - } - - list($this->accessKey, $this->signature) = explode(':', $authHeader[1]); - - return true; - } - - /** - * Returns the username for the request. - */ - public function getAccessKey(): string - { - return $this->accessKey; - } - - /** - * Validates the signature based on the secretKey. - */ - public function validate(string $secretKey): bool - { - $contentMD5 = $this->request->getHeader('Content-MD5'); - - if ($contentMD5) { - // We need to validate the integrity of the request - $body = $this->request->getBody(); - $this->request->setBody($body); - - if ($contentMD5 !== base64_encode(md5((string) $body, true))) { - // content-md5 header did not match md5 signature of body - $this->errorCode = self::ERR_MD5CHECKSUMWRONG; - - return false; - } - } - - if (!$requestDate = $this->request->getHeader('x-amz-date')) { - $requestDate = $this->request->getHeader('Date'); - } - - if (!$this->validateRFC2616Date((string) $requestDate)) { - return false; - } - - $amzHeaders = $this->getAmzHeaders(); - - $signature = base64_encode( - $this->hmacsha1($secretKey, - $this->request->getMethod()."\n". - $contentMD5."\n". - $this->request->getHeader('Content-type')."\n". - $requestDate."\n". - $amzHeaders. - $this->request->getUrl() - ) - ); - - if ($this->signature !== $signature) { - $this->errorCode = self::ERR_INVALIDSIGNATURE; - - return false; - } - - return true; - } - - /** - * Returns an HTTP 401 header, forcing login. - * - * This should be called when username and password are incorrect, or not supplied at all - */ - public function requireLogin() - { - $this->response->addHeader('WWW-Authenticate', 'AWS'); - $this->response->setStatus(401); - } - - /** - * 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 - * 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 - * system date, to prevent replay attacks. - */ - protected function validateRFC2616Date(string $dateHeader): bool - { - $date = HTTP\parseDate($dateHeader); - - // Unknown format - if (!$date) { - $this->errorCode = self::ERR_INVALIDDATEFORMAT; - - return false; - } - - $min = new \DateTime('-15 minutes'); - $max = new \DateTime('+15 minutes'); - - // We allow 15 minutes around the current date/time - if ($date > $max || $date < $min) { - $this->errorCode = self::ERR_REQUESTTIMESKEWED; - - return false; - } - - return true; - } - - /** - * Returns a list of AMZ headers. - */ - protected function getAmzHeaders(): string - { - $amzHeaders = []; - $headers = $this->request->getHeaders(); - foreach ($headers as $headerName => $headerValue) { - if (0 === strpos(strtolower($headerName), 'x-amz-')) { - $amzHeaders[strtolower($headerName)] = str_replace(["\r\n"], [' '], $headerValue[0])."\n"; - } - } - ksort($amzHeaders); - - $headerStr = ''; - foreach ($amzHeaders as $h => $v) { - $headerStr .= $h.':'.$v; - } - - return $headerStr; - } - - /** - * Generates an HMAC-SHA1 signature. - */ - private function hmacsha1(string $key, string $message): string - { - if (function_exists('hash_hmac')) { - return hash_hmac('sha1', $message, $key, true); - } - - $blocksize = 64; - if (strlen($key) > $blocksize) { - $key = pack('H*', sha1($key)); - } - $key = str_pad($key, $blocksize, chr(0x00)); - $ipad = str_repeat(chr(0x36), $blocksize); - $opad = str_repeat(chr(0x5C), $blocksize); - $hmac = pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message)))); - - return $hmac; - } -} diff --git a/lib/vendor/sabre/http/lib/Auth/AbstractAuth.php b/lib/vendor/sabre/http/lib/Auth/AbstractAuth.php deleted file mode 100644 index 07f451b..0000000 --- a/lib/vendor/sabre/http/lib/Auth/AbstractAuth.php +++ /dev/null @@ -1,65 +0,0 @@ -realm = $realm; - $this->request = $request; - $this->response = $response; - } - - /** - * This method sends the needed HTTP header and status code (401) to force - * the user to login. - */ - abstract public function requireLogin(); - - /** - * Returns the HTTP realm. - */ - public function getRealm(): string - { - return $this->realm; - } -} diff --git a/lib/vendor/sabre/http/lib/Auth/Basic.php b/lib/vendor/sabre/http/lib/Auth/Basic.php deleted file mode 100644 index c1bad1a..0000000 --- a/lib/vendor/sabre/http/lib/Auth/Basic.php +++ /dev/null @@ -1,60 +0,0 @@ -request->getHeader('Authorization'); - - if (!$auth) { - return null; - } - - if ('basic ' !== strtolower(substr($auth, 0, 6))) { - return null; - } - - $credentials = explode(':', base64_decode(substr($auth, 6)), 2); - - if (2 !== count($credentials)) { - return null; - } - - return $credentials; - } - - /** - * This method sends the needed HTTP header and status code (401) to force - * the user to login. - */ - public function requireLogin() - { - $this->response->addHeader('WWW-Authenticate', 'Basic realm="'.$this->realm.'", charset="UTF-8"'); - $this->response->setStatus(401); - } -} diff --git a/lib/vendor/sabre/http/lib/Auth/Bearer.php b/lib/vendor/sabre/http/lib/Auth/Bearer.php deleted file mode 100644 index 580e239..0000000 --- a/lib/vendor/sabre/http/lib/Auth/Bearer.php +++ /dev/null @@ -1,53 +0,0 @@ -request->getHeader('Authorization'); - - if (!$auth) { - return null; - } - - if ('bearer ' !== strtolower(substr($auth, 0, 7))) { - return null; - } - - return substr($auth, 7); - } - - /** - * This method sends the needed HTTP header and status code (401) to force - * authentication. - */ - public function requireLogin() - { - $this->response->addHeader('WWW-Authenticate', 'Bearer realm="'.$this->realm.'"'); - $this->response->setStatus(401); - } -} diff --git a/lib/vendor/sabre/http/lib/Auth/Digest.php b/lib/vendor/sabre/http/lib/Auth/Digest.php deleted file mode 100644 index 08fa34f..0000000 --- a/lib/vendor/sabre/http/lib/Auth/Digest.php +++ /dev/null @@ -1,208 +0,0 @@ -nonce = uniqid(); - $this->opaque = md5($realm); - parent::__construct($realm, $request, $response); - } - - /** - * Gathers all information from the headers. - * - * This method needs to be called prior to anything else. - */ - public function init() - { - $digest = $this->getDigest(); - $this->digestParts = $this->parseDigest((string) $digest); - } - - /** - * Sets the quality of protection value. - * - * Possible values are: - * Sabre\HTTP\DigestAuth::QOP_AUTH - * Sabre\HTTP\DigestAuth::QOP_AUTHINT - * - * 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 - * request body to be md5'ed, which can put strains on CPU and memory. - */ - public function setQOP(int $qop) - { - $this->qop = $qop; - } - - /** - * Validates the user. - * - * The A1 parameter should be md5($username . ':' . $realm . ':' . $password); - */ - public function validateA1(string $A1): bool - { - $this->A1 = $A1; - - return $this->validate(); - } - - /** - * 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. - */ - public function validatePassword(string $password): bool - { - $this->A1 = md5($this->digestParts['username'].':'.$this->realm.':'.$password); - - return $this->validate(); - } - - /** - * Returns the username for the request. - * Returns null if there were none. - * - * @return string|null - */ - public function getUsername() - { - return $this->digestParts['username'] ?? null; - } - - /** - * Validates the digest challenge. - */ - protected function validate(): bool - { - if (!is_array($this->digestParts)) { - return false; - } - - $A2 = $this->request->getMethod().':'.$this->digestParts['uri']; - - if ('auth-int' === $this->digestParts['qop']) { - // Making sure we support this qop value - if (!($this->qop & self::QOP_AUTHINT)) { - return false; - } - // We need to add an md5 of the entire request body to the A2 part of the hash - $body = $this->request->getBody(); - $this->request->setBody($body); - $A2 .= ':'.md5($body); - } elseif (!($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}"); - - return $this->digestParts['response'] === $validResponse; - } - - /** - * Returns an HTTP 401 header, forcing login. - * - * This should be called when username and password are incorrect, or not supplied at all - */ - public function requireLogin() - { - $qop = ''; - switch ($this->qop) { - case self::QOP_AUTH: - $qop = 'auth'; - break; - case self::QOP_AUTHINT: - $qop = 'auth-int'; - break; - case self::QOP_AUTH | self::QOP_AUTHINT: - $qop = 'auth,auth-int'; - break; - } - - $this->response->addHeader('WWW-Authenticate', 'Digest realm="'.$this->realm.'",qop="'.$qop.'",nonce="'.$this->nonce.'",opaque="'.$this->opaque.'"'); - $this->response->setStatus(401); - } - - /** - * This method returns the full digest string. - * - * It should be compatible with mod_php format and other webservers. - * - * If the header could not be found, null will be returned - */ - public function getDigest() - { - return $this->request->getHeader('Authorization'); - } - - /** - * Parses the different pieces of the digest string into an array. - * - * This method returns false if an incomplete digest was supplied - * - * @return bool|array - */ - protected function parseDigest(string $digest) - { - // protect against missing data - $needed_parts = ['nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1]; - $data = []; - - preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $digest, $matches, PREG_SET_ORDER); - - foreach ($matches as $m) { - $data[$m[1]] = $m[2] ?: $m[3]; - unset($needed_parts[$m[1]]); - } - - return $needed_parts ? false : $data; - } -} diff --git a/lib/vendor/sabre/http/lib/Client.php b/lib/vendor/sabre/http/lib/Client.php deleted file mode 100644 index c00f9e1..0000000 --- a/lib/vendor/sabre/http/lib/Client.php +++ /dev/null @@ -1,620 +0,0 @@ -curlSettings = [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_NOBODY => false, - CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ]; - if ($separatedHeaders) { - $this->curlSettings[CURLOPT_HEADERFUNCTION] = [$this, 'receiveCurlHeader']; - } else { - $this->curlSettings[CURLOPT_HEADER] = true; - } - } - - protected function receiveCurlHeader($curlHandle, $headerLine) - { - $this->headerLinesMap[(int) $curlHandle][] = $headerLine; - - return strlen($headerLine); - } - - /** - * Sends a request to a HTTP server, and returns a response. - */ - public function send(RequestInterface $request): ResponseInterface - { - $this->emit('beforeRequest', [$request]); - - $retryCount = 0; - $redirects = 0; - - do { - $doRedirect = false; - $retry = false; - - try { - $response = $this->doRequest($request); - - $code = $response->getStatus(); - - // We are doing in-PHP redirects, because curl's - // FOLLOW_LOCATION throws errors when PHP is configured with - // open_basedir. - // - // https://github.com/fruux/sabre-http/issues/12 - if ($redirects < $this->maxRedirects && in_array($code, [301, 302, 307, 308])) { - $oldLocation = $request->getUrl(); - - // Creating a new instance of the request object. - $request = clone $request; - - // Setting the new location - $request->setUrl(Uri\resolve( - $oldLocation, - $response->getHeader('Location') - )); - - $doRedirect = true; - ++$redirects; - } - - // This was a HTTP error - if ($code >= 400) { - $this->emit('error', [$request, $response, &$retry, $retryCount]); - $this->emit('error:'.$code, [$request, $response, &$retry, $retryCount]); - } - } catch (ClientException $e) { - $this->emit('exception', [$request, $e, &$retry, $retryCount]); - - // If retry was still set to false, it means no event handler - // dealt with the problem. In this case we just re-throw the - // exception. - if (!$retry) { - throw $e; - } - } - - if ($retry) { - ++$retryCount; - } - } while ($retry || $doRedirect); - - $this->emit('afterRequest', [$request, $response]); - - if ($this->throwExceptions && $code >= 400) { - throw new ClientHttpException($response); - } - - return $response; - } - - /** - * Sends a HTTP request asynchronously. - * - * Due to the nature of PHP, you must from time to time poll to see if any - * new responses came in. - * - * After calling sendAsync, you must therefore occasionally call the poll() - * method, or wait(). - */ - public function sendAsync(RequestInterface $request, ?callable $success = null, ?callable $error = null) - { - $this->emit('beforeRequest', [$request]); - $this->sendAsyncInternal($request, $success, $error); - $this->poll(); - } - - /** - * This method checks if any http requests have gotten results, and if so, - * call the appropriate success or error handlers. - * - * This method will return true if there are still requests waiting to - * return, and false if all the work is done. - */ - public function poll(): bool - { - // nothing to do? - if (!$this->curlMultiMap) { - return false; - } - - do { - $r = curl_multi_exec( - $this->curlMultiHandle, - $stillRunning - ); - } while (CURLM_CALL_MULTI_PERFORM === $r); - - $messagesInQueue = 0; - do { - messageQueue: - - $status = curl_multi_info_read( - $this->curlMultiHandle, - $messagesInQueue - ); - - if ($status && CURLMSG_DONE === $status['msg']) { - $resourceId = (int) $status['handle']; - list( - $request, - $successCallback, - $errorCallback, - $retryCount) = $this->curlMultiMap[$resourceId]; - unset($this->curlMultiMap[$resourceId]); - - $curlHandle = $status['handle']; - $curlResult = $this->parseResponse(curl_multi_getcontent($curlHandle), $curlHandle); - $retry = false; - - if (self::STATUS_CURLERROR === $curlResult['status']) { - $e = new ClientException($curlResult['curl_errmsg'], $curlResult['curl_errno']); - $this->emit('exception', [$request, $e, &$retry, $retryCount]); - - if ($retry) { - ++$retryCount; - $this->sendAsyncInternal($request, $successCallback, $errorCallback, $retryCount); - goto messageQueue; - } - - $curlResult['request'] = $request; - - if ($errorCallback) { - $errorCallback($curlResult); - } - } elseif (self::STATUS_HTTPERROR === $curlResult['status']) { - $this->emit('error', [$request, $curlResult['response'], &$retry, $retryCount]); - $this->emit('error:'.$curlResult['http_code'], [$request, $curlResult['response'], &$retry, $retryCount]); - - if ($retry) { - ++$retryCount; - $this->sendAsyncInternal($request, $successCallback, $errorCallback, $retryCount); - goto messageQueue; - } - - $curlResult['request'] = $request; - - if ($errorCallback) { - $errorCallback($curlResult); - } - } else { - $this->emit('afterRequest', [$request, $curlResult['response']]); - - if ($successCallback) { - $successCallback($curlResult['response']); - } - } - } - } while ($messagesInQueue > 0); - - return count($this->curlMultiMap) > 0; - } - - /** - * Processes every HTTP request in the queue, and waits till they are all - * completed. - */ - public function wait() - { - do { - curl_multi_select($this->curlMultiHandle); - $stillRunning = $this->poll(); - } while ($stillRunning); - } - - /** - * If this is set to true, the Client will automatically throw exceptions - * upon HTTP errors. - * - * This means that if a response came back with a status code greater than - * or equal to 400, we will throw a ClientHttpException. - * - * This only works for the send() method. Throwing exceptions for - * sendAsync() is not supported. - */ - public function setThrowExceptions(bool $throwExceptions) - { - $this->throwExceptions = $throwExceptions; - } - - /** - * Adds a CURL setting. - * - * These settings will be included in every HTTP request. - */ - public function addCurlSetting(int $name, $value) - { - $this->curlSettings[$name] = $value; - } - - /** - * This method is responsible for performing a single request. - */ - protected function doRequest(RequestInterface $request): ResponseInterface - { - $settings = $this->createCurlSettingsArray($request); - - if (!$this->curlHandle) { - $this->curlHandle = curl_init(); - } else { - curl_reset($this->curlHandle); - } - - curl_setopt_array($this->curlHandle, $settings); - $response = $this->curlExec($this->curlHandle); - $response = $this->parseResponse($response, $this->curlHandle); - if (self::STATUS_CURLERROR === $response['status']) { - throw new ClientException($response['curl_errmsg'], $response['curl_errno']); - } - - return $response['response']; - } - - /** - * Cached curl handle. - * - * By keeping this resource around for the lifetime of this object, things - * like persistent connections are possible. - * - * @var resource - */ - private $curlHandle; - - /** - * Handler for curl_multi requests. - * - * The first time sendAsync is used, this will be created. - * - * @var resource - */ - private $curlMultiHandle; - - /** - * Has a list of curl handles, as well as their associated success and - * error callbacks. - * - * @var array - */ - private $curlMultiMap = []; - - /** - * Turns a RequestInterface object into an array with settings that can be - * fed to curl_setopt. - */ - protected function createCurlSettingsArray(RequestInterface $request): array - { - $settings = $this->curlSettings; - - switch ($request->getMethod()) { - case 'HEAD': - $settings[CURLOPT_NOBODY] = true; - $settings[CURLOPT_CUSTOMREQUEST] = 'HEAD'; - break; - case 'GET': - $settings[CURLOPT_CUSTOMREQUEST] = 'GET'; - break; - default: - $body = $request->getBody(); - if (is_resource($body)) { - $bodyStat = fstat($body); - - // This needs to be set to PUT, regardless of the actual - // method used. Without it, INFILE will be ignored for some - // reason. - $settings[CURLOPT_PUT] = true; - $settings[CURLOPT_INFILE] = $body; - if (false !== $bodyStat && array_key_exists('size', $bodyStat)) { - $settings[CURLOPT_INFILESIZE] = $bodyStat['size']; - } - } else { - // For security we cast this to a string. If somehow an array could - // be passed here, it would be possible for an attacker to use @ to - // post local files. - $settings[CURLOPT_POSTFIELDS] = (string) $body; - } - $settings[CURLOPT_CUSTOMREQUEST] = $request->getMethod(); - break; - } - - $nHeaders = []; - foreach ($request->getHeaders() as $key => $values) { - foreach ($values as $value) { - $nHeaders[] = $key.': '.$value; - } - } - - if ([] !== $nHeaders) { - $settings[CURLOPT_HTTPHEADER] = $nHeaders; - } - $settings[CURLOPT_URL] = $request->getUrl(); - // FIXME: CURLOPT_PROTOCOLS is currently unsupported by HHVM - if (defined('CURLOPT_PROTOCOLS')) { - $settings[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - // FIXME: CURLOPT_REDIR_PROTOCOLS is currently unsupported by HHVM - if (defined('CURLOPT_REDIR_PROTOCOLS')) { - $settings[CURLOPT_REDIR_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - return $settings; - } - - public const STATUS_SUCCESS = 0; - public const STATUS_CURLERROR = 1; - public const STATUS_HTTPERROR = 2; - - private function parseResponse(string $response, $curlHandle): array - { - $settings = $this->curlSettings; - $separatedHeaders = isset($settings[CURLOPT_HEADERFUNCTION]) && (bool) $settings[CURLOPT_HEADERFUNCTION]; - - if ($separatedHeaders) { - $resourceId = (int) $curlHandle; - if (isset($this->headerLinesMap[$resourceId])) { - $headers = $this->headerLinesMap[$resourceId]; - } else { - $headers = []; - } - $response = $this->parseCurlResponse($headers, $response, $curlHandle); - } else { - $response = $this->parseCurlResult($response, $curlHandle); - } - - return $response; - } - - /** - * Parses the result of a curl call in a format that's a bit more - * convenient to work with. - * - * The method returns an array with the following elements: - * * status - one of the 3 STATUS constants. - * * curl_errno - A curl error number. Only set if status is - * STATUS_CURLERROR. - * * curl_errmsg - A current error message. Only set if status is - * STATUS_CURLERROR. - * * response - Response object. Only set if status is STATUS_SUCCESS, or - * STATUS_HTTPERROR. - * * http_code - HTTP status code, as an int. Only set if Only set if - * status is STATUS_SUCCESS, or STATUS_HTTPERROR - * - * @param resource $curlHandle - */ - protected function parseCurlResponse(array $headerLines, string $body, $curlHandle): array - { - list( - $curlInfo, - $curlErrNo, - $curlErrMsg - ) = $this->curlStuff($curlHandle); - - if ($curlErrNo) { - return [ - 'status' => self::STATUS_CURLERROR, - 'curl_errno' => $curlErrNo, - 'curl_errmsg' => $curlErrMsg, - ]; - } - - $response = new Response(); - $response->setStatus($curlInfo['http_code']); - $response->setBody($body); - - foreach ($headerLines as $header) { - $parts = explode(':', $header, 2); - if (2 === count($parts)) { - $response->addHeader(trim($parts[0]), trim($parts[1])); - } - } - - $httpCode = $response->getStatus(); - - return [ - 'status' => $httpCode >= 400 ? self::STATUS_HTTPERROR : self::STATUS_SUCCESS, - 'response' => $response, - 'http_code' => $httpCode, - ]; - } - - /** - * Parses the result of a curl call in a format that's a bit more - * convenient to work with. - * - * The method returns an array with the following elements: - * * status - one of the 3 STATUS constants. - * * curl_errno - A curl error number. Only set if status is - * STATUS_CURLERROR. - * * curl_errmsg - A current error message. Only set if status is - * STATUS_CURLERROR. - * * response - Response object. Only set if status is STATUS_SUCCESS, or - * STATUS_HTTPERROR. - * * http_code - HTTP status code, as an int. Only set if Only set if - * status is STATUS_SUCCESS, or STATUS_HTTPERROR - * - * @deprecated Use parseCurlResponse instead - * - * @param resource $curlHandle - */ - protected function parseCurlResult(string $response, $curlHandle): array - { - list( - $curlInfo, - $curlErrNo, - $curlErrMsg - ) = $this->curlStuff($curlHandle); - - if ($curlErrNo) { - return [ - 'status' => self::STATUS_CURLERROR, - 'curl_errno' => $curlErrNo, - 'curl_errmsg' => $curlErrMsg, - ]; - } - - $headerBlob = substr($response, 0, $curlInfo['header_size']); - // In the case of 204 No Content, strlen($response) == $curlInfo['header_size]. - // This will cause substr($response, $curlInfo['header_size']) return FALSE instead of NULL - // An exception will be thrown when calling getBodyAsString then - $responseBody = substr($response, $curlInfo['header_size']) ?: ''; - - unset($response); - - // 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); - - return $this->parseCurlResponse($headerBlob, $responseBody, $curlHandle); - } - - /** - * Sends an asynchronous HTTP request. - * - * We keep this in a separate method, so we can call it without triggering - * the beforeRequest event and don't do the poll(). - */ - protected function sendAsyncInternal(RequestInterface $request, callable $success, callable $error, int $retryCount = 0) - { - if (!$this->curlMultiHandle) { - $this->curlMultiHandle = curl_multi_init(); - } - $curl = curl_init(); - curl_setopt_array( - $curl, - $this->createCurlSettingsArray($request) - ); - curl_multi_add_handle($this->curlMultiHandle, $curl); - - $resourceId = (int) $curl; - $this->headerLinesMap[$resourceId] = []; - $this->curlMultiMap[$resourceId] = [ - $request, - $success, - $error, - $retryCount, - ]; - } - - // @codeCoverageIgnoreStart - - /** - * Calls curl_exec. - * - * This method exists so it can easily be overridden and mocked. - * - * @param resource $curlHandle - */ - protected function curlExec($curlHandle): string - { - $this->headerLinesMap[(int) $curlHandle] = []; - - $result = curl_exec($curlHandle); - if (false === $result) { - $result = ''; - } - - return $result; - } - - /** - * Returns a bunch of information about a curl request. - * - * This method exists so it can easily be overridden and mocked. - * - * @param resource $curlHandle - */ - protected function curlStuff($curlHandle): array - { - return [ - curl_getinfo($curlHandle), - curl_errno($curlHandle), - curl_error($curlHandle), - ]; - } - - // @codeCoverageIgnoreEnd -} diff --git a/lib/vendor/sabre/http/lib/ClientException.php b/lib/vendor/sabre/http/lib/ClientException.php deleted file mode 100644 index 2ca4a28..0000000 --- a/lib/vendor/sabre/http/lib/ClientException.php +++ /dev/null @@ -1,17 +0,0 @@ -response = $response; - parent::__construct($response->getStatusText(), $response->getStatus()); - } - - /** - * The http status code for the error. - */ - public function getHttpStatus(): int - { - return $this->response->getStatus(); - } - - /** - * Returns the full response object. - */ - public function getResponse(): ResponseInterface - { - return $this->response; - } -} diff --git a/lib/vendor/sabre/http/lib/HttpException.php b/lib/vendor/sabre/http/lib/HttpException.php deleted file mode 100644 index 80b3ae6..0000000 --- a/lib/vendor/sabre/http/lib/HttpException.php +++ /dev/null @@ -1,31 +0,0 @@ -getBody(); - if (is_callable($this->body)) { - $body = $this->getBodyAsString(); - } - if (is_string($body) || null === $body) { - $stream = fopen('php://temp', 'r+'); - fwrite($stream, (string) $body); - rewind($stream); - - return $stream; - } - - return $body; - } - - /** - * Returns the body as a string. - * - * Note that because the underlying data may be based on a stream, this - * method could only work correctly the first time. - */ - public function getBodyAsString(): string - { - $body = $this->getBody(); - if (is_string($body)) { - return $body; - } - if (null === $body) { - return ''; - } - if (is_callable($body)) { - ob_start(); - $body(); - - return ob_get_clean(); - } - /** - * @var string|int|null - */ - $contentLength = $this->getHeader('Content-Length'); - if (null !== $contentLength && (is_int($contentLength) || ctype_digit($contentLength))) { - return stream_get_contents($body, (int) $contentLength); - } - - return stream_get_contents($body); - } - - /** - * Returns the message body, as its internal representation. - * - * This could be either a string, a stream or a callback writing the body to php://output. - * - * @return resource|string|callable - */ - public function getBody() - { - return $this->body; - } - - /** - * Replaces the body resource with a new stream, string or a callback writing the body to php://output. - * - * @param resource|string|callable $body - */ - public function setBody($body) - { - $this->body = $body; - } - - /** - * Returns all the HTTP headers as an array. - * - * Every header is returned as an array, with one or more values. - */ - public function getHeaders(): array - { - $result = []; - foreach ($this->headers as $headerInfo) { - $result[$headerInfo[0]] = $headerInfo[1]; - } - - return $result; - } - - /** - * Will return true or false, depending on if a HTTP header exists. - */ - public function hasHeader(string $name): bool - { - return isset($this->headers[strtolower($name)]); - } - - /** - * Returns a specific HTTP header, based on its name. - * - * The name must be treated as case-insensitive. - * If the header does not exist, this method must return null. - * - * If a header appeared more than once in a HTTP request, this method will - * concatenate all the values with a comma. - * - * Note that this not make sense for all headers. Some, such as - * `Set-Cookie` cannot be logically combined with a comma. In those cases - * you *should* use getHeaderAsArray(). - * - * @return string|null - */ - public function getHeader(string $name) - { - $name = strtolower($name); - - if (isset($this->headers[$name])) { - return implode(',', $this->headers[$name][1]); - } - - return null; - } - - /** - * Returns a HTTP header as an array. - * - * For every time the HTTP header appeared in the request or response, an - * item will appear in the array. - * - * If the header did not exist, this method will return an empty array. - * - * @return string[] - */ - public function getHeaderAsArray(string $name): array - { - $name = strtolower($name); - - if (isset($this->headers[$name])) { - return $this->headers[$name][1]; - } - - return []; - } - - /** - * Updates a HTTP header. - * - * The case-sensitivity of the name value must be retained as-is. - * - * If the header already existed, it will be overwritten. - * - * @param string|string[] $value - */ - public function setHeader(string $name, $value) - { - $this->headers[strtolower($name)] = [$name, (array) $value]; - } - - /** - * Sets a new set of HTTP headers. - * - * The headers array should contain headernames for keys, and their value - * should be specified as either a string or an array. - * - * Any header that already existed will be overwritten. - */ - public function setHeaders(array $headers) - { - foreach ($headers as $name => $value) { - $this->setHeader($name, $value); - } - } - - /** - * Adds a HTTP header. - * - * This method will not overwrite any existing HTTP header, but instead add - * another value. Individual values can be retrieved with - * getHeadersAsArray. - * - * @param string|string[] $value - */ - public function addHeader(string $name, $value) - { - $lName = strtolower($name); - if (isset($this->headers[$lName])) { - $this->headers[$lName][1] = array_merge( - $this->headers[$lName][1], - (array) $value - ); - } else { - $this->headers[$lName] = [ - $name, - (array) $value, - ]; - } - } - - /** - * Adds a new set of HTTP headers. - * - * Any existing headers will not be overwritten. - */ - public function addHeaders(array $headers) - { - foreach ($headers as $name => $value) { - $this->addHeader($name, $value); - } - } - - /** - * Removes a HTTP header. - * - * The specified header name must be treated as case-insensitive. - * This method should return true if the header was successfully deleted, - * and false if the header did not exist. - */ - public function removeHeader(string $name): bool - { - $name = strtolower($name); - if (!isset($this->headers[$name])) { - return false; - } - unset($this->headers[$name]); - - return true; - } - - /** - * Sets the HTTP version. - * - * Should be 1.0, 1.1 or 2.0. - */ - public function setHttpVersion(string $version) - { - $this->httpVersion = $version; - } - - /** - * Returns the HTTP version. - */ - public function getHttpVersion(): string - { - return $this->httpVersion; - } -} diff --git a/lib/vendor/sabre/http/lib/MessageDecoratorTrait.php b/lib/vendor/sabre/http/lib/MessageDecoratorTrait.php deleted file mode 100644 index 191ba0f..0000000 --- a/lib/vendor/sabre/http/lib/MessageDecoratorTrait.php +++ /dev/null @@ -1,206 +0,0 @@ -inner->getBodyAsStream(); - } - - /** - * Returns the body as a string. - * - * Note that because the underlying data may be based on a stream, this - * method could only work correctly the first time. - */ - public function getBodyAsString(): string - { - return $this->inner->getBodyAsString(); - } - - /** - * Returns the message body, as its internal representation. - * - * This could be either a string or a stream. - * - * @return resource|string - */ - public function getBody() - { - return $this->inner->getBody(); - } - - /** - * Updates the body resource with a new stream. - * - * @param resource|string|callable $body - */ - public function setBody($body) - { - $this->inner->setBody($body); - } - - /** - * Returns all the HTTP headers as an array. - * - * Every header is returned as an array, with one or more values. - */ - public function getHeaders(): array - { - return $this->inner->getHeaders(); - } - - /** - * Will return true or false, depending on if a HTTP header exists. - */ - public function hasHeader(string $name): bool - { - return $this->inner->hasHeader($name); - } - - /** - * Returns a specific HTTP header, based on its name. - * - * The name must be treated as case-insensitive. - * If the header does not exist, this method must return null. - * - * If a header appeared more than once in a HTTP request, this method will - * concatenate all the values with a comma. - * - * Note that this not make sense for all headers. Some, such as - * `Set-Cookie` cannot be logically combined with a comma. In those cases - * you *should* use getHeaderAsArray(). - * - * @return string|null - */ - public function getHeader(string $name) - { - return $this->inner->getHeader($name); - } - - /** - * Returns a HTTP header as an array. - * - * For every time the HTTP header appeared in the request or response, an - * item will appear in the array. - * - * If the header did not exist, this method will return an empty array. - */ - public function getHeaderAsArray(string $name): array - { - return $this->inner->getHeaderAsArray($name); - } - - /** - * Updates a HTTP header. - * - * The case-sensitivity of the name value must be retained as-is. - * - * If the header already existed, it will be overwritten. - * - * @param string|string[] $value - */ - public function setHeader(string $name, $value) - { - $this->inner->setHeader($name, $value); - } - - /** - * Sets a new set of HTTP headers. - * - * The headers array should contain headernames for keys, and their value - * should be specified as either a string or an array. - * - * Any header that already existed will be overwritten. - */ - public function setHeaders(array $headers) - { - $this->inner->setHeaders($headers); - } - - /** - * Adds a HTTP header. - * - * This method will not overwrite any existing HTTP header, but instead add - * another value. Individual values can be retrieved with - * getHeadersAsArray. - * - * @param string|string[] $value - */ - public function addHeader(string $name, $value) - { - $this->inner->addHeader($name, $value); - } - - /** - * Adds a new set of HTTP headers. - * - * Any existing headers will not be overwritten. - */ - public function addHeaders(array $headers) - { - $this->inner->addHeaders($headers); - } - - /** - * Removes a HTTP header. - * - * The specified header name must be treated as case-insensitive. - * This method should return true if the header was successfully deleted, - * and false if the header did not exist. - */ - public function removeHeader(string $name): bool - { - return $this->inner->removeHeader($name); - } - - /** - * Sets the HTTP version. - * - * Should be 1.0, 1.1 or 2.0. - */ - public function setHttpVersion(string $version) - { - $this->inner->setHttpVersion($version); - } - - /** - * Returns the HTTP version. - */ - public function getHttpVersion(): string - { - return $this->inner->getHttpVersion(); - } -} diff --git a/lib/vendor/sabre/http/lib/MessageInterface.php b/lib/vendor/sabre/http/lib/MessageInterface.php deleted file mode 100644 index 4531654..0000000 --- a/lib/vendor/sabre/http/lib/MessageInterface.php +++ /dev/null @@ -1,151 +0,0 @@ -setMethod($method); - $this->setUrl($url); - $this->setHeaders($headers); - $this->setBody($body); - } - - /** - * Returns the current HTTP method. - */ - public function getMethod(): string - { - return $this->method; - } - - /** - * Sets the HTTP method. - */ - public function setMethod(string $method) - { - $this->method = $method; - } - - /** - * Returns the request url. - */ - public function getUrl(): string - { - return $this->url; - } - - /** - * Sets the request url. - */ - public function setUrl(string $url) - { - $this->url = $url; - } - - /** - * Returns the list of query parameters. - * - * This is equivalent to PHP's $_GET superglobal. - */ - public function getQueryParameters(): array - { - $url = $this->getUrl(); - if (false === ($index = strpos($url, '?'))) { - return []; - } - - parse_str(substr($url, $index + 1), $queryParams); - - return $queryParams; - } - - protected $absoluteUrl; - - /** - * Sets the absolute url. - */ - public function setAbsoluteUrl(string $url) - { - $this->absoluteUrl = $url; - } - - /** - * Returns the absolute url. - */ - public function getAbsoluteUrl(): string - { - if (!$this->absoluteUrl) { - $url = $this->getUrl(); - if (parse_url($url, PHP_URL_SCHEME)) { - // It's already an absolute URL - $this->absoluteUrl = $url; - } else { - $host = $this->getHeader('Host') - ?? parse_url($url, PHP_URL_HOST) - ?? 'localhost'; - // Guessing we're a http endpoint. - $this->absoluteUrl = "http://$host$url"; - } - } - - return $this->absoluteUrl; - } - - /** - * Base url. - * - * @var string - */ - protected $baseUrl = '/'; - - /** - * Sets a base url. - * - * This url is used for relative path calculations. - */ - public function setBaseUrl(string $url) - { - $this->baseUrl = $url; - } - - /** - * Returns the current base url. - */ - public function getBaseUrl(): string - { - return $this->baseUrl; - } - - /** - * Returns the relative path. - * - * This is being calculated using the base url. This path will not start - * with a slash, so it will always return something like - * 'example/path.html'. - * - * If the full path is equal to the base url, this method will return an - * empty string. - * - * This method will also urldecode the path, and if the url was encoded as - * ISO-8859-1, it will convert it to UTF-8. - * - * If the path is outside of the base url, a LogicException will be thrown. - */ - public function getPath(): string - { - // Removing duplicated slashes. - $uri = str_replace('//', '/', $this->getUrl()); - - $uri = Uri\normalize($uri); - $baseUri = Uri\normalize($this->getBaseUrl()); - - if (0 === strpos($uri, $baseUri)) { - // We're not interested in the query part (everything after the ?). - list($uri) = explode('?', $uri); - - return trim(decodePath(substr($uri, strlen($baseUri))), '/'); - } - - if ($uri.'/' === $baseUri) { - return ''; - } - // A special case, if the baseUri was accessed without a trailing - // slash, we'll accept it as well. - - throw new \LogicException('Requested uri ('.$this->getUrl().') is out of base uri ('.$this->getBaseUrl().')'); - } - - /** - * Equivalent of PHP's $_POST. - * - * @var array - */ - protected $postData = []; - - /** - * Sets the post data. - * - * This is equivalent to PHP's $_POST superglobal. - * - * This would not have been needed, if POST data was accessible as - * php://input, but unfortunately we need to special case it. - */ - public function setPostData(array $postData) - { - $this->postData = $postData; - } - - /** - * Returns the POST data. - * - * This is equivalent to PHP's $_POST superglobal. - */ - public function getPostData(): array - { - return $this->postData; - } - - /** - * An array containing the raw _SERVER array. - * - * @var array - */ - protected $rawServerData; - - /** - * Returns an item from the _SERVER array. - * - * If the value does not exist in the array, null is returned. - * - * @return string|null - */ - public function getRawServerValue(string $valueName) - { - return $this->rawServerData[$valueName] ?? null; - } - - /** - * Sets the _SERVER array. - */ - public function setRawServerData(array $data) - { - $this->rawServerData = $data; - } - - /** - * Serializes the request object as a string. - * - * This is useful for debugging purposes. - */ - public function __toString(): string - { - $out = $this->getMethod().' '.$this->getUrl().' HTTP/'.$this->getHttpVersion()."\r\n"; - - foreach ($this->getHeaders() as $key => $value) { - foreach ($value as $v) { - if ('Authorization' === $key) { - list($v) = explode(' ', $v, 2); - $v .= ' REDACTED'; - } - $out .= $key.': '.$v."\r\n"; - } - } - $out .= "\r\n"; - $out .= $this->getBodyAsString(); - - return $out; - } -} diff --git a/lib/vendor/sabre/http/lib/RequestDecorator.php b/lib/vendor/sabre/http/lib/RequestDecorator.php deleted file mode 100644 index 23e790e..0000000 --- a/lib/vendor/sabre/http/lib/RequestDecorator.php +++ /dev/null @@ -1,179 +0,0 @@ -inner = $inner; - } - - /** - * Returns the current HTTP method. - */ - public function getMethod(): string - { - return $this->inner->getMethod(); - } - - /** - * Sets the HTTP method. - */ - public function setMethod(string $method) - { - $this->inner->setMethod($method); - } - - /** - * Returns the request url. - */ - public function getUrl(): string - { - return $this->inner->getUrl(); - } - - /** - * Sets the request url. - */ - public function setUrl(string $url) - { - $this->inner->setUrl($url); - } - - /** - * Returns the absolute url. - */ - public function getAbsoluteUrl(): string - { - return $this->inner->getAbsoluteUrl(); - } - - /** - * Sets the absolute url. - */ - public function setAbsoluteUrl(string $url) - { - $this->inner->setAbsoluteUrl($url); - } - - /** - * Returns the current base url. - */ - public function getBaseUrl(): string - { - return $this->inner->getBaseUrl(); - } - - /** - * Sets a base url. - * - * This url is used for relative path calculations. - * - * The base url should default to / - */ - public function setBaseUrl(string $url) - { - $this->inner->setBaseUrl($url); - } - - /** - * Returns the relative path. - * - * This is being calculated using the base url. This path will not start - * with a slash, so it will always return something like - * 'example/path.html'. - * - * If the full path is equal to the base url, this method will return an - * empty string. - * - * This method will also urldecode the path, and if the url was encoded as - * ISO-8859-1, it will convert it to UTF-8. - * - * If the path is outside of the base url, a LogicException will be thrown. - */ - public function getPath(): string - { - return $this->inner->getPath(); - } - - /** - * Returns the list of query parameters. - * - * This is equivalent to PHP's $_GET superglobal. - */ - public function getQueryParameters(): array - { - return $this->inner->getQueryParameters(); - } - - /** - * Returns the POST data. - * - * This is equivalent to PHP's $_POST superglobal. - */ - public function getPostData(): array - { - return $this->inner->getPostData(); - } - - /** - * Sets the post data. - * - * This is equivalent to PHP's $_POST superglobal. - * - * This would not have been needed, if POST data was accessible as - * php://input, but unfortunately we need to special case it. - */ - public function setPostData(array $postData) - { - $this->inner->setPostData($postData); - } - - /** - * Returns an item from the _SERVER array. - * - * If the value does not exist in the array, null is returned. - * - * @return string|null - */ - public function getRawServerValue(string $valueName) - { - return $this->inner->getRawServerValue($valueName); - } - - /** - * Sets the _SERVER array. - */ - public function setRawServerData(array $data) - { - $this->inner->setRawServerData($data); - } - - /** - * Serializes the request object as a string. - * - * This is useful for debugging purposes. - */ - public function __toString(): string - { - return $this->inner->__toString(); - } -} diff --git a/lib/vendor/sabre/http/lib/RequestInterface.php b/lib/vendor/sabre/http/lib/RequestInterface.php deleted file mode 100644 index 5ec7777..0000000 --- a/lib/vendor/sabre/http/lib/RequestInterface.php +++ /dev/null @@ -1,114 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 207 => 'Multi-Status', // RFC 4918 - 208 => 'Already Reported', // RFC 5842 - 226 => 'IM Used', // RFC 3229 - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 307 => 'Temporary Redirect', - 308 => 'Permanent Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 418 => 'I\'m a teapot', // RFC 2324 - 421 => 'Misdirected Request', // RFC7540 (HTTP/2) - 422 => 'Unprocessable Entity', // RFC 4918 - 423 => 'Locked', // RFC 4918 - 424 => 'Failed Dependency', // RFC 4918 - 426 => 'Upgrade Required', - 428 => 'Precondition Required', // RFC 6585 - 429 => 'Too Many Requests', // RFC 6585 - 431 => 'Request Header Fields Too Large', // RFC 6585 - 451 => 'Unavailable For Legal Reasons', // draft-tbray-http-legally-restricted-status - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version not supported', - 506 => 'Variant Also Negotiates', - 507 => 'Insufficient Storage', // RFC 4918 - 508 => 'Loop Detected', // RFC 5842 - 509 => 'Bandwidth Limit Exceeded', // non-standard - 510 => 'Not extended', - 511 => 'Network Authentication Required', // RFC 6585 - ]; - - /** - * HTTP status code. - * - * @var int - */ - protected $status; - - /** - * HTTP status text. - * - * @var string - */ - protected $statusText; - - /** - * Creates the response object. - * - * @param string|int $status - * @param resource $body - */ - public function __construct($status = 500, ?array $headers = null, $body = null) - { - if (null !== $status) { - $this->setStatus($status); - } - if (null !== $headers) { - $this->setHeaders($headers); - } - if (null !== $body) { - $this->setBody($body); - } - } - - /** - * Returns the current HTTP status code. - */ - public function getStatus(): int - { - return $this->status; - } - - /** - * Returns the human-readable status string. - * - * In the case of a 200, this may for example be 'OK'. - */ - public function getStatusText(): string - { - return $this->statusText; - } - - /** - * Sets the HTTP status code. - * - * This can be either the full HTTP status code with human-readable string, - * for example: "403 I can't let you do that, Dave". - * - * Or just the code, in which case the appropriate default message will be - * added. - * - * @param string|int $status - * - * @throws \InvalidArgumentException - */ - public function setStatus($status) - { - if (is_int($status) || ctype_digit($status)) { - $statusCode = $status; - $statusText = self::$statusCodes[$status] ?? 'Unknown'; - } else { - list( - $statusCode, - $statusText - ) = explode(' ', $status, 2); - $statusCode = (int) $statusCode; - } - if ($statusCode < 100 || $statusCode > 999) { - throw new \InvalidArgumentException('The HTTP status code must be exactly 3 digits'); - } - - $this->status = $statusCode; - $this->statusText = $statusText; - } - - /** - * Serializes the response object as a string. - * - * This is useful for debugging purposes. - */ - public function __toString(): string - { - $str = 'HTTP/'.$this->httpVersion.' '.$this->getStatus().' '.$this->getStatusText()."\r\n"; - foreach ($this->getHeaders() as $key => $value) { - foreach ($value as $v) { - $str .= $key.': '.$v."\r\n"; - } - } - $str .= "\r\n"; - $str .= $this->getBodyAsString(); - - return $str; - } -} diff --git a/lib/vendor/sabre/http/lib/ResponseDecorator.php b/lib/vendor/sabre/http/lib/ResponseDecorator.php deleted file mode 100644 index 30b9ec0..0000000 --- a/lib/vendor/sabre/http/lib/ResponseDecorator.php +++ /dev/null @@ -1,72 +0,0 @@ -inner = $inner; - } - - /** - * Returns the current HTTP status code. - */ - public function getStatus(): int - { - return $this->inner->getStatus(); - } - - /** - * Returns the human-readable status string. - * - * In the case of a 200, this may for example be 'OK'. - */ - public function getStatusText(): string - { - return $this->inner->getStatusText(); - } - - /** - * Sets the HTTP status code. - * - * This can be either the full HTTP status code with human-readable string, - * for example: "403 I can't let you do that, Dave". - * - * Or just the code, in which case the appropriate default message will be - * added. - * - * @param string|int $status - */ - public function setStatus($status) - { - $this->inner->setStatus($status); - } - - /** - * Serializes the request object as a string. - * - * This is useful for debugging purposes. - */ - public function __toString(): string - { - return $this->inner->__toString(); - } -} diff --git a/lib/vendor/sabre/http/lib/ResponseInterface.php b/lib/vendor/sabre/http/lib/ResponseInterface.php deleted file mode 100644 index fd73d25..0000000 --- a/lib/vendor/sabre/http/lib/ResponseInterface.php +++ /dev/null @@ -1,42 +0,0 @@ -setBody(fopen('php://input', 'r')); - $r->setPostData($_POST); - - return $r; - } - - /** - * Sends the HTTP response back to a HTTP client. - * - * This calls php's header() function and streams the body to php://output. - */ - public static function sendResponse(ResponseInterface $response) - { - header('HTTP/'.$response->getHttpVersion().' '.$response->getStatus().' '.$response->getStatusText()); - foreach ($response->getHeaders() as $key => $value) { - foreach ($value as $k => $v) { - if (0 === $k) { - header($key.': '.$v); - } else { - header($key.': '.$v, false); - } - } - } - - $body = $response->getBody(); - if (null === $body) { - return; - } - - if (is_callable($body)) { - $body(); - - return; - } - - $contentLength = $response->getHeader('Content-Length'); - if (null !== $contentLength) { - $output = fopen('php://output', 'wb'); - if (is_resource($body) && 'stream' == get_resource_type($body)) { - // a workaround to make PHP more possible to use mmap based copy, see https://github.com/sabre-io/http/pull/119 - $left = (int) $contentLength; - // copy with 4MiB chunks - $chunk_size = 4 * 1024 * 1024; - stream_set_chunk_size($output, $chunk_size); - // If this is a partial response, flush the beginning bytes until the first position that is a multiple of the page size. - $contentRange = $response->getHeader('Content-Range'); - // Matching "Content-Range: bytes 1234-5678/7890" - if (null !== $contentRange && preg_match('/^bytes\s([0-9]+)-([0-9]+)\//i', $contentRange, $matches)) { - // 4kB should be the default page size on most architectures - $pageSize = 4096; - $offset = (int) $matches[1]; - $delta = ($offset % $pageSize) > 0 ? ($pageSize - $offset % $pageSize) : 0; - if ($delta > 0) { - $left -= stream_copy_to_stream($body, $output, min($delta, $left)); - } - } - while ($left > 0) { - $copied = stream_copy_to_stream($body, $output, min($left, $chunk_size)); - // stream_copy_to_stream($src, $dest, $maxLength) must return the number of bytes copied or false in case of failure - // But when the $maxLength is greater than the total number of bytes remaining in the stream, - // It returns the negative number of bytes copied - // So break the loop in such cases. - if ($copied <= 0) { - break; - } - // Abort on client disconnect. - // With ignore_user_abort(true), the script is not aborted on client disconnect. - // To avoid reading the entire stream and dismissing the data afterward, check between the chunks if the client is still there. - if (1 === ignore_user_abort() && 1 === connection_aborted()) { - break; - } - $left -= $copied; - } - } else { - fwrite($output, $body, (int) $contentLength); - } - } else { - file_put_contents('php://output', $body); - } - - if (is_resource($body)) { - fclose($body); - } - } - - /** - * This static method will create a new Request object, based on a PHP - * $_SERVER array. - * - * REQUEST_URI and REQUEST_METHOD are required. - */ - public static function createFromServerArray(array $serverArray): Request - { - $headers = []; - $method = null; - $url = null; - $httpVersion = '1.1'; - - $protocol = 'http'; - $hostName = 'localhost'; - - foreach ($serverArray as $key => $value) { - $key = (string) $key; - switch ($key) { - case 'SERVER_PROTOCOL': - if ('HTTP/1.0' === $value) { - $httpVersion = '1.0'; - } elseif ('HTTP/2.0' === $value) { - $httpVersion = '2.0'; - } - break; - case 'REQUEST_METHOD': - $method = $value; - break; - case 'REQUEST_URI': - $url = $value; - break; - - // These sometimes show up without a HTTP_ prefix - case 'CONTENT_TYPE': - $headers['Content-Type'] = $value; - break; - case 'CONTENT_LENGTH': - $headers['Content-Length'] = $value; - break; - - // mod_php on apache will put credentials in these variables. - // (fast)cgi does not usually do this, however. - case 'PHP_AUTH_USER': - if (isset($serverArray['PHP_AUTH_PW'])) { - $headers['Authorization'] = 'Basic '.base64_encode($value.':'.$serverArray['PHP_AUTH_PW']); - } - break; - - // Similarly, mod_php may also screw around with digest auth. - case 'PHP_AUTH_DIGEST': - $headers['Authorization'] = 'Digest '.$value; - break; - - // Apache may prefix the HTTP_AUTHORIZATION header with - // REDIRECT_, if mod_rewrite was used. - case 'REDIRECT_HTTP_AUTHORIZATION': - $headers['Authorization'] = $value; - break; - - case 'HTTP_HOST': - $hostName = $value; - $headers['Host'] = $value; - break; - - case 'HTTPS': - if (!empty($value) && 'off' !== $value) { - $protocol = 'https'; - } - break; - - default: - if ('HTTP_' === substr($key, 0, 5)) { - // It's a HTTP header - - // Normalizing it to be prettier - $header = strtolower(substr($key, 5)); - - // Transforming dashes into spaces, and upper-casing - // every first letter. - $header = ucwords(str_replace('_', ' ', $header)); - - // Turning spaces into dashes. - $header = str_replace(' ', '-', $header); - $headers[$header] = $value; - } - break; - } - } - - if (null === $url) { - throw new \InvalidArgumentException('The _SERVER array must have a REQUEST_URI key'); - } - - if (null === $method) { - throw new \InvalidArgumentException('The _SERVER array must have a REQUEST_METHOD key'); - } - $r = new Request($method, $url, $headers); - $r->setHttpVersion($httpVersion); - $r->setRawServerData($serverArray); - $r->setAbsoluteUrl($protocol.'://'.$hostName.$url); - - return $r; - } -} diff --git a/lib/vendor/sabre/http/lib/Version.php b/lib/vendor/sabre/http/lib/Version.php deleted file mode 100644 index 84c877b..0000000 --- a/lib/vendor/sabre/http/lib/Version.php +++ /dev/null @@ -1,20 +0,0 @@ -setTimezone(new \DateTimeZone('GMT')); - - return $dateTime->format('D, d M Y H:i:s \G\M\T'); -} - -/** - * This function can be used to aid with content negotiation. - * - * It takes 2 arguments, the $acceptHeaderValue, which usually comes from - * an Accept header, and $availableOptions, which contains an array of - * items that the server can support. - * - * The result of this function will be the 'best possible option'. If no - * best possible option could be found, null is returned. - * - * When it's null you can according to the spec either return a default, or - * you can choose to emit 406 Not Acceptable. - * - * The method also accepts sending 'null' for the $acceptHeaderValue, - * implying that no accept header was sent. - * - * @param string|null $acceptHeaderValue - * - * @return string|null - */ -function negotiateContentType($acceptHeaderValue, array $availableOptions) -{ - if (!$acceptHeaderValue) { - // Grabbing the first in the list. - return reset($availableOptions); - } - - $proposals = array_map( - 'Sabre\HTTP\parseMimeType', - explode(',', $acceptHeaderValue) - ); - - // Ensuring array keys are reset. - $availableOptions = array_values($availableOptions); - - $options = array_map( - 'Sabre\HTTP\parseMimeType', - $availableOptions - ); - - $lastQuality = 0; - $lastSpecificity = 0; - $lastOptionIndex = 0; - $lastChoice = null; - - foreach ($proposals as $proposal) { - // Ignoring broken values. - if (null === $proposal) { - continue; - } - - // If the quality is lower we don't have to bother comparing. - if ($proposal['quality'] < $lastQuality) { - continue; - } - - foreach ($options as $optionIndex => $option) { - if ('*' !== $proposal['type'] && $proposal['type'] !== $option['type']) { - // no match on type. - continue; - } - if ('*' !== $proposal['subType'] && $proposal['subType'] !== $option['subType']) { - // no match on subtype. - continue; - } - - // Any parameters appearing on the options must appear on - // proposals. - foreach ($option['parameters'] as $paramName => $paramValue) { - if (!array_key_exists($paramName, $proposal['parameters'])) { - continue 2; - } - if ($paramValue !== $proposal['parameters'][$paramName]) { - continue 2; - } - } - - // If we got here, we have a match on parameters, type and - // subtype. We need to calculate a score for how specific the - // match was. - $specificity = - ('*' !== $proposal['type'] ? 20 : 0) + - ('*' !== $proposal['subType'] ? 10 : 0) + - count($option['parameters']); - - // Does this entry win? - if ( - ($proposal['quality'] > $lastQuality) - || ($proposal['quality'] === $lastQuality && $specificity > $lastSpecificity) - || ($proposal['quality'] === $lastQuality && $specificity === $lastSpecificity && $optionIndex < $lastOptionIndex) - ) { - $lastQuality = $proposal['quality']; - $lastSpecificity = $specificity; - $lastOptionIndex = $optionIndex; - $lastChoice = $availableOptions[$optionIndex]; - } - } - } - - return $lastChoice; -} - -/** - * Parses the Prefer header, as defined in RFC7240. - * - * Input can be given as a single header value (string) or multiple headers - * (array of string). - * - * This method will return a key->value array with the various Prefer - * parameters. - * - * Prefer: return=minimal will result in: - * - * [ 'return' => 'minimal' ] - * - * Prefer: foo, wait=10 will result in: - * - * [ 'foo' => true, 'wait' => '10'] - * - * This method also supports the formats from older drafts of RFC7240, and - * it will automatically map them to the new values, as the older values - * are still pretty common. - * - * Parameters are currently discarded. There's no known prefer value that - * uses them. - * - * @param string|string[] $input - */ -function parsePrefer($input): array -{ - $token = '[!#$%&\'*+\-.^_`~A-Za-z0-9]+'; - - // Work in progress - $word = '(?: [a-zA-Z0-9]+ | "[a-zA-Z0-9]*" )'; - - $regex = << $token) # Prefer property name -\s* # Optional space -(?: = \s* # Prefer property value - (? $word) -)? -(?: \s* ; (?: .*))? # Prefer parameters (ignored) -$ -/x -REGEX; - - $output = []; - foreach (getHeaderValues($input) as $value) { - if (!preg_match($regex, $value, $matches)) { - // Ignore - continue; - } - - // Mapping old values to their new counterparts - switch ($matches['name']) { - case 'return-asynch': - $output['respond-async'] = true; - break; - case 'return-representation': - $output['return'] = 'representation'; - break; - case 'return-minimal': - $output['return'] = 'minimal'; - break; - case 'strict': - $output['handling'] = 'strict'; - break; - case 'lenient': - $output['handling'] = 'lenient'; - break; - default: - if (isset($matches['value'])) { - $value = trim($matches['value'], '"'); - } else { - $value = true; - } - $output[strtolower($matches['name'])] = empty($value) ? true : $value; - break; - } - } - - return $output; -} - -/** - * This method splits up headers into all their individual values. - * - * A HTTP header may have more than one header, such as this: - * Cache-Control: private, no-store - * - * Header values are always split with a comma. - * - * You can pass either a string, or an array. The resulting value is always - * an array with each spliced value. - * - * If the second headers argument is set, this value will simply be merged - * in. This makes it quicker to merge an old list of values with a new set. - * - * @param string|string[] $values - * @param string|string[] $values2 - */ -function getHeaderValues($values, $values2 = null): array -{ - $values = (array) $values; - if ($values2) { - $values = array_merge($values, (array) $values2); - } - - $result = []; - foreach ($values as $l1) { - foreach (explode(',', $l1) as $l2) { - $result[] = trim($l2); - } - } - - return $result; -} - -/** - * Parses a mime-type and splits it into:. - * - * 1. type - * 2. subtype - * 3. quality - * 4. parameters - */ -function parseMimeType(string $str): array -{ - $parameters = []; - // If no q= parameter appears, then quality = 1. - $quality = 1; - - $parts = explode(';', $str); - - // The first part is the mime-type. - $mimeType = trim(array_shift($parts)); - - if ('*' === $mimeType) { - $mimeType = '*/*'; - } - - $mimeType = explode('/', $mimeType); - if (2 !== count($mimeType)) { - // Illegal value - var_dump($mimeType); - exit; - // throw new InvalidArgumentException('Not a valid mime-type: '.$str); - } - list($type, $subType) = $mimeType; - - foreach ($parts as $part) { - $part = trim($part); - if (strpos($part, '=')) { - list($partName, $partValue) = - explode('=', $part, 2); - } else { - $partName = $part; - $partValue = null; - } - - // The quality parameter, if it appears, also marks the end of - // the parameter list. Anything after the q= counts as an - // 'accept extension' and could introduce new semantics in - // content-negotiation. - if ('q' !== $partName) { - $parameters[$partName] = $part; - } else { - $quality = (float) $partValue; - break; // Stop parsing parts - } - } - - return [ - 'type' => $type, - 'subType' => $subType, - 'quality' => $quality, - 'parameters' => $parameters, - ]; -} - -/** - * Encodes the path of a url. - * - * slashes (/) are treated as path-separators. - */ -function encodePath(string $path): string -{ - 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 - */ -function encodePathSegment(string $pathSegment): string -{ - return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\):@])/', function ($match) { - return '%'.sprintf('%02x', ord($match[0])); - }, $pathSegment); -} - -/** - * Decodes a url-encoded path. - */ -function decodePath(string $path): string -{ - return decodePathSegment($path); -} - -/** - * Decodes a url-encoded path segment. - */ -function decodePathSegment(string $path): string -{ - $path = rawurldecode($path); - - if (!mb_check_encoding($path, 'UTF-8') && mb_check_encoding($path, 'ISO-8859-1')) { - $path = mb_convert_encoding($path, 'UTF-8', 'ISO-8859-1'); - } - - return $path; -} diff --git a/lib/vendor/sabre/http/phpstan.neon b/lib/vendor/sabre/http/phpstan.neon deleted file mode 100644 index 213da6d..0000000 --- a/lib/vendor/sabre/http/phpstan.neon +++ /dev/null @@ -1,2 +0,0 @@ -parameters: - level: 1 diff --git a/lib/vendor/sabre/http/tests/HTTP/Auth/AWSTest.php b/lib/vendor/sabre/http/tests/HTTP/Auth/AWSTest.php deleted file mode 100644 index a019adc..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/Auth/AWSTest.php +++ /dev/null @@ -1,236 +0,0 @@ -response = new Response(); - $this->request = new Request('GET', '/'); - $this->auth = new AWS(self::REALM, $this->request, $this->response); - } - - public function testNoHeader() - { - $this->request->setMethod('GET'); - $result = $this->auth->init(); - - $this->assertFalse($result, 'No AWS Authorization header was supplied, so we should have gotten false'); - $this->assertEquals(AWS::ERR_NOAWSHEADER, $this->auth->errorCode); - } - - public function testInvalidAuthorizationHeader() - { - $this->request->setMethod('GET'); - $this->request->setHeader('Authorization', 'Invalid Auth Header'); - - $this->assertFalse($this->auth->init(), 'The Invalid AWS authorization header'); - } - - public function testIncorrectContentMD5() - { - $accessKey = 'accessKey'; - $secretKey = 'secretKey'; - - $this->request->setMethod('GET'); - $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", - 'Content-MD5' => 'garbage', - ]); - $this->request->setUrl('/'); - - $this->auth->init(); - $result = $this->auth->validate($secretKey); - - $this->assertFalse($result); - $this->assertEquals(AWS::ERR_MD5CHECKSUMWRONG, $this->auth->errorCode); - } - - public function testNoDate() - { - $accessKey = 'accessKey'; - $secretKey = 'secretKey'; - $content = 'thisisthebody'; - $contentMD5 = base64_encode(md5($content, true)); - - $this->request->setMethod('POST'); - $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", - 'Content-MD5' => $contentMD5, - ]); - $this->request->setUrl('/'); - $this->request->setBody($content); - - $this->auth->init(); - $result = $this->auth->validate($secretKey); - - $this->assertFalse($result); - $this->assertEquals(AWS::ERR_INVALIDDATEFORMAT, $this->auth->errorCode); - } - - public function testFutureDate() - { - $accessKey = 'accessKey'; - $secretKey = 'secretKey'; - $content = 'thisisthebody'; - $contentMD5 = base64_encode(md5($content, true)); - - $date = new \DateTime('@'.(time() + (60 * 20))); - $date->setTimeZone(new \DateTimeZone('GMT')); - $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); - - $this->request->setMethod('POST'); - $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", - 'Content-MD5' => $contentMD5, - 'Date' => $date, - ]); - - $this->request->setBody($content); - - $this->auth->init(); - $result = $this->auth->validate($secretKey); - - $this->assertFalse($result); - $this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); - } - - public function testPastDate() - { - $accessKey = 'accessKey'; - $secretKey = 'secretKey'; - $content = 'thisisthebody'; - $contentMD5 = base64_encode(md5($content, true)); - - $date = new \DateTime('@'.(time() - (60 * 20))); - $date->setTimeZone(new \DateTimeZone('GMT')); - $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); - - $this->request->setMethod('POST'); - $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", - 'Content-MD5' => $contentMD5, - 'Date' => $date, - ]); - - $this->request->setBody($content); - - $this->auth->init(); - $result = $this->auth->validate($secretKey); - - $this->assertFalse($result); - $this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); - } - - public function testIncorrectSignature() - { - $accessKey = 'accessKey'; - $secretKey = 'secretKey'; - $content = 'thisisthebody'; - - $contentMD5 = base64_encode(md5($content, true)); - - $date = new \DateTime('now'); - $date->setTimeZone(new \DateTimeZone('GMT')); - $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); - - $this->request->setUrl('/'); - $this->request->setMethod('POST'); - $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:sig", - 'Content-MD5' => $contentMD5, - 'X-amz-date' => $date, - ]); - $this->request->setBody($content); - - $this->auth->init(); - $result = $this->auth->validate($secretKey); - - $this->assertFalse($result); - $this->assertEquals(AWS::ERR_INVALIDSIGNATURE, $this->auth->errorCode); - } - - public function testValidRequest() - { - $accessKey = 'accessKey'; - $secretKey = 'secretKey'; - $content = 'thisisthebody'; - $contentMD5 = base64_encode(md5($content, true)); - - $date = new \DateTime('now'); - $date->setTimeZone(new \DateTimeZone('GMT')); - $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); - - $sig = base64_encode($this->hmacsha1($secretKey, - "POST\n$contentMD5\n\n$date\nx-amz-date:$date\n/evert" - )); - - $this->request->setUrl('/evert'); - $this->request->setMethod('POST'); - $this->request->setHeaders([ - 'Authorization' => "AWS $accessKey:$sig", - 'Content-MD5' => $contentMD5, - 'X-amz-date' => $date, - ]); - - $this->request->setBody($content); - - $this->auth->init(); - $result = $this->auth->validate($secretKey); - - $this->assertTrue($result, 'Signature did not validate, got errorcode '.$this->auth->errorCode); - $this->assertEquals($accessKey, $this->auth->getAccessKey()); - } - - public function test401() - { - $this->auth->requireLogin(); - $test = preg_match('/^AWS$/', $this->response->getHeader('WWW-Authenticate'), $matches); - $this->assertTrue(true == $test, 'The WWW-Authenticate response didn\'t match our pattern'); - } - - /** - * Generates an HMAC-SHA1 signature. - * - * @param string $key - * @param string $message - * - * @return string - */ - private function hmacsha1($key, $message) - { - $blocksize = 64; - if (strlen($key) > $blocksize) { - $key = pack('H*', sha1($key)); - } - $key = str_pad($key, $blocksize, chr(0x00)); - $ipad = str_repeat(chr(0x36), $blocksize); - $opad = str_repeat(chr(0x5C), $blocksize); - $hmac = pack('H*', sha1(($key ^ $opad).pack('H*', sha1(($key ^ $ipad).$message)))); - - return $hmac; - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/Auth/BasicTest.php b/lib/vendor/sabre/http/tests/HTTP/Auth/BasicTest.php deleted file mode 100644 index ef333eb..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/Auth/BasicTest.php +++ /dev/null @@ -1,67 +0,0 @@ - 'Basic '.base64_encode('user:pass:bla'), - ]); - - $basic = new Basic('Dagger', $request, new Response()); - - $this->assertEquals([ - 'user', - 'pass:bla', - ], $basic->getCredentials()); - } - - public function testGetInvalidCredentialsColonMissing() - { - $request = new Request('GET', '/', [ - 'Authorization' => 'Basic '.base64_encode('userpass'), - ]); - - $basic = new Basic('Dagger', $request, new Response()); - - $this->assertNull($basic->getCredentials()); - } - - public function testGetCredentialsNoHeader() - { - $request = new Request('GET', '/', []); - $basic = new Basic('Dagger', $request, new Response()); - - $this->assertNull($basic->getCredentials()); - } - - public function testGetCredentialsNotBasic() - { - $request = new Request('GET', '/', [ - 'Authorization' => 'QBasic '.base64_encode('user:pass:bla'), - ]); - $basic = new Basic('Dagger', $request, new Response()); - - $this->assertNull($basic->getCredentials()); - } - - public function testRequireLogin() - { - $response = new Response(); - $request = new Request('GET', '/'); - - $basic = new Basic('Dagger', $request, $response); - - $basic->requireLogin(); - - $this->assertEquals('Basic realm="Dagger", charset="UTF-8"', $response->getHeader('WWW-Authenticate')); - $this->assertEquals(401, $response->getStatus()); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/Auth/BearerTest.php b/lib/vendor/sabre/http/tests/HTTP/Auth/BearerTest.php deleted file mode 100644 index 82e18d2..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/Auth/BearerTest.php +++ /dev/null @@ -1,55 +0,0 @@ - 'Bearer 12345', - ]); - - $bearer = new Bearer('Dagger', $request, new Response()); - - $this->assertEquals( - '12345', - $bearer->getToken() - ); - } - - public function testGetCredentialsNoHeader() - { - $request = new Request('GET', '/', []); - $bearer = new Bearer('Dagger', $request, new Response()); - - $this->assertNull($bearer->getToken()); - } - - public function testGetCredentialsNotBearer() - { - $request = new Request('GET', '/', [ - 'Authorization' => 'QBearer 12345', - ]); - $bearer = new Bearer('Dagger', $request, new Response()); - - $this->assertNull($bearer->getToken()); - } - - public function testRequireLogin() - { - $response = new Response(); - $request = new Request('GET', '/'); - $bearer = new Bearer('Dagger', $request, $response); - - $bearer->requireLogin(); - - $this->assertEquals('Bearer realm="Dagger"', $response->getHeader('WWW-Authenticate')); - $this->assertEquals(401, $response->getStatus()); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/Auth/DigestTest.php b/lib/vendor/sabre/http/tests/HTTP/Auth/DigestTest.php deleted file mode 100644 index f3be054..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/Auth/DigestTest.php +++ /dev/null @@ -1,185 +0,0 @@ -response = new Response(); - $this->request = new Request('GET', '/'); - $this->auth = new Digest(self::REALM, $this->request, $this->response); - } - - public function testDigest() - { - list($nonce, $opaque) = $this->getServerTokens(); - - $username = 'admin'; - $password = '12345'; - $nc = '00002'; - $cnonce = uniqid(); - - $digestHash = md5( - md5($username.':'.self::REALM.':'.$password).':'. - $nonce.':'. - $nc.':'. - $cnonce.':'. - 'auth:'. - md5('GET:/') - ); - - $this->request->setMethod('GET'); - $this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth,nc='.$nc.',cnonce="'.$cnonce.'"'); - - $this->auth->init(); - - $this->assertEquals($username, $this->auth->getUsername()); - $this->assertEquals(self::REALM, $this->auth->getRealm()); - $this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); - $this->assertTrue($this->auth->validatePassword($password), 'Authentication is deemed invalid through validatePassword'); - } - - public function testInvalidDigest() - { - list($nonce, $opaque) = $this->getServerTokens(); - - $username = 'admin'; - $password = 12345; - $nc = '00002'; - $cnonce = uniqid(); - - $digestHash = md5( - md5($username.':'.self::REALM.':'.$password).':'. - $nonce.':'. - $nc.':'. - $cnonce.':'. - 'auth:'. - md5('GET:/') - ); - - $this->request->setMethod('GET'); - $this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth,nc='.$nc.',cnonce="'.$cnonce.'"'); - - $this->auth->init(); - - $this->assertFalse($this->auth->validateA1(md5($username.':'.self::REALM.':'.($password.'randomness'))), 'Authentication is deemed invalid through validateA1'); - } - - public function testInvalidDigest2() - { - $this->request->setMethod('GET'); - $this->request->setHeader('Authorization', 'basic blablabla'); - - $this->auth->init(); - $this->assertFalse($this->auth->validateA1(md5('user:realm:password'))); - } - - public function testDigestAuthInt() - { - $this->auth->setQOP(Digest::QOP_AUTHINT); - list($nonce, $opaque) = $this->getServerTokens(Digest::QOP_AUTHINT); - - $username = 'admin'; - $password = 12345; - $nc = '00003'; - $cnonce = uniqid(); - - $digestHash = md5( - md5($username.':'.self::REALM.':'.$password).':'. - $nonce.':'. - $nc.':'. - $cnonce.':'. - 'auth-int:'. - md5('POST:/:'.md5('body')) - ); - - $this->request->setMethod('POST'); - $this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth-int,nc='.$nc.',cnonce="'.$cnonce.'"'); - $this->request->setBody('body'); - - $this->auth->init(); - - $this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); - } - - public function testDigestAuthBoth() - { - $this->auth->setQOP(Digest::QOP_AUTHINT | Digest::QOP_AUTH); - list($nonce, $opaque) = $this->getServerTokens(Digest::QOP_AUTHINT | Digest::QOP_AUTH); - - $username = 'admin'; - $password = 12345; - $nc = '00003'; - $cnonce = uniqid(); - - $digestHash = md5( - md5($username.':'.self::REALM.':'.$password).':'. - $nonce.':'. - $nc.':'. - $cnonce.':'. - 'auth-int:'. - md5('POST:/:'.md5('body')) - ); - - $this->request->setMethod('POST'); - $this->request->setHeader('Authorization', 'Digest username="'.$username.'", realm="'.self::REALM.'", nonce="'.$nonce.'", uri="/", response="'.$digestHash.'", opaque="'.$opaque.'", qop=auth-int,nc='.$nc.',cnonce="'.$cnonce.'"'); - $this->request->setBody('body'); - - $this->auth->init(); - - $this->assertTrue($this->auth->validateA1(md5($username.':'.self::REALM.':'.$password)), 'Authentication is deemed invalid through validateA1'); - } - - private function getServerTokens($qop = Digest::QOP_AUTH) - { - $this->auth->requireLogin(); - - switch ($qop) { - case Digest::QOP_AUTH: $qopstr = 'auth'; - break; - case Digest::QOP_AUTHINT: $qopstr = 'auth-int'; - break; - default: $qopstr = 'auth,auth-int'; - break; - } - - $test = preg_match('/Digest realm="'.self::REALM.'",qop="'.$qopstr.'",nonce="([0-9a-f]*)",opaque="([0-9a-f]*)"/', - $this->response->getHeader('WWW-Authenticate'), $matches); - - $this->assertTrue(true == $test, 'The WWW-Authenticate response didn\'t match our pattern. We received: '.$this->response->getHeader('WWW-Authenticate')); - - $nonce = $matches[1]; - $opaque = $matches[2]; - - // Reset our environment - $this->setUp(); - $this->auth->setQOP($qop); - - return [$nonce, $opaque]; - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/ClientTest.php b/lib/vendor/sabre/http/tests/HTTP/ClientTest.php deleted file mode 100644 index 8e7efef..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/ClientTest.php +++ /dev/null @@ -1,605 +0,0 @@ -addCurlSetting(CURLOPT_POSTREDIR, 0); - - $request = new Request('GET', 'http://example.org/', ['X-Foo' => 'bar']); - - $settings = [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_POSTREDIR => 0, - CURLOPT_HTTPHEADER => ['X-Foo: bar'], - CURLOPT_NOBODY => false, - CURLOPT_URL => 'http://example.org/', - CURLOPT_CUSTOMREQUEST => 'GET', - CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ]; - - // FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM - // at least if this unit test fails in the future we know it is :) - if (false === defined('HHVM_VERSION')) { - $settings[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - $settings[CURLOPT_REDIR_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - $this->assertEquals($settings, $client->createCurlSettingsArray($request)); - } - - public function testCreateCurlSettingsHTTPHeader(): void - { - $client = new ClientMock(); - $header = [ - 'Authorization: Bearer 12345', - ]; - $client->addCurlSetting(CURLOPT_POSTREDIR, 0); - $client->addCurlSetting(CURLOPT_HTTPHEADER, $header); - - $request = new Request('GET', 'http://example.org/'); - - $settings = [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_POSTREDIR => 0, - CURLOPT_HTTPHEADER => ['Authorization: Bearer 12345'], - CURLOPT_NOBODY => false, - CURLOPT_URL => 'http://example.org/', - CURLOPT_CUSTOMREQUEST => 'GET', - CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS, - CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS, - ]; - - self::assertEquals($settings, $client->createCurlSettingsArray($request)); - } - - public function testCreateCurlSettingsArrayHEAD() - { - $client = new ClientMock(); - $request = new Request('HEAD', 'http://example.org/', ['X-Foo' => 'bar']); - - $settings = [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_NOBODY => true, - CURLOPT_CUSTOMREQUEST => 'HEAD', - CURLOPT_HTTPHEADER => ['X-Foo: bar'], - CURLOPT_URL => 'http://example.org/', - CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ]; - - // FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM - // at least if this unit test fails in the future we know it is :) - if (false === defined('HHVM_VERSION')) { - $settings[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - $settings[CURLOPT_REDIR_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - $this->assertEquals($settings, $client->createCurlSettingsArray($request)); - } - - public function testCreateCurlSettingsArrayGETAfterHEAD() - { - $client = new ClientMock(); - $request = new Request('HEAD', 'http://example.org/', ['X-Foo' => 'bar']); - - // Parsing the settings for this method, and discarding the result. - // This will cause the client to automatically persist previous - // settings and will help us detect problems. - $client->createCurlSettingsArray($request); - - // This is the real request. - $request = new Request('GET', 'http://example.org/', ['X-Foo' => 'bar']); - - $settings = [ - CURLOPT_CUSTOMREQUEST => 'GET', - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_HTTPHEADER => ['X-Foo: bar'], - CURLOPT_NOBODY => false, - CURLOPT_URL => 'http://example.org/', - CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ]; - - // FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM - // at least if this unit test fails in the future we know it is :) - if (false === defined('HHVM_VERSION')) { - $settings[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - $settings[CURLOPT_REDIR_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - $this->assertEquals($settings, $client->createCurlSettingsArray($request)); - } - - public function testCreateCurlSettingsArrayPUTStream() - { - $client = new ClientMock(); - - $fileContent = 'booh'; - $h = fopen('php://memory', 'r+'); - fwrite($h, $fileContent); - $request = new Request('PUT', 'http://example.org/', ['X-Foo' => 'bar'], $h); - - $settings = [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_PUT => true, - CURLOPT_INFILE => $h, - CURLOPT_INFILESIZE => strlen($fileContent), - CURLOPT_NOBODY => false, - CURLOPT_CUSTOMREQUEST => 'PUT', - CURLOPT_HTTPHEADER => ['X-Foo: bar'], - CURLOPT_URL => 'http://example.org/', - CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ]; - - // FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM - // at least if this unit test fails in the future we know it is :) - if (false === defined('HHVM_VERSION')) { - $settings[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - $settings[CURLOPT_REDIR_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - $this->assertEquals($settings, $client->createCurlSettingsArray($request)); - } - - public function testCreateCurlSettingsArrayPUTString() - { - $client = new ClientMock(); - $request = new Request('PUT', 'http://example.org/', ['X-Foo' => 'bar'], 'boo'); - - $settings = [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_NOBODY => false, - CURLOPT_POSTFIELDS => 'boo', - CURLOPT_CUSTOMREQUEST => 'PUT', - CURLOPT_HTTPHEADER => ['X-Foo: bar'], - CURLOPT_URL => 'http://example.org/', - CURLOPT_USERAGENT => 'sabre-http/'.Version::VERSION.' (http://sabre.io/)', - ]; - - // FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM - // at least if this unit test fails in the future we know it is :) - if (false === defined('HHVM_VERSION')) { - $settings[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - $settings[CURLOPT_REDIR_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - $this->assertEquals($settings, $client->createCurlSettingsArray($request)); - } - - public function testIssue89MultiplePutInfileGivesWarning() - { - $client = new ClientMock(); - $tmpFile = tmpfile(); - $request = new Request('POST', 'http://example.org/', ['X-Foo' => 'bar'], 'body'); - - $settings = $client->createCurlSettingsArray($request); - $this->assertArrayNotHasKey(CURLOPT_PUT, $settings); - $this->assertArrayNotHasKey(CURLOPT_INFILE, $settings); - - $request = new Request('POST', 'http://example.org/', ['X-Foo' => 'bar'], $tmpFile); - - $settings = $client->createCurlSettingsArray($request); - $this->assertEquals(true, $settings[CURLOPT_PUT]); - $this->assertEquals($tmpFile, $settings[CURLOPT_INFILE]); - - $request = new Request('POST', 'http://example.org/', ['X-Foo' => 'bar'], 'body'); - - $settings = $client->createCurlSettingsArray($request); - $this->assertArrayNotHasKey(CURLOPT_PUT, $settings); - $this->assertArrayNotHasKey(CURLOPT_INFILE, $settings); - } - - public function testSend() - { - $client = new ClientMock(); - $request = new Request('GET', 'http://example.org/'); - - $client->on('doRequest', function ($request, &$response) { - $response = new Response(200); - }); - - $response = $client->send($request); - - $this->assertEquals(200, $response->getStatus()); - } - - protected function getAbsoluteUrl($path) - { - $baseUrl = getenv('BASEURL'); - if ($baseUrl) { - $path = ltrim($path, '/'); - - return "$baseUrl/$path"; - } - - return false; - } - - /** - * @group ci - */ - public function testSendToGetLargeContent() - { - $url = $this->getAbsoluteUrl('/large.php'); - if (!$url) { - $this->markTestSkipped('Set an environment value BASEURL to continue'); - } - - // Allow the peak memory usage limit to be specified externally, if needed. - // When running this test in different environments it may be appropriate to set a different limit. - $maxPeakMemoryUsageEnvVariable = 'SABRE_HTTP_TEST_GET_LARGE_CONTENT_MAX_PEAK_MEMORY_USAGE'; - $maxPeakMemoryUsage = \getenv($maxPeakMemoryUsageEnvVariable); - if (false === $maxPeakMemoryUsage) { - $maxPeakMemoryUsage = 60 * pow(1024, 2); - } - - $request = new Request('GET', $url); - $client = new Client(); - $response = $client->send($request); - - $this->assertEquals(200, $response->getStatus()); - $this->assertLessThan( - (int) $maxPeakMemoryUsage, - memory_get_peak_usage(), - "Hint: you can adjust the max peak memory usage allowed for this test by defining env variable $maxPeakMemoryUsageEnvVariable to be the desired max bytes" - ); - } - - /** - * @group ci - */ - public function testSendAsync() - { - $url = $this->getAbsoluteUrl('/foo'); - if (!$url) { - $this->markTestSkipped('Set an environment value BASEURL to continue'); - } - - $client = new Client(); - - $request = new Request('GET', $url); - $client->sendAsync($request, function (ResponseInterface $response) { - $this->assertEquals("foo\n", $response->getBody()); - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals(4, $response->getHeader('Content-Length')); - }, function ($error) use ($request) { - $url = $request->getUrl(); - $this->fail("Failed to GET $url"); - }); - - $client->wait(); - } - - /** - * @group ci - */ - public function testSendAsynConsecutively() - { - $url = $this->getAbsoluteUrl('/foo'); - if (!$url) { - $this->markTestSkipped('Set an environment value BASEURL to continue'); - } - - $client = new Client(); - - $request = new Request('GET', $url); - $client->sendAsync($request, function (ResponseInterface $response) { - $this->assertEquals("foo\n", $response->getBody()); - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals(4, $response->getHeader('Content-Length')); - }, function ($error) use ($request) { - $url = $request->getUrl(); - $this->fail("Failed to get $url"); - }); - - $url = $this->getAbsoluteUrl('/bar.php'); - $request = new Request('GET', $url); - $client->sendAsync($request, function (ResponseInterface $response) { - $this->assertEquals("bar\n", $response->getBody()); - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals('Bar', $response->getHeader('X-Test')); - }, function ($error) use ($request) { - $url = $request->getUrl(); - $this->fail("Failed to get $url"); - }); - - $client->wait(); - } - - public function testSendClientError() - { - $client = new ClientMock(); - $request = new Request('GET', 'http://example.org/'); - - $client->on('doRequest', function ($request, &$response) { - throw new ClientException('aaah', 1); - }); - $called = false; - $client->on('exception', function () use (&$called) { - $called = true; - }); - - try { - $client->send($request); - $this->fail('send() should have thrown an exception'); - } catch (ClientException $e) { - } - $this->assertTrue($called); - } - - public function testSendHttpError() - { - $client = new ClientMock(); - $request = new Request('GET', 'http://example.org/'); - - $client->on('doRequest', function ($request, &$response) { - $response = new Response(404); - }); - $called = 0; - $client->on('error', function () use (&$called) { - ++$called; - }); - $client->on('error:404', function () use (&$called) { - ++$called; - }); - - $client->send($request); - $this->assertEquals(2, $called); - } - - public function testSendRetry() - { - $client = new ClientMock(); - $request = new Request('GET', 'http://example.org/'); - - $called = 0; - $client->on('doRequest', function ($request, &$response) use (&$called) { - ++$called; - if ($called < 3) { - $response = new Response(404); - } else { - $response = new Response(200); - } - }); - - $errorCalled = 0; - $client->on('error', function ($request, $response, &$retry, $retryCount) use (&$errorCalled) { - ++$errorCalled; - $retry = true; - }); - - $response = $client->send($request); - $this->assertEquals(3, $called); - $this->assertEquals(2, $errorCalled); - $this->assertEquals(200, $response->getStatus()); - } - - public function testHttpErrorException() - { - $client = new ClientMock(); - $client->setThrowExceptions(true); - $request = new Request('GET', 'http://example.org/'); - - $client->on('doRequest', function ($request, &$response) { - $response = new Response(404); - }); - - try { - $client->send($request); - $this->fail('An exception should have been thrown'); - } catch (ClientHttpException $e) { - $this->assertEquals(404, $e->getHttpStatus()); - $this->assertInstanceOf('Sabre\HTTP\Response', $e->getResponse()); - } - } - - public function testParseCurlResult() - { - $client = new ClientMock(); - $client->on('curlStuff', function (&$return) { - $return = [ - [ - 'header_size' => 33, - 'http_code' => 200, - ], - 0, - '', - ]; - }); - - $body = "HTTP/1.1 200 OK\r\nHeader1:Val1\r\n\r\nFoo"; - $result = $client->parseCurlResult($body, 'foobar'); - - $this->assertEquals(Client::STATUS_SUCCESS, $result['status']); - $this->assertEquals(200, $result['http_code']); - $this->assertEquals(200, $result['response']->getStatus()); - $this->assertEquals(['Header1' => ['Val1']], $result['response']->getHeaders()); - $this->assertEquals('Foo', $result['response']->getBodyAsString()); - } - - public function testParseCurlResultEmptyBody() - { - $client = new ClientMock(); - $client->on('curlStuff', function (&$return) { - $return = [ - [ - 'header_size' => 33, - 'http_code' => 200, - ], - 0, - '', - ]; - }); - - $body = "HTTP/1.1 200 OK\r\nHeader1:Val1\r\n\r\n"; - $result = $client->parseCurlResult($body, 'foobar'); - - $this->assertEquals(Client::STATUS_SUCCESS, $result['status']); - $this->assertEquals(200, $result['http_code']); - $this->assertEquals(200, $result['response']->getStatus()); - $this->assertEquals(['Header1' => ['Val1']], $result['response']->getHeaders()); - $this->assertEquals('', $result['response']->getBodyAsString()); - } - - public function testParseCurlError() - { - $client = new ClientMock(); - $client->on('curlStuff', function (&$return) { - $return = [ - [], - 1, - 'Curl error', - ]; - }); - - $body = "HTTP/1.1 200 OK\r\nHeader1:Val1\r\n\r\nFoo"; - $result = $client->parseCurlResult($body, 'foobar'); - - $this->assertEquals(Client::STATUS_CURLERROR, $result['status']); - $this->assertEquals(1, $result['curl_errno']); - $this->assertEquals('Curl error', $result['curl_errmsg']); - } - - public function testDoRequest() - { - $client = new ClientMock(); - $request = new Request('GET', 'http://example.org/'); - $client->on('curlExec', function (&$return) { - $return = "HTTP/1.1 200 OK\r\nHeader1:Val1\r\n\r\nFoo"; - }); - $client->on('curlStuff', function (&$return) { - $return = [ - [ - 'header_size' => 33, - 'http_code' => 200, - ], - 0, - '', - ]; - }); - $response = $client->doRequest($request); - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals(['Header1' => ['Val1']], $response->getHeaders()); - $this->assertEquals('Foo', $response->getBodyAsString()); - } - - public function testDoRequestCurlError() - { - $client = new ClientMock(); - $request = new Request('GET', 'http://example.org/'); - $client->on('curlExec', function (&$return) { - $return = ''; - }); - $client->on('curlStuff', function (&$return) { - $return = [ - [], - 1, - 'Curl error', - ]; - }); - - try { - $response = $client->doRequest($request); - $this->fail('This should have thrown an exception'); - } catch (ClientException $e) { - $this->assertEquals(1, $e->getCode()); - $this->assertEquals('Curl error', $e->getMessage()); - } - } -} - -class ClientMock extends Client -{ - protected $persistedSettings = []; - - /** - * Making this method public. - */ - public function receiveCurlHeader($curlHandle, $headerLine) - { - return parent::receiveCurlHeader($curlHandle, $headerLine); - } - - /** - * Making this method public. - */ - public function createCurlSettingsArray(RequestInterface $request): array - { - return parent::createCurlSettingsArray($request); - } - - /** - * Making this method public. - */ - public function parseCurlResult(string $response, $curlHandle): array - { - return parent::parseCurlResult($response, $curlHandle); - } - - /** - * This method is responsible for performing a single request. - */ - public function doRequest(RequestInterface $request): ResponseInterface - { - $response = null; - $this->emit('doRequest', [$request, &$response]); - - // If nothing modified $response, we're using the default behavior. - if (is_null($response)) { - return parent::doRequest($request); - } else { - return $response; - } - } - - /** - * Returns a bunch of information about a curl request. - * - * This method exists so it can easily be overridden and mocked. - * - * @param resource $curlHandle - */ - protected function curlStuff($curlHandle): array - { - $return = null; - $this->emit('curlStuff', [&$return]); - - // If nothing modified $return, we're using the default behavior. - if (is_null($return)) { - return parent::curlStuff($curlHandle); - } else { - return $return; - } - } - - /** - * Calls curl_exec. - * - * This method exists so it can easily be overridden and mocked. - * - * @param resource $curlHandle - */ - protected function curlExec($curlHandle): string - { - $return = null; - $this->emit('curlExec', [&$return]); - - // If nothing modified $return, we're using the default behavior. - if (is_null($return)) { - return parent::curlExec($curlHandle); - } else { - return $return; - } - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/FunctionsTest.php b/lib/vendor/sabre/http/tests/HTTP/FunctionsTest.php deleted file mode 100644 index 3bdbb60..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/FunctionsTest.php +++ /dev/null @@ -1,212 +0,0 @@ -assertEquals($result, getHeaderValues($values1, $values2)); - } - - public function getHeaderValuesDataOnValues2() - { - return [ - [ - ['a', 'b'], - ['a'], - ['b'], - ], - [ - ['a', 'b', 'c', 'd', 'e'], - ['a', 'b', 'c'], - ['d', 'e'], - ], - ]; - } - - /** - * @dataProvider getHeaderValuesData - */ - public function testGetHeaderValues($input, $output) - { - $this->assertEquals( - $output, - getHeaderValues($input) - ); - } - - public function getHeaderValuesData() - { - return [ - [ - 'a', - ['a'], - ], - [ - 'a,b', - ['a', 'b'], - ], - [ - 'a, b', - ['a', 'b'], - ], - [ - ['a, b'], - ['a', 'b'], - ], - [ - ['a, b', 'c', 'd,e'], - ['a', 'b', 'c', 'd', 'e'], - ], - ]; - } - - /** - * @dataProvider preferData - */ - public function testPrefer($input, $output) - { - $this->assertEquals( - $output, - parsePrefer($input) - ); - } - - public function preferData() - { - return [ - [ - 'foo; bar', - ['foo' => true], - ], - [ - 'foo; bar=""', - ['foo' => true], - ], - [ - 'foo=""; bar', - ['foo' => true], - ], - [ - 'FOO', - ['foo' => true], - ], - [ - 'respond-async', - ['respond-async' => true], - ], - [ - ['respond-async, wait=100', 'handling=lenient'], - ['respond-async' => true, 'wait' => 100, 'handling' => 'lenient'], - ], - [ - ['respond-async, wait=100, handling=lenient'], - ['respond-async' => true, 'wait' => 100, 'handling' => 'lenient'], - ], - // Old values - [ - 'return-asynch, return-representation', - ['respond-async' => true, 'return' => 'representation'], - ], - [ - 'return-minimal', - ['return' => 'minimal'], - ], - [ - 'strict', - ['handling' => 'strict'], - ], - [ - 'lenient', - ['handling' => 'lenient'], - ], - // Invalid token - [ - ['foo=%bar%'], - [], - ], - ]; - } - - public function testParseHTTPDate() - { - $times = [ - 'Wed, 13 Oct 2010 10:26:00 GMT', - 'Wednesday, 13-Oct-10 10:26:00 GMT', - 'Wed Oct 13 10:26:00 2010', - ]; - - $expected = 1286965560; - - foreach ($times as $time) { - $result = parseDate($time); - $this->assertEquals($expected, $result->format('U')); - } - - $result = parseDate('Wed Oct 6 10:26:00 2010'); - $this->assertEquals(1286360760, $result->format('U')); - } - - public function testParseHTTPDateFail() - { - $times = [ - // random string - 'NOW', - // not-GMT timezone - 'Wednesday, 13-Oct-10 10:26:00 UTC', - // No space before the 6 - 'Wed Oct 6 10:26:00 2010', - // Invalid day - 'Wed Oct 0 10:26:00 2010', - 'Wed Oct 32 10:26:00 2010', - 'Wed, 0 Oct 2010 10:26:00 GMT', - 'Wed, 32 Oct 2010 10:26:00 GMT', - 'Wednesday, 32-Oct-10 10:26:00 GMT', - // Invalid hour - 'Wed, 13 Oct 2010 24:26:00 GMT', - 'Wednesday, 13-Oct-10 24:26:00 GMT', - 'Wed Oct 13 24:26:00 2010', - ]; - - foreach ($times as $time) { - $this->assertFalse(parseDate($time), 'We used the string: '.$time); - } - } - - public function testTimezones() - { - $default = date_default_timezone_get(); - date_default_timezone_set('Europe/Amsterdam'); - - $this->testParseHTTPDate(); - - date_default_timezone_set($default); - } - - public function testToHTTPDate() - { - $dt = new \DateTime('2011-12-10 12:00:00 +0200'); - - $this->assertEquals( - 'Sat, 10 Dec 2011 10:00:00 GMT', - toDate($dt) - ); - } - - public function testParseMimeTypeOnInvalidMimeType() - { - if (false === \getenv('EXECUTE_INVALID_MIME_TYPE_TEST')) { - $this->markTestSkipped('Test skipped because parseMimeType with an invalid mime type will exit in 5.x'); - } - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Not a valid mime-type: invalid_mime_type'); - - parseMimeType('invalid_mime_type'); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/MessageDecoratorTest.php b/lib/vendor/sabre/http/tests/HTTP/MessageDecoratorTest.php deleted file mode 100644 index 78293eb..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/MessageDecoratorTest.php +++ /dev/null @@ -1,91 +0,0 @@ -inner = new Request('GET', '/'); - $this->outer = new RequestDecorator($this->inner); - } - - public function testBody() - { - $this->outer->setBody('foo'); - $this->assertEquals('foo', stream_get_contents($this->inner->getBodyAsStream())); - $this->assertEquals('foo', stream_get_contents($this->outer->getBodyAsStream())); - $this->assertEquals('foo', $this->inner->getBodyAsString()); - $this->assertEquals('foo', $this->outer->getBodyAsString()); - $this->assertEquals('foo', $this->inner->getBody()); - $this->assertEquals('foo', $this->outer->getBody()); - } - - public function testHeaders() - { - $this->outer->setHeaders([ - 'a' => 'b', - ]); - - $this->assertEquals(['a' => ['b']], $this->inner->getHeaders()); - $this->assertEquals(['a' => ['b']], $this->outer->getHeaders()); - - $this->outer->setHeaders([ - 'c' => 'd', - ]); - - $this->assertEquals(['a' => ['b'], 'c' => ['d']], $this->inner->getHeaders()); - $this->assertEquals(['a' => ['b'], 'c' => ['d']], $this->outer->getHeaders()); - - $this->outer->addHeaders([ - 'e' => 'f', - ]); - - $this->assertEquals(['a' => ['b'], 'c' => ['d'], 'e' => ['f']], $this->inner->getHeaders()); - $this->assertEquals(['a' => ['b'], 'c' => ['d'], 'e' => ['f']], $this->outer->getHeaders()); - } - - public function testHeader() - { - $this->assertFalse($this->outer->hasHeader('a')); - $this->assertFalse($this->inner->hasHeader('a')); - $this->outer->setHeader('a', 'c'); - $this->assertTrue($this->outer->hasHeader('a')); - $this->assertTrue($this->inner->hasHeader('a')); - - $this->assertEquals('c', $this->inner->getHeader('A')); - $this->assertEquals('c', $this->outer->getHeader('A')); - - $this->outer->addHeader('A', 'd'); - - $this->assertEquals( - ['c', 'd'], - $this->inner->getHeaderAsArray('A') - ); - $this->assertEquals( - ['c', 'd'], - $this->outer->getHeaderAsArray('A') - ); - - $success = $this->outer->removeHeader('a'); - - $this->assertTrue($success); - $this->assertNull($this->inner->getHeader('A')); - $this->assertNull($this->outer->getHeader('A')); - - $this->assertFalse($this->outer->removeHeader('i-dont-exist')); - } - - public function testHttpVersion() - { - $this->outer->setHttpVersion('1.0'); - - $this->assertEquals('1.0', $this->inner->getHttpVersion()); - $this->assertEquals('1.0', $this->outer->getHttpVersion()); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/MessageTest.php b/lib/vendor/sabre/http/tests/HTTP/MessageTest.php deleted file mode 100644 index 597067e..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/MessageTest.php +++ /dev/null @@ -1,281 +0,0 @@ -assertInstanceOf('Sabre\HTTP\Message', $message); - } - - public function testStreamBody() - { - $body = 'foo'; - $h = fopen('php://memory', 'r+'); - fwrite($h, $body); - rewind($h); - - $message = new MessageMock(); - $message->setBody($h); - - $this->assertEquals($body, $message->getBodyAsString()); - rewind($h); - $this->assertEquals($body, stream_get_contents($message->getBodyAsStream())); - rewind($h); - $this->assertEquals($body, stream_get_contents($message->getBody())); - } - - public function testStringBody() - { - $body = 'foo'; - - $message = new MessageMock(); - $message->setBody($body); - - $this->assertEquals($body, $message->getBodyAsString()); - $this->assertEquals($body, stream_get_contents($message->getBodyAsStream())); - $this->assertEquals($body, $message->getBody()); - } - - public function testCallbackBodyAsString() - { - $body = $this->createCallback('foo'); - - $message = new MessageMock(); - $message->setBody($body); - - $string = $message->getBodyAsString(); - - $this->assertSame('foo', $string); - } - - public function testCallbackBodyAsStream() - { - $body = $this->createCallback('foo'); - - $message = new MessageMock(); - $message->setBody($body); - - $stream = $message->getBodyAsStream(); - - $this->assertSame('foo', stream_get_contents($stream)); - } - - public function testGetBodyWhenCallback() - { - $callback = $this->createCallback('foo'); - - $message = new MessageMock(); - $message->setBody($callback); - - $this->assertSame($callback, $message->getBody()); - } - - /** - * It's possible that streams contains more data than the Content-Length. - * - * The request object should make sure to never emit more than - * Content-Length, if Content-Length is set. - * - * This is in particular useful when responding to range requests with - * streams that represent files on the filesystem, as it's possible to just - * seek the stream to a certain point, set the content-length and let the - * request object do the rest. - */ - public function testLongStreamToStringBody() - { - $body = fopen('php://memory', 'r+'); - fwrite($body, 'abcdefg'); - fseek($body, 2); - - $message = new MessageMock(); - $message->setBody($body); - $message->setHeader('Content-Length', '4'); - - $this->assertEquals( - 'cdef', - $message->getBodyAsString() - ); - } - - /** - * Some clients include a content-length header, but the header is empty. - * This is definitely broken behavior, but we should support it. - */ - public function testEmptyContentLengthHeader() - { - $body = fopen('php://memory', 'r+'); - fwrite($body, 'abcdefg'); - fseek($body, 2); - - $message = new MessageMock(); - $message->setBody($body); - $message->setHeader('Content-Length', ''); - - $this->assertEquals( - 'cdefg', - $message->getBodyAsString() - ); - } - - public function testGetEmptyBodyStream() - { - $message = new MessageMock(); - $body = $message->getBodyAsStream(); - - $this->assertEquals('', stream_get_contents($body)); - } - - public function testGetEmptyBodyString() - { - $message = new MessageMock(); - $body = $message->getBodyAsString(); - - $this->assertEquals('', $body); - } - - public function testHeaders() - { - $message = new MessageMock(); - $message->setHeader('X-Foo', 'bar'); - - // Testing caselessness - $this->assertEquals('bar', $message->getHeader('X-Foo')); - $this->assertEquals('bar', $message->getHeader('x-fOO')); - - $this->assertTrue( - $message->removeHeader('X-FOO') - ); - $this->assertNull($message->getHeader('X-Foo')); - $this->assertFalse( - $message->removeHeader('X-FOO') - ); - } - - public function testSetHeaders() - { - $message = new MessageMock(); - - $headers = [ - 'X-Foo' => ['1'], - 'X-Bar' => ['2'], - ]; - - $message->setHeaders($headers); - $this->assertEquals($headers, $message->getHeaders()); - - $message->setHeaders([ - 'X-Foo' => ['3', '4'], - 'X-Bar' => '5', - ]); - - $expected = [ - 'X-Foo' => ['3', '4'], - 'X-Bar' => ['5'], - ]; - - $this->assertEquals($expected, $message->getHeaders()); - } - - public function testAddHeaders() - { - $message = new MessageMock(); - - $headers = [ - 'X-Foo' => ['1'], - 'X-Bar' => ['2'], - ]; - - $message->addHeaders($headers); - $this->assertEquals($headers, $message->getHeaders()); - - $message->addHeaders([ - 'X-Foo' => ['3', '4'], - 'X-Bar' => '5', - ]); - - $expected = [ - 'X-Foo' => ['1', '3', '4'], - 'X-Bar' => ['2', '5'], - ]; - - $this->assertEquals($expected, $message->getHeaders()); - } - - public function testSendBody() - { - $message = new MessageMock(); - - // String - $message->setBody('foo'); - - // Stream - $h = fopen('php://memory', 'r+'); - fwrite($h, 'bar'); - rewind($h); - $message->setBody($h); - - $body = $message->getBody(); - rewind($body); - - $this->assertEquals('bar', stream_get_contents($body)); - } - - public function testMultipleHeaders() - { - $message = new MessageMock(); - $message->setHeader('a', '1'); - $message->addHeader('A', '2'); - - $this->assertEquals( - '1,2', - $message->getHeader('A') - ); - $this->assertEquals( - '1,2', - $message->getHeader('a') - ); - - $this->assertEquals( - ['1', '2'], - $message->getHeaderAsArray('a') - ); - $this->assertEquals( - ['1', '2'], - $message->getHeaderAsArray('A') - ); - $this->assertEquals( - [], - $message->getHeaderAsArray('B') - ); - } - - public function testHasHeaders() - { - $message = new MessageMock(); - - $this->assertFalse($message->hasHeader('X-Foo')); - $message->setHeader('X-Foo', 'Bar'); - $this->assertTrue($message->hasHeader('X-Foo')); - } - - /** - * @param string $content - * - * @return \Closure Returns a callback printing $content to php://output stream - */ - private function createCallback($content) - { - return function () use ($content) { - echo $content; - }; - } -} - -class MessageMock extends Message -{ -} diff --git a/lib/vendor/sabre/http/tests/HTTP/NegotiateTest.php b/lib/vendor/sabre/http/tests/HTTP/NegotiateTest.php deleted file mode 100644 index 82f14ea..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/NegotiateTest.php +++ /dev/null @@ -1,135 +0,0 @@ -assertEquals( - $expected, - negotiateContentType($acceptHeader, $available) - ); - } - - public function negotiateData() - { - return [ - [ // simple - 'application/xml', - ['application/xml'], - 'application/xml', - ], - [ // no header - null, - ['application/xml'], - 'application/xml', - ], - [ // 2 options - 'application/json', - ['application/xml', 'application/json'], - 'application/json', - ], - [ // 2 choices - 'application/json, application/xml', - ['application/xml'], - 'application/xml', - ], - [ // quality - 'application/xml;q=0.2, application/json', - ['application/xml', 'application/json'], - 'application/json', - ], - [ // wildcard - 'image/jpeg, image/png, */*', - ['application/xml', 'application/json'], - 'application/xml', - ], - [ // wildcard + quality - 'image/jpeg, image/png; q=0.5, */*', - ['application/xml', 'application/json', 'image/png'], - 'application/xml', - ], - [ // no match - 'image/jpeg', - ['application/xml'], - null, - ], - [ // This is used in sabre/dav - 'text/vcard; version=4.0', - [ - // Most often used mime-type. Version 3 - 'text/x-vcard', - // The correct standard mime-type. Defaults to version 3 as - // well. - 'text/vcard', - // vCard 4 - 'text/vcard; version=4.0', - // vCard 3 - 'text/vcard; version=3.0', - // jCard - 'application/vcard+json', - ], - 'text/vcard; version=4.0', - ], - [ // rfc7231 example 1 - 'audio/*; q=0.2, audio/basic', - [ - 'audio/pcm', - 'audio/basic', - ], - 'audio/basic', - ], - [ // Lower quality after - 'audio/pcm; q=0.2, audio/basic; q=0.1', - [ - 'audio/pcm', - 'audio/basic', - ], - 'audio/pcm', - ], - [ // Random parameter, should be ignored - 'audio/pcm; hello; q=0.2, audio/basic; q=0.1', - [ - 'audio/pcm', - 'audio/basic', - ], - 'audio/pcm', - ], - [ // No whitespace after type, should pick the one that is the most specific. - 'text/vcard;version=3.0, text/vcard', - [ - 'text/vcard', - 'text/vcard; version=3.0', - ], - 'text/vcard; version=3.0', - ], - [ // Same as last one, but order is different - 'text/vcard, text/vcard;version=3.0', - [ - 'text/vcard; version=3.0', - 'text/vcard', - ], - 'text/vcard; version=3.0', - ], - [ // Charset should be ignored here. - 'text/vcard; charset=utf-8; version=3.0, text/vcard', - [ - 'text/vcard', - 'text/vcard; version=3.0', - ], - 'text/vcard; version=3.0', - ], - [ // Undefined offset issue. - 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2', - ['application/xml', 'application/json', 'image/png'], - 'application/xml', - ], - ]; - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/RequestDecoratorTest.php b/lib/vendor/sabre/http/tests/HTTP/RequestDecoratorTest.php deleted file mode 100644 index f6f3a72..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/RequestDecoratorTest.php +++ /dev/null @@ -1,103 +0,0 @@ -inner = new Request('GET', '/'); - $this->outer = new RequestDecorator($this->inner); - } - - public function testMethod() - { - $this->outer->setMethod('FOO'); - $this->assertEquals('FOO', $this->inner->getMethod()); - $this->assertEquals('FOO', $this->outer->getMethod()); - } - - public function testUrl() - { - $this->outer->setUrl('/foo'); - $this->assertEquals('/foo', $this->inner->getUrl()); - $this->assertEquals('/foo', $this->outer->getUrl()); - } - - public function testAbsoluteUrl() - { - $this->outer->setAbsoluteUrl('http://example.org/foo'); - $this->assertEquals('http://example.org/foo', $this->inner->getAbsoluteUrl()); - $this->assertEquals('http://example.org/foo', $this->outer->getAbsoluteUrl()); - } - - public function testBaseUrl() - { - $this->outer->setBaseUrl('/foo'); - $this->assertEquals('/foo', $this->inner->getBaseUrl()); - $this->assertEquals('/foo', $this->outer->getBaseUrl()); - } - - public function testPath() - { - $this->outer->setBaseUrl('/foo'); - $this->outer->setUrl('/foo/bar'); - $this->assertEquals('bar', $this->inner->getPath()); - $this->assertEquals('bar', $this->outer->getPath()); - } - - public function testQueryParams() - { - $this->outer->setUrl('/foo?a=b&c=d&e'); - $expected = [ - 'a' => 'b', - 'c' => 'd', - 'e' => null, - ]; - - $this->assertEquals($expected, $this->inner->getQueryParameters()); - $this->assertEquals($expected, $this->outer->getQueryParameters()); - } - - public function testPostData() - { - $postData = [ - 'a' => 'b', - 'c' => 'd', - 'e' => null, - ]; - - $this->outer->setPostData($postData); - $this->assertEquals($postData, $this->inner->getPostData()); - $this->assertEquals($postData, $this->outer->getPostData()); - } - - public function testServerData() - { - $serverData = [ - 'HTTPS' => 'On', - ]; - - $this->outer->setRawServerData($serverData); - $this->assertEquals('On', $this->inner->getRawServerValue('HTTPS')); - $this->assertEquals('On', $this->outer->getRawServerValue('HTTPS')); - - $this->assertNull($this->inner->getRawServerValue('FOO')); - $this->assertNull($this->outer->getRawServerValue('FOO')); - } - - public function testToString() - { - $this->inner->setMethod('POST'); - $this->inner->setUrl('/foo/bar/'); - $this->inner->setBody('foo'); - $this->inner->setHeader('foo', 'bar'); - - $this->assertEquals((string) $this->inner, (string) $this->outer); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/RequestTest.php b/lib/vendor/sabre/http/tests/HTTP/RequestTest.php deleted file mode 100644 index e432a78..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/RequestTest.php +++ /dev/null @@ -1,151 +0,0 @@ - 'Evert', - ]); - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'User-Agent' => ['Evert'], - ], $request->getHeaders()); - } - - public function testGetQueryParameters() - { - $request = new Request('GET', '/foo?a=b&c&d=e'); - $this->assertEquals([ - 'a' => 'b', - 'c' => null, - 'd' => 'e', - ], $request->getQueryParameters()); - } - - public function testGetQueryParametersNoData() - { - $request = new Request('GET', '/foo'); - $this->assertEquals([], $request->getQueryParameters()); - } - - /** - * @backupGlobals - */ - public function testCreateFromPHPRequest() - { - $_SERVER['REQUEST_URI'] = '/'; - $_SERVER['REQUEST_METHOD'] = 'PUT'; - - $request = Sapi::getRequest(); - $this->assertEquals('PUT', $request->getMethod()); - } - - public function testGetAbsoluteUrl() - { - $r = new Request('GET', '/foo', [ - 'Host' => 'sabredav.org', - ]); - - $this->assertEquals('http://sabredav.org/foo', $r->getAbsoluteUrl()); - - $s = [ - 'HTTP_HOST' => 'sabredav.org', - 'REQUEST_URI' => '/foo', - 'REQUEST_METHOD' => 'GET', - 'HTTPS' => 'on', - ]; - - $r = Sapi::createFromServerArray($s); - - $this->assertEquals('https://sabredav.org/foo', $r->getAbsoluteUrl()); - } - - public function testGetPostData() - { - $post = [ - 'bla' => 'foo', - ]; - $r = new Request('POST', '/'); - $r->setPostData($post); - $this->assertEquals($post, $r->getPostData()); - } - - public function testGetPath() - { - $request = new Request('GET', '/foo/bar/'); - $request->setBaseUrl('/foo'); - $request->setUrl('/foo/bar/'); - - $this->assertEquals('bar', $request->getPath()); - } - - public function testGetPathStrippedQuery() - { - $request = new Request('GET', '/foo/bar?a=B'); - $request->setBaseUrl('/foo'); - - $this->assertEquals('bar', $request->getPath()); - } - - public function testGetPathMissingSlash() - { - $request = new Request('GET', '/foo'); - $request->setBaseUrl('/foo/'); - - $this->assertEquals('', $request->getPath()); - } - - public function testGetPathOutsideBaseUrl() - { - $this->expectException('LogicException'); - $request = new Request('GET', '/bar/'); - $request->setBaseUrl('/foo/'); - - $request->getPath(); - } - - public function testToString() - { - $request = new Request('PUT', '/foo/bar', ['Content-Type' => 'text/xml']); - $request->setBody('foo'); - - $expected = "PUT /foo/bar HTTP/1.1\r\n" - ."Content-Type: text/xml\r\n" - ."\r\n" - .'foo'; - $this->assertEquals($expected, (string) $request); - } - - public function testToStringAuthorization() - { - $request = new Request('PUT', '/foo/bar', ['Content-Type' => 'text/xml', 'Authorization' => 'Basic foobar']); - $request->setBody('foo'); - - $expected = "PUT /foo/bar HTTP/1.1\r\n" - ."Content-Type: text/xml\r\n" - ."Authorization: Basic REDACTED\r\n" - ."\r\n" - .'foo'; - $this->assertEquals($expected, (string) $request); - } - - public function testAbsoluteUrlHttp(): void - { - $request = new Request('GET', 'http://example.com/foo/bar?a=b&c=d'); - self::assertEquals('http://example.com/foo/bar?a=b&c=d', $request->getAbsoluteUrl()); - } - - public function testAbsoluteUrlHttpHostPrevalence(): void - { - $request = new Request('GET', 'http://example.com/foo/bar?a=b&c=d', [ - 'Host' => 'example.org', - ]); - self::assertEquals('http://example.com/foo/bar?a=b&c=d', $request->getAbsoluteUrl()); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/ResponseDecoratorTest.php b/lib/vendor/sabre/http/tests/HTTP/ResponseDecoratorTest.php deleted file mode 100644 index a4ef31c..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/ResponseDecoratorTest.php +++ /dev/null @@ -1,35 +0,0 @@ -inner = new Response(); - $this->outer = new ResponseDecorator($this->inner); - } - - public function testStatus() - { - $this->outer->setStatus(201); - $this->assertEquals(201, $this->inner->getStatus()); - $this->assertEquals(201, $this->outer->getStatus()); - $this->assertEquals('Created', $this->inner->getStatusText()); - $this->assertEquals('Created', $this->outer->getStatusText()); - } - - public function testToString() - { - $this->inner->setStatus(201); - $this->inner->setBody('foo'); - $this->inner->setHeader('foo', 'bar'); - - $this->assertEquals((string) $this->inner, (string) $this->outer); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/ResponseTest.php b/lib/vendor/sabre/http/tests/HTTP/ResponseTest.php deleted file mode 100644 index ef21294..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/ResponseTest.php +++ /dev/null @@ -1,41 +0,0 @@ - 'text/xml']); - $this->assertEquals(200, $response->getStatus()); - $this->assertEquals('OK', $response->getStatusText()); - } - - public function testSetStatus() - { - $response = new Response(); - $response->setStatus('402 Where\'s my money?'); - $this->assertEquals(402, $response->getStatus()); - $this->assertEquals('Where\'s my money?', $response->getStatusText()); - } - - public function testInvalidStatus() - { - $this->expectException('InvalidArgumentException'); - $response = new Response(1000); - } - - public function testToString() - { - $response = new Response(200, ['Content-Type' => 'text/xml']); - $response->setBody('foo'); - - $expected = "HTTP/1.1 200 OK\r\n" - ."Content-Type: text/xml\r\n" - ."\r\n" - .'foo'; - $this->assertEquals($expected, (string) $response); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/SapiTest.php b/lib/vendor/sabre/http/tests/HTTP/SapiTest.php deleted file mode 100644 index a0b4c6f..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/SapiTest.php +++ /dev/null @@ -1,326 +0,0 @@ - '/foo', - 'REQUEST_METHOD' => 'GET', - 'HTTP_USER_AGENT' => 'Evert', - 'CONTENT_TYPE' => 'text/xml', - 'CONTENT_LENGTH' => '400', - 'SERVER_PROTOCOL' => 'HTTP/1.0', - ]); - - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'User-Agent' => ['Evert'], - 'Content-Type' => ['text/xml'], - 'Content-Length' => ['400'], - ], $request->getHeaders()); - - $this->assertEquals('1.0', $request->getHttpVersion()); - - $this->assertEquals('400', $request->getRawServerValue('CONTENT_LENGTH')); - $this->assertNull($request->getRawServerValue('FOO')); - } - - public function testConstructFromServerArrayOnNullUrl() - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('The _SERVER array must have a REQUEST_URI key'); - - $request = Sapi::createFromServerArray([ - 'REQUEST_METHOD' => 'GET', - 'HTTP_USER_AGENT' => 'Evert', - 'CONTENT_TYPE' => 'text/xml', - 'CONTENT_LENGTH' => '400', - 'SERVER_PROTOCOL' => 'HTTP/1.0', - ]); - } - - public function testConstructFromServerArrayOnNullMethod() - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('The _SERVER array must have a REQUEST_METHOD key'); - - $request = Sapi::createFromServerArray([ - 'REQUEST_URI' => '/foo', - 'HTTP_USER_AGENT' => 'Evert', - 'CONTENT_TYPE' => 'text/xml', - 'CONTENT_LENGTH' => '400', - 'SERVER_PROTOCOL' => 'HTTP/1.0', - ]); - } - - public function testConstructPHPAuth() - { - $request = Sapi::createFromServerArray([ - 'REQUEST_URI' => '/foo', - 'REQUEST_METHOD' => 'GET', - 'PHP_AUTH_USER' => 'user', - 'PHP_AUTH_PW' => 'pass', - ]); - - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'Authorization' => ['Basic '.base64_encode('user:pass')], - ], $request->getHeaders()); - } - - public function testConstructPHPAuthDigest() - { - $request = Sapi::createFromServerArray([ - 'REQUEST_URI' => '/foo', - 'REQUEST_METHOD' => 'GET', - 'PHP_AUTH_DIGEST' => 'blabla', - ]); - - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'Authorization' => ['Digest blabla'], - ], $request->getHeaders()); - } - - public function testConstructRedirectAuth() - { - $request = Sapi::createFromServerArray([ - 'REQUEST_URI' => '/foo', - 'REQUEST_METHOD' => 'GET', - 'REDIRECT_HTTP_AUTHORIZATION' => 'Basic bla', - ]); - - $this->assertEquals('GET', $request->getMethod()); - $this->assertEquals('/foo', $request->getUrl()); - $this->assertEquals([ - 'Authorization' => ['Basic bla'], - ], $request->getHeaders()); - } - - /** - * @runInSeparateProcess - * - * Unfortunately we have no way of testing if the HTTP response code got - * changed. - */ - public function testSend() - { - if (!function_exists('xdebug_get_headers')) { - $this->markTestSkipped('XDebug needs to be installed for this test to run'); - } - - $response = new Response(204, ['Content-Type' => 'text/xml;charset=UTF-8']); - - // Second Content-Type header. Normally this doesn't make sense. - $response->addHeader('Content-Type', 'application/xml'); - $response->setBody('foo'); - - ob_start(); - - Sapi::sendResponse($response); - $headers = xdebug_get_headers(); - - $result = ob_get_clean(); - header_remove(); - - $this->assertEquals( - [ - 'Content-Type: text/xml;charset=UTF-8', - 'Content-Type: application/xml', - ], - $headers - ); - - $this->assertEquals('foo', $result); - } - - /** - * @runInSeparateProcess - * - * @depends testSend - */ - public function testSendLimitedByContentLengthString() - { - $response = new Response(200); - - $response->addHeader('Content-Length', 19); - $response->setBody('Send this sentence. Ignore this one.'); - - ob_start(); - - Sapi::sendResponse($response); - - $result = ob_get_clean(); - header_remove(); - - $this->assertEquals('Send this sentence.', $result); - } - - /** - * Tests whether http2 is recognized. - */ - public function testRecognizeHttp2() - { - $request = Sapi::createFromServerArray([ - 'SERVER_PROTOCOL' => 'HTTP/2.0', - 'REQUEST_URI' => 'bla', - 'REQUEST_METHOD' => 'GET', - ]); - - $this->assertEquals('2.0', $request->getHttpVersion()); - } - - /** - * @runInSeparateProcess - * - * @depends testSend - */ - public function testSendLimitedByContentLengthStream() - { - $response = new Response(200, ['Content-Length' => 19]); - - $body = fopen('php://memory', 'w'); - fwrite($body, 'Ignore this. Send this sentence. Ignore this too.'); - rewind($body); - fread($body, 13); - $response->setBody($body); - - ob_start(); - - Sapi::sendResponse($response); - - $result = ob_get_clean(); - header_remove(); - - $this->assertEquals('Send this sentence.', $result); - } - - /** - * @runInSeparateProcess - * - * @depends testSend - * - * @dataProvider sendContentRangeStreamData - */ - public function testSendContentRangeStream($ignoreAtStart, $sendText, $multiplier, $ignoreAtEnd, $contentLength) - { - $partial = str_repeat($sendText, $multiplier); - $ignoreAtStartLength = strlen($ignoreAtStart); - $ignoreAtEndLength = strlen($ignoreAtEnd); - $body = fopen('php://memory', 'w'); - if (!$contentLength) { - $contentLength = strlen($partial); - } - fwrite($body, $ignoreAtStart); - fwrite($body, $partial); - if ($ignoreAtEndLength > 0) { - fwrite($body, $ignoreAtEnd); - } - rewind($body); - if ($ignoreAtStartLength > 0) { - fread($body, $ignoreAtStartLength); - } - $response = new Response(200, [ - 'Content-Length' => $contentLength, - 'Content-Range' => sprintf('bytes %d-%d/%d', $ignoreAtStartLength, $ignoreAtStartLength + strlen($partial) - 1, $ignoreAtStartLength + strlen($partial) + $ignoreAtEndLength), - ]); - $response->setBody($body); - - ob_start(); - - Sapi::sendResponse($response); - - $result = ob_get_clean(); - header_remove(); - - $this->assertEquals($partial, $result); - } - - public function sendContentRangeStreamData() - { - return [ - ['Ignore this. ', 'Send this.', 10, ' Ignore this at end.'], - ['Ignore this. ', 'Send this.', 1000, ' Ignore this at end.'], - ['Ignore this. ', 'S', 4096, ' Ignore this at end.'], - ['I', 'S', 4094, 'E'], - ['', 'Send this.', 10, ' Ignore this at end.'], - ['', 'Send this.', 1000, ' Ignore this at end.'], - ['', 'S', 4096, ' Ignore this at end.'], - ['', 'S', 4094, 'En'], - ['Ignore this. ', 'Send this.', 10, ''], - ['Ignore this. ', 'Send this.', 1000, ''], - ['Ignore this. ', 'S', 4096, ''], - ['Ig', 'S', 4094, ''], - - // Provide contentLength greater than the bytes remaining in the stream. - ['Ignore this. ', 'Send this.', 10, '', 101], - ['Ignore this. ', 'Send this.', 1000, '', 10001], - ['Ignore this. ', 'S', 4096, '', 5000000], - ['I', 'S', 4094, '', 8095], - // Provide contentLength equal to the bytes remaining in the stream. - ['', 'Send this.', 10, '', 100], - ['Ignore this. ', 'Send this.', 1000, '', 10000], - ]; - } - - /** - * @runInSeparateProcess - * - * @depends testSend - */ - public function testSendWorksWithCallbackAsBody() - { - $response = new Response(200, [], function () { - $fd = fopen('php://output', 'r+'); - fwrite($fd, 'foo'); - fclose($fd); - }); - - ob_start(); - - Sapi::sendResponse($response); - - $result = ob_get_clean(); - - $this->assertEquals('foo', $result); - } - - public function testSendConnectionAborted(): void - { - $baseUrl = getenv('BASEURL'); - if (!$baseUrl) { - $this->markTestSkipped('Set an environment value BASEURL to continue'); - } - - $url = rtrim($baseUrl, '/').'/connection_aborted.php'; - $chunk_size = 4 * 1024 * 1024; - $fetch_size = 6 * 1024 * 1024; - - $stream = fopen($url, 'r'); - $size = 0; - - while ($size <= $fetch_size) { - $temp = fread($stream, 8192); - if (false === $temp) { - break; - } - $size += strlen($temp); - } - - fclose($stream); - - sleep(5); - - $bytes_read = file_get_contents(sys_get_temp_dir().'/dummy_stream_read_counter'); - $this->assertEquals($chunk_size * 2, $bytes_read); - $this->assertGreaterThanOrEqual($fetch_size, $bytes_read); - } -} diff --git a/lib/vendor/sabre/http/tests/HTTP/URLUtilTest.php b/lib/vendor/sabre/http/tests/HTTP/URLUtilTest.php deleted file mode 100644 index bf0503e..0000000 --- a/lib/vendor/sabre/http/tests/HTTP/URLUtilTest.php +++ /dev/null @@ -1,114 +0,0 @@ -assertEquals( - '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. - '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. - '%20%21%22%23%24%25%26%27()%2a%2b%2c-./'. - '0123456789:%3b%3c%3d%3e%3f'. - '@ABCDEFGHIJKLMNO'. - 'PQRSTUVWXYZ%5b%5c%5d%5e_'. - '%60abcdefghijklmno'. - 'pqrstuvwxyz%7b%7c%7d~%7f', - $newStr); - - $this->assertEquals($str, decodePath($newStr)); - } - - public function testEncodePathSegment() - { - $str = ''; - for ($i = 0; $i < 128; ++$i) { - $str .= chr($i); - } - - $newStr = encodePathSegment($str); - - // Note: almost exactly the same as the last test, with the - // exception of the encoding of / (ascii code 2f) - $this->assertEquals( - '%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e%0f'. - '%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d%1e%1f'. - '%20%21%22%23%24%25%26%27()%2a%2b%2c-.%2f'. - '0123456789:%3b%3c%3d%3e%3f'. - '@ABCDEFGHIJKLMNO'. - 'PQRSTUVWXYZ%5b%5c%5d%5e_'. - '%60abcdefghijklmno'. - 'pqrstuvwxyz%7b%7c%7d~%7f', - $newStr); - - $this->assertEquals($str, decodePathSegment($newStr)); - } - - public function testDecode() - { - $str = 'Hello%20Test+Test2.txt'; - $newStr = decodePath($str); - $this->assertEquals('Hello Test+Test2.txt', $newStr); - } - - /** - * @depends testDecode - */ - public function testDecodeUmlaut() - { - $str = 'Hello%C3%BC.txt'; - $newStr = decodePath($str); - $this->assertEquals("Hello\xC3\xBC.txt", $newStr); - } - - /** - * @depends testDecode - */ - public function testDecodeSlavicWords() - { - $words = [ - 'Ostroměr', - 'Šventaragis', - 'Świętopełk', - 'Dušan', - 'Živko', - ]; - foreach ($words as $word) { - $str = rawurlencode($word); - $newStr = decodePath($str); - $this->assertEquals($word, $newStr); - } - } - - /** - * @depends testDecodeUmlaut - */ - public function testDecodeUmlautLatin1() - { - $str = 'Hello%FC.txt'; - $newStr = decodePath($str); - $this->assertEquals("Hello\xC3\xBC.txt", $newStr); - } - - /** - * This testcase was sent by a bug reporter. - * - * @depends testDecode - */ - public function testDecodeAccentsWindows7() - { - $str = '/webdav/%C3%A0fo%C3%B3'; - $newStr = decodePath($str); - $this->assertEquals(strtolower($str), encodePath($newStr)); - } -} diff --git a/lib/vendor/sabre/http/tests/bootstrap.php b/lib/vendor/sabre/http/tests/bootstrap.php deleted file mode 100644 index b47f704..0000000 --- a/lib/vendor/sabre/http/tests/bootstrap.php +++ /dev/null @@ -1,17 +0,0 @@ - - - - HTTP/ - - - - - - ../lib/ - - - - - - - diff --git a/lib/vendor/sabre/http/tests/www/bar.php b/lib/vendor/sabre/http/tests/www/bar.php deleted file mode 100644 index 05de39e..0000000 --- a/lib/vendor/sabre/http/tests/www/bar.php +++ /dev/null @@ -1,5 +0,0 @@ - -bar diff --git a/lib/vendor/sabre/http/tests/www/connection_aborted.php b/lib/vendor/sabre/http/tests/www/connection_aborted.php deleted file mode 100644 index 724ad2d..0000000 --- a/lib/vendor/sabre/http/tests/www/connection_aborted.php +++ /dev/null @@ -1,69 +0,0 @@ -position = 0; - - return true; - } - - public function stream_read(int $count): string - { - $this->position += $count; - - return random_bytes($count); - } - - public function stream_tell(): int - { - return $this->position; - } - - public function stream_eof(): bool - { - return $this->position > 25 * 1024 * 1024; - } - - public function stream_close(): void - { - file_put_contents(sys_get_temp_dir().'/dummy_stream_read_counter', $this->position); - } -} - -/* - * The DummyStream wrapper has two functions: - * - Provide dummy data. - * - Count how many bytes have been read. - */ -stream_wrapper_register('dummy', DummyStream::class); - -/* - * Overwrite default connection handling. - * The default behaviour is however for your script to be aborted when the remote client disconnects. - * - * Nextcloud/ownCloud set ignore_user_abort(true) on purpose to work around - * some edge cases where the default behavior would end a script too early. - * - * https://github.com/owncloud/core/issues/22370 - * https://github.com/owncloud/core/pull/26775 - */ -ignore_user_abort(true); - -$body = fopen('dummy://hello', 'r'); - -$response = new HTTP\Response(); -$response->setStatus(200); -$response->addHeader('Content-Length', 25 * 1024 * 1024); -$response->setBody($body); - -HTTP\Sapi::sendResponse($response); diff --git a/lib/vendor/sabre/http/tests/www/foo b/lib/vendor/sabre/http/tests/www/foo deleted file mode 100644 index 257cc56..0000000 --- a/lib/vendor/sabre/http/tests/www/foo +++ /dev/null @@ -1 +0,0 @@ -foo diff --git a/lib/vendor/sabre/http/tests/www/large.php b/lib/vendor/sabre/http/tests/www/large.php deleted file mode 100644 index 65fefb5..0000000 --- a/lib/vendor/sabre/http/tests/www/large.php +++ /dev/null @@ -1,7 +0,0 @@ -exclude('vendor') - ->in(__DIR__); - -$config = new PhpCsFixer\Config(); -$config->setRules([ - '@PSR1' => true, - '@Symfony' => true, - 'nullable_type_declaration' => [ - 'syntax' => 'question_mark', - ], - 'nullable_type_declaration_for_default_null_value' => true, -]); -$config->setFinder($finder); -return $config; \ No newline at end of file diff --git a/lib/vendor/sabre/uri/LICENSE b/lib/vendor/sabre/uri/LICENSE deleted file mode 100644 index ae2c992..0000000 --- a/lib/vendor/sabre/uri/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (C) 2014-2019 fruux GmbH (https://fruux.com/) - -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 Sabre 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/lib/vendor/sabre/uri/composer.json b/lib/vendor/sabre/uri/composer.json deleted file mode 100644 index ba4a8e0..0000000 --- a/lib/vendor/sabre/uri/composer.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "sabre/uri", - "description": "Functions for making sense out of URIs.", - "keywords": [ - "URI", - "URL", - "rfc3986" - ], - "homepage": "http://sabre.io/uri/", - "license": "BSD-3-Clause", - "require": { - "php": "^7.4 || ^8.0" - }, - "authors": [ - { - "name": "Evert Pot", - "email": "me@evertpot.com", - "homepage": "http://evertpot.com/", - "role": "Developer" - } - ], - "support": { - "forum": "https://groups.google.com/group/sabredav-discuss", - "source": "https://github.com/fruux/sabre-uri" - }, - "autoload": { - "files" : [ - "lib/functions.php" - ], - "psr-4" : { - "Sabre\\Uri\\" : "lib/" - } - }, - "autoload-dev": { - "psr-4": { - "Sabre\\Uri\\": "tests/Uri" - } - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.63", - "phpstan/phpstan": "^1.12", - "phpstan/phpstan-phpunit": "^1.4", - "phpstan/phpstan-strict-rules": "^1.6", - "phpstan/extension-installer": "^1.4", - "phpunit/phpunit" : "^9.6" - }, - "scripts": { - "phpstan": [ - "phpstan analyse lib tests" - ], - "cs-fixer": [ - "php-cs-fixer fix" - ], - "phpunit": [ - "phpunit --configuration tests/phpunit.xml" - ], - "test": [ - "composer phpstan", - "composer cs-fixer", - "composer phpunit" - ] - }, - "config": { - "allow-plugins": { - "phpstan/extension-installer": true - } - } -} diff --git a/lib/vendor/sabre/uri/lib/InvalidUriException.php b/lib/vendor/sabre/uri/lib/InvalidUriException.php deleted file mode 100644 index 7f37ca5..0000000 --- a/lib/vendor/sabre/uri/lib/InvalidUriException.php +++ /dev/null @@ -1,19 +0,0 @@ - 0) { - // If the path starts with a slash - if ('/' === $delta['path'][0]) { - $path = $delta['path']; - } else { - // Removing last component from base path. - $path = (string) $base['path']; - $length = strrpos($path, '/'); - if (false !== $length) { - $path = substr($path, 0, $length); - } - $path .= '/'.$delta['path']; - } - } else { - $path = $base['path'] ?? '/'; - if ('' === $path) { - $path = '/'; - } - } - // Removing .. and . - $pathParts = explode('/', $path); - $newPathParts = []; - foreach ($pathParts as $pathPart) { - switch ($pathPart) { - // case '' : - case '.': - break; - case '..': - array_pop($newPathParts); - break; - default: - $newPathParts[] = $pathPart; - break; - } - } - - $path = implode('/', $newPathParts); - - // If the source url ended with a /, we want to preserve that. - $newParts['path'] = 0 === strpos($path, '/') ? $path : '/'.$path; - // From PHP 8, no "?" query at all causes 'query' to be null. - // An empty query "http://example.com/foo?" causes 'query' to be the empty string - if (null !== $delta['query'] && '' !== $delta['query']) { - $newParts['query'] = $delta['query']; - } elseif (isset($base['query']) && null === $delta['host'] && null === $delta['path']) { - // Keep the old query if host and path didn't change - $newParts['query'] = $base['query']; - } - // From PHP 8, no "#" fragment at all causes 'fragment' to be null. - // An empty fragment "http://example.com/foo#" causes 'fragment' to be the empty string - if (null !== $delta['fragment'] && '' !== $delta['fragment']) { - $newParts['fragment'] = $delta['fragment']; - } - - return build($newParts); -} - -/** - * Takes a URI or partial URI as its argument, and normalizes it. - * - * After normalizing a URI, you can safely compare it to other URIs. - * This function will for instance convert a %7E into a tilde, according to - * rfc3986. - * - * It will also change a %3a into a %3A. - * - * @throws InvalidUriException - */ -function normalize(string $uri): string -{ - $parts = parse($uri); - - if (null !== $parts['path']) { - $pathParts = explode('/', ltrim($parts['path'], '/')); - $newPathParts = []; - foreach ($pathParts as $pathPart) { - switch ($pathPart) { - case '.': - // skip - break; - case '..': - // One level up in the hierarchy - array_pop($newPathParts); - break; - default: - // Ensuring that everything is correctly percent-encoded. - $newPathParts[] = rawurlencode(rawurldecode($pathPart)); - break; - } - } - $parts['path'] = '/'.implode('/', $newPathParts); - } - - if (null !== $parts['scheme']) { - $parts['scheme'] = strtolower($parts['scheme']); - $defaultPorts = [ - 'http' => '80', - 'https' => '443', - ]; - - if (null !== $parts['port'] && isset($defaultPorts[$parts['scheme']]) && $defaultPorts[$parts['scheme']] == $parts['port']) { - // Removing default ports. - unset($parts['port']); - } - // A few HTTP specific rules. - switch ($parts['scheme']) { - case 'http': - case 'https': - if (null === $parts['path']) { - // An empty path is equivalent to / in http. - $parts['path'] = '/'; - } - break; - } - } - - if (null !== $parts['host']) { - $parts['host'] = strtolower($parts['host']); - } - - return build($parts); -} - -/** - * Parses a URI and returns its individual components. - * - * This method largely behaves the same as PHP's parse_url, except that it will - * return an array with all the array keys, including the ones that are not - * set by parse_url, which makes it a bit easier to work with. - * - * Unlike PHP's parse_url, it will also convert any non-ascii characters to - * percent-encoded strings. PHP's parse_url corrupts these characters on OS X. - * - * In the return array, key "port" is an int value. Other keys have a string value. - * "Unused" keys have value null. - * - * @return array{scheme: string|null, host: string|null, path: string|null, port: positive-int|null, user: string|null, query: string|null, fragment: string|null} - * - * @throws InvalidUriException - */ -function parse(string $uri): array -{ - // Normally a URI must be ASCII. However, often it's not and - // parse_url might corrupt these strings. - // - // For that reason we take any non-ascii characters from the uri and - // uriencode them first. - $uri = preg_replace_callback( - '/[^[:ascii:]]/u', - function ($matches) { - return rawurlencode($matches[0]); - }, - $uri - ); - - if (null === $uri) { - throw new InvalidUriException('Invalid, or could not parse URI'); - } - - $result = parse_url($uri); - if (false === $result) { - $result = _parse_fallback($uri); - } - - /* - * phpstan is not able to process all the things that happen while this function - * constructs the result array. It only understands the $result is - * non-empty-array - * - * But the detail of the returned array is correctly specified in the PHPdoc - * above the function call. - * - * @phpstan-ignore-next-line - */ - return - $result + [ - 'scheme' => null, - 'host' => null, - 'path' => null, - 'port' => null, - 'user' => null, - 'query' => null, - 'fragment' => null, - ]; -} - -/** - * This function takes the components returned from PHP's parse_url, and uses - * it to generate a new uri. - * - * @param array $parts - */ -function build(array $parts): string -{ - $uri = ''; - - $authority = ''; - if (isset($parts['host'])) { - $authority = $parts['host']; - if (isset($parts['user'])) { - $authority = $parts['user'].'@'.$authority; - } - if (isset($parts['port'])) { - $authority = $authority.':'.$parts['port']; - } - } - - if (isset($parts['scheme'])) { - // If there's a scheme, there's also a host. - $uri = $parts['scheme'].':'; - } - if ('' !== $authority || (isset($parts['scheme']) && 'file' === $parts['scheme'])) { - // No scheme, but there is a host. - $uri .= '//'.$authority; - } - - if (isset($parts['path'])) { - $uri .= $parts['path']; - } - if (isset($parts['query'])) { - $uri .= '?'.$parts['query']; - } - if (isset($parts['fragment'])) { - $uri .= '#'.$parts['fragment']; - } - - return $uri; -} - -/** - * 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) and we need a method that just operates on UTF-8 characters. - * - * In addition basename and dirname are platform aware, and will treat - * backslash (\) as a directory separator on Windows. - * - * This method returns the 2 components as an array. - * - * If there is no dirname, it will return an empty string. Any / appearing at - * the end of the string is stripped off. - * - * @return array - */ -function split(string $path): array -{ - $matches = []; - if (1 === preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u', $path, $matches)) { - return [$matches[1], $matches[2]]; - } - - return [null, null]; -} - -/** - * This function is another implementation of parse_url, except this one is - * fully written in PHP. - * - * The reason is that the PHP bug team is not willing to admit that there are - * bugs in the parse_url implementation. - * - * This function is only called if the main parse method fails. It's pretty - * crude and probably slow, so the original parse_url is usually preferred. - * - * @return array{scheme: string|null, host: string|null, path: string|null, port: positive-int|null, user: string|null, query: string|null, fragment: string|null} - * - * @throws InvalidUriException - */ -function _parse_fallback(string $uri): array -{ - // Normally a URI must be ASCII, however. However, often it's not and - // parse_url might corrupt these strings. - // - // For that reason we take any non-ascii characters from the uri and - // uriencode them first. - $uri = preg_replace_callback( - '/[^[:ascii:]]/u', - function ($matches) { - return rawurlencode($matches[0]); - }, - $uri - ); - - if (null === $uri) { - throw new InvalidUriException('Invalid, or could not parse URI'); - } - - $result = [ - 'scheme' => null, - 'host' => null, - 'port' => null, - 'user' => null, - 'path' => null, - 'fragment' => null, - 'query' => null, - ]; - - if (1 === preg_match('% ^([A-Za-z][A-Za-z0-9+-\.]+): %x', $uri, $matches)) { - $result['scheme'] = $matches[1]; - // Take what's left. - $uri = substr($uri, strlen($result['scheme']) + 1); - if (false === $uri) { - // There was nothing left. - $uri = ''; - } - } - - // Taking off a fragment part - if (false !== strpos($uri, '#')) { - list($uri, $result['fragment']) = explode('#', $uri, 2); - } - // Taking off the query part - if (false !== strpos($uri, '?')) { - list($uri, $result['query']) = explode('?', $uri, 2); - } - - if ('///' === substr($uri, 0, 3)) { - // The triple slash uris are a bit unusual, but we have special handling - // for them. - $path = substr($uri, 2); - if (false === $path) { - throw new \RuntimeException('The string cannot be false'); - } - $result['path'] = $path; - $result['host'] = ''; - } elseif ('//' === substr($uri, 0, 2)) { - // Uris that have an authority part. - $regex = '%^ - // - (?: (? [^:@]+) (: (? [^@]+)) @)? - (? ( [^:/]* | \[ [^\]]+ \] )) - (?: : (? [0-9]+))? - (? / .*)? - $%x'; - if (1 !== preg_match($regex, $uri, $matches)) { - throw new InvalidUriException('Invalid, or could not parse URI'); - } - if (isset($matches['host']) && '' !== $matches['host']) { - $result['host'] = $matches['host']; - } - if (isset($matches['port'])) { - $port = (int) $matches['port']; - if ($port > 0) { - $result['port'] = $port; - } - } - if (isset($matches['path'])) { - $result['path'] = $matches['path']; - } - if (isset($matches['user']) && '' !== $matches['user']) { - $result['user'] = $matches['user']; - } - if (isset($matches['pass']) && '' !== $matches['pass']) { - $result['pass'] = $matches['pass']; - } - } else { - $result['path'] = $uri; - } - - return $result; -} diff --git a/lib/vendor/sabre/vobject/LICENSE b/lib/vendor/sabre/vobject/LICENSE deleted file mode 100644 index a99c8da..0000000 --- a/lib/vendor/sabre/vobject/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (C) 2011-2016 fruux GmbH (https://fruux.com/) - -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 Sabre 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/lib/vendor/sabre/vobject/README.md b/lib/vendor/sabre/vobject/README.md deleted file mode 100644 index 659e3fa..0000000 --- a/lib/vendor/sabre/vobject/README.md +++ /dev/null @@ -1,55 +0,0 @@ -sabre/vobject -============= - -The VObject library allows you to easily parse and manipulate [iCalendar](https://tools.ietf.org/html/rfc5545) -and [vCard](https://tools.ietf.org/html/rfc6350) objects using PHP. - -The goal of the VObject library is to create a very complete library, with an easy-to-use API. - - -Installation ------------- - -Make sure you have [Composer][1] installed, and then run: - - composer require sabre/vobject "^4.0" - -This package requires PHP 5.5. If you need the PHP 5.3/5.4 version of this package instead, use: - - - composer require sabre/vobject "^3.4" - - -Usage ------ - -* [Working with vCards](http://sabre.io/vobject/vcard/) -* [Working with iCalendar](http://sabre.io/vobject/icalendar/) - - - -Build status ------------- - -| branch | status | -| ------ | ------ | -| master | [![Build Status](https://travis-ci.org/sabre-io/vobject.svg?branch=master)](https://travis-ci.org/sabre-io/vobject) | -| 3.5 | [![Build Status](https://travis-ci.org/sabre-io/vobject.svg?branch=3.5)](https://travis-ci.org/sabre-io/vobject) | -| 3.4 | [![Build Status](https://travis-ci.org/sabre-io/vobject.svg?branch=3.4)](https://travis-ci.org/sabre-io/vobject) | -| 3.1 | [![Build Status](https://travis-ci.org/sabre-io/vobject.svg?branch=3.1)](https://travis-ci.org/sabre-io/vobject) | -| 2.1 | [![Build Status](https://travis-ci.org/sabre-io/vobject.svg?branch=2.1)](https://travis-ci.org/sabre-io/vobject) | -| 2.0 | [![Build Status](https://travis-ci.org/sabre-io/vobject.svg?branch=2.0)](https://travis-ci.org/sabre-io/vobject) | - - - -Support -------- - -Head over to the [SabreDAV mailing list](http://groups.google.com/group/sabredav-discuss) for any questions. - -Made at fruux -------------- - -This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support. - -[1]: https://getcomposer.org/ diff --git a/lib/vendor/sabre/vobject/bin/bench.php b/lib/vendor/sabre/vobject/bin/bench.php deleted file mode 100755 index 0a2736f..0000000 --- a/lib/vendor/sabre/vobject/bin/bench.php +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env php -parse->start(); - -$vcal = Sabre\VObject\Reader::read(fopen($inputFile, 'r')); - -$bench->parse->stop(); - -$repeat = 100; -$start = new \DateTime('2000-01-01'); -$end = new \DateTime('2020-01-01'); -$timeZone = new \DateTimeZone('America/Toronto'); - -$bench->fb->start(); - -for ($i = 0; $i < $repeat; ++$i) { - $fb = new Sabre\VObject\FreeBusyGenerator($start, $end, $vcal, $timeZone); - $results = $fb->getResult(); -} -$bench->fb->stop(); - -echo $bench,"\n"; - -function formatMemory($input) -{ - if (strlen($input) > 6) { - return round($input / (1024 * 1024)).'M'; - } elseif (strlen($input) > 3) { - return round($input / 1024).'K'; - } -} - -unset($input, $splitter); - -echo 'peak memory usage: '.formatMemory(memory_get_peak_usage()), "\n"; -echo 'current memory usage: '.formatMemory(memory_get_usage()), "\n"; diff --git a/lib/vendor/sabre/vobject/bin/bench_manipulatevcard.php b/lib/vendor/sabre/vobject/bin/bench_manipulatevcard.php deleted file mode 100644 index df6d9f2..0000000 --- a/lib/vendor/sabre/vobject/bin/bench_manipulatevcard.php +++ /dev/null @@ -1,64 +0,0 @@ -parse->start(); - $vcard = $splitter->getNext(); - $bench->parse->pause(); - - if (!$vcard) { - break; - } - - $bench->manipulate->start(); - $vcard->{'X-FOO'} = 'Random new value!'; - $emails = []; - if (isset($vcard->EMAIL)) { - foreach ($vcard->EMAIL as $email) { - $emails[] = (string) $email; - } - } - $bench->manipulate->pause(); - - $bench->serialize->start(); - $vcard2 = $vcard->serialize(); - $bench->serialize->pause(); - - $vcard->destroy(); -} - -echo $bench,"\n"; - -function formatMemory($input) -{ - if (strlen($input) > 6) { - return round($input / (1024 * 1024)).'M'; - } elseif (strlen($input) > 3) { - return round($input / 1024).'K'; - } -} - -unset($input, $splitter); - -echo 'peak memory usage: '.formatMemory(memory_get_peak_usage()), "\n"; -echo 'current memory usage: '.formatMemory(memory_get_usage()), "\n"; diff --git a/lib/vendor/sabre/vobject/bin/fetch_windows_zones.php b/lib/vendor/sabre/vobject/bin/fetch_windows_zones.php deleted file mode 100755 index 2361dc3..0000000 --- a/lib/vendor/sabre/vobject/bin/fetch_windows_zones.php +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env php -xpath('//mapZone') as $mapZone) { - $from = (string) $mapZone['other']; - $to = (string) $mapZone['type']; - - list($to) = explode(' ', $to, 2); - - if (!isset($map[$from])) { - $map[$from] = $to; - } -} - -ksort($map); -echo "Writing to: $outputFile\n"; - -$f = fopen($outputFile, 'w'); -fwrite($f, " testdata.vcf - -HI; - - fwrite(STDERR, $help); - exit(2); -} - -$count = (int)$argv[1]; -if ($count < 1) { - fwrite(STDERR, "Count must be at least 1\n"); - exit(2); -} - -fwrite(STDERR, "sabre/vobject " . Version::VERSION . "\n"); -fwrite(STDERR, "Generating " . $count . " vcards in vCard 4.0 format\n"); - -/** - * The following list is just some random data we compiled from various - * sources online. - * - * Very little thought went into compiling this list, and certainly nothing - * political or ethical. - * - * We would _love_ more additions to this to add more variation to this list. - * - * Send us PR's and don't be shy adding your own first and last name for fun. - */ - -$sets = array( - "nl" => array( - "country" => "Netherlands", - "boys" => array( - "Anno", - "Bram", - "Daan", - "Evert", - "Finn", - "Jayden", - "Jens", - "Jesse", - "Levi", - "Lucas", - "Luuk", - "Milan", - "René", - "Sem", - "Sibrand", - "Willem", - ), - "girls" => array( - "Celia", - "Emma", - "Fenna", - "Geke", - "Inge", - "Julia", - "Lisa", - "Lotte", - "Mila", - "Sara", - "Sophie", - "Tess", - "Zoë", - ), - "last" => array( - "Bakker", - "Bos", - "De Boer", - "De Groot", - "De Jong", - "De Vries", - "Jansen", - "Janssen", - "Meyer", - "Mulder", - "Peters", - "Smit", - "Van Dijk", - "Van den Berg", - "Visser", - "Vos", - ), - ), - "us" => array( - "country" => "United States", - "boys" => array( - "Aiden", - "Alexander", - "Charles", - "David", - "Ethan", - "Jacob", - "James", - "Jayden", - "John", - "Joseph", - "Liam", - "Mason", - "Michael", - "Noah", - "Richard", - "Robert", - "Thomas", - "William", - ), - "girls" => array( - "Ava", - "Barbara", - "Chloe", - "Dorothy", - "Elizabeth", - "Emily", - "Emma", - "Isabella", - "Jennifer", - "Lily", - "Linda", - "Margaret", - "Maria", - "Mary", - "Mia", - "Olivia", - "Patricia", - "Roxy", - "Sophia", - "Susan", - "Zoe", - ), - "last" => array( - "Smith", - "Johnson", - "Williams", - "Jones", - "Brown", - "Davis", - "Miller", - "Wilson", - "Moore", - "Taylor", - "Anderson", - "Thomas", - "Jackson", - "White", - "Harris", - "Martin", - "Thompson", - "Garcia", - "Martinez", - "Robinson", - ), - ), -); - -$current = 0; - -$r = function($arr) { - - return $arr[mt_rand(0,count($arr)-1)]; - -}; - -$bdayStart = strtotime('-85 years'); -$bdayEnd = strtotime('-20 years'); - -while($current < $count) { - - $current++; - fwrite(STDERR, "\033[100D$current/$count"); - - $country = array_rand($sets); - $gender = mt_rand(0,1)?'girls':'boys'; - - $vcard = new Component\VCard(array( - 'VERSION' => '4.0', - 'FN' => $r($sets[$country][$gender]) . ' ' . $r($sets[$country]['last']), - 'UID' => UUIDUtil::getUUID(), - )); - - $bdayRatio = mt_rand(0,9); - - if($bdayRatio < 2) { - // 20% has a birthday property with a full date - $dt = new \DateTime('@' . mt_rand($bdayStart, $bdayEnd)); - $vcard->add('BDAY', $dt->format('Ymd')); - - } elseif ($bdayRatio < 3) { - // 10% we only know the month and date of - $dt = new \DateTime('@' . mt_rand($bdayStart, $bdayEnd)); - $vcard->add('BDAY', '--' . $dt->format('md')); - } - if ($result = $vcard->validate()) { - ob_start(); - echo "\nWe produced an invalid vcard somehow!\n"; - foreach($result as $message) { - echo " " . $message['message'] . "\n"; - } - fwrite(STDERR, ob_get_clean()); - } - echo $vcard->serialize(); - -} - -fwrite(STDERR,"\nDone.\n"); diff --git a/lib/vendor/sabre/vobject/bin/generateicalendardata.php b/lib/vendor/sabre/vobject/bin/generateicalendardata.php deleted file mode 100755 index 019ed97..0000000 --- a/lib/vendor/sabre/vobject/bin/generateicalendardata.php +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env php -add('VEVENT'); - $event->DTSTART = 'bla'; - $event->SUMMARY = 'Event #'.$ii; - $event->UID = md5(microtime(true)); - - $doctorRandom = mt_rand(1, 1000); - - switch ($doctorRandom) { - // All-day event - case 1: - $event->DTEND = 'bla'; - $dtStart = clone $currentDate; - $dtEnd = clone $currentDate; - $dtEnd->modify('+'.mt_rand(1, 3).' days'); - $event->DTSTART->setDateTime($dtStart); - $event->DTSTART['VALUE'] = 'DATE'; - $event->DTEND->setDateTime($dtEnd); - break; - case 2: - $event->RRULE = 'FREQ=DAILY;COUNT='.mt_rand(1, 10); - // no break intentional - default: - $dtStart = clone $currentDate; - $dtStart->setTime(mt_rand(1, 23), mt_rand(0, 59), mt_rand(0, 59)); - $event->DTSTART->setDateTime($dtStart); - $event->DURATION = 'PT'.mt_rand(1, 3).'H'; - break; - } - - $currentDate->modify('+ '.mt_rand(0, 3).' days'); -} -fwrite(STDERR, "Validating\n"); - -$result = $calendar->validate(); -if ($result) { - fwrite(STDERR, "Errors!\n"); - fwrite(STDERR, print_r($result, true)); - exit(-1); -} - -fwrite(STDERR, "Serializing this beast\n"); - -echo $calendar->serialize(); - -fwrite(STDERR, "done.\n"); diff --git a/lib/vendor/sabre/vobject/bin/mergeduplicates.php b/lib/vendor/sabre/vobject/bin/mergeduplicates.php deleted file mode 100755 index 31b2c14..0000000 --- a/lib/vendor/sabre/vobject/bin/mergeduplicates.php +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env php - 0, - 'No FN property' => 0, - 'Ignored duplicates' => 0, - 'Merged values' => 0, - 'Error' => 0, - 'Unique cards' => 0, - 'Total written' => 0, -]; - -function writeStats() -{ - global $stats; - foreach ($stats as $name => $value) { - echo str_pad($name, 23, ' ', STR_PAD_RIGHT), str_pad($value, 6, ' ', STR_PAD_LEFT), "\n"; - } - // Moving cursor back a few lines. - echo "\033[".count($stats).'A'; -} - -function write($vcard) -{ - global $stats, $output; - - ++$stats['Total written']; - fwrite($output, $vcard->serialize()."\n"); -} - -while ($vcard = $splitter->getNext()) { - ++$stats['Total vcards']; - writeStats(); - - $fn = isset($vcard->FN) ? (string) $vcard->FN : null; - - if (empty($fn)) { - // Immediately write this vcard, we don't compare it. - ++$stats['No FN property']; - ++$stats['Unique cards']; - write($vcard); - $vcard->destroy(); - continue; - } - - if (!isset($collectedNames[$fn])) { - $collectedNames[$fn] = $vcard; - ++$stats['Unique cards']; - continue; - } else { - // Starting comparison for all properties. We only check if properties - // in the current vcard exactly appear in the earlier vcard as well. - foreach ($vcard->children() as $newProp) { - if (in_array($newProp->name, $ignoredProperties)) { - // We don't care about properties such as UID and REV. - continue; - } - $ok = false; - foreach ($collectedNames[$fn]->select($newProp->name) as $compareProp) { - if ($compareProp->serialize() === $newProp->serialize()) { - $ok = true; - break; - } - } - - if (!$ok) { - if ('EMAIL' === $newProp->name || 'TEL' === $newProp->name) { - // We're going to make another attempt to find this - // property, this time just by value. If we find it, we - // consider it a success. - foreach ($collectedNames[$fn]->select($newProp->name) as $compareProp) { - if ($compareProp->getValue() === $newProp->getValue()) { - $ok = true; - break; - } - } - - if (!$ok) { - // Merging the new value in the old vcard. - $collectedNames[$fn]->add(clone $newProp); - $ok = true; - ++$stats['Merged values']; - } - } - } - - if (!$ok) { - // echo $newProp->serialize() . " does not appear in earlier vcard!\n"; - ++$stats['Error']; - if ($debug) { - fwrite($debug, "Missing '".$newProp->name."' property in duplicate. Earlier vcard:\n".$collectedNames[$fn]->serialize()."\n\nLater:\n".$vcard->serialize()."\n\n"); - } - - $vcard->destroy(); - continue 2; - } - } - } - - $vcard->destroy(); - ++$stats['Ignored duplicates']; -} - -foreach ($collectedNames as $vcard) { - // Overwriting any old PRODID - $vcard->PRODID = '-//Sabre//Sabre VObject '.Version::VERSION.'//EN'; - write($vcard); - writeStats(); -} - -echo str_repeat("\n", count($stats)), "\nDone.\n"; diff --git a/lib/vendor/sabre/vobject/bin/rrulebench.php b/lib/vendor/sabre/vobject/bin/rrulebench.php deleted file mode 100644 index 6900800..0000000 --- a/lib/vendor/sabre/vobject/bin/rrulebench.php +++ /dev/null @@ -1,32 +0,0 @@ -parse->start(); - -echo "Parsing.\n"; -$vobj = Sabre\VObject\Reader::read(fopen($inputFile, 'r')); - -$bench->parse->stop(); - -echo "Expanding.\n"; -$bench->expand->start(); - -$vobj->expand(new DateTime($startDate), new DateTime($endDate)); - -$bench->expand->stop(); - -echo $bench,"\n"; diff --git a/lib/vendor/sabre/vobject/bin/vobject b/lib/vendor/sabre/vobject/bin/vobject deleted file mode 100755 index 2aca7e7..0000000 --- a/lib/vendor/sabre/vobject/bin/vobject +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env php -main($argv)); - diff --git a/lib/vendor/sabre/vobject/composer.json b/lib/vendor/sabre/vobject/composer.json deleted file mode 100644 index 9d1b426..0000000 --- a/lib/vendor/sabre/vobject/composer.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "name": "sabre/vobject", - "description" : "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects", - "keywords" : [ - "iCalendar", - "iCal", - "vCalendar", - "vCard", - "jCard", - "jCal", - "ics", - "vcf", - "xCard", - "xCal", - "freebusy", - "recurrence", - "availability", - "rfc2425", - "rfc2426", - "rfc2739", - "rfc4770", - "rfc5545", - "rfc5546", - "rfc6321", - "rfc6350", - "rfc6351", - "rfc6474", - "rfc6638", - "rfc6715", - "rfc6868" - ], - "homepage" : "http://sabre.io/vobject/", - "license" : "BSD-3-Clause", - "require" : { - "php" : "^7.1 || ^8.0", - "ext-mbstring" : "*", - "sabre/xml" : "^2.1 || ^3.0 || ^4.0" - }, - "require-dev" : { - "friendsofphp/php-cs-fixer": "~2.17.1", - "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.6", - "phpunit/php-invoker" : "^2.0 || ^3.1", - "phpstan/phpstan": "^0.12 || ^1.12 || ^2.0" - }, - "suggest" : { - "hoa/bench" : "If you would like to run the benchmark scripts" - }, - "authors" : [ - { - "name" : "Evert Pot", - "email" : "me@evertpot.com", - "homepage" : "http://evertpot.com/", - "role" : "Developer" - }, - { - "name" : "Dominik Tobschall", - "email" : "dominik@fruux.com", - "homepage" : "http://tobschall.de/", - "role" : "Developer" - }, - { - "name" : "Ivan Enderlin", - "email" : "ivan.enderlin@hoa-project.net", - "homepage" : "http://mnt.io/", - "role" : "Developer" - } - ], - "support" : { - "forum" : "https://groups.google.com/group/sabredav-discuss", - "source" : "https://github.com/fruux/sabre-vobject" - }, - "autoload" : { - "psr-4" : { - "Sabre\\VObject\\" : "lib/" - } - }, - "autoload-dev" : { - "psr-4" : { - "Sabre\\VObject\\" : "tests/VObject" - } - }, - "bin" : [ - "bin/vobject", - "bin/generate_vcards" - ], - "extra" : { - "branch-alias" : { - "dev-master" : "4.0.x-dev" - } - }, - "scripts": { - "phpstan": [ - "phpstan analyse lib tests" - ], - "cs-fixer": [ - "php-cs-fixer fix" - ], - "phpunit": [ - "phpunit --configuration tests/phpunit.xml" - ], - "test": [ - "composer phpstan", - "composer cs-fixer", - "composer phpunit" - ] - } -} diff --git a/lib/vendor/sabre/vobject/lib/BirthdayCalendarGenerator.php b/lib/vendor/sabre/vobject/lib/BirthdayCalendarGenerator.php deleted file mode 100644 index fade50e..0000000 --- a/lib/vendor/sabre/vobject/lib/BirthdayCalendarGenerator.php +++ /dev/null @@ -1,172 +0,0 @@ -setObjects($objects); - } - } - - /** - * Sets the input objects. - * - * You must either supply a vCard as a string or as a Component/VCard object. - * It's also possible to supply an array of strings or objects. - * - * @param mixed $objects - */ - public function setObjects($objects) - { - if (!is_array($objects)) { - $objects = [$objects]; - } - - $this->objects = []; - foreach ($objects as $object) { - if (is_string($object)) { - $vObj = Reader::read($object); - if (!$vObj instanceof Component\VCard) { - throw new \InvalidArgumentException('String could not be parsed as \\Sabre\\VObject\\Component\\VCard by setObjects'); - } - - $this->objects[] = $vObj; - } elseif ($object instanceof Component\VCard) { - $this->objects[] = $object; - } else { - throw new \InvalidArgumentException('You can only pass strings or \\Sabre\\VObject\\Component\\VCard arguments to setObjects'); - } - } - } - - /** - * Sets the output format for the SUMMARY. - * - * @param string $format - */ - public function setFormat($format) - { - $this->format = $format; - } - - /** - * Parses the input data and returns a VCALENDAR. - * - * @return Component/VCalendar - */ - public function getResult() - { - $calendar = new VCalendar(); - - foreach ($this->objects as $object) { - // Skip if there is no BDAY property. - if (!$object->select('BDAY')) { - continue; - } - - // We've seen clients (ez-vcard) putting "BDAY:" properties - // without a value into vCards. If we come across those, we'll - // skip them. - if (empty($object->BDAY->getValue())) { - continue; - } - - // We're always converting to vCard 4.0 so we can rely on the - // VCardConverter handling the X-APPLE-OMIT-YEAR property for us. - $object = $object->convert(Document::VCARD40); - - // Skip if the card has no FN property. - if (!isset($object->FN)) { - continue; - } - - // Skip if the BDAY property is not of the right type. - if (!$object->BDAY instanceof Property\VCard\DateAndOrTime) { - continue; - } - - // Skip if we can't parse the BDAY value. - try { - $dateParts = DateTimeParser::parseVCardDateTime($object->BDAY->getValue()); - } catch (InvalidDataException $e) { - continue; - } - - // Set a year if it's not set. - $unknownYear = false; - - if (!$dateParts['year']) { - $object->BDAY = self::DEFAULT_YEAR.'-'.$dateParts['month'].'-'.$dateParts['date']; - - $unknownYear = true; - } - - // Create event. - $event = $calendar->add('VEVENT', [ - 'SUMMARY' => sprintf($this->format, $object->FN->getValue()), - 'DTSTART' => new \DateTime($object->BDAY->getValue()), - 'RRULE' => 'FREQ=YEARLY', - 'TRANSP' => 'TRANSPARENT', - ]); - - // add VALUE=date - $event->DTSTART['VALUE'] = 'DATE'; - - // Add X-SABRE-BDAY property. - if ($unknownYear) { - $event->add('X-SABRE-BDAY', 'BDAY', [ - 'X-SABRE-VCARD-UID' => $object->UID->getValue(), - 'X-SABRE-VCARD-FN' => $object->FN->getValue(), - 'X-SABRE-OMIT-YEAR' => self::DEFAULT_YEAR, - ]); - } else { - $event->add('X-SABRE-BDAY', 'BDAY', [ - 'X-SABRE-VCARD-UID' => $object->UID->getValue(), - 'X-SABRE-VCARD-FN' => $object->FN->getValue(), - ]); - } - } - - return $calendar; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Cli.php b/lib/vendor/sabre/vobject/lib/Cli.php deleted file mode 100644 index 3bde16f..0000000 --- a/lib/vendor/sabre/vobject/lib/Cli.php +++ /dev/null @@ -1,705 +0,0 @@ -stderr) { - $this->stderr = fopen('php://stderr', 'w'); - } - if (!$this->stdout) { - $this->stdout = fopen('php://stdout', 'w'); - } - if (!$this->stdin) { - $this->stdin = fopen('php://stdin', 'r'); - } - - // @codeCoverageIgnoreEnd - - try { - list($options, $positional) = $this->parseArguments($argv); - - if (isset($options['q'])) { - $this->quiet = true; - } - $this->log($this->colorize('green', 'sabre/vobject ').$this->colorize('yellow', Version::VERSION)); - - foreach ($options as $name => $value) { - switch ($name) { - case 'q': - // Already handled earlier. - break; - case 'h': - case 'help': - $this->showHelp(); - - return 0; - break; - case 'format': - switch ($value) { - // jcard/jcal documents - case 'jcard': - case 'jcal': - // specific document versions - case 'vcard21': - case 'vcard30': - case 'vcard40': - case 'icalendar20': - // specific formats - case 'json': - case 'mimedir': - // icalendar/vcad - case 'icalendar': - case 'vcard': - $this->format = $value; - break; - - default: - throw new InvalidArgumentException('Unknown format: '.$value); - } - break; - case 'pretty': - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - $this->pretty = true; - } - break; - case 'forgiving': - $this->forgiving = true; - break; - case 'inputformat': - switch ($value) { - // json formats - case 'jcard': - case 'jcal': - case 'json': - $this->inputFormat = 'json'; - break; - - // mimedir formats - case 'mimedir': - case 'icalendar': - case 'vcard': - case 'vcard21': - case 'vcard30': - case 'vcard40': - case 'icalendar20': - $this->inputFormat = 'mimedir'; - break; - - default: - throw new InvalidArgumentException('Unknown format: '.$value); - } - break; - default: - throw new InvalidArgumentException('Unknown option: '.$name); - } - } - - if (0 === count($positional)) { - $this->showHelp(); - - return 1; - } - - if (1 === count($positional)) { - throw new InvalidArgumentException('Inputfile is a required argument'); - } - - if (count($positional) > 3) { - throw new InvalidArgumentException('Too many arguments'); - } - - if (!in_array($positional[0], ['validate', 'repair', 'convert', 'color'])) { - throw new InvalidArgumentException('Unknown command: '.$positional[0]); - } - } catch (InvalidArgumentException $e) { - $this->showHelp(); - $this->log('Error: '.$e->getMessage(), 'red'); - - return 1; - } - - $command = $positional[0]; - - $this->inputPath = $positional[1]; - $this->outputPath = isset($positional[2]) ? $positional[2] : '-'; - - if ('-' !== $this->outputPath) { - $this->stdout = fopen($this->outputPath, 'w'); - } - - if (!$this->inputFormat) { - if ('.json' === substr($this->inputPath, -5)) { - $this->inputFormat = 'json'; - } else { - $this->inputFormat = 'mimedir'; - } - } - if (!$this->format) { - if ('.json' === substr($this->outputPath, -5)) { - $this->format = 'json'; - } else { - $this->format = 'mimedir'; - } - } - - $realCode = 0; - - try { - while ($input = $this->readInput()) { - $returnCode = $this->$command($input); - if (0 !== $returnCode) { - $realCode = $returnCode; - } - } - } catch (EofException $e) { - // end of file - } catch (\Exception $e) { - $this->log('Error: '.$e->getMessage(), 'red'); - - return 2; - } - - return $realCode; - } - - /** - * Shows the help message. - */ - protected function showHelp() - { - $this->log('Usage:', 'yellow'); - $this->log(' vobject [options] command [arguments]'); - $this->log(''); - $this->log('Options:', 'yellow'); - $this->log($this->colorize('green', ' -q ')."Don't output anything."); - $this->log($this->colorize('green', ' -help -h ').'Display this help message.'); - $this->log($this->colorize('green', ' --format ').'Convert to a specific format. Must be one of: vcard, vcard21,'); - $this->log($this->colorize('green', ' --forgiving ').'Makes the parser less strict.'); - $this->log(' vcard30, vcard40, icalendar20, jcal, jcard, json, mimedir.'); - $this->log($this->colorize('green', ' --inputformat ').'If the input format cannot be guessed from the extension, it'); - $this->log(' must be specified here.'); - // Only PHP 5.4 and up - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - $this->log($this->colorize('green', ' --pretty ').'json pretty-print.'); - } - $this->log(''); - $this->log('Commands:', 'yellow'); - $this->log($this->colorize('green', ' validate').' source_file Validates a file for correctness.'); - $this->log($this->colorize('green', ' repair').' source_file [output_file] Repairs a file.'); - $this->log($this->colorize('green', ' convert').' source_file [output_file] Converts a file.'); - $this->log($this->colorize('green', ' color').' source_file Colorize a file, useful for debugging.'); - $this->log( - <<log('Examples:', 'yellow'); - $this->log(' vobject convert contact.vcf contact.json'); - $this->log(' vobject convert --format=vcard40 old.vcf new.vcf'); - $this->log(' vobject convert --inputformat=json --format=mimedir - -'); - $this->log(' vobject color calendar.ics'); - $this->log(''); - $this->log('https://github.com/fruux/sabre-vobject', 'purple'); - } - - /** - * Validates a VObject file. - * - * @return int - */ - protected function validate(Component $vObj) - { - $returnCode = 0; - - switch ($vObj->name) { - case 'VCALENDAR': - $this->log('iCalendar: '.(string) $vObj->VERSION); - break; - case 'VCARD': - $this->log('vCard: '.(string) $vObj->VERSION); - break; - } - - $warnings = $vObj->validate(); - if (!count($warnings)) { - $this->log(' No warnings!'); - } else { - $levels = [ - 1 => 'REPAIRED', - 2 => 'WARNING', - 3 => 'ERROR', - ]; - $returnCode = 2; - foreach ($warnings as $warn) { - $extra = ''; - if ($warn['node'] instanceof Property) { - $extra = ' (property: "'.$warn['node']->name.'")'; - } - $this->log(' ['.$levels[$warn['level']].'] '.$warn['message'].$extra); - } - } - - return $returnCode; - } - - /** - * Repairs a VObject file. - * - * @return int - */ - protected function repair(Component $vObj) - { - $returnCode = 0; - - switch ($vObj->name) { - case 'VCALENDAR': - $this->log('iCalendar: '.(string) $vObj->VERSION); - break; - case 'VCARD': - $this->log('vCard: '.(string) $vObj->VERSION); - break; - } - - $warnings = $vObj->validate(Node::REPAIR); - if (!count($warnings)) { - $this->log(' No warnings!'); - } else { - $levels = [ - 1 => 'REPAIRED', - 2 => 'WARNING', - 3 => 'ERROR', - ]; - $returnCode = 2; - foreach ($warnings as $warn) { - $extra = ''; - if ($warn['node'] instanceof Property) { - $extra = ' (property: "'.$warn['node']->name.'")'; - } - $this->log(' ['.$levels[$warn['level']].'] '.$warn['message'].$extra); - } - } - fwrite($this->stdout, $vObj->serialize()); - - return $returnCode; - } - - /** - * Converts a vObject file to a new format. - * - * @param Component $vObj - * - * @return int - */ - protected function convert($vObj) - { - $json = false; - $convertVersion = null; - $forceInput = null; - - switch ($this->format) { - case 'json': - $json = true; - if ('VCARD' === $vObj->name) { - $convertVersion = Document::VCARD40; - } - break; - case 'jcard': - $json = true; - $forceInput = 'VCARD'; - $convertVersion = Document::VCARD40; - break; - case 'jcal': - $json = true; - $forceInput = 'VCALENDAR'; - break; - case 'mimedir': - case 'icalendar': - case 'icalendar20': - case 'vcard': - break; - case 'vcard21': - $convertVersion = Document::VCARD21; - break; - case 'vcard30': - $convertVersion = Document::VCARD30; - break; - case 'vcard40': - $convertVersion = Document::VCARD40; - break; - } - - if ($forceInput && $vObj->name !== $forceInput) { - throw new \Exception('You cannot convert a '.strtolower($vObj->name).' to '.$this->format); - } - if ($convertVersion) { - $vObj = $vObj->convert($convertVersion); - } - if ($json) { - $jsonOptions = 0; - if ($this->pretty) { - $jsonOptions = JSON_PRETTY_PRINT; - } - fwrite($this->stdout, json_encode($vObj->jsonSerialize(), $jsonOptions)); - } else { - fwrite($this->stdout, $vObj->serialize()); - } - - return 0; - } - - /** - * Colorizes a file. - * - * @param Component $vObj - */ - protected function color($vObj) - { - $this->serializeComponent($vObj); - } - - /** - * Returns an ansi color string for a color name. - * - * @param string $color - * - * @return string - */ - protected function colorize($color, $str, $resetTo = 'default') - { - $colors = [ - 'cyan' => '1;36', - 'red' => '1;31', - 'yellow' => '1;33', - 'blue' => '0;34', - 'green' => '0;32', - 'default' => '0', - 'purple' => '0;35', - ]; - - return "\033[".$colors[$color].'m'.$str."\033[".$colors[$resetTo].'m'; - } - - /** - * Writes out a string in specific color. - * - * @param string $color - * @param string $str - */ - protected function cWrite($color, $str) - { - fwrite($this->stdout, $this->colorize($color, $str)); - } - - protected function serializeComponent(Component $vObj) - { - $this->cWrite('cyan', 'BEGIN'); - $this->cWrite('red', ':'); - $this->cWrite('yellow', $vObj->name."\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 lower in the list. - * To avoid score collisions, each "score category" has a reasonable - * space to accommodate elements. The $key is added to the $score to - * preserve the original relative order of elements. - * - * @param int $key - * @param array $array - * - * @return int - */ - $sortScore = function ($key, $array) { - if ($array[$key] instanceof Component) { - // We want to encode VTIMEZONE first, this is a personal - // preference. - if ('VTIMEZONE' === $array[$key]->name) { - $score = 300000000; - - return $score + $key; - } else { - $score = 400000000; - - return $score + $key; - } - } else { - // Properties get encoded first - // VCARD version 4.0 wants the VERSION property to appear first - if ($array[$key] instanceof Property) { - if ('VERSION' === $array[$key]->name) { - $score = 100000000; - - return $score + $key; - } else { - // All other properties - $score = 200000000; - - return $score + $key; - } - } - } - }; - - $children = $vObj->children(); - $tmp = $children; - uksort( - $children, - function ($a, $b) use ($sortScore, $tmp) { - $sA = $sortScore($a, $tmp); - $sB = $sortScore($b, $tmp); - - return $sA - $sB; - } - ); - - foreach ($children as $child) { - if ($child instanceof Component) { - $this->serializeComponent($child); - } else { - $this->serializeProperty($child); - } - } - - $this->cWrite('cyan', 'END'); - $this->cWrite('red', ':'); - $this->cWrite('yellow', $vObj->name."\n"); - } - - /** - * Colorizes a property. - */ - protected function serializeProperty(Property $property) - { - if ($property->group) { - $this->cWrite('default', $property->group); - $this->cWrite('red', '.'); - } - - $this->cWrite('yellow', $property->name); - - foreach ($property->parameters as $param) { - $this->cWrite('red', ';'); - $this->cWrite('blue', $param->serialize()); - } - $this->cWrite('red', ':'); - - if ($property instanceof Property\Binary) { - $this->cWrite('default', 'embedded binary stripped. ('.strlen($property->getValue()).' bytes)'); - } else { - $parts = $property->getParts(); - $first1 = true; - // Looping through property values - foreach ($parts as $part) { - if ($first1) { - $first1 = false; - } else { - $this->cWrite('red', $property->delimiter); - } - $first2 = true; - // Looping through property sub-values - foreach ((array) $part as $subPart) { - if ($first2) { - $first2 = false; - } else { - // The sub-value delimiter is always comma - $this->cWrite('red', ','); - } - - $subPart = strtr( - $subPart, - [ - '\\' => $this->colorize('purple', '\\\\', 'green'), - ';' => $this->colorize('purple', '\;', 'green'), - ',' => $this->colorize('purple', '\,', 'green'), - "\n" => $this->colorize('purple', "\\n\n\t", 'green'), - "\r" => '', - ] - ); - - $this->cWrite('green', $subPart); - } - } - } - $this->cWrite('default', "\n"); - } - - /** - * Parses the list of arguments. - */ - protected function parseArguments(array $argv) - { - $positional = []; - $options = []; - - for ($ii = 0; $ii < count($argv); ++$ii) { - // Skipping the first argument. - if (0 === $ii) { - continue; - } - - $v = $argv[$ii]; - - if ('--' === substr($v, 0, 2)) { - // This is a long-form option. - $optionName = substr($v, 2); - $optionValue = true; - if (strpos($optionName, '=')) { - list($optionName, $optionValue) = explode('=', $optionName); - } - $options[$optionName] = $optionValue; - } elseif ('-' === substr($v, 0, 1) && strlen($v) > 1) { - // This is a short-form option. - foreach (str_split(substr($v, 1)) as $option) { - $options[$option] = true; - } - } else { - $positional[] = $v; - } - } - - return [$options, $positional]; - } - - protected $parser; - - /** - * Reads the input file. - * - * @return Component - */ - protected function readInput() - { - if (!$this->parser) { - if ('-' !== $this->inputPath) { - $this->stdin = fopen($this->inputPath, 'r'); - } - - if ('mimedir' === $this->inputFormat) { - $this->parser = new Parser\MimeDir($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); - } else { - $this->parser = new Parser\Json($this->stdin, ($this->forgiving ? Reader::OPTION_FORGIVING : 0)); - } - } - - return $this->parser->parse(); - } - - /** - * Sends a message to STDERR. - * - * @param string $msg - */ - protected function log($msg, $color = 'default') - { - if (!$this->quiet) { - if ('default' !== $color) { - $msg = $this->colorize($color, $msg); - } - fwrite($this->stderr, $msg."\n"); - } - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component.php b/lib/vendor/sabre/vobject/lib/Component.php deleted file mode 100644 index ca82ad4..0000000 --- a/lib/vendor/sabre/vobject/lib/Component.php +++ /dev/null @@ -1,672 +0,0 @@ - - */ - protected $children = []; - - /** - * Creates a new component. - * - * You can specify the children either in key=>value syntax, in which case - * properties will automatically be created, or you can just pass a list of - * Component and Property object. - * - * By default, a set of sensible values will be added to the component. For - * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To - * ensure that this does not happen, set $defaults to false. - * - * @param string|null $name such as VCALENDAR, VEVENT - * @param bool $defaults - */ - public function __construct(Document $root, $name, array $children = [], $defaults = true) - { - $this->name = isset($name) ? strtoupper($name) : ''; - $this->root = $root; - - if ($defaults) { - // This is a terribly convoluted way to do this, but this ensures - // that the order of properties as they are specified in both - // defaults and the childrens list, are inserted in the object in a - // natural way. - $list = $this->getDefaults(); - $nodes = []; - foreach ($children as $key => $value) { - if ($value instanceof Node) { - if (isset($list[$value->name])) { - unset($list[$value->name]); - } - $nodes[] = $value; - } else { - $list[$key] = $value; - } - } - foreach ($list as $key => $value) { - $this->add($key, $value); - } - foreach ($nodes as $node) { - $this->add($node); - } - } else { - foreach ($children as $k => $child) { - if ($child instanceof Node) { - // Component or Property - $this->add($child); - } else { - // Property key=>value - $this->add($k, $child); - } - } - } - } - - /** - * Adds a new property or component, and returns the new item. - * - * This method has 3 possible signatures: - * - * add(Component $comp) // Adds a new component - * add(Property $prop) // Adds a new property - * add($name, $value, array $parameters = []) // Adds a new property - * add($name, array $children = []) // Adds a new component - * by name. - * - * @return Node - */ - public function add() - { - $arguments = func_get_args(); - - if ($arguments[0] instanceof Node) { - if (isset($arguments[1])) { - throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject Node'); - } - $arguments[0]->parent = $this; - $newNode = $arguments[0]; - } elseif (is_string($arguments[0])) { - $newNode = call_user_func_array([$this->root, 'create'], $arguments); - } else { - throw new \InvalidArgumentException('The first argument must either be a \\Sabre\\VObject\\Node or a string'); - } - - $name = $newNode->name; - if (isset($this->children[$name])) { - $this->children[$name][] = $newNode; - } else { - $this->children[$name] = [$newNode]; - } - - return $newNode; - } - - /** - * This method removes a component or property from this component. - * - * You can either specify the item by name (like DTSTART), in which case - * all properties/components with that name will be removed, or you can - * pass an instance of a property or component, in which case only that - * exact item will be removed. - * - * @param string|Property|Component $item - */ - public function remove($item) - { - if (is_string($item)) { - // If there's no dot in the name, it's an exact property name and - // we can just wipe out all those properties. - // - if (false === strpos($item, '.')) { - unset($this->children[strtoupper($item)]); - - return; - } - // If there was a dot, we need to ask select() to help us out and - // then we just call remove recursively. - foreach ($this->select($item) as $child) { - $this->remove($child); - } - } else { - foreach ($this->select($item->name) as $k => $child) { - if ($child === $item) { - unset($this->children[$item->name][$k]); - - return; - } - } - - throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component'); - } - } - - /** - * Returns a flat list of all the properties and components in this - * component. - * - * @return array - */ - public function children() - { - $result = []; - foreach ($this->children as $childGroup) { - $result = array_merge($result, $childGroup); - } - - return $result; - } - - /** - * This method only returns a list of sub-components. Properties are - * ignored. - * - * @return array - */ - public function getComponents() - { - $result = []; - - foreach ($this->children as $childGroup) { - foreach ($childGroup as $child) { - if ($child instanceof self) { - $result[] = $child; - } - } - } - - return $result; - } - - /** - * 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 - * has not been assigned a group, specify ".EMAIL". - * - * @param string $name - * - * @return array - */ - public function select($name) - { - $group = null; - $name = strtoupper($name); - if (false !== strpos($name, '.')) { - list($group, $name) = explode('.', $name, 2); - } - if ('' === $name) { - $name = null; - } - - if (!is_null($name)) { - $result = isset($this->children[$name]) ? $this->children[$name] : []; - - if (is_null($group)) { - return $result; - } else { - // If we have a group filter as well, we need to narrow it down - // more. - return array_filter( - $result, - function ($child) use ($group) { - return $child instanceof Property && (null !== $child->group ? strtoupper($child->group) : '') === $group; - } - ); - } - } - - // If we got to this point, it means there was no 'name' specified for - // searching, implying that this is a group-only search. - $result = []; - foreach ($this->children as $childGroup) { - foreach ($childGroup as $child) { - if ($child instanceof Property && (null !== $child->group ? strtoupper($child->group) : '') === $group) { - $result[] = $child; - } - } - } - - return $result; - } - - /** - * 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 lower in the list. - * To avoid score collisions, each "score category" has a reasonable - * space to accommodate elements. The $key is added to the $score to - * preserve the original relative order of elements. - * - * @param int $key - * @param array $array - * - * @return int - */ - $sortScore = function ($key, $array) { - if ($array[$key] instanceof Component) { - // We want to encode VTIMEZONE first, this is a personal - // preference. - if ('VTIMEZONE' === $array[$key]->name) { - $score = 300000000; - - return $score + $key; - } else { - $score = 400000000; - - return $score + $key; - } - } else { - // Properties get encoded first - // VCARD version 4.0 wants the VERSION property to appear first - if ($array[$key] instanceof Property) { - if ('VERSION' === $array[$key]->name) { - $score = 100000000; - - return $score + $key; - } else { - // All other properties - $score = 200000000; - - return $score + $key; - } - } - } - }; - - $children = $this->children(); - $tmp = $children; - uksort( - $children, - function ($a, $b) use ($sortScore, $tmp) { - $sA = $sortScore($a, $tmp); - $sB = $sortScore($b, $tmp); - - return $sA - $sB; - } - ); - - foreach ($children as $child) { - $str .= $child->serialize(); - } - $str .= 'END:'.$this->name."\r\n"; - - return $str; - } - - /** - * This method returns an array, with the representation as it should be - * encoded in JSON. This is used to create jCard or jCal documents. - * - * @return array - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - $components = []; - $properties = []; - - foreach ($this->children as $childGroup) { - foreach ($childGroup as $child) { - if ($child instanceof self) { - $components[] = $child->jsonSerialize(); - } else { - $properties[] = $child->jsonSerialize(); - } - } - } - - return [ - strtolower($this->name), - $properties, - $components, - ]; - } - - /** - * This method serializes the data into XML. This is used to create xCard or - * xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - public function xmlSerialize(Xml\Writer $writer): void - { - $components = []; - $properties = []; - - foreach ($this->children as $childGroup) { - foreach ($childGroup as $child) { - if ($child instanceof self) { - $components[] = $child; - } else { - $properties[] = $child; - } - } - } - - $writer->startElement(strtolower($this->name)); - - if (!empty($properties)) { - $writer->startElement('properties'); - - foreach ($properties as $property) { - $property->xmlSerialize($writer); - } - - $writer->endElement(); - } - - if (!empty($components)) { - $writer->startElement('components'); - - foreach ($components as $component) { - $component->xmlSerialize($writer); - } - - $writer->endElement(); - } - - $writer->endElement(); - } - - /** - * This method should return a list of default property values. - * - * @return array - */ - protected function getDefaults() - { - return []; - } - - /* Magic property accessors {{{ */ - - /** - * Using 'get' you will either get a property or component. - * - * If there were no child-elements found with the specified name, - * null is returned. - * - * To use this, this may look something like this: - * - * $event = $calendar->VEVENT; - * - * @param string $name - * - * @return Property|null - */ - public function __get($name) - { - if ('children' === $name) { - throw new \RuntimeException('Starting sabre/vobject 4.0 the children property is now protected. You should use the children() method instead'); - } - - $matches = $this->select($name); - if (0 === count($matches)) { - return; - } else { - $firstMatch = current($matches); - /* @var $firstMatch Property */ - $firstMatch->setIterator(new ElementList(array_values($matches))); - - return $firstMatch; - } - } - - /** - * This method checks if a sub-element with the specified name exists. - * - * @param string $name - * - * @return bool - */ - public function __isset($name) - { - $matches = $this->select($name); - - return count($matches) > 0; - } - - /** - * Using the setter method you can add properties or subcomponents. - * - * You can either pass a Component, Property - * object, or a string to automatically create a Property. - * - * 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 - */ - public function __set($name, $value) - { - $name = strtoupper($name); - $this->remove($name); - if ($value instanceof self || $value instanceof Property) { - $this->add($value); - } else { - $this->add($name, $value); - } - } - - /** - * Removes all properties and components within this component with the - * specified name. - * - * @param string $name - */ - public function __unset($name) - { - $this->remove($name); - } - - /* }}} */ - - /** - * This method is automatically called when the object is cloned. - * Specifically, this will ensure all child elements are also cloned. - */ - public function __clone() - { - foreach ($this->children as $childName => $childGroup) { - foreach ($childGroup as $key => $child) { - $clonedChild = clone $child; - $clonedChild->parent = $this; - $clonedChild->root = $this->root; - $this->children[$childName][$key] = $clonedChild; - } - } - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * It is also possible to specify defaults and severity levels for - * violating the rule. - * - * See the VEVENT implementation for getValidationRules for a more complex - * example. - * - * @var array - */ - public function getValidationRules() - { - return []; - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes. - * Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on). - * 2 - A warning. - * 3 - An error. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $rules = $this->getValidationRules(); - $defaults = $this->getDefaults(); - - $propertyCounters = []; - - $messages = []; - - foreach ($this->children() as $child) { - $name = strtoupper($child->name); - if (!isset($propertyCounters[$name])) { - $propertyCounters[$name] = 1; - } else { - ++$propertyCounters[$name]; - } - $messages = array_merge($messages, $child->validate($options)); - } - - foreach ($rules as $propName => $rule) { - switch ($rule) { - case '0': - if (isset($propertyCounters[$propName])) { - $messages[] = [ - 'level' => 3, - 'message' => $propName.' MUST NOT appear in a '.$this->name.' component', - 'node' => $this, - ]; - } - break; - case '1': - if (!isset($propertyCounters[$propName]) || 1 !== $propertyCounters[$propName]) { - $repaired = false; - if ($options & self::REPAIR && isset($defaults[$propName])) { - $this->add($propName, $defaults[$propName]); - $repaired = true; - } - $messages[] = [ - 'level' => $repaired ? 1 : 3, - 'message' => $propName.' MUST appear exactly once in a '.$this->name.' component', - 'node' => $this, - ]; - } - break; - case '+': - if (!isset($propertyCounters[$propName]) || $propertyCounters[$propName] < 1) { - $messages[] = [ - 'level' => 3, - 'message' => $propName.' MUST appear at least once in a '.$this->name.' component', - 'node' => $this, - ]; - } - break; - case '*': - break; - case '?': - if (isset($propertyCounters[$propName]) && $propertyCounters[$propName] > 1) { - $level = 3; - - // We try to repair the same property appearing multiple times with the exact same value - // by removing the duplicates and keeping only one property - if ($options & self::REPAIR) { - $properties = array_unique($this->select($propName), SORT_REGULAR); - - if (1 === count($properties)) { - $this->remove($propName); - $this->add($properties[0]); - - $level = 1; - } - } - - $messages[] = [ - 'level' => $level, - 'message' => $propName.' MUST NOT appear more than once in a '.$this->name.' component', - 'node' => $this, - ]; - } - break; - } - } - - return $messages; - } - - /** - * Call this method on a document if you're done using it. - * - * It's intended to remove all circular references, so PHP can easily clean - * it up. - */ - public function destroy() - { - parent::destroy(); - foreach ($this->children as $childGroup) { - foreach ($childGroup as $child) { - $child->destroy(); - } - } - $this->children = []; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/Available.php b/lib/vendor/sabre/vobject/lib/Component/Available.php deleted file mode 100644 index 5510b9e..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/Available.php +++ /dev/null @@ -1,123 +0,0 @@ -DTSTART->getDateTime(); - if (isset($this->DTEND)) { - $effectiveEnd = $this->DTEND->getDateTime(); - } else { - $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION)); - } - - return [$effectiveStart, $effectiveEnd]; - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'UID' => 1, - 'DTSTART' => 1, - 'DTSTAMP' => 1, - - 'DTEND' => '?', - 'DURATION' => '?', - - 'CREATED' => '?', - 'DESCRIPTION' => '?', - 'LAST-MODIFIED' => '?', - 'RECURRENCE-ID' => '?', - 'RRULE' => '?', - 'SUMMARY' => '?', - - 'CATEGORIES' => '*', - 'COMMENT' => '*', - 'CONTACT' => '*', - 'EXDATE' => '*', - 'RDATE' => '*', - - 'AVAILABLE' => '*', - ]; - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes. - * Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on). - * 2 - A warning. - * 3 - An error. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $result = parent::validate($options); - - if (isset($this->DTEND) && isset($this->DURATION)) { - $result[] = [ - 'level' => 3, - 'message' => 'DTEND and DURATION cannot both be present', - 'node' => $this, - ]; - } - - return $result; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VAlarm.php b/lib/vendor/sabre/vobject/lib/Component/VAlarm.php deleted file mode 100644 index bd00eb6..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VAlarm.php +++ /dev/null @@ -1,138 +0,0 @@ -TRIGGER; - if (!isset($trigger['VALUE']) || 'DURATION' === strtoupper($trigger['VALUE'])) { - $triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER); - $related = (isset($trigger['RELATED']) && 'END' == strtoupper($trigger['RELATED'])) ? 'END' : 'START'; - - $parentComponent = $this->parent; - if ('START' === $related) { - if ('VTODO' === $parentComponent->name) { - $propName = 'DUE'; - } else { - $propName = 'DTSTART'; - } - - $effectiveTrigger = $parentComponent->$propName->getDateTime(); - $effectiveTrigger = $effectiveTrigger->add($triggerDuration); - } else { - if ('VTODO' === $parentComponent->name) { - $endProp = 'DUE'; - } elseif ('VEVENT' === $parentComponent->name) { - $endProp = 'DTEND'; - } else { - throw new InvalidDataException('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT'); - } - - if (isset($parentComponent->$endProp)) { - $effectiveTrigger = $parentComponent->$endProp->getDateTime(); - $effectiveTrigger = $effectiveTrigger->add($triggerDuration); - } elseif (isset($parentComponent->DURATION)) { - $effectiveTrigger = $parentComponent->DTSTART->getDateTime(); - $duration = VObject\DateTimeParser::parseDuration($parentComponent->DURATION); - $effectiveTrigger = $effectiveTrigger->add($duration); - $effectiveTrigger = $effectiveTrigger->add($triggerDuration); - } else { - $effectiveTrigger = $parentComponent->DTSTART->getDateTime(); - $effectiveTrigger = $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(DateTimeInterface $start, DateTimeInterface $end) - { - $effectiveTrigger = $this->getEffectiveTriggerTime(); - - if (isset($this->DURATION)) { - $duration = 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; - } - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'ACTION' => 1, - 'TRIGGER' => 1, - - 'DURATION' => '?', - 'REPEAT' => '?', - - 'ATTACH' => '?', - ]; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VAvailability.php b/lib/vendor/sabre/vobject/lib/Component/VAvailability.php deleted file mode 100644 index 04ec38d..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VAvailability.php +++ /dev/null @@ -1,149 +0,0 @@ -getEffectiveStartEnd(); - - return - (is_null($effectiveStart) || $start < $effectiveEnd) && - (is_null($effectiveEnd) || $end > $effectiveStart) - ; - } - - /** - * Returns the 'effective start' and 'effective end' of this VAVAILABILITY - * component. - * - * We use the DTSTART and DTEND or DURATION to determine this. - * - * The returned value is an array containing DateTimeImmutable instances. - * If either the start or end is 'unbounded' its value will be null - * instead. - * - * @return array - */ - public function getEffectiveStartEnd() - { - $effectiveStart = null; - $effectiveEnd = null; - - if (isset($this->DTSTART)) { - $effectiveStart = $this->DTSTART->getDateTime(); - } - if (isset($this->DTEND)) { - $effectiveEnd = $this->DTEND->getDateTime(); - } elseif ($effectiveStart && isset($this->DURATION)) { - $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION)); - } - - return [$effectiveStart, $effectiveEnd]; - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'UID' => 1, - 'DTSTAMP' => 1, - - 'BUSYTYPE' => '?', - 'CLASS' => '?', - 'CREATED' => '?', - 'DESCRIPTION' => '?', - 'DTSTART' => '?', - 'LAST-MODIFIED' => '?', - 'ORGANIZER' => '?', - 'PRIORITY' => '?', - 'SEQUENCE' => '?', - 'SUMMARY' => '?', - 'URL' => '?', - 'DTEND' => '?', - 'DURATION' => '?', - - 'CATEGORIES' => '*', - 'COMMENT' => '*', - 'CONTACT' => '*', - ]; - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes. - * Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on). - * 2 - A warning. - * 3 - An error. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $result = parent::validate($options); - - if (isset($this->DTEND) && isset($this->DURATION)) { - $result[] = [ - 'level' => 3, - 'message' => 'DTEND and DURATION cannot both be present', - 'node' => $this, - ]; - } - - return $result; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VCalendar.php b/lib/vendor/sabre/vobject/lib/Component/VCalendar.php deleted file mode 100644 index 017aed7..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VCalendar.php +++ /dev/null @@ -1,528 +0,0 @@ - self::class, - 'VALARM' => VAlarm::class, - 'VEVENT' => VEvent::class, - 'VFREEBUSY' => VFreeBusy::class, - 'VAVAILABILITY' => VAvailability::class, - 'AVAILABLE' => Available::class, - 'VJOURNAL' => VJournal::class, - 'VTIMEZONE' => VTimeZone::class, - 'VTODO' => VTodo::class, - ]; - - /** - * List of value-types, and which classes they map to. - * - * @var array - */ - public static $valueMap = [ - 'BINARY' => VObject\Property\Binary::class, - 'BOOLEAN' => VObject\Property\Boolean::class, - 'CAL-ADDRESS' => VObject\Property\ICalendar\CalAddress::class, - 'DATE' => VObject\Property\ICalendar\Date::class, - 'DATE-TIME' => VObject\Property\ICalendar\DateTime::class, - 'DURATION' => VObject\Property\ICalendar\Duration::class, - 'FLOAT' => VObject\Property\FloatValue::class, - 'INTEGER' => VObject\Property\IntegerValue::class, - 'PERIOD' => VObject\Property\ICalendar\Period::class, - 'RECUR' => VObject\Property\ICalendar\Recur::class, - 'TEXT' => VObject\Property\Text::class, - 'TIME' => VObject\Property\Time::class, - 'UNKNOWN' => VObject\Property\Unknown::class, // jCard / jCal-only. - 'URI' => VObject\Property\Uri::class, - 'UTC-OFFSET' => VObject\Property\UtcOffset::class, - ]; - - /** - * List of properties, and which classes they map to. - * - * @var array - */ - public static $propertyMap = [ - // Calendar properties - 'CALSCALE' => VObject\Property\FlatText::class, - 'METHOD' => VObject\Property\FlatText::class, - 'PRODID' => VObject\Property\FlatText::class, - 'VERSION' => VObject\Property\FlatText::class, - - // Component properties - 'ATTACH' => VObject\Property\Uri::class, - 'CATEGORIES' => VObject\Property\Text::class, - 'CLASS' => VObject\Property\FlatText::class, - 'COMMENT' => VObject\Property\FlatText::class, - 'DESCRIPTION' => VObject\Property\FlatText::class, - 'GEO' => VObject\Property\FloatValue::class, - 'LOCATION' => VObject\Property\FlatText::class, - 'PERCENT-COMPLETE' => VObject\Property\IntegerValue::class, - 'PRIORITY' => VObject\Property\IntegerValue::class, - 'RESOURCES' => VObject\Property\Text::class, - 'STATUS' => VObject\Property\FlatText::class, - 'SUMMARY' => VObject\Property\FlatText::class, - - // Date and Time Component Properties - 'COMPLETED' => VObject\Property\ICalendar\DateTime::class, - 'DTEND' => VObject\Property\ICalendar\DateTime::class, - 'DUE' => VObject\Property\ICalendar\DateTime::class, - 'DTSTART' => VObject\Property\ICalendar\DateTime::class, - 'DURATION' => VObject\Property\ICalendar\Duration::class, - 'FREEBUSY' => VObject\Property\ICalendar\Period::class, - 'TRANSP' => VObject\Property\FlatText::class, - - // Time Zone Component Properties - 'TZID' => VObject\Property\FlatText::class, - 'TZNAME' => VObject\Property\FlatText::class, - 'TZOFFSETFROM' => VObject\Property\UtcOffset::class, - 'TZOFFSETTO' => VObject\Property\UtcOffset::class, - 'TZURL' => VObject\Property\Uri::class, - - // Relationship Component Properties - 'ATTENDEE' => VObject\Property\ICalendar\CalAddress::class, - 'CONTACT' => VObject\Property\FlatText::class, - 'ORGANIZER' => VObject\Property\ICalendar\CalAddress::class, - 'RECURRENCE-ID' => VObject\Property\ICalendar\DateTime::class, - 'RELATED-TO' => VObject\Property\FlatText::class, - 'URL' => VObject\Property\Uri::class, - 'UID' => VObject\Property\FlatText::class, - - // Recurrence Component Properties - 'EXDATE' => VObject\Property\ICalendar\DateTime::class, - 'RDATE' => VObject\Property\ICalendar\DateTime::class, - 'RRULE' => VObject\Property\ICalendar\Recur::class, - 'EXRULE' => VObject\Property\ICalendar\Recur::class, // Deprecated since rfc5545 - - // Alarm Component Properties - 'ACTION' => VObject\Property\FlatText::class, - 'REPEAT' => VObject\Property\IntegerValue::class, - 'TRIGGER' => VObject\Property\ICalendar\Duration::class, - - // Change Management Component Properties - 'CREATED' => VObject\Property\ICalendar\DateTime::class, - 'DTSTAMP' => VObject\Property\ICalendar\DateTime::class, - 'LAST-MODIFIED' => VObject\Property\ICalendar\DateTime::class, - 'SEQUENCE' => VObject\Property\IntegerValue::class, - - // Request Status - 'REQUEST-STATUS' => VObject\Property\Text::class, - - // Additions from draft-daboo-valarm-extensions-04 - 'ALARM-AGENT' => VObject\Property\Text::class, - 'ACKNOWLEDGED' => VObject\Property\ICalendar\DateTime::class, - 'PROXIMITY' => VObject\Property\Text::class, - 'DEFAULT-ALARM' => VObject\Property\Boolean::class, - - // Additions from draft-daboo-calendar-availability-05 - 'BUSYTYPE' => VObject\Property\Text::class, - ]; - - /** - * Returns the current document type. - * - * @return int - */ - public function getDocumentType() - { - return self::ICALENDAR20; - } - - /** - * 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 VObject\Component[] - */ - public function getBaseComponents($componentName = null) - { - $isBaseComponent = function ($component) { - if (!$component instanceof VObject\Component) { - return false; - } - if ('VTIMEZONE' === $component->name) { - return false; - } - if (isset($component->{'RECURRENCE-ID'})) { - return false; - } - - return true; - }; - - if ($componentName) { - // Early exit - return array_filter( - $this->select($componentName), - $isBaseComponent - ); - } - - $components = []; - foreach ($this->children as $childGroup) { - foreach ($childGroup as $child) { - if (!$child instanceof Component) { - // If one child is not a component, they all are so we skip - // the entire group. - continue 2; - } - if ($isBaseComponent($child)) { - $components[] = $child; - } - } - } - - return $components; - } - - /** - * Returns the first component that is not a VTIMEZONE, and does not have - * an RECURRENCE-ID. - * - * If there is no such component, null will be returned. - * - * @param string $componentName filter by component name - * - * @return VObject\Component|null - */ - public function getBaseComponent($componentName = null) - { - $isBaseComponent = function ($component) { - if (!$component instanceof VObject\Component) { - return false; - } - if ('VTIMEZONE' === $component->name) { - return false; - } - if (isset($component->{'RECURRENCE-ID'})) { - return false; - } - - return true; - }; - - if ($componentName) { - foreach ($this->select($componentName) as $child) { - if ($isBaseComponent($child)) { - return $child; - } - } - - return null; - } - - // Searching all components - foreach ($this->children as $childGroup) { - foreach ($childGroup as $child) { - if ($isBaseComponent($child)) { - return $child; - } - } - } - - return null; - } - - /** - * Expand all events in this VCalendar object and return a new VCalendar - * with the expanded events. - * - * 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 its 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. - * - * @param DateTimeZone $timeZone reference timezone for floating dates and - * times - * - * @return VCalendar - */ - public function expand(DateTimeInterface $start, DateTimeInterface $end, ?DateTimeZone $timeZone = null) - { - $newChildren = []; - $recurringEvents = []; - - if (!$timeZone) { - $timeZone = new DateTimeZone('UTC'); - } - - $stripTimezones = function (Component $component) use ($timeZone, &$stripTimezones) { - foreach ($component->children() as $componentChild) { - if ($componentChild instanceof Property\ICalendar\DateTime && $componentChild->hasTime()) { - $dt = $componentChild->getDateTimes($timeZone); - // We only need to update the first timezone, because - // setDateTimes will match all other timezones to the - // first. - $dt[0] = $dt[0]->setTimeZone(new DateTimeZone('UTC')); - $componentChild->setDateTimes($dt); - } elseif ($componentChild instanceof Component) { - $stripTimezones($componentChild); - } - } - - return $component; - }; - - foreach ($this->children() as $child) { - if ($child instanceof Property && 'PRODID' !== $child->name) { - // We explicitly want to ignore PRODID, because we want to - // overwrite it with our own. - $newChildren[] = clone $child; - } elseif ($child instanceof Component && 'VTIMEZONE' !== $child->name) { - // We're also stripping all VTIMEZONE objects because we're - // converting everything to UTC. - if ('VEVENT' === $child->name && (isset($child->{'RECURRENCE-ID'}) || isset($child->RRULE) || isset($child->RDATE))) { - // Handle these a bit later. - $uid = (string) $child->UID; - if (!$uid) { - throw new InvalidDataException('Every VEVENT object must have a UID property'); - } - if (isset($recurringEvents[$uid])) { - $recurringEvents[$uid][] = clone $child; - } else { - $recurringEvents[$uid] = [clone $child]; - } - } elseif ('VEVENT' === $child->name && $child->isInTimeRange($start, $end)) { - $newChildren[] = $stripTimezones(clone $child); - } - } - } - - foreach ($recurringEvents as $events) { - try { - $it = new EventIterator($events, null, $timeZone); - } catch (NoInstancesException $e) { - // This event is recurring, but it doesn't have a single - // instance. We are skipping this event from the output - // entirely. - continue; - } - $it->fastForward($start); - - while ($it->valid() && $it->getDTStart() < $end) { - if ($it->getDTEnd() > $start) { - $newChildren[] = $stripTimezones($it->getEventObject()); - } - $it->next(); - } - } - - return new self($newChildren); - } - - /** - * This method should return a list of default property values. - * - * @return array - */ - protected function getDefaults() - { - return [ - 'VERSION' => '2.0', - 'PRODID' => '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN', - 'CALSCALE' => 'GREGORIAN', - ]; - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'PRODID' => 1, - 'VERSION' => 1, - - 'CALSCALE' => '?', - 'METHOD' => '?', - ]; - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * Node::PROFILE_CARDDAV - Validate the vCard for CardDAV purposes. - * Node::PROFILE_CALDAV - Validate the iCalendar for CalDAV purposes. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on). - * 2 - A warning. - * 3 - An error. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $warnings = parent::validate($options); - - if ($ver = $this->VERSION) { - if ('2.0' !== (string) $ver) { - $warnings[] = [ - 'level' => 3, - 'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.', - 'node' => $this, - ]; - } - } - - $uidList = []; - $componentsFound = 0; - $componentTypes = []; - - foreach ($this->children() as $child) { - if ($child instanceof Component) { - ++$componentsFound; - - if (!in_array($child->name, ['VEVENT', 'VTODO', 'VJOURNAL'])) { - continue; - } - $componentTypes[] = $child->name; - - $uid = (string) $child->UID; - $isMaster = isset($child->{'RECURRENCE-ID'}) ? 0 : 1; - if (isset($uidList[$uid])) { - ++$uidList[$uid]['count']; - if ($isMaster && $uidList[$uid]['hasMaster']) { - $warnings[] = [ - 'level' => 3, - 'message' => 'More than one master object was found for the object with UID '.$uid, - 'node' => $this, - ]; - } - $uidList[$uid]['hasMaster'] += $isMaster; - } else { - $uidList[$uid] = [ - 'count' => 1, - 'hasMaster' => $isMaster, - ]; - } - } - } - - if (0 === $componentsFound) { - $warnings[] = [ - 'level' => 3, - 'message' => 'An iCalendar object must have at least 1 component.', - 'node' => $this, - ]; - } - - if ($options & self::PROFILE_CALDAV) { - if (count($uidList) > 1) { - $warnings[] = [ - 'level' => 3, - 'message' => 'A calendar object on a CalDAV server may only have components with the same UID.', - 'node' => $this, - ]; - } - if (0 === count($componentTypes)) { - $warnings[] = [ - 'level' => 3, - 'message' => 'A calendar object on a CalDAV server must have at least 1 component (VTODO, VEVENT, VJOURNAL).', - 'node' => $this, - ]; - } - if (count(array_unique($componentTypes)) > 1) { - $warnings[] = [ - 'level' => 3, - 'message' => 'A calendar object on a CalDAV server may only have 1 type of component (VEVENT, VTODO or VJOURNAL).', - 'node' => $this, - ]; - } - - if (isset($this->METHOD)) { - $warnings[] = [ - 'level' => 3, - 'message' => 'A calendar object on a CalDAV server MUST NOT have a METHOD property.', - 'node' => $this, - ]; - } - } - - return $warnings; - } - - /** - * Returns all components with a specific UID value. - * - * @return array - */ - public function getByUID($uid) - { - return array_filter($this->getComponents(), function ($item) use ($uid) { - if (!$itemUid = $item->select('UID')) { - return false; - } - $itemUid = current($itemUid)->getValue(); - - return $uid === $itemUid; - }); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VCard.php b/lib/vendor/sabre/vobject/lib/Component/VCard.php deleted file mode 100644 index 82fab82..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VCard.php +++ /dev/null @@ -1,541 +0,0 @@ - VCard::class, - ]; - - /** - * List of value-types, and which classes they map to. - * - * @var array - */ - public static $valueMap = [ - 'BINARY' => VObject\Property\Binary::class, - 'BOOLEAN' => VObject\Property\Boolean::class, - 'CONTENT-ID' => VObject\Property\FlatText::class, // vCard 2.1 only - 'DATE' => VObject\Property\VCard\Date::class, - 'DATE-TIME' => VObject\Property\VCard\DateTime::class, - 'DATE-AND-OR-TIME' => VObject\Property\VCard\DateAndOrTime::class, // vCard only - 'FLOAT' => VObject\Property\FloatValue::class, - 'INTEGER' => VObject\Property\IntegerValue::class, - 'LANGUAGE-TAG' => VObject\Property\VCard\LanguageTag::class, - 'PHONE-NUMBER' => VObject\Property\VCard\PhoneNumber::class, // vCard 3.0 only - 'TIMESTAMP' => VObject\Property\VCard\TimeStamp::class, - 'TEXT' => VObject\Property\Text::class, - 'TIME' => VObject\Property\Time::class, - 'UNKNOWN' => VObject\Property\Unknown::class, // jCard / jCal-only. - 'URI' => VObject\Property\Uri::class, - 'URL' => VObject\Property\Uri::class, // vCard 2.1 only - 'UTC-OFFSET' => VObject\Property\UtcOffset::class, - ]; - - /** - * List of properties, and which classes they map to. - * - * @var array - */ - public static $propertyMap = [ - // vCard 2.1 properties and up - 'N' => VObject\Property\Text::class, - 'FN' => VObject\Property\FlatText::class, - 'PHOTO' => VObject\Property\Binary::class, - 'BDAY' => VObject\Property\VCard\DateAndOrTime::class, - 'ADR' => VObject\Property\Text::class, - 'LABEL' => VObject\Property\FlatText::class, // Removed in vCard 4.0 - 'TEL' => VObject\Property\FlatText::class, - 'EMAIL' => VObject\Property\FlatText::class, - 'MAILER' => VObject\Property\FlatText::class, // Removed in vCard 4.0 - 'GEO' => VObject\Property\FlatText::class, - 'TITLE' => VObject\Property\FlatText::class, - 'ROLE' => VObject\Property\FlatText::class, - 'LOGO' => VObject\Property\Binary::class, - // 'AGENT' => 'Sabre\\VObject\\Property\\', // Todo: is an embedded vCard. Probably rare, so - // not supported at the moment - 'ORG' => VObject\Property\Text::class, - 'NOTE' => VObject\Property\FlatText::class, - 'REV' => VObject\Property\VCard\TimeStamp::class, - 'SOUND' => VObject\Property\FlatText::class, - 'URL' => VObject\Property\Uri::class, - 'UID' => VObject\Property\FlatText::class, - 'VERSION' => VObject\Property\FlatText::class, - 'KEY' => VObject\Property\FlatText::class, - 'TZ' => VObject\Property\Text::class, - - // vCard 3.0 properties - 'CATEGORIES' => VObject\Property\Text::class, - 'SORT-STRING' => VObject\Property\FlatText::class, - 'PRODID' => VObject\Property\FlatText::class, - 'NICKNAME' => VObject\Property\Text::class, - 'CLASS' => VObject\Property\FlatText::class, // Removed in vCard 4.0 - - // rfc2739 properties - 'FBURL' => VObject\Property\Uri::class, - 'CAPURI' => VObject\Property\Uri::class, - 'CALURI' => VObject\Property\Uri::class, - 'CALADRURI' => VObject\Property\Uri::class, - - // rfc4770 properties - 'IMPP' => VObject\Property\Uri::class, - - // vCard 4.0 properties - 'SOURCE' => VObject\Property\Uri::class, - 'XML' => VObject\Property\FlatText::class, - 'ANNIVERSARY' => VObject\Property\VCard\DateAndOrTime::class, - 'CLIENTPIDMAP' => VObject\Property\Text::class, - 'LANG' => VObject\Property\VCard\LanguageTag::class, - 'GENDER' => VObject\Property\Text::class, - 'KIND' => VObject\Property\FlatText::class, - 'MEMBER' => VObject\Property\Uri::class, - 'RELATED' => VObject\Property\Uri::class, - - // rfc6474 properties - 'BIRTHPLACE' => VObject\Property\FlatText::class, - 'DEATHPLACE' => VObject\Property\FlatText::class, - 'DEATHDATE' => VObject\Property\VCard\DateAndOrTime::class, - - // rfc6715 properties - 'EXPERTISE' => VObject\Property\FlatText::class, - 'HOBBY' => VObject\Property\FlatText::class, - 'INTEREST' => VObject\Property\FlatText::class, - 'ORG-DIRECTORY' => VObject\Property\FlatText::class, - ]; - - /** - * Returns the current document type. - * - * @return int - */ - public function getDocumentType() - { - if (!$this->version) { - $version = (string) $this->VERSION; - - switch ($version) { - case '2.1': - $this->version = self::VCARD21; - break; - case '3.0': - $this->version = self::VCARD30; - break; - case '4.0': - $this->version = self::VCARD40; - break; - default: - // We don't want to cache the version if it's unknown, - // because we might get a version property in a bit. - return self::UNKNOWN; - } - } - - return $this->version; - } - - /** - * Converts the document to a different vcard version. - * - * Use one of the VCARD constants for the target. This method will return - * a copy of the vcard in the new version. - * - * At the moment the only supported conversion is from 3.0 to 4.0. - * - * If input and output version are identical, a clone is returned. - * - * @param int $target - * - * @return VCard - */ - public function convert($target) - { - $converter = new VObject\VCardConverter(); - - return $converter->convert($this, $target); - } - - /** - * VCards with version 2.1, 3.0 and 4.0 are found. - * - * If the VCARD doesn't know its version, 2.1 is assumed. - */ - const DEFAULT_VERSION = self::VCARD21; - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on) - * 2 - An inconsequential issue - * 3 - A severe issue. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $warnings = []; - - $versionMap = [ - self::VCARD21 => '2.1', - self::VCARD30 => '3.0', - self::VCARD40 => '4.0', - ]; - - $version = $this->select('VERSION'); - if (1 === count($version)) { - $version = (string) $this->VERSION; - if ('2.1' !== $version && '3.0' !== $version && '4.0' !== $version) { - $warnings[] = [ - 'level' => 3, - 'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.', - 'node' => $this, - ]; - if ($options & self::REPAIR) { - $this->VERSION = $versionMap[self::DEFAULT_VERSION]; - } - } - if ('2.1' === $version && ($options & self::PROFILE_CARDDAV)) { - $warnings[] = [ - 'level' => 3, - 'message' => 'CardDAV servers are not allowed to accept vCard 2.1.', - 'node' => $this, - ]; - } - } - $uid = $this->select('UID'); - if (0 === count($uid)) { - if ($options & self::PROFILE_CARDDAV) { - // Required for CardDAV - $warningLevel = 3; - $message = 'vCards on CardDAV servers MUST have a UID property.'; - } else { - // Not required for regular vcards - $warningLevel = 2; - $message = 'Adding a UID to a vCard property is recommended.'; - } - if ($options & self::REPAIR) { - $this->UID = VObject\UUIDUtil::getUUID(); - $warningLevel = 1; - } - $warnings[] = [ - 'level' => $warningLevel, - 'message' => $message, - 'node' => $this, - ]; - } - - $fn = $this->select('FN'); - if (1 !== count($fn)) { - $repaired = false; - if (($options & self::REPAIR) && 0 === count($fn)) { - // We're going to try to see if we can use the contents of the - // N property. - if (isset($this->N)) { - $value = explode(';', (string) $this->N); - if (isset($value[1]) && $value[1]) { - $this->FN = $value[1].' '.$value[0]; - } else { - $this->FN = $value[0]; - } - $repaired = true; - - // Otherwise, the ORG property may work - } elseif (isset($this->ORG)) { - $this->FN = (string) $this->ORG; - $repaired = true; - - // Otherwise, the NICKNAME property may work - } elseif (isset($this->NICKNAME)) { - $this->FN = (string) $this->NICKNAME; - $repaired = true; - - // Otherwise, the EMAIL property may work - } elseif (isset($this->EMAIL)) { - $this->FN = (string) $this->EMAIL; - $repaired = true; - } - } - $warnings[] = [ - 'level' => $repaired ? 1 : 3, - 'message' => 'The FN property must appear in the VCARD component exactly 1 time', - 'node' => $this, - ]; - } - - return array_merge( - parent::validate($options), - $warnings - ); - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'ADR' => '*', - 'ANNIVERSARY' => '?', - 'BDAY' => '?', - 'CALADRURI' => '*', - 'CALURI' => '*', - 'CATEGORIES' => '*', - 'CLIENTPIDMAP' => '*', - 'EMAIL' => '*', - 'FBURL' => '*', - 'IMPP' => '*', - 'GENDER' => '?', - 'GEO' => '*', - 'KEY' => '*', - 'KIND' => '?', - 'LANG' => '*', - 'LOGO' => '*', - 'MEMBER' => '*', - 'N' => '?', - 'NICKNAME' => '*', - 'NOTE' => '*', - 'ORG' => '*', - 'PHOTO' => '*', - 'PRODID' => '?', - 'RELATED' => '*', - 'REV' => '?', - 'ROLE' => '*', - 'SOUND' => '*', - 'SOURCE' => '*', - 'TEL' => '*', - 'TITLE' => '*', - 'TZ' => '*', - 'URL' => '*', - 'VERSION' => '1', - 'XML' => '*', - - // FN is commented out, because it's already handled by the - // validate function, which may also try to repair it. - // 'FN' => '+', - 'UID' => '?', - ]; - } - - /** - * Returns a preferred field. - * - * VCards can indicate whether a field such as ADR, TEL or EMAIL is - * preferred by specifying TYPE=PREF (vcard 2.1, 3) or PREF=x (vcard 4, x - * being a number between 1 and 100). - * - * If neither of those parameters are specified, the first is returned, if - * a field with that name does not exist, null is returned. - * - * @param string $fieldName - * - * @return VObject\Property|null - */ - public function preferred($propertyName) - { - $preferred = null; - $lastPref = 101; - foreach ($this->select($propertyName) as $field) { - $pref = 101; - if (isset($field['TYPE']) && $field['TYPE']->has('PREF')) { - $pref = 1; - } elseif (isset($field['PREF'])) { - $pref = $field['PREF']->getValue(); - } - - if ($pref < $lastPref || is_null($preferred)) { - $preferred = $field; - $lastPref = $pref; - } - } - - return $preferred; - } - - /** - * Returns a property with a specific TYPE value (ADR, TEL, or EMAIL). - * - * This function will return null if the property does not exist. If there are - * multiple properties with the same TYPE value, only one will be returned. - * - * @param string $propertyName - * @param string $type - * - * @return VObject\Property|null - */ - public function getByType($propertyName, $type) - { - foreach ($this->select($propertyName) as $field) { - if (isset($field['TYPE']) && $field['TYPE']->has($type)) { - return $field; - } - } - } - - /** - * This method should return a list of default property values. - * - * @return array - */ - protected function getDefaults() - { - return [ - 'VERSION' => '4.0', - 'PRODID' => '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN', - 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), - ]; - } - - /** - * This method returns an array, with the representation as it should be - * encoded in json. This is used to create jCard or jCal documents. - * - * @return array - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - // A vcard does not have sub-components, so we're overriding this - // method to remove that array element. - $properties = []; - - foreach ($this->children() as $child) { - $properties[] = $child->jsonSerialize(); - } - - return [ - strtolower($this->name), - $properties, - ]; - } - - /** - * This method serializes the data into XML. This is used to create xCard or - * xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - public function xmlSerialize(Xml\Writer $writer): void - { - $propertiesByGroup = []; - - foreach ($this->children() as $property) { - $group = $property->group; - - if (!isset($propertiesByGroup[$group])) { - $propertiesByGroup[$group] = []; - } - - $propertiesByGroup[$group][] = $property; - } - - $writer->startElement(strtolower($this->name)); - - foreach ($propertiesByGroup as $group => $properties) { - if (!empty($group)) { - $writer->startElement('group'); - $writer->writeAttribute('name', strtolower($group)); - } - - foreach ($properties as $property) { - switch ($property->name) { - case 'VERSION': - break; - - case 'XML': - $value = $property->getParts(); - $fragment = new Xml\Element\XmlFragment($value[0]); - $writer->write($fragment); - break; - - default: - $property->xmlSerialize($writer); - break; - } - } - - if (!empty($group)) { - $writer->endElement(); - } - } - - $writer->endElement(); - } - - /** - * Returns the default class for a property name. - * - * @param string $propertyName - * - * @return string - */ - public function getClassNameForPropertyName($propertyName) - { - $className = parent::getClassNameForPropertyName($propertyName); - - // In vCard 4, BINARY no longer exists, and we need URI instead. - if (VObject\Property\Binary::class == $className && self::VCARD40 === $this->getDocumentType()) { - return VObject\Property\Uri::class; - } - - return $className; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VEvent.php b/lib/vendor/sabre/vobject/lib/Component/VEvent.php deleted file mode 100644 index a385a09..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VEvent.php +++ /dev/null @@ -1,140 +0,0 @@ -RRULE || $this->RDATE) { - try { - $it = new EventIterator($this, null, $start->getTimezone()); - } catch (NoInstancesException $e) { - // If we've caught this exception, there are no instances - // for the event that fall into the specified time-range. - return false; - } - - $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($start->getTimezone()); - if (isset($this->DTEND)) { - // The DTEND property is considered non inclusive. So for a 3 day - // event in july, dtstart and dtend would have to be July 1st and - // July 4th respectively. - // - // See: - // http://tools.ietf.org/html/rfc5545#page-54 - $effectiveEnd = $this->DTEND->getDateTime($end->getTimezone()); - } elseif (isset($this->DURATION)) { - $effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION)); - } elseif (!$this->DTSTART->hasTime()) { - $effectiveEnd = $effectiveStart->modify('+1 day'); - } else { - $effectiveEnd = $effectiveStart; - } - - return - ($start < $effectiveEnd) && ($end > $effectiveStart) - ; - } - - /** - * This method should return a list of default property values. - * - * @return array - */ - protected function getDefaults() - { - return [ - 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), - 'DTSTAMP' => gmdate('Ymd\\THis\\Z'), - ]; - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - $hasMethod = isset($this->parent->METHOD); - - return [ - 'UID' => 1, - 'DTSTAMP' => 1, - 'DTSTART' => $hasMethod ? '?' : '1', - 'CLASS' => '?', - 'CREATED' => '?', - 'DESCRIPTION' => '?', - 'GEO' => '?', - 'LAST-MODIFIED' => '?', - 'LOCATION' => '?', - 'ORGANIZER' => '?', - 'PRIORITY' => '?', - 'SEQUENCE' => '?', - 'STATUS' => '?', - 'SUMMARY' => '?', - 'TRANSP' => '?', - 'URL' => '?', - 'RECURRENCE-ID' => '?', - 'RRULE' => '?', - 'DTEND' => '?', - 'DURATION' => '?', - - 'ATTACH' => '*', - 'ATTENDEE' => '*', - 'CATEGORIES' => '*', - 'COMMENT' => '*', - 'CONTACT' => '*', - 'EXDATE' => '*', - 'REQUEST-STATUS' => '*', - 'RELATED-TO' => '*', - 'RESOURCES' => '*', - 'RDATE' => '*', - ]; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VFreeBusy.php b/lib/vendor/sabre/vobject/lib/Component/VFreeBusy.php deleted file mode 100644 index fef418b..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VFreeBusy.php +++ /dev/null @@ -1,93 +0,0 @@ -select('FREEBUSY') as $freebusy) { - // We are only interested in FBTYPE=BUSY (the default), - // FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE. - if (isset($freebusy['FBTYPE']) && 'BUSY' !== strtoupper(substr((string) $freebusy['FBTYPE'], 0, 4))) { - continue; - } - - // The freebusy component can hold more than 1 value, separated by - // commas. - $periods = explode(',', (string) $freebusy); - - foreach ($periods as $period) { - // Every period is formatted as [start]/[end]. The start is an - // absolute UTC time, the end may be an absolute UTC time, or - // duration (relative) value. - list($busyStart, $busyEnd) = explode('/', $period); - - $busyStart = VObject\DateTimeParser::parse($busyStart); - $busyEnd = VObject\DateTimeParser::parse($busyEnd); - if ($busyEnd instanceof \DateInterval) { - $busyEnd = $busyStart->add($busyEnd); - } - - if ($start < $busyEnd && $end > $busyStart) { - return false; - } - } - } - - return true; - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'UID' => 1, - 'DTSTAMP' => 1, - - 'CONTACT' => '?', - 'DTSTART' => '?', - 'DTEND' => '?', - 'ORGANIZER' => '?', - 'URL' => '?', - - 'ATTENDEE' => '*', - 'COMMENT' => '*', - 'FREEBUSY' => '*', - 'REQUEST-STATUS' => '*', - ]; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VJournal.php b/lib/vendor/sabre/vobject/lib/Component/VJournal.php deleted file mode 100644 index 9b7f1b8..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VJournal.php +++ /dev/null @@ -1,101 +0,0 @@ -DTSTART) ? $this->DTSTART->getDateTime() : null; - if ($dtstart) { - $effectiveEnd = $dtstart; - if (!$this->DTSTART->hasTime()) { - $effectiveEnd = $effectiveEnd->modify('+1 day'); - } - - return $start <= $effectiveEnd && $end > $dtstart; - } - - return false; - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'UID' => 1, - 'DTSTAMP' => 1, - - 'CLASS' => '?', - 'CREATED' => '?', - 'DTSTART' => '?', - 'LAST-MODIFIED' => '?', - 'ORGANIZER' => '?', - 'RECURRENCE-ID' => '?', - 'SEQUENCE' => '?', - 'STATUS' => '?', - 'SUMMARY' => '?', - 'URL' => '?', - - 'RRULE' => '?', - - 'ATTACH' => '*', - 'ATTENDEE' => '*', - 'CATEGORIES' => '*', - 'COMMENT' => '*', - 'CONTACT' => '*', - 'DESCRIPTION' => '*', - 'EXDATE' => '*', - 'RELATED-TO' => '*', - 'RDATE' => '*', - ]; - } - - /** - * This method should return a list of default property values. - * - * @return array - */ - protected function getDefaults() - { - return [ - 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), - 'DTSTAMP' => gmdate('Ymd\\THis\\Z'), - ]; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VTimeZone.php b/lib/vendor/sabre/vobject/lib/Component/VTimeZone.php deleted file mode 100644 index 21c0623..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VTimeZone.php +++ /dev/null @@ -1,63 +0,0 @@ -TZID, $this->root); - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'TZID' => 1, - - 'LAST-MODIFIED' => '?', - 'TZURL' => '?', - - // At least 1 STANDARD or DAYLIGHT must appear. - // - // The validator is not specific yet to pick this up, so these - // rules are too loose. - 'STANDARD' => '*', - 'DAYLIGHT' => '*', - ]; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Component/VTodo.php b/lib/vendor/sabre/vobject/lib/Component/VTodo.php deleted file mode 100644 index 6f022ba..0000000 --- a/lib/vendor/sabre/vobject/lib/Component/VTodo.php +++ /dev/null @@ -1,181 +0,0 @@ -DTSTART) ? $this->DTSTART->getDateTime() : null; - $duration = isset($this->DURATION) ? 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 = $dtstart->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; - } - - /** - * A simple list of validation rules. - * - * This is simply a list of properties, and how many times they either - * must or must not appear. - * - * Possible values per property: - * * 0 - Must not appear. - * * 1 - Must appear exactly once. - * * + - Must appear at least once. - * * * - Can appear any number of times. - * * ? - May appear, but not more than once. - * - * @var array - */ - public function getValidationRules() - { - return [ - 'UID' => 1, - 'DTSTAMP' => 1, - - 'CLASS' => '?', - 'COMPLETED' => '?', - 'CREATED' => '?', - 'DESCRIPTION' => '?', - 'DTSTART' => '?', - 'GEO' => '?', - 'LAST-MODIFIED' => '?', - 'LOCATION' => '?', - 'ORGANIZER' => '?', - 'PERCENT' => '?', - 'PRIORITY' => '?', - 'RECURRENCE-ID' => '?', - 'SEQUENCE' => '?', - 'STATUS' => '?', - 'SUMMARY' => '?', - 'URL' => '?', - - 'RRULE' => '?', - 'DUE' => '?', - 'DURATION' => '?', - - 'ATTACH' => '*', - 'ATTENDEE' => '*', - 'CATEGORIES' => '*', - 'COMMENT' => '*', - 'CONTACT' => '*', - 'EXDATE' => '*', - 'REQUEST-STATUS' => '*', - 'RELATED-TO' => '*', - 'RESOURCES' => '*', - 'RDATE' => '*', - ]; - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on) - * 2 - An inconsequential issue - * 3 - A severe issue. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $result = parent::validate($options); - if (isset($this->DUE) && isset($this->DTSTART)) { - $due = $this->DUE; - $dtStart = $this->DTSTART; - - if ($due->getValueType() !== $dtStart->getValueType()) { - $result[] = [ - 'level' => 3, - 'message' => 'The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART', - 'node' => $due, - ]; - } elseif ($due->getDateTime() < $dtStart->getDateTime()) { - $result[] = [ - 'level' => 3, - 'message' => 'DUE must occur after DTSTART', - 'node' => $due, - ]; - } - } - - return $result; - } - - /** - * This method should return a list of default property values. - * - * @return array - */ - protected function getDefaults() - { - return [ - 'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(), - 'DTSTAMP' => date('Ymd\\THis\\Z'), - ]; - } -} diff --git a/lib/vendor/sabre/vobject/lib/DateTimeParser.php b/lib/vendor/sabre/vobject/lib/DateTimeParser.php deleted file mode 100644 index 69072ef..0000000 --- a/lib/vendor/sabre/vobject/lib/DateTimeParser.php +++ /dev/null @@ -1,560 +0,0 @@ -\+|-)?P((?\d+)W)?((?\d+)D)?(T((?\d+)H)?((?\d+)M)?((?\d+)S)?)?$/', $duration, $matches); - if (!$result) { - throw new InvalidDataException('The supplied iCalendar duration value is incorrect: '.$duration); - } - - if (!$asString) { - $invert = false; - - if (isset($matches['plusminus']) && '-' === $matches['plusminus']) { - $invert = true; - } - - $parts = [ - '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'; - } - } - - if ('P' === $duration) { - $duration = 'PT0S'; - } - - $iv = new DateInterval($duration); - - if ($invert) { - $iv->invert = true; - } - - return $iv; - } - - $parts = [ - '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); - - if ('+' === $newDur) { - $newDur = '+0 seconds'; - } - - return $newDur; - } - - /** - * Parses either a Date or DateTime, or Duration value. - * - * @param string $date - * @param DateTimeZone|string $referenceTz - * - * @return DateTimeImmutable|DateInterval - */ - public static function parse($date, $referenceTz = null) - { - if ('P' === $date[0] || ('-' === $date[0] && 'P' === $date[1])) { - return self::parseDuration($date); - } elseif (8 === strlen($date)) { - return self::parseDate($date, $referenceTz); - } else { - return self::parseDateTime($date, $referenceTz); - } - } - - /** - * This method parses a vCard date and or time value. - * - * This can be used for the DATE, DATE-TIME, TIMESTAMP and - * DATE-AND-OR-TIME value. - * - * This method returns an array, not a DateTime value. - * - * The elements in the array are in the following order: - * year, month, date, hour, minute, second, timezone - * - * Almost any part of the string may be omitted. It's for example legal to - * just specify seconds, leave out the year, etc. - * - * Timezone is either returned as 'Z' or as '+0800' - * - * For any non-specified values null is returned. - * - * List of date formats that are supported: - * YYYY - * YYYY-MM - * YYYYMMDD - * --MMDD - * ---DD - * - * YYYY-MM-DD - * --MM-DD - * ---DD - * - * List of supported time formats: - * - * HH - * HHMM - * HHMMSS - * -MMSS - * --SS - * - * HH - * HH:MM - * HH:MM:SS - * -MM:SS - * --SS - * - * A full basic-format date-time string looks like : - * 20130603T133901 - * - * A full extended-format date-time string looks like : - * 2013-06-03T13:39:01 - * - * Times may be postfixed by a timezone offset. This can be either 'Z' for - * UTC, or a string like -0500 or +1100. - * - * @param string $date - * - * @return array - */ - public static function parseVCardDateTime($date) - { - $regex = '/^ - (?: # date part - (?: - (?: (? [0-9]{4}) (?: -)?| --) - (? [0-9]{2})? - |---) - (? [0-9]{2})? - )? - (?:T # time part - (? [0-9]{2} | -) - (? [0-9]{2} | -)? - (? [0-9]{2})? - - (?: \.[0-9]{3})? # milliseconds - (?P # timezone offset - - Z | (?: \+|-)(?: [0-9]{4}) - - )? - - )? - $/x'; - - if (!preg_match($regex, $date, $matches)) { - // Attempting to parse the extended format. - $regex = '/^ - (?: # date part - (?: (? [0-9]{4}) - | -- ) - (? [0-9]{2}) - - (? [0-9]{2}) - )? - (?:T # time part - - (?: (? [0-9]{2}) : | -) - (?: (? [0-9]{2}) : | -)? - (? [0-9]{2})? - - (?: \.[0-9]{3})? # milliseconds - (?P # timezone offset - - Z | (?: \+|-)(?: [0-9]{2}:[0-9]{2}) - - )? - - )? - $/x'; - - if (!preg_match($regex, $date, $matches)) { - throw new InvalidDataException('Invalid vCard date-time string: '.$date); - } - } - $parts = [ - 'year', - 'month', - 'date', - 'hour', - 'minute', - 'second', - 'timezone', - ]; - - $result = []; - foreach ($parts as $part) { - if (empty($matches[$part])) { - $result[$part] = null; - } elseif ('-' === $matches[$part] || '--' === $matches[$part]) { - $result[$part] = null; - } else { - $result[$part] = $matches[$part]; - } - } - - return $result; - } - - /** - * This method parses a vCard TIME value. - * - * This method returns an array, not a DateTime value. - * - * The elements in the array are in the following order: - * hour, minute, second, timezone - * - * Almost any part of the string may be omitted. It's for example legal to - * just specify seconds, leave out the hour etc. - * - * Timezone is either returned as 'Z' or as '+08:00' - * - * For any non-specified values null is returned. - * - * List of supported time formats: - * - * HH - * HHMM - * HHMMSS - * -MMSS - * --SS - * - * HH - * HH:MM - * HH:MM:SS - * -MM:SS - * --SS - * - * A full basic-format time string looks like : - * 133901 - * - * A full extended-format time string looks like : - * 13:39:01 - * - * Times may be postfixed by a timezone offset. This can be either 'Z' for - * UTC, or a string like -0500 or +11:00. - * - * @param string $date - * - * @return array - */ - public static function parseVCardTime($date) - { - $regex = '/^ - (? [0-9]{2} | -) - (? [0-9]{2} | -)? - (? [0-9]{2})? - - (?: \.[0-9]{3})? # milliseconds - (?P # timezone offset - - Z | (?: \+|-)(?: [0-9]{4}) - - )? - $/x'; - - if (!preg_match($regex, $date, $matches)) { - // Attempting to parse the extended format. - $regex = '/^ - (?: (? [0-9]{2}) : | -) - (?: (? [0-9]{2}) : | -)? - (? [0-9]{2})? - - (?: \.[0-9]{3})? # milliseconds - (?P # timezone offset - - Z | (?: \+|-)(?: [0-9]{2}:[0-9]{2}) - - )? - $/x'; - - if (!preg_match($regex, $date, $matches)) { - throw new InvalidDataException('Invalid vCard time string: '.$date); - } - } - $parts = [ - 'hour', - 'minute', - 'second', - 'timezone', - ]; - - $result = []; - foreach ($parts as $part) { - if (empty($matches[$part])) { - $result[$part] = null; - } elseif ('-' === $matches[$part]) { - $result[$part] = null; - } else { - $result[$part] = $matches[$part]; - } - } - - return $result; - } - - /** - * This method parses a vCard date and or time value. - * - * This can be used for the DATE, DATE-TIME and - * DATE-AND-OR-TIME value. - * - * This method returns an array, not a DateTime value. - * The elements in the array are in the following order: - * year, month, date, hour, minute, second, timezone - * Almost any part of the string may be omitted. It's for example legal to - * just specify seconds, leave out the year, etc. - * - * Timezone is either returned as 'Z' or as '+0800' - * - * For any non-specified values null is returned. - * - * List of date formats that are supported: - * 20150128 - * 2015-01 - * --01 - * --0128 - * ---28 - * - * List of supported time formats: - * 13 - * 1353 - * 135301 - * -53 - * -5301 - * --01 (unreachable, see the tests) - * --01Z - * --01+1234 - * - * List of supported date-time formats: - * 20150128T13 - * --0128T13 - * ---28T13 - * ---28T1353 - * ---28T135301 - * ---28T13Z - * ---28T13+1234 - * - * See the regular expressions for all the possible patterns. - * - * Times may be postfixed by a timezone offset. This can be either 'Z' for - * UTC, or a string like -0500 or +1100. - * - * @param string $date - * - * @return array - */ - public static function parseVCardDateAndOrTime($date) - { - // \d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d - $valueDate = '/^(?J)(?:'. - '(?\d{4})(?\d\d)(?\d\d)'. - '|(?\d{4})-(?\d\d)'. - '|--(?\d\d)(?\d\d)?'. - '|---(?\d\d)'. - ')$/'; - - // (\d\d(\d\d(\d\d)?)?|-\d\d(\d\d)?|--\d\d)(Z|[+\-]\d\d(\d\d)?)? - $valueTime = '/^(?J)(?:'. - '((?\d\d)((?\d\d)(?\d\d)?)?'. - '|-(?\d\d)(?\d\d)?'. - '|--(?\d\d))'. - '(?(Z|[+\-]\d\d(\d\d)?))?'. - ')$/'; - - // (\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?(Z|[+\-]\d\d(\d\d?)? - $valueDateTime = '/^(?:'. - '((?\d{4})(?\d\d)(?\d\d)'. - '|--(?\d\d)(?\d\d)'. - '|---(?\d\d))'. - 'T'. - '(?\d\d)((?\d\d)(?\d\d)?)?'. - '(?(Z|[+\-]\d\d(\d\d?)))?'. - ')$/'; - - // date-and-or-time is date | date-time | time - // in this strict order. - - if (0 === preg_match($valueDate, $date, $matches) - && 0 === preg_match($valueDateTime, $date, $matches) - && 0 === preg_match($valueTime, $date, $matches)) { - throw new InvalidDataException('Invalid vCard date-time string: '.$date); - } - - $parts = [ - 'year' => null, - 'month' => null, - 'date' => null, - 'hour' => null, - 'minute' => null, - 'second' => null, - 'timezone' => null, - ]; - - // The $valueDateTime expression has a bug with (?J) so we simulate it. - $parts['date0'] = &$parts['date']; - $parts['date1'] = &$parts['date']; - $parts['date2'] = &$parts['date']; - $parts['month0'] = &$parts['month']; - $parts['month1'] = &$parts['month']; - $parts['year0'] = &$parts['year']; - - foreach ($parts as $part => &$value) { - if (!empty($matches[$part])) { - $value = $matches[$part]; - } - } - - unset($parts['date0']); - unset($parts['date1']); - unset($parts['date2']); - unset($parts['month0']); - unset($parts['month1']); - unset($parts['year0']); - - return $parts; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Document.php b/lib/vendor/sabre/vobject/lib/Document.php deleted file mode 100644 index 36f20dd..0000000 --- a/lib/vendor/sabre/vobject/lib/Document.php +++ /dev/null @@ -1,269 +0,0 @@ -value syntax, in which case - * properties will automatically be created, or you can just pass a list of - * Component and Property object. - * - * By default, a set of sensible values will be added to the component. For - * an iCalendar object, this may be something like CALSCALE:GREGORIAN. To - * ensure that this does not happen, set $defaults to false. - * - * @param string $name - * @param array $children - * @param bool $defaults - * - * @return Component - */ - public function createComponent($name, ?array $children = null, $defaults = true) - { - $name = strtoupper($name); - $class = Component::class; - - if (isset(static::$componentMap[$name])) { - $class = static::$componentMap[$name]; - } - if (is_null($children)) { - $children = []; - } - - return new $class($this, $name, $children, $defaults); - } - - /** - * Factory method for creating new properties. - * - * This method automatically searches for the correct property class, based - * on its name. - * - * You can specify the parameters either in key=>value syntax, in which case - * parameters will automatically be created, or you can just pass a list of - * Parameter objects. - * - * @param string $name - * @param mixed $value - * @param array $parameters - * @param string $valueType Force a specific valuetype, such as URI or TEXT - */ - public function createProperty($name, $value = null, ?array $parameters = null, $valueType = null, ?int $lineIndex = null, ?string $lineString = null): Property - { - // If there's a . in the name, it means it's prefixed by a groupname. - if (false !== ($i = strpos($name, '.'))) { - $group = substr($name, 0, $i); - $name = strtoupper(substr($name, $i + 1)); - } else { - $name = strtoupper($name); - $group = null; - } - - $class = null; - - // If a VALUE parameter is supplied, we have to use that - // According to https://datatracker.ietf.org/doc/html/rfc5545#section-3.2.20 - // If the property's value is the default value type, then this - // parameter need not be specified. However, if the property's - // default value type is overridden by some other allowable value - // type, then this parameter MUST be specified. - if (!$valueType) { - $valueType = $parameters['VALUE'] ?? null; - } - - if ($valueType) { - // The valueType argument comes first to figure out the correct - // class. - $class = $this->getClassNameForPropertyValue($valueType); - } - - // If the value parameter is not set or set to something we do not recognize - // we do not attempt to interpret or parse the datass value as specified in - // https://datatracker.ietf.org/doc/html/rfc5545#section-3.2.20 - // So when we so far did not get a class-name, we use the default for the property - if (is_null($class)) { - $class = $this->getClassNameForPropertyName($name); - } - - if (is_null($parameters)) { - $parameters = []; - } - - return new $class($this, $name, $value, $parameters, $group, $lineIndex, $lineString); - } - - /** - * This method returns a full class-name for a value parameter. - * - * For instance, DTSTART may have VALUE=DATE. In that case we will look in - * our valueMap table and return the appropriate class name. - * - * This method returns null if we don't have a specialized class. - * - * @param string $valueParam - * - * @return string|null - */ - public function getClassNameForPropertyValue($valueParam) - { - $valueParam = strtoupper($valueParam); - if (isset(static::$valueMap[$valueParam])) { - return static::$valueMap[$valueParam]; - } - } - - /** - * Returns the default class for a property name. - * - * @param string $propertyName - * - * @return string - */ - public function getClassNameForPropertyName($propertyName) - { - if (isset(static::$propertyMap[$propertyName])) { - return static::$propertyMap[$propertyName]; - } else { - return Property\Unknown::class; - } - } -} diff --git a/lib/vendor/sabre/vobject/lib/ElementList.php b/lib/vendor/sabre/vobject/lib/ElementList.php deleted file mode 100644 index e419d48..0000000 --- a/lib/vendor/sabre/vobject/lib/ElementList.php +++ /dev/null @@ -1,52 +0,0 @@ -vevent where there's multiple VEVENT objects. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class ElementList extends ArrayIterator -{ - /* {{{ ArrayAccess Interface */ - - /** - * Sets an item through ArrayAccess. - * - * @param int $offset - * @param mixed $value - * - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) - { - throw new LogicException('You can not add new objects to an ElementList'); - } - - /** - * Sets an item through ArrayAccess. - * - * This method just forwards the request to the inner iterator - * - * @param int $offset - * - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) - { - throw new LogicException('You can not remove objects from an ElementList'); - } - - /* }}} */ -} diff --git a/lib/vendor/sabre/vobject/lib/EofException.php b/lib/vendor/sabre/vobject/lib/EofException.php deleted file mode 100644 index 837af7e..0000000 --- a/lib/vendor/sabre/vobject/lib/EofException.php +++ /dev/null @@ -1,15 +0,0 @@ -start = $start; - $this->end = $end; - $this->data = []; - - $this->data[] = [ - 'start' => $this->start, - 'end' => $this->end, - 'type' => 'FREE', - ]; - } - - /** - * Adds free or busytime to the data. - * - * @param int $start - * @param int $end - * @param string $type FREE, BUSY, BUSY-UNAVAILABLE or BUSY-TENTATIVE - */ - public function add($start, $end, $type) - { - if ($start > $this->end || $end < $this->start) { - // This new data is outside our timerange. - return; - } - - if ($start < $this->start) { - // The item starts before our requested time range - $start = $this->start; - } - if ($end > $this->end) { - // The item ends after our requested time range - $end = $this->end; - } - - // Finding out where we need to insert the new item. - $currentIndex = 0; - while ($start > $this->data[$currentIndex]['end']) { - ++$currentIndex; - } - - // The standard insertion point will be one _after_ the first - // overlapping item. - $insertStartIndex = $currentIndex + 1; - - $newItem = [ - 'start' => $start, - 'end' => $end, - 'type' => $type, - ]; - - $precedingItem = $this->data[$insertStartIndex - 1]; - if ($this->data[$insertStartIndex - 1]['start'] === $start) { - // The old item starts at the exact same point as the new item. - --$insertStartIndex; - } - - // Now we know where to insert the item, we need to know where it - // starts overlapping with items on the tail end. We need to start - // looking one item before the insertStartIndex, because it's possible - // that the new item 'sits inside' the previous old item. - if ($insertStartIndex > 0) { - $currentIndex = $insertStartIndex - 1; - } else { - $currentIndex = 0; - } - - while ($end > $this->data[$currentIndex]['end']) { - ++$currentIndex; - } - - // What we are about to insert into the array - $newItems = [ - $newItem, - ]; - - // This is the amount of items that are completely overwritten by the - // new item. - $itemsToDelete = $currentIndex - $insertStartIndex; - if ($this->data[$currentIndex]['end'] <= $end) { - ++$itemsToDelete; - } - - // If itemsToDelete was -1, it means that the newly inserted item is - // actually sitting inside an existing one. This means we need to split - // the item at the current position in two and insert the new item in - // between. - if (-1 === $itemsToDelete) { - $itemsToDelete = 0; - if ($newItem['end'] < $precedingItem['end']) { - $newItems[] = [ - 'start' => $newItem['end'] + 1, - 'end' => $precedingItem['end'], - 'type' => $precedingItem['type'], - ]; - } - } - - array_splice( - $this->data, - $insertStartIndex, - $itemsToDelete, - $newItems - ); - - $doMerge = false; - $mergeOffset = $insertStartIndex; - $mergeItem = $newItem; - $mergeDelete = 1; - - if (isset($this->data[$insertStartIndex - 1])) { - // Updating the start time of the previous item. - $this->data[$insertStartIndex - 1]['end'] = $start; - - // If the previous and the current are of the same type, we can - // merge them into one item. - if ($this->data[$insertStartIndex - 1]['type'] === $this->data[$insertStartIndex]['type']) { - $doMerge = true; - --$mergeOffset; - ++$mergeDelete; - $mergeItem['start'] = $this->data[$insertStartIndex - 1]['start']; - } - } - if (isset($this->data[$insertStartIndex + 1])) { - // Updating the start time of the next item. - $this->data[$insertStartIndex + 1]['start'] = $end; - - // If the next and the current are of the same type, we can - // merge them into one item. - if ($this->data[$insertStartIndex + 1]['type'] === $this->data[$insertStartIndex]['type']) { - $doMerge = true; - ++$mergeDelete; - $mergeItem['end'] = $this->data[$insertStartIndex + 1]['end']; - } - } - if ($doMerge) { - array_splice( - $this->data, - $mergeOffset, - $mergeDelete, - [$mergeItem] - ); - } - } - - public function getData() - { - return $this->data; - } -} diff --git a/lib/vendor/sabre/vobject/lib/FreeBusyGenerator.php b/lib/vendor/sabre/vobject/lib/FreeBusyGenerator.php deleted file mode 100644 index 56ae166..0000000 --- a/lib/vendor/sabre/vobject/lib/FreeBusyGenerator.php +++ /dev/null @@ -1,549 +0,0 @@ -setTimeRange($start, $end); - - if ($objects) { - $this->setObjects($objects); - } - if (is_null($timeZone)) { - $timeZone = new DateTimeZone('UTC'); - } - $this->setTimeZone($timeZone); - } - - /** - * 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. - */ - public function setBaseObject(Document $vcalendar) - { - $this->baseObject = $vcalendar; - } - - /** - * Sets a VAVAILABILITY document. - */ - public function setVAvailability(Document $vcalendar) - { - $this->vavailability = $vcalendar; - } - - /** - * Sets the input objects. - * - * You must either specify a vcalendar object as a string, or as the parse - * Component. - * It's also possible to specify multiple objects as an array. - * - * @param mixed $objects - */ - public function setObjects($objects) - { - if (!is_array($objects)) { - $objects = [$objects]; - } - - $this->objects = []; - foreach ($objects as $object) { - if (is_string($object) || is_resource($object)) { - $this->objects[] = Reader::read($object); - } elseif ($object instanceof 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 DateTimeInterface $start - * @param DateTimeInterface $end - */ - public function setTimeRange(?DateTimeInterface $start = null, ?DateTimeInterface $end = null) - { - if (!$start) { - $start = new DateTimeImmutable(Settings::$minDate); - } - if (!$end) { - $end = new DateTimeImmutable(Settings::$maxDate); - } - $this->start = $start; - $this->end = $end; - } - - /** - * Sets the reference timezone for floating times. - */ - public function setTimeZone(DateTimeZone $timeZone) - { - $this->timeZone = $timeZone; - } - - /** - * Parses the input data and returns a correct VFREEBUSY object, wrapped in - * a VCALENDAR. - * - * @return Component - */ - public function getResult() - { - $fbData = new FreeBusyData( - $this->start->getTimeStamp(), - $this->end->getTimeStamp() - ); - if ($this->vavailability) { - $this->calculateAvailability($fbData, $this->vavailability); - } - - $this->calculateBusy($fbData, $this->objects); - - return $this->generateFreeBusyCalendar($fbData); - } - - /** - * This method takes a VAVAILABILITY component and figures out all the - * available times. - */ - protected function calculateAvailability(FreeBusyData $fbData, VCalendar $vavailability) - { - $vavailComps = iterator_to_array($vavailability->VAVAILABILITY); - usort( - $vavailComps, - function ($a, $b) { - // We need to order the components by priority. Priority 1 - // comes first, up until priority 9. Priority 0 comes after - // priority 9. No priority implies priority 0. - // - // Yes, I'm serious. - $priorityA = isset($a->PRIORITY) ? (int) $a->PRIORITY->getValue() : 0; - $priorityB = isset($b->PRIORITY) ? (int) $b->PRIORITY->getValue() : 0; - - if (0 === $priorityA) { - $priorityA = 10; - } - if (0 === $priorityB) { - $priorityB = 10; - } - - return $priorityA - $priorityB; - } - ); - - // Now we go over all the VAVAILABILITY components and figure if - // there's any we don't need to consider. - // - // This is can be because of one of two reasons: either the - // VAVAILABILITY component falls outside the time we are interested in, - // or a different VAVAILABILITY component with a higher priority has - // already completely covered the time-range. - $old = $vavailComps; - $new = []; - - foreach ($old as $vavail) { - list($compStart, $compEnd) = $vavail->getEffectiveStartEnd(); - - // We don't care about datetimes that are earlier or later than the - // start and end of the freebusy report, so this gets normalized - // first. - if (is_null($compStart) || $compStart < $this->start) { - $compStart = $this->start; - } - if (is_null($compEnd) || $compEnd > $this->end) { - $compEnd = $this->end; - } - - // If the item fell out of the timerange, we can just skip it. - if ($compStart > $this->end || $compEnd < $this->start) { - continue; - } - - // Going through our existing list of components to see if there's - // a higher priority component that already fully covers this one. - foreach ($new as $higherVavail) { - list($higherStart, $higherEnd) = $higherVavail->getEffectiveStartEnd(); - if ( - (is_null($higherStart) || $higherStart < $compStart) && - (is_null($higherEnd) || $higherEnd > $compEnd) - ) { - // Component is fully covered by a higher priority - // component. We can skip this component. - continue 2; - } - } - - // We're keeping it! - $new[] = $vavail; - } - - // Lastly, we need to traverse the remaining components and fill in the - // freebusydata slots. - // - // We traverse the components in reverse, because we want the higher - // priority components to override the lower ones. - foreach (array_reverse($new) as $vavail) { - $busyType = isset($vavail->BUSYTYPE) ? strtoupper($vavail->BUSYTYPE) : 'BUSY-UNAVAILABLE'; - list($vavailStart, $vavailEnd) = $vavail->getEffectiveStartEnd(); - - // Making the component size no larger than the requested free-busy - // report range. - if (!$vavailStart || $vavailStart < $this->start) { - $vavailStart = $this->start; - } - if (!$vavailEnd || $vavailEnd > $this->end) { - $vavailEnd = $this->end; - } - - // Marking the entire time range of the VAVAILABILITY component as - // busy. - $fbData->add( - $vavailStart->getTimeStamp(), - $vavailEnd->getTimeStamp(), - $busyType - ); - - // Looping over the AVAILABLE components. - if (isset($vavail->AVAILABLE)) { - foreach ($vavail->AVAILABLE as $available) { - list($availStart, $availEnd) = $available->getEffectiveStartEnd(); - $fbData->add( - $availStart->getTimeStamp(), - $availEnd->getTimeStamp(), - 'FREE' - ); - - if ($available->RRULE) { - // Our favourite thing: recurrence!! - - $rruleIterator = new Recur\RRuleIterator( - $available->RRULE->getValue(), - $availStart - ); - $rruleIterator->fastForward($vavailStart); - - $startEndDiff = $availStart->diff($availEnd); - - while ($rruleIterator->valid()) { - $recurStart = $rruleIterator->current(); - $recurEnd = $recurStart->add($startEndDiff); - - if ($recurStart > $vavailEnd) { - // We're beyond the legal timerange. - break; - } - - if ($recurEnd > $vavailEnd) { - // Truncating the end if it exceeds the - // VAVAILABILITY end. - $recurEnd = $vavailEnd; - } - - $fbData->add( - $recurStart->getTimeStamp(), - $recurEnd->getTimeStamp(), - 'FREE' - ); - - $rruleIterator->next(); - } - } - } - } - } - } - - /** - * This method takes an array of iCalendar objects and applies its busy - * times on fbData. - * - * @param VCalendar[] $objects - */ - protected function calculateBusy(FreeBusyData $fbData, array $objects) - { - foreach ($objects as $key => $object) { - foreach ($object->getBaseComponents() as $component) { - switch ($component->name) { - case 'VEVENT': - $FBTYPE = 'BUSY'; - if (isset($component->TRANSP) && ('TRANSPARENT' === strtoupper($component->TRANSP))) { - break; - } - if (isset($component->STATUS)) { - $status = strtoupper($component->STATUS); - if ('CANCELLED' === $status) { - break; - } - if ('TENTATIVE' === $status) { - $FBTYPE = 'BUSY-TENTATIVE'; - } - } - - $times = []; - - if ($component->RRULE) { - try { - $iterator = new EventIterator($object, (string) $component->UID, $this->timeZone); - } catch (NoInstancesException $e) { - // This event is recurring, but it doesn't have a single - // instance. We are skipping this event from the output - // entirely. - unset($this->objects[$key]); - break; - } - - if ($this->start) { - $iterator->fastForward($this->start); - } - - $maxRecurrences = Settings::$maxRecurrences; - - while ($iterator->valid() && --$maxRecurrences) { - $startTime = $iterator->getDTStart(); - if ($this->end && $startTime > $this->end) { - break; - } - $times[] = [ - $iterator->getDTStart(), - $iterator->getDTEnd(), - ]; - - $iterator->next(); - } - } else { - $startTime = $component->DTSTART->getDateTime($this->timeZone); - if ($this->end && $startTime > $this->end) { - break; - } - $endTime = null; - if (isset($component->DTEND)) { - $endTime = $component->DTEND->getDateTime($this->timeZone); - } elseif (isset($component->DURATION)) { - $duration = DateTimeParser::parseDuration((string) $component->DURATION); - $endTime = clone $startTime; - $endTime = $endTime->add($duration); - } elseif (!$component->DTSTART->hasTime()) { - $endTime = clone $startTime; - $endTime = $endTime->modify('+1 day'); - } else { - // The event had no duration (0 seconds) - break; - } - - $times[] = [$startTime, $endTime]; - } - - foreach ($times as $time) { - if ($this->end && $time[0] > $this->end) { - break; - } - if ($this->start && $time[1] < $this->start) { - break; - } - - $fbData->add( - $time[0]->getTimeStamp(), - $time[1]->getTimeStamp(), - $FBTYPE - ); - } - break; - - case 'VFREEBUSY': - foreach ($component->FREEBUSY as $freebusy) { - $fbType = isset($freebusy['FBTYPE']) ? strtoupper($freebusy['FBTYPE']) : 'BUSY'; - - // Skipping intervals marked as 'free' - if ('FREE' === $fbType) { - continue; - } - - $values = explode(',', $freebusy); - foreach ($values as $value) { - list($startTime, $endTime) = explode('/', $value); - $startTime = DateTimeParser::parseDateTime($startTime); - - if ('P' === substr($endTime, 0, 1) || '-P' === substr($endTime, 0, 2)) { - $duration = DateTimeParser::parseDuration($endTime); - $endTime = clone $startTime; - $endTime = $endTime->add($duration); - } else { - $endTime = DateTimeParser::parseDateTime($endTime); - } - - if ($this->start && $this->start > $endTime) { - continue; - } - if ($this->end && $this->end < $startTime) { - continue; - } - $fbData->add( - $startTime->getTimeStamp(), - $endTime->getTimeStamp(), - $fbType - ); - } - } - break; - } - } - } - } - - /** - * This method takes a FreeBusyData object and generates the VCALENDAR - * object associated with it. - * - * @return VCalendar - */ - protected function generateFreeBusyCalendar(FreeBusyData $fbData) - { - if ($this->baseObject) { - $calendar = $this->baseObject; - } else { - $calendar = new VCalendar(); - } - - $vfreebusy = $calendar->createComponent('VFREEBUSY'); - $calendar->add($vfreebusy); - - if ($this->start) { - $dtstart = $calendar->createProperty('DTSTART'); - $dtstart->setDateTime($this->start); - $vfreebusy->add($dtstart); - } - if ($this->end) { - $dtend = $calendar->createProperty('DTEND'); - $dtend->setDateTime($this->end); - $vfreebusy->add($dtend); - } - - $tz = new \DateTimeZone('UTC'); - $dtstamp = $calendar->createProperty('DTSTAMP'); - $dtstamp->setDateTime(new DateTimeImmutable('now', $tz)); - $vfreebusy->add($dtstamp); - - foreach ($fbData->getData() as $busyTime) { - $busyType = strtoupper($busyTime['type']); - - // Ignoring all the FREE parts, because those are already assumed. - if ('FREE' === $busyType) { - continue; - } - - $busyTime[0] = new \DateTimeImmutable('@'.$busyTime['start'], $tz); - $busyTime[1] = new \DateTimeImmutable('@'.$busyTime['end'], $tz); - - $prop = $calendar->createProperty( - 'FREEBUSY', - $busyTime[0]->format('Ymd\\THis\\Z').'/'.$busyTime[1]->format('Ymd\\THis\\Z') - ); - - // Only setting FBTYPE if it's not BUSY, because BUSY is the - // default anyway. - if ('BUSY' !== $busyType) { - $prop['FBTYPE'] = $busyType; - } - $vfreebusy->add($prop); - } - - return $calendar; - } -} diff --git a/lib/vendor/sabre/vobject/lib/ITip/Broker.php b/lib/vendor/sabre/vobject/lib/ITip/Broker.php deleted file mode 100644 index e100c14..0000000 --- a/lib/vendor/sabre/vobject/lib/ITip/Broker.php +++ /dev/null @@ -1,1003 +0,0 @@ -component) { - return false; - } - - switch ($itipMessage->method) { - case 'REQUEST': - return $this->processMessageRequest($itipMessage, $existingObject); - - case 'CANCEL': - return $this->processMessageCancel($itipMessage, $existingObject); - - case 'REPLY': - return $this->processMessageReply($itipMessage, $existingObject); - - default: - // Unsupported iTip message - return; - } - - return $existingObject; - } - - /** - * This function parses a VCALENDAR object and figure out if any messages - * need to be sent. - * - * A VCALENDAR object will be created from the perspective of either an - * attendee, or an organizer. You must pass a string identifying the - * current user, so we can figure out who in the list of attendees or the - * organizer we are sending this message on behalf of. - * - * It's possible to specify the current user as an array, in case the user - * has more than one identifying href (such as multiple emails). - * - * It $oldCalendar is specified, it is assumed that the operation is - * updating an existing event, which means that we need to look at the - * differences between events, and potentially send old attendees - * cancellations, and current attendees updates. - * - * If $calendar is null, but $oldCalendar is specified, we treat the - * operation as if the user has deleted an event. If the user was an - * organizer, this means that we need to send cancellation notices to - * people. If the user was an attendee, we need to make sure that the - * organizer gets the 'declined' message. - * - * @param VCalendar|string $calendar - * @param string|array $userHref - * @param VCalendar|string|null $oldCalendar - * - * @return array - */ - public function parseEvent($calendar, $userHref, $oldCalendar = null) - { - if ($oldCalendar) { - if (is_string($oldCalendar)) { - $oldCalendar = Reader::read($oldCalendar); - } - if (!isset($oldCalendar->VEVENT)) { - // We only support events at the moment - return []; - } - - $oldEventInfo = $this->parseEventInfo($oldCalendar); - } else { - $oldEventInfo = [ - 'organizer' => null, - 'significantChangeHash' => '', - 'attendees' => [], - ]; - } - - $userHref = (array) $userHref; - - if (!is_null($calendar)) { - if (is_string($calendar)) { - $calendar = Reader::read($calendar); - } - if (!isset($calendar->VEVENT)) { - // We only support events at the moment - return []; - } - $eventInfo = $this->parseEventInfo($calendar); - if (!$eventInfo['attendees'] && !$oldEventInfo['attendees']) { - // If there were no attendees on either side of the equation, - // we don't need to do anything. - return []; - } - if (!$eventInfo['organizer'] && !$oldEventInfo['organizer']) { - // There was no organizer before or after the change. - return []; - } - - $baseCalendar = $calendar; - - // If the new object didn't have an organizer, the organizer - // changed the object from a scheduling object to a non-scheduling - // object. We just copy the info from the old object. - if (!$eventInfo['organizer'] && $oldEventInfo['organizer']) { - $eventInfo['organizer'] = $oldEventInfo['organizer']; - $eventInfo['organizerName'] = $oldEventInfo['organizerName']; - } - } else { - // The calendar object got deleted, we need to process this as a - // cancellation / decline. - if (!$oldCalendar) { - // No old and no new calendar, there's no thing to do. - return []; - } - - $eventInfo = $oldEventInfo; - - if (in_array($eventInfo['organizer'], $userHref)) { - // This is an organizer deleting the event. - $eventInfo['attendees'] = []; - // Increasing the sequence, but only if the organizer deleted - // the event. - ++$eventInfo['sequence']; - } else { - // This is an attendee deleting the event. - foreach ($eventInfo['attendees'] as $key => $attendee) { - if (in_array($attendee['href'], $userHref)) { - $eventInfo['attendees'][$key]['instances'] = ['master' => ['id' => 'master', 'partstat' => 'DECLINED'], - ]; - } - } - } - $baseCalendar = $oldCalendar; - } - - // Check if the user is the organizer - if (in_array($eventInfo['organizer'], $userHref)) { - return $this->parseEventForOrganizer($baseCalendar, $eventInfo, $oldEventInfo); - } - - // Check if the user is an attendee - foreach ($eventInfo['attendees'] as $attendee) { - if (in_array($attendee['href'], $userHref)) { - // If this is a event update, we always generate a reply - if ($oldCalendar) { - return $this->parseEventForAttendee($baseCalendar, $eventInfo, $oldEventInfo, $attendee['href']); - } - - // If this is a new event, we only generate a reply if the participation status is set - foreach ($attendee['instances'] as $instance) { - if (isset($instance['partstat']) && 'NEEDS-ACTION' !== $instance['partstat']) { - // Attendee has responded (ACCEPTED/DECLINED/TENTATIVE) - generate REPLY - return $this->parseEventForAttendee($baseCalendar, $eventInfo, $oldEventInfo, $attendee['href']); - } - } - - // User is attendee but no response to process - break; - } - } - - return []; - } - - /** - * Processes incoming REQUEST messages. - * - * This is message from an organizer, and is either a new event - * invite, or an update to an existing one. - * - * @param VCalendar $existingObject - * - * @return VCalendar|null - */ - protected function processMessageRequest(Message $itipMessage, ?VCalendar $existingObject = null) - { - if (!$existingObject) { - // This is a new invite, and we're just going to copy over - // all the components from the invite. - $existingObject = new VCalendar(); - foreach ($itipMessage->message->getComponents() as $component) { - $existingObject->add(clone $component); - } - } else { - // We need to update an existing object with all the new - // information. We can just remove all existing components - // and create new ones. - foreach ($existingObject->getComponents() as $component) { - $existingObject->remove($component); - } - foreach ($itipMessage->message->getComponents() as $component) { - $existingObject->add(clone $component); - } - } - - return $existingObject; - } - - /** - * Processes incoming CANCEL messages. - * - * This is a message from an organizer, and means that either an - * attendee got removed from an event, or an event got cancelled - * altogether. - * - * @param VCalendar $existingObject - * - * @return VCalendar|null - */ - protected function processMessageCancel(Message $itipMessage, ?VCalendar $existingObject = null) - { - if (!$existingObject) { - // The event didn't exist in the first place, so we're just - // ignoring this message. - } else { - foreach ($existingObject->VEVENT as $vevent) { - $vevent->STATUS = 'CANCELLED'; - $vevent->SEQUENCE = $itipMessage->sequence; - } - } - - return $existingObject; - } - - /** - * Processes incoming REPLY messages. - * - * The message is a reply. This is for example an attendee telling - * an organizer he accepted the invite, or declined it. - * - * @param VCalendar $existingObject - * - * @return VCalendar|null - */ - protected function processMessageReply(Message $itipMessage, ?VCalendar $existingObject = null) - { - // A reply can only be processed based on an existing object. - // If the object is not available, the reply is ignored. - if (!$existingObject) { - return; - } - $instances = []; - $requestStatus = '2.0'; - - // Finding all the instances the attendee replied to. - foreach ($itipMessage->message->VEVENT as $vevent) { - // Use the Unix timestamp returned by getTimestamp as a unique identifier for the recurrence. - // The Unix timestamp will be the same for an event, even if the reply from the attendee - // used a different format/timezone to express the event date-time. - $recurId = isset($vevent->{'RECURRENCE-ID'}) ? $vevent->{'RECURRENCE-ID'}->getDateTime()->getTimestamp() : 'master'; - $attendee = $vevent->ATTENDEE; - $instances[$recurId] = $attendee['PARTSTAT']->getValue(); - if (isset($vevent->{'REQUEST-STATUS'})) { - $requestStatus = $vevent->{'REQUEST-STATUS'}->getValue(); - list($requestStatus) = explode(';', $requestStatus); - } - } - - // Now we need to loop through the original organizer event, to find - // all the instances where we have a reply for. - $masterObject = null; - foreach ($existingObject->VEVENT as $vevent) { - // Use the Unix timestamp returned by getTimestamp as a unique identifier for the recurrence. - $recurId = isset($vevent->{'RECURRENCE-ID'}) ? $vevent->{'RECURRENCE-ID'}->getDateTime()->getTimestamp() : 'master'; - if ('master' === $recurId) { - $masterObject = $vevent; - } - if (isset($instances[$recurId])) { - $attendeeFound = false; - if (isset($vevent->ATTENDEE)) { - foreach ($vevent->ATTENDEE as $attendee) { - if ($attendee->getValue() === $itipMessage->sender) { - $attendeeFound = true; - $attendee['PARTSTAT'] = $instances[$recurId]; - $attendee['SCHEDULE-STATUS'] = $requestStatus; - // Un-setting the RSVP status, because we now know - // that the attendee already replied. - unset($attendee['RSVP']); - break; - } - } - } - if (!$attendeeFound) { - // Adding a new attendee. The iTip documentation calls this - // a party crasher. - $attendee = $vevent->add('ATTENDEE', $itipMessage->sender, [ - 'PARTSTAT' => $instances[$recurId], - ]); - if ($itipMessage->senderName) { - $attendee['CN'] = $itipMessage->senderName; - } - } - unset($instances[$recurId]); - } - } - - if (!$masterObject) { - // No master object, we can't add new instances. - return; - } - // If we got replies to instances that did not exist in the - // original list, it means that new exceptions must be created. - foreach ($instances as $recurId => $partstat) { - $recurrenceIterator = new EventIterator($existingObject, $itipMessage->uid); - $found = false; - $iterations = 1000; - do { - $newObject = $recurrenceIterator->getEventObject(); - $recurrenceIterator->next(); - - // Compare the Unix timestamp returned by getTimestamp with the previously calculated timestamp. - // If they are the same, then this is a matching recurrence, even though its date-time may have - // been expressed in a different format/timezone. - if (isset($newObject->{'RECURRENCE-ID'}) && $newObject->{'RECURRENCE-ID'}->getDateTime()->getTimestamp() === $recurId) { - $found = true; - } - --$iterations; - } while ($recurrenceIterator->valid() && !$found && $iterations); - - // Invalid recurrence id. Skipping this object. - if (!$found) { - continue; - } - - unset( - $newObject->RRULE, - $newObject->EXDATE, - $newObject->RDATE - ); - $attendeeFound = false; - if (isset($newObject->ATTENDEE)) { - foreach ($newObject->ATTENDEE as $attendee) { - if ($attendee->getValue() === $itipMessage->sender) { - $attendeeFound = true; - $attendee['PARTSTAT'] = $partstat; - break; - } - } - } - if (!$attendeeFound) { - // Adding a new attendee - $attendee = $newObject->add('ATTENDEE', $itipMessage->sender, [ - 'PARTSTAT' => $partstat, - ]); - if ($itipMessage->senderName) { - $attendee['CN'] = $itipMessage->senderName; - } - } - $existingObject->add($newObject); - } - - return $existingObject; - } - - /** - * This method is used in cases where an event got updated, and we - * potentially need to send emails to attendees to let them know of updates - * in the events. - * - * We will detect which attendees got added, which got removed and create - * specific messages for these situations. - * - * @return array - */ - protected function parseEventForOrganizer(VCalendar $calendar, array $eventInfo, array $oldEventInfo) - { - // Merging attendee lists. - $attendees = []; - foreach ($oldEventInfo['attendees'] as $attendee) { - $attendees[$attendee['href']] = [ - 'href' => $attendee['href'], - 'oldInstances' => $attendee['instances'], - 'newInstances' => [], - 'name' => $attendee['name'], - 'forceSend' => null, - ]; - } - foreach ($eventInfo['attendees'] as $attendee) { - if (isset($attendees[$attendee['href']])) { - $attendees[$attendee['href']]['name'] = $attendee['name']; - $attendees[$attendee['href']]['newInstances'] = $attendee['instances']; - $attendees[$attendee['href']]['forceSend'] = $attendee['forceSend']; - } else { - $attendees[$attendee['href']] = [ - 'href' => $attendee['href'], - 'oldInstances' => [], - 'newInstances' => $attendee['instances'], - 'name' => $attendee['name'], - 'forceSend' => $attendee['forceSend'], - ]; - } - } - - $messages = []; - foreach ($attendees as $attendee) { - // An organizer can also be an attendee. We should not generate any - // messages for those. - if ($attendee['href'] === $eventInfo['organizer']) { - continue; - } - - $message = new Message(); - $message->uid = $eventInfo['uid']; - $message->component = 'VEVENT'; - $message->sequence = $eventInfo['sequence']; - $message->sender = $eventInfo['organizer']; - $message->senderName = $eventInfo['organizerName']; - $message->recipient = $attendee['href']; - $message->recipientName = $attendee['name']; - - // Creating the new iCalendar body. - $icalMsg = new VCalendar(); - - foreach ($calendar->select('VTIMEZONE') as $timezone) { - $icalMsg->add(clone $timezone); - } - - if (!$attendee['newInstances'] || 'CANCELLED' === $eventInfo['status']) { - // If there are no instances the attendee is a part of, it means - // the attendee was removed and we need to send them a CANCEL message. - // Also If the meeting STATUS property was changed to CANCELLED - // we need to send the attendee a CANCEL message. - $message->method = 'CANCEL'; - - $icalMsg->METHOD = $message->method; - - $event = $icalMsg->add('VEVENT', [ - 'UID' => $message->uid, - 'SEQUENCE' => $message->sequence, - 'DTSTAMP' => gmdate('Ymd\\THis\\Z'), - ]); - if (isset($calendar->VEVENT->SUMMARY)) { - $event->add('SUMMARY', $calendar->VEVENT->SUMMARY->getValue()); - } - $event->add(clone $calendar->VEVENT->DTSTART); - if (isset($calendar->VEVENT->DTEND)) { - $event->add(clone $calendar->VEVENT->DTEND); - } elseif (isset($calendar->VEVENT->DURATION)) { - $event->add(clone $calendar->VEVENT->DURATION); - } - $org = $event->add('ORGANIZER', $eventInfo['organizer']); - if ($eventInfo['organizerName']) { - $org['CN'] = $eventInfo['organizerName']; - } - $event->add('ATTENDEE', $attendee['href'], [ - 'CN' => $attendee['name'], - ]); - $message->significantChange = true; - } else { - // The attendee gets the updated event body - $message->method = 'REQUEST'; - - $icalMsg->METHOD = $message->method; - - // We need to find out that this change is significant. If it's - // not, systems may opt to not send messages. - // - // We do this based on the 'significantChangeHash' which is - // some value that changes if there's a certain set of - // properties changed in the event, or simply if there's a - // difference in instances that the attendee is invited to. - - $oldAttendeeInstances = array_keys($attendee['oldInstances']); - $newAttendeeInstances = array_keys($attendee['newInstances']); - - $message->significantChange = - 'REQUEST' === $attendee['forceSend'] || - count($oldAttendeeInstances) != count($newAttendeeInstances) || - count(array_diff($oldAttendeeInstances, $newAttendeeInstances)) > 0 || - $oldEventInfo['significantChangeHash'] !== $eventInfo['significantChangeHash']; - - foreach ($attendee['newInstances'] as $instanceId => $instanceInfo) { - $currentEvent = clone $eventInfo['instances'][$instanceId]; - if ('master' === $instanceId) { - // We need to find a list of events that the attendee - // is not a part of to add to the list of exceptions. - $exceptions = []; - foreach ($eventInfo['instances'] as $instanceId => $vevent) { - if (!isset($attendee['newInstances'][$instanceId])) { - $exceptions[] = $instanceId; - } - } - - // If there were exceptions, we need to add it to an - // existing EXDATE property, if it exists. - if ($exceptions) { - if (isset($currentEvent->EXDATE)) { - $currentEvent->EXDATE->setParts(array_merge( - $currentEvent->EXDATE->getParts(), - $exceptions - )); - } else { - $currentEvent->EXDATE = $exceptions; - if ($currentEvent->DTSTART['TZID']) { - $currentEvent->EXDATE['TZID'] = clone $currentEvent->DTSTART['TZID']; - } - } - } - - // Cleaning up any scheduling information that - // shouldn't be sent along. - unset($currentEvent->ORGANIZER['SCHEDULE-FORCE-SEND']); - unset($currentEvent->ORGANIZER['SCHEDULE-STATUS']); - - foreach ($currentEvent->ATTENDEE as $currentEventAttendee) { - unset($currentEventAttendee['SCHEDULE-FORCE-SEND']); - unset($currentEventAttendee['SCHEDULE-STATUS']); - - // We're adding PARTSTAT=NEEDS-ACTION to ensure that - // iOS shows an "Inbox Item" - if (!isset($currentEventAttendee['PARTSTAT'])) { - $currentEventAttendee['PARTSTAT'] = 'NEEDS-ACTION'; - } - } - } - - $currentEvent->DTSTAMP = gmdate('Ymd\\THis\\Z'); - $icalMsg->add($currentEvent); - } - } - - $message->message = $icalMsg; - $messages[] = $message; - } - - return $messages; - } - - /** - * Parse an event update for an attendee. - * - * This function figures out if we need to send a reply to an organizer. - * - * @param string $attendee - * - * @return Message[] - */ - protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, array $oldEventInfo, $attendee) - { - if ($this->scheduleAgentServerRules && 'CLIENT' === $eventInfo['organizerScheduleAgent']) { - return []; - } - - // Don't bother generating messages for events that have already been - // cancelled. - if ('CANCELLED' === $eventInfo['status']) { - return []; - } - - $oldInstances = !empty($oldEventInfo['attendees'][$attendee]['instances']) ? - $oldEventInfo['attendees'][$attendee]['instances'] : - []; - - $instances = []; - foreach ($oldInstances as $instance) { - $instances[$instance['id']] = [ - 'id' => $instance['id'], - 'oldstatus' => $instance['partstat'], - 'newstatus' => null, - ]; - } - foreach ($eventInfo['attendees'][$attendee]['instances'] as $instance) { - if (isset($instances[$instance['id']])) { - $instances[$instance['id']]['newstatus'] = $instance['partstat']; - } else { - $instances[$instance['id']] = [ - 'id' => $instance['id'], - 'oldstatus' => null, - 'newstatus' => $instance['partstat'], - ]; - } - } - - // We need to also look for differences in EXDATE. If there are new - // items in EXDATE, it means that an attendee deleted instances of an - // event, which means we need to send DECLINED specifically for those - // instances. - // We only need to do that though, if the master event is not declined. - if (isset($instances['master']) && 'DECLINED' !== $instances['master']['newstatus']) { - foreach ($eventInfo['exdate'] as $exDate) { - if (!in_array($exDate, $oldEventInfo['exdate'])) { - if (isset($instances[$exDate])) { - $instances[$exDate]['newstatus'] = 'DECLINED'; - } else { - $instances[$exDate] = [ - 'id' => $exDate, - 'oldstatus' => null, - 'newstatus' => 'DECLINED', - ]; - } - } - } - } - - // Gathering a few extra properties for each instance. - foreach ($instances as $recurId => $instanceInfo) { - if (isset($eventInfo['instances'][$recurId])) { - $instances[$recurId]['dtstart'] = clone $eventInfo['instances'][$recurId]->DTSTART; - } else { - $instances[$recurId]['dtstart'] = $recurId; - } - } - - $message = new Message(); - $message->uid = $eventInfo['uid']; - $message->method = 'REPLY'; - $message->component = 'VEVENT'; - $message->sequence = $eventInfo['sequence']; - $message->sender = $attendee; - $message->senderName = $eventInfo['attendees'][$attendee]['name']; - $message->recipient = $eventInfo['organizer']; - $message->recipientName = $eventInfo['organizerName']; - - $icalMsg = new VCalendar(); - $icalMsg->METHOD = 'REPLY'; - - foreach ($calendar->select('VTIMEZONE') as $timezone) { - $icalMsg->add(clone $timezone); - } - - $hasReply = false; - - foreach ($instances as $instance) { - if ($instance['oldstatus'] == $instance['newstatus'] && 'REPLY' !== $eventInfo['organizerForceSend']) { - // Skip - continue; - } - - $event = $icalMsg->add('VEVENT', [ - 'UID' => $message->uid, - 'SEQUENCE' => $message->sequence, - ]); - $summary = isset($calendar->VEVENT->SUMMARY) ? $calendar->VEVENT->SUMMARY->getValue() : ''; - // Adding properties from the correct source instance - if (isset($eventInfo['instances'][$instance['id']])) { - $instanceObj = $eventInfo['instances'][$instance['id']]; - $event->add(clone $instanceObj->DTSTART); - if (isset($instanceObj->DTEND)) { - $event->add(clone $instanceObj->DTEND); - } elseif (isset($instanceObj->DURATION)) { - $event->add(clone $instanceObj->DURATION); - } - if (isset($instanceObj->SUMMARY)) { - $event->add('SUMMARY', $instanceObj->SUMMARY->getValue()); - } elseif ($summary) { - $event->add('SUMMARY', $summary); - } - } else { - // This branch of the code is reached, when a reply is - // generated for an instance of a recurring event, through the - // fact that the instance has disappeared by showing up in - // EXDATE - $dt = DateTimeParser::parse($instance['id'], $eventInfo['timezone']); - // Treat is as a DATE field - if (strlen($instance['id']) <= 8) { - $event->add('DTSTART', $dt, ['VALUE' => 'DATE']); - } else { - $event->add('DTSTART', $dt); - } - if ($summary) { - $event->add('SUMMARY', $summary); - } - } - if ('master' !== $instance['id']) { - $dt = DateTimeParser::parse($instance['id'], $eventInfo['timezone']); - // Treat is as a DATE field - if (strlen($instance['id']) <= 8) { - $event->add('RECURRENCE-ID', $dt, ['VALUE' => 'DATE']); - } else { - $event->add('RECURRENCE-ID', $dt); - } - } - $organizer = $event->add('ORGANIZER', $message->recipient); - if ($message->recipientName) { - $organizer['CN'] = $message->recipientName; - } - $attendee = $event->add('ATTENDEE', $message->sender, [ - 'PARTSTAT' => $instance['newstatus'], - ]); - if ($message->senderName) { - $attendee['CN'] = $message->senderName; - } - $hasReply = true; - } - - if ($hasReply) { - $message->message = $icalMsg; - - return [$message]; - } else { - return []; - } - } - - /** - * Returns attendee information and information about instances of an - * event. - * - * Returns an array with the following keys: - * - * 1. uid - * 2. organizer - * 3. organizerName - * 4. organizerScheduleAgent - * 5. organizerForceSend - * 6. instances - * 7. attendees - * 8. sequence - * 9. exdate - * 10. timezone - strictly the timezone on which the recurrence rule is - * based on. - * 11. significantChangeHash - * 12. status - * - * @param VCalendar $calendar - * - * @return array - */ - protected function parseEventInfo(?VCalendar $calendar = null) - { - $uid = null; - $organizer = null; - $organizerName = null; - $organizerForceSend = null; - $sequence = null; - $timezone = null; - $status = null; - $organizerScheduleAgent = 'SERVER'; - - $significantChangeHash = ''; - - // Now we need to collect a list of attendees, and which instances they - // are a part of. - $attendees = []; - - $instances = []; - $exdate = []; - - $significantChangeEventProperties = []; - - foreach ($calendar->VEVENT as $vevent) { - $eventSignificantChangeHash = ''; - $rrule = []; - - if (is_null($uid)) { - $uid = $vevent->UID->getValue(); - } else { - if ($uid !== $vevent->UID->getValue()) { - throw new ITipException('If a calendar contained more than one event, they must have the same UID.'); - } - } - - if (!isset($vevent->DTSTART)) { - throw new ITipException('An event MUST have a DTSTART property.'); - } - - if (isset($vevent->ORGANIZER)) { - if (is_null($organizer)) { - $organizer = $vevent->ORGANIZER->getNormalizedValue(); - $organizerName = isset($vevent->ORGANIZER['CN']) ? $vevent->ORGANIZER['CN'] : null; - } else { - if (strtoupper($organizer) !== strtoupper($vevent->ORGANIZER->getNormalizedValue())) { - throw new SameOrganizerForAllComponentsException('Every instance of the event must have the same organizer.'); - } - } - $organizerForceSend = - isset($vevent->ORGANIZER['SCHEDULE-FORCE-SEND']) ? - strtoupper($vevent->ORGANIZER['SCHEDULE-FORCE-SEND']) : - null; - $organizerScheduleAgent = - isset($vevent->ORGANIZER['SCHEDULE-AGENT']) ? - strtoupper((string) $vevent->ORGANIZER['SCHEDULE-AGENT']) : - 'SERVER'; - } - if (is_null($sequence) && isset($vevent->SEQUENCE)) { - $sequence = $vevent->SEQUENCE->getValue(); - } - if (isset($vevent->EXDATE)) { - foreach ($vevent->select('EXDATE') as $val) { - $exdate = array_merge($exdate, $val->getParts()); - } - sort($exdate); - } - if (isset($vevent->RRULE)) { - foreach ($vevent->select('RRULE') as $rr) { - foreach ($rr->getParts() as $key => $val) { - // ignore default values (https://github.com/sabre-io/vobject/issues/126) - if ('INTERVAL' === $key && 1 == $val) { - continue; - } - if (is_array($val)) { - $val = implode(',', $val); - } - $rrule[] = "$key=$val"; - } - } - sort($rrule); - } - if (isset($vevent->STATUS)) { - $status = strtoupper($vevent->STATUS->getValue()); - } - - $recurId = isset($vevent->{'RECURRENCE-ID'}) ? $vevent->{'RECURRENCE-ID'}->getValue() : 'master'; - if (is_null($timezone)) { - if ('master' === $recurId) { - $timezone = $vevent->DTSTART->getDateTime()->getTimeZone(); - } else { - $timezone = $vevent->{'RECURRENCE-ID'}->getDateTime()->getTimeZone(); - } - } - - $instances[$recurId] = $vevent; - - if (isset($vevent->ATTENDEE)) { - foreach ($vevent->ATTENDEE as $attendee) { - if ($this->scheduleAgentServerRules && - isset($attendee['SCHEDULE-AGENT']) && - 'CLIENT' === strtoupper($attendee['SCHEDULE-AGENT']->getValue()) - ) { - continue; - } - $partStat = - isset($attendee['PARTSTAT']) ? - strtoupper($attendee['PARTSTAT']) : - 'NEEDS-ACTION'; - - $forceSend = - isset($attendee['SCHEDULE-FORCE-SEND']) ? - strtoupper($attendee['SCHEDULE-FORCE-SEND']) : - null; - - if (isset($attendees[$attendee->getNormalizedValue()])) { - $attendees[$attendee->getNormalizedValue()]['instances'][$recurId] = [ - 'id' => $recurId, - 'partstat' => $partStat, - 'forceSend' => $forceSend, - ]; - } else { - $attendees[$attendee->getNormalizedValue()] = [ - 'href' => $attendee->getNormalizedValue(), - 'instances' => [ - $recurId => [ - 'id' => $recurId, - 'partstat' => $partStat, - ], - ], - 'name' => isset($attendee['CN']) ? (string) $attendee['CN'] : null, - 'forceSend' => $forceSend, - ]; - } - } - } - - foreach ($this->significantChangeProperties as $prop) { - if (isset($vevent->$prop)) { - $propertyValues = $vevent->select($prop); - - $eventSignificantChangeHash .= $prop.':'; - - if ('EXDATE' === $prop) { - $eventSignificantChangeHash .= implode(',', $exdate).';'; - } elseif ('RRULE' === $prop) { - $eventSignificantChangeHash .= implode(',', $rrule).';'; - } else { - foreach ($propertyValues as $val) { - $eventSignificantChangeHash .= $val->getValue().';'; - } - } - } - } - $significantChangeEventProperties[] = $eventSignificantChangeHash; - } - - asort($significantChangeEventProperties); - - foreach ($significantChangeEventProperties as $eventSignificantChangeHash) { - $significantChangeHash .= $eventSignificantChangeHash; - } - $significantChangeHash = md5($significantChangeHash); - - return compact( - 'uid', - 'organizer', - 'organizerName', - 'organizerScheduleAgent', - 'organizerForceSend', - 'instances', - 'attendees', - 'sequence', - 'exdate', - 'timezone', - 'significantChangeHash', - 'status' - ); - } -} diff --git a/lib/vendor/sabre/vobject/lib/ITip/ITipException.php b/lib/vendor/sabre/vobject/lib/ITip/ITipException.php deleted file mode 100644 index 9495636..0000000 --- a/lib/vendor/sabre/vobject/lib/ITip/ITipException.php +++ /dev/null @@ -1,16 +0,0 @@ -scheduleStatus) { - return false; - } else { - list($scheduleStatus) = explode(';', $this->scheduleStatus); - - return $scheduleStatus; - } - } -} diff --git a/lib/vendor/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php b/lib/vendor/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php deleted file mode 100644 index 4c48625..0000000 --- a/lib/vendor/sabre/vobject/lib/ITip/SameOrganizerForAllComponentsException.php +++ /dev/null @@ -1,18 +0,0 @@ -parent = null; - $this->root = null; - } - - /* {{{ IteratorAggregator interface */ - - /** - * Returns the iterator for this object. - * - * @return ElementList - */ - #[\ReturnTypeWillChange] - public function getIterator() - { - if (!is_null($this->iterator)) { - return $this->iterator; - } - - return new ElementList([$this]); - } - - /** - * Sets the overridden iterator. - * - * Note that this is not actually part of the iterator interface - */ - public function setIterator(ElementList $iterator) - { - $this->iterator = $iterator; - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on) - * 2 - An inconsequential issue - * 3 - A severe issue. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - return []; - } - - /* }}} */ - - /* {{{ Countable interface */ - - /** - * Returns the number of elements. - * - * @return int - */ - #[\ReturnTypeWillChange] - public function count() - { - $it = $this->getIterator(); - - return $it->count(); - } - - /* }}} */ - - /* {{{ ArrayAccess Interface */ - - /** - * Checks if an item exists through ArrayAccess. - * - * This method just forwards the request to the inner iterator - * - * @param int $offset - * - * @return bool - */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) - { - $iterator = $this->getIterator(); - - return $iterator->offsetExists($offset); - } - - /** - * Gets an item through ArrayAccess. - * - * This method just forwards the request to the inner iterator - * - * @param int $offset - * - * @return mixed - */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) - { - $iterator = $this->getIterator(); - - return $iterator->offsetGet($offset); - } - - /** - * Sets an item through ArrayAccess. - * - * This method just forwards the request to the inner iterator - * - * @param int $offset - * @param mixed $value - * - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) - { - $iterator = $this->getIterator(); - $iterator->offsetSet($offset, $value); - - // @codeCoverageIgnoreStart - // - // This method always throws an exception, so we ignore the closing - // brace - } - - // @codeCoverageIgnoreEnd - - /** - * Sets an item through ArrayAccess. - * - * This method just forwards the request to the inner iterator - * - * @param int $offset - * - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) - { - $iterator = $this->getIterator(); - $iterator->offsetUnset($offset); - - // @codeCoverageIgnoreStart - // - // This method always throws an exception, so we ignore the closing - // brace - } - - // @codeCoverageIgnoreEnd - - /* }}} */ -} diff --git a/lib/vendor/sabre/vobject/lib/PHPUnitAssertions.php b/lib/vendor/sabre/vobject/lib/PHPUnitAssertions.php deleted file mode 100644 index 45c0a21..0000000 --- a/lib/vendor/sabre/vobject/lib/PHPUnitAssertions.php +++ /dev/null @@ -1,75 +0,0 @@ -fail('Input must be a string, stream or VObject component'); - } - unset($input->PRODID); - if ($input instanceof Component\VCalendar && 'GREGORIAN' === (string) $input->CALSCALE) { - unset($input->CALSCALE); - } - - return $input; - }; - - $expected = $getObj($expected)->serialize(); - $actual = $getObj($actual)->serialize(); - - // Finding wildcards in expected. - preg_match_all('|^([A-Z]+):\\*\\*ANY\\*\\*\r$|m', $expected, $matches, PREG_SET_ORDER); - - foreach ($matches as $match) { - $actual = preg_replace( - '|^'.preg_quote($match[1], '|').':(.*)\r$|m', - $match[1].':**ANY**'."\r", - $actual - ); - } - - $this->assertEquals( - $expected, - $actual, - $message - ); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Parameter.php b/lib/vendor/sabre/vobject/lib/Parameter.php deleted file mode 100644 index 0f0b586..0000000 --- a/lib/vendor/sabre/vobject/lib/Parameter.php +++ /dev/null @@ -1,368 +0,0 @@ -root = $root; - if (is_null($name)) { - $this->noName = true; - $this->name = static::guessParameterNameByValue($value); - } else { - $this->name = strtoupper($name); - } - - // If guessParameterNameByValue() returns an empty string - // above, we're actually dealing with a parameter that has no value. - // In that case we have to move the value to the name. - if ('' === $this->name) { - $this->noName = false; - $this->name = strtoupper($value); - } else { - $this->setValue($value); - } - } - - /** - * Try to guess property name by value, can be used for vCard 2.1 nameless parameters. - * - * Figuring out what the name should have been. Note that a ton of - * these are rather silly in 2014 and would probably rarely be - * used, but we like to be complete. - * - * @param string $value - * - * @return string - */ - public static function guessParameterNameByValue($value) - { - switch (strtoupper($value)) { - // Encodings - case '7-BIT': - case 'QUOTED-PRINTABLE': - case 'BASE64': - $name = 'ENCODING'; - break; - - // Common types - case 'WORK': - case 'HOME': - case 'PREF': - // Delivery Label Type - case 'DOM': - case 'INTL': - case 'POSTAL': - case 'PARCEL': - // Telephone types - case 'VOICE': - case 'FAX': - case 'MSG': - case 'CELL': - case 'PAGER': - case 'BBS': - case 'MODEM': - case 'CAR': - case 'ISDN': - case 'VIDEO': - // EMAIL types (lol) - case 'AOL': - case 'APPLELINK': - case 'ATTMAIL': - case 'CIS': - case 'EWORLD': - case 'INTERNET': - case 'IBMMAIL': - case 'MCIMAIL': - case 'POWERSHARE': - case 'PRODIGY': - case 'TLX': - case 'X400': - // Photo / Logo format types - case 'GIF': - case 'CGM': - case 'WMF': - case 'BMP': - case 'DIB': - case 'PICT': - case 'TIFF': - case 'PDF': - case 'PS': - case 'JPEG': - case 'MPEG': - case 'MPEG2': - case 'AVI': - case 'QTIME': - // Sound Digital Audio Type - case 'WAVE': - case 'PCM': - case 'AIFF': - // Key types - case 'X509': - case 'PGP': - $name = 'TYPE'; - break; - - // Value types - case 'INLINE': - case 'URL': - case 'CONTENT-ID': - case 'CID': - $name = 'VALUE'; - break; - - default: - $name = ''; - } - - return $name; - } - - /** - * Updates the current value. - * - * This may be either a single, or multiple strings in an array. - * - * @param string|array $value - */ - public function setValue($value) - { - $this->value = $value; - } - - /** - * Returns the current value. - * - * This method will always return a string, or null. If there were multiple - * values, it will automatically concatenate them (separated by comma). - * - * @return string|null - */ - public function getValue() - { - if (is_array($this->value)) { - return implode(',', $this->value); - } else { - return $this->value; - } - } - - /** - * Sets multiple values for this parameter. - */ - public function setParts(array $value) - { - $this->value = $value; - } - - /** - * Returns all values for this parameter. - * - * If there were no values, an empty array will be returned. - * - * @return array - */ - public function getParts() - { - if (is_array($this->value)) { - return $this->value; - } elseif (is_null($this->value)) { - return []; - } else { - return [$this->value]; - } - } - - /** - * Adds a value to this parameter. - * - * If the argument is specified as an array, all items will be added to the - * parameter value list. - * - * @param string|array $part - */ - public function addValue($part) - { - if (is_null($this->value)) { - $this->value = $part; - } else { - $this->value = array_merge((array) $this->value, (array) $part); - } - } - - /** - * Checks if this parameter contains the specified value. - * - * This is a case-insensitive match. It makes sense to call this for for - * instance the TYPE parameter, to see if it contains a keyword such as - * 'WORK' or 'FAX'. - * - * @param string $value - * - * @return bool - */ - public function has($value) - { - return in_array( - strtolower($value), - array_map('strtolower', (array) $this->value) - ); - } - - /** - * Turns the object back into a serialized blob. - * - * @return string - */ - public function serialize() - { - $value = $this->getParts(); - - if (0 === count($value)) { - return $this->name.'='; - } - - if (Document::VCARD21 === $this->root->getDocumentType() && $this->noName) { - return implode(';', $value); - } - - return $this->name.'='.array_reduce( - $value, - function ($out, $item) { - if (!is_null($out)) { - $out .= ','; - } - - // If there's no special characters in the string, we'll use the simple - // format. - // - // The list of special characters is defined as: - // - // Any character except CONTROL, DQUOTE, ";", ":", "," - // - // by the iCalendar spec: - // https://tools.ietf.org/html/rfc5545#section-3.1 - // - // And we add ^ to that because of: - // https://tools.ietf.org/html/rfc6868 - // - // But we've found that iCal (7.0, shipped with OSX 10.9) - // severely trips on + characters not being quoted, so we - // added + as well. - if (!preg_match('#(?: [\n":;\^,\+] )#x', $item)) { - return $out.$item; - } else { - // Enclosing in double-quotes, and using RFC6868 for encoding any - // special characters - $out .= '"'.strtr( - $item, - [ - '^' => '^^', - "\n" => '^n', - '"' => '^\'', - ] - ).'"'; - - return $out; - } - } - ); - } - - /** - * This method returns an array, with the representation as it should be - * encoded in JSON. This is used to create jCard or jCal documents. - * - * @return array - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - return $this->value; - } - - /** - * This method serializes the data into XML. This is used to create xCard or - * xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - public function xmlSerialize(Xml\Writer $writer): void - { - foreach (explode(',', $this->value) as $value) { - $writer->writeElement('text', $value); - } - } - - /** - * Called when this object is being cast to a string. - * - * @return string - */ - public function __toString() - { - return (string) $this->getValue(); - } - - /** - * Returns the iterator for this object. - * - * @return ElementList - */ - #[\ReturnTypeWillChange] - public function getIterator() - { - if (!is_null($this->iterator)) { - return $this->iterator; - } - - return $this->iterator = new ArrayIterator((array) $this->value); - } -} diff --git a/lib/vendor/sabre/vobject/lib/ParseException.php b/lib/vendor/sabre/vobject/lib/ParseException.php deleted file mode 100644 index a8f497b..0000000 --- a/lib/vendor/sabre/vobject/lib/ParseException.php +++ /dev/null @@ -1,14 +0,0 @@ -setInput($input); - } - if (is_null($this->input)) { - throw new EofException('End of input stream, or no input supplied'); - } - - if (0 !== $options) { - $this->options = $options; - } - - switch ($this->input[0]) { - case 'vcalendar': - $this->root = new VCalendar([], false); - break; - case 'vcard': - $this->root = new VCard([], false); - break; - default: - throw new ParseException('The root component must either be a vcalendar, or a vcard'); - } - foreach ($this->input[1] as $prop) { - $this->root->add($this->parseProperty($prop)); - } - if (isset($this->input[2])) { - foreach ($this->input[2] as $comp) { - $this->root->add($this->parseComponent($comp)); - } - } - - // Resetting the input so we can throw an feof exception the next time. - $this->input = null; - - return $this->root; - } - - /** - * Parses a component. - * - * @return \Sabre\VObject\Component - */ - public function parseComponent(array $jComp) - { - // We can remove $self from PHP 5.4 onward. - $self = $this; - - $properties = array_map( - function ($jProp) use ($self) { - return $self->parseProperty($jProp); - }, - $jComp[1] - ); - - if (isset($jComp[2])) { - $components = array_map( - function ($jComp) use ($self) { - return $self->parseComponent($jComp); - }, - $jComp[2] - ); - } else { - $components = []; - } - - return $this->root->createComponent( - $jComp[0], - array_merge($properties, $components), - $defaults = false - ); - } - - /** - * Parses properties. - * - * @return \Sabre\VObject\Property - */ - public function parseProperty(array $jProp) - { - list( - $propertyName, - $parameters, - $valueType - ) = $jProp; - - $propertyName = strtoupper($propertyName); - - // This is the default class we would be using if we didn't know the - // value type. We're using this value later in this function. - $defaultPropertyClass = $this->root->getClassNameForPropertyName($propertyName); - - $parameters = (array) $parameters; - - $value = array_slice($jProp, 3); - - $valueType = strtoupper($valueType); - - if (isset($parameters['group'])) { - $propertyName = $parameters['group'].'.'.$propertyName; - unset($parameters['group']); - } - - $prop = $this->root->createProperty($propertyName, null, $parameters, $valueType); - $prop->setJsonValue($value); - - // We have to do something awkward here. FlatText as well as Text - // represents TEXT values. We have to normalize these here. In the - // future we can get rid of FlatText once we're allowed to break BC - // again. - if (FlatText::class === $defaultPropertyClass) { - $defaultPropertyClass = Text::class; - } - - // If the value type we received (e.g.: TEXT) was not the default value - // type for the given property (e.g.: BDAY), we need to add a VALUE= - // parameter. - if ($defaultPropertyClass !== get_class($prop)) { - $prop['VALUE'] = $valueType; - } - - return $prop; - } - - /** - * Sets the input data. - * - * @param resource|string|array $input - */ - public function setInput($input) - { - if (is_resource($input)) { - $input = stream_get_contents($input); - } - if (is_string($input)) { - $input = json_decode($input); - } - $this->input = $input; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Parser/MimeDir.php b/lib/vendor/sabre/vobject/lib/Parser/MimeDir.php deleted file mode 100644 index 5520530..0000000 --- a/lib/vendor/sabre/vobject/lib/Parser/MimeDir.php +++ /dev/null @@ -1,710 +0,0 @@ -root = null; - - if (!is_null($input)) { - $this->setInput($input); - } - - if (!\is_resource($this->input)) { - // Null was passed as input, but there was no existing input buffer - // There is nothing to parse. - throw new ParseException('No input provided to parse'); - } - - if (0 !== $options) { - $this->options = $options; - } - - $this->parseDocument(); - - return $this->root; - } - - /** - * By default all input will be assumed to be UTF-8. - * - * However, both iCalendar and vCard might be encoded using different - * character sets. The character set is usually set in the mime-type. - * - * If this is the case, use setEncoding to specify that a different - * encoding will be used. If this is set, the parser will automatically - * convert all incoming data to UTF-8. - * - * @param string $charset - */ - public function setCharset($charset) - { - if (!in_array($charset, self::$SUPPORTED_CHARSETS)) { - throw new \InvalidArgumentException('Unsupported encoding. (Supported encodings: '.implode(', ', self::$SUPPORTED_CHARSETS).')'); - } - $this->charset = $charset; - } - - /** - * Sets the input buffer. Must be a string or stream. - * - * @param resource|string $input - */ - public function setInput($input) - { - // Resetting the parser - $this->lineIndex = 0; - $this->startLine = 0; - - if (is_string($input)) { - // Converting to a stream. - $stream = fopen('php://temp', 'r+'); - fwrite($stream, $input); - rewind($stream); - $this->input = $stream; - } elseif (is_resource($input)) { - $this->input = $input; - } else { - throw new \InvalidArgumentException('This parser can only read from strings or streams.'); - } - } - - /** - * Parses an entire document. - */ - protected function parseDocument() - { - $line = $this->readLine(); - - // BOM is ZERO WIDTH NO-BREAK SPACE (U+FEFF). - // It's 0xEF 0xBB 0xBF in UTF-8 hex. - if (3 <= strlen($line) - && 0xef === ord($line[0]) - && 0xbb === ord($line[1]) - && 0xbf === ord($line[2])) { - $line = substr($line, 3); - } - - switch (strtoupper($line)) { - case 'BEGIN:VCALENDAR': - $class = VCalendar::$componentMap['VCALENDAR']; - break; - case 'BEGIN:VCARD': - $class = VCard::$componentMap['VCARD']; - break; - default: - throw new ParseException('This parser only supports VCARD and VCALENDAR files'); - } - - $this->root = new $class([], false); - - while (true) { - // Reading until we hit END: - try { - $line = $this->readLine(); - } catch (EofException $oEx) { - $line = 'END:'.$this->root->name; - } - if ('END:' === strtoupper(substr($line, 0, 4))) { - break; - } - $result = $this->parseLine($line); - if ($result) { - $this->root->add($result); - } - } - - $name = strtoupper(substr($line, 4)); - if ($name !== $this->root->name) { - throw new ParseException('Invalid MimeDir file. expected: "END:'.$this->root->name.'" got: "END:'.$name.'"'); - } - } - - /** - * Parses a line, and if it hits a component, it will also attempt to parse - * the entire component. - * - * @param string $line Unfolded line - * - * @return Node - */ - protected function parseLine($line) - { - // Start of a new component - if ('BEGIN:' === strtoupper(substr($line, 0, 6))) { - if (substr($line, 6) === $this->root->name) { - throw new ParseException('Invalid MimeDir file. Unexpected component: "'.$line.'" in document type '.$this->root->name); - } - $component = $this->root->createComponent(substr($line, 6), [], false); - - while (true) { - // Reading until we hit END: - $line = $this->readLine(); - if ('END:' === strtoupper(substr($line, 0, 4))) { - break; - } - $result = $this->parseLine($line); - if ($result) { - $component->add($result); - } - } - - $name = strtoupper(substr($line, 4)); - if ($name !== $component->name) { - throw new ParseException('Invalid MimeDir file. expected: "END:'.$component->name.'" got: "END:'.$name.'"'); - } - - return $component; - } else { - // Property reader - $property = $this->readProperty($line); - if (!$property) { - // Ignored line - return false; - } - - return $property; - } - } - - /** - * We need to look ahead 1 line every time to see if we need to 'unfold' - * the next line. - * - * If that was not the case, we store it here. - * - * @var string|null - */ - protected $lineBuffer; - - /** - * The real current line number. - */ - protected $lineIndex = 0; - - /** - * In the case of unfolded lines, this property holds the line number for - * the start of the line. - * - * @var int - */ - protected $startLine = 0; - - /** - * Contains a 'raw' representation of the current line. - * - * @var string - */ - protected $rawLine; - - /** - * Reads a single line from the buffer. - * - * This method strips any newlines and also takes care of unfolding. - * - * @throws \Sabre\VObject\EofException - * - * @return string - */ - protected function readLine() - { - if (!\is_null($this->lineBuffer)) { - $rawLine = $this->lineBuffer; - $this->lineBuffer = null; - } else { - do { - $eof = \feof($this->input); - - $rawLine = \fgets($this->input); - - if ($eof || (\feof($this->input) && false === $rawLine)) { - throw new EofException('End of document reached prematurely'); - } - if (false === $rawLine) { - throw new ParseException('Error reading from input stream'); - } - $rawLine = \rtrim($rawLine, "\r\n"); - } while ('' === $rawLine); // Skipping empty lines - ++$this->lineIndex; - } - $line = $rawLine; - - $this->startLine = $this->lineIndex; - - // Looking ahead for folded lines. - while (true) { - $nextLine = \rtrim(\fgets($this->input), "\r\n"); - ++$this->lineIndex; - if (!$nextLine) { - break; - } - if ("\t" === $nextLine[0] || ' ' === $nextLine[0]) { - $curLine = \substr($nextLine, 1); - $line .= $curLine; - $rawLine .= "\n ".$curLine; - } else { - $this->lineBuffer = $nextLine; - break; - } - } - $this->rawLine = $rawLine; - - return $line; - } - - /** - * Reads a property or component from a line. - */ - protected function readProperty($line) - { - if ($this->options & self::OPTION_FORGIVING) { - $propNameToken = 'A-Z0-9\-\._\\/'; - } else { - $propNameToken = 'A-Z0-9\-\.'; - } - - $paramNameToken = 'A-Z0-9\-'; - $safeChar = '^";:,'; - $qSafeChar = '^"'; - - $regex = "/ - ^(?P [$propNameToken]+ ) (?=[;:]) # property name - | - (?<=:)(?P .+)$ # property value - | - ;(?P [$paramNameToken]+) (?=[=;:]) # parameter name - | - (=|,)(?P # parameter value - (?: [$safeChar]*) | - \"(?: [$qSafeChar]+)\" - ) (?=[;:,]) - /xi"; - - //echo $regex, "\n"; exit(); - preg_match_all($regex, $line, $matches, PREG_SET_ORDER); - - $property = [ - 'name' => null, - 'parameters' => [], - 'value' => null, - ]; - - /* - * Keep track on the last token we parsed in order to do - * better error checking - */ - $lastToken = null; - - $lastParam = null; - - /* - * Looping through all the tokens. - * - * Note that we are looping through them in reverse order, because if a - * sub-pattern matched, the subsequent named patterns will not show up - * in the result. - */ - foreach ($matches as $match) { - if (isset($match['paramValue'])) { - if ($match['paramValue'] && '"' === $match['paramValue'][0]) { - $value = substr($match['paramValue'], 1, -1); - } else { - $value = $match['paramValue']; - } - - $value = $this->unescapeParam($value); - - if (is_null($lastParam)) { - if ($this->options & self::OPTION_IGNORE_INVALID_LINES) { - // When the property can't be matched and the configuration - // option is set to ignore invalid lines, we ignore this line - // This can happen when servers provide faulty data as iCloud - // frequently does with X-APPLE-STRUCTURED-LOCATION - $lastToken = self::TOKEN_PARAMVALUE; - continue; - } - throw new ParseException('Invalid Mimedir file. Line starting at '.$this->startLine.' did not follow iCalendar/vCard conventions'); - } - - if ('=' == $match[0][0] && self::TOKEN_PARAMNAME != $lastToken) { - throw new ParseException('Invalid Mimedir file. Line starting at '.$this->startLine.': Missing parameter name for parameter value "'.$match['paramValue'].'"'); - } - - if (is_null($property['parameters'][$lastParam])) { - $property['parameters'][$lastParam] = $value; - } elseif (is_array($property['parameters'][$lastParam])) { - $property['parameters'][$lastParam][] = $value; - } elseif ($property['parameters'][$lastParam] === $value) { - // When the current value of the parameter is the same as the - // new one, then we can leave the current parameter as it is. - } else { - $property['parameters'][$lastParam] = [ - $property['parameters'][$lastParam], - $value, - ]; - } - $lastToken = self::TOKEN_PARAMVALUE; - continue; - } - if (isset($match['paramName'])) { - $lastParam = strtoupper($match['paramName']); - if (!isset($property['parameters'][$lastParam])) { - $property['parameters'][$lastParam] = null; - } - $lastToken = self::TOKEN_PARAMNAME; - continue; - } - if (isset($match['propValue'])) { - $property['value'] = $match['propValue']; - $lastToken = self::TOKEN_PROPVALUE; - continue; - } - if (isset($match['name']) && 0 < strlen($match['name'])) { - $property['name'] = strtoupper($match['name']); - $lastToken = self::TOKEN_PROPNAME; - continue; - } - - // @codeCoverageIgnoreStart - throw new \LogicException('This code should not be reachable'); - // @codeCoverageIgnoreEnd - } - - if (is_null($property['value'])) { - $property['value'] = ''; - } - if (!isset($property['name']) || 0 == strlen($property['name'])) { - if ($this->options & self::OPTION_IGNORE_INVALID_LINES) { - return false; - } - throw new ParseException('Invalid Mimedir file. Line starting at '.$this->startLine.' did not follow iCalendar/vCard conventions'); - } - - // vCard 2.1 states that parameters may appear without a name, and only - // a value. We can deduce the value based on its name. - // - // Our parser will get those as parameters without a value instead, so - // we're filtering these parameters out first. - $namedParameters = []; - $namelessParameters = []; - - foreach ($property['parameters'] as $name => $value) { - if (!is_null($value)) { - $namedParameters[$name] = $value; - } else { - $namelessParameters[] = $name; - } - } - - $propObj = $this->root->createProperty($property['name'], null, $namedParameters, null, $this->startLine, $line); - - foreach ($namelessParameters as $namelessParameter) { - $propObj->add(null, $namelessParameter); - } - - if (isset($propObj['ENCODING']) && 'QUOTED-PRINTABLE' === strtoupper($propObj['ENCODING'])) { - $propObj->setQuotedPrintableValue($this->extractQuotedPrintableValue()); - } else { - $charset = $this->charset; - if (Document::VCARD21 === $this->root->getDocumentType() && isset($propObj['CHARSET'])) { - // vCard 2.1 allows the character set to be specified per property. - $charset = (string) $propObj['CHARSET']; - } - switch (strtolower($charset)) { - case 'utf-8': - break; - case 'windows-1252': - case 'iso-8859-1': - $property['value'] = mb_convert_encoding($property['value'], 'UTF-8', $charset); - break; - default: - throw new ParseException('Unsupported CHARSET: '.$propObj['CHARSET']); - } - $propObj->setRawMimeDirValue($property['value']); - } - - return $propObj; - } - - /** - * Unescapes a property value. - * - * vCard 2.1 says: - * * Semi-colons must be escaped in some property values, specifically - * ADR, ORG and N. - * * Semi-colons must be escaped in parameter values, because semi-colons - * are also use to separate values. - * * No mention of escaping backslashes with another backslash. - * * newlines are not escaped either, instead QUOTED-PRINTABLE is used to - * span values over more than 1 line. - * - * vCard 3.0 says: - * * (rfc2425) Backslashes, newlines (\n or \N) and comma's must be - * escaped, all time time. - * * Comma's are used for delimiters in multiple values - * * (rfc2426) Adds to to this that the semi-colon MUST also be escaped, - * as in some properties semi-colon is used for separators. - * * Properties using semi-colons: N, ADR, GEO, ORG - * * Both ADR and N's individual parts may be broken up further with a - * comma. - * * Properties using commas: NICKNAME, CATEGORIES - * - * vCard 4.0 (rfc6350) says: - * * Commas must be escaped. - * * Semi-colons may be escaped, an unescaped semi-colon _may_ be a - * delimiter, depending on the property. - * * Backslashes must be escaped - * * Newlines must be escaped as either \N or \n. - * * Some compound properties may contain multiple parts themselves, so a - * comma within a semi-colon delimited property may also be unescaped - * to denote multiple parts _within_ the compound property. - * * Text-properties using semi-colons: N, ADR, ORG, CLIENTPIDMAP. - * * Text-properties using commas: NICKNAME, RELATED, CATEGORIES, PID. - * - * Even though the spec says that commas must always be escaped, the - * example for GEO in Section 6.5.2 seems to violate this. - * - * iCalendar 2.0 (rfc5545) says: - * * Commas or semi-colons may be used as delimiters, depending on the - * property. - * * Commas, semi-colons, backslashes, newline (\N or \n) are always - * escaped, unless they are delimiters. - * * Colons shall not be escaped. - * * Commas can be considered the 'default delimiter' and is described as - * the delimiter in cases where the order of the multiple values is - * insignificant. - * * Semi-colons are described as the delimiter for 'structured values'. - * They are specifically used in Semi-colons are used as a delimiter in - * REQUEST-STATUS, RRULE, GEO and EXRULE. EXRULE is deprecated however. - * - * Now for the parameters - * - * If delimiter is not set (empty string) this method will just return a string. - * If it's a comma or a semi-colon the string will be split on those - * characters, and always return an array. - * - * @param string $input - * @param string $delimiter - * - * @return string|string[] - */ - public static function unescapeValue($input, $delimiter = ';') - { - $regex = '# (?: (\\\\ (?: \\\\ | N | n | ; | , ) )'; - if ($delimiter) { - $regex .= ' | ('.$delimiter.')'; - } - $regex .= ') #x'; - - $matches = preg_split($regex, $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); - - $resultArray = []; - $result = ''; - - foreach ($matches as $match) { - switch ($match) { - case '\\\\': - $result .= '\\'; - break; - case '\N': - case '\n': - $result .= "\n"; - break; - case '\;': - $result .= ';'; - break; - case '\,': - $result .= ','; - break; - case $delimiter: - $resultArray[] = $result; - $result = ''; - break; - default: - $result .= $match; - break; - } - } - - $resultArray[] = $result; - - return $delimiter ? $resultArray : $result; - } - - /** - * Unescapes a parameter value. - * - * vCard 2.1: - * * Does not mention a mechanism for this. In addition, double quotes - * are never used to wrap values. - * * This means that parameters can simply not contain colons or - * semi-colons. - * - * vCard 3.0 (rfc2425, rfc2426): - * * Parameters _may_ be surrounded by double quotes. - * * If this is not the case, semi-colon, colon and comma may simply not - * occur (the comma used for multiple parameter values though). - * * If it is surrounded by double-quotes, it may simply not contain - * double-quotes. - * * This means that a parameter can in no case encode double-quotes, or - * newlines. - * - * vCard 4.0 (rfc6350) - * * Behavior seems to be identical to vCard 3.0 - * - * iCalendar 2.0 (rfc5545) - * * Behavior seems to be identical to vCard 3.0 - * - * Parameter escaping mechanism (rfc6868) : - * * This rfc describes a new way to escape parameter values. - * * New-line is encoded as ^n - * * ^ is encoded as ^^. - * * " is encoded as ^' - * - * @param string $input - */ - private function unescapeParam($input) - { - return - preg_replace_callback( - '#(\^(\^|n|\'))#', - function ($matches) { - switch ($matches[2]) { - case 'n': - return "\n"; - case '^': - return '^'; - case '\'': - return '"'; - - // @codeCoverageIgnoreStart - } - // @codeCoverageIgnoreEnd - }, - $input - ); - } - - /** - * Gets the full quoted printable value. - * - * We need a special method for this, because newlines have both a meaning - * in vCards, and in QuotedPrintable. - * - * This method does not do any decoding. - * - * @return string - */ - private function extractQuotedPrintableValue() - { - // We need to parse the raw line again to get the start of the value. - // - // We are basically looking for the first colon (:), but we need to - // skip over the parameters first, as they may contain one. - $regex = '/^ - (?: [^:])+ # Anything but a colon - (?: "[^"]")* # A parameter in double quotes - : # start of the value we really care about - (.*)$ - /xs'; - - preg_match($regex, $this->rawLine, $matches); - - $value = $matches[1]; - // Removing the first whitespace character from every line. Kind of - // like unfolding, but we keep the newline. - $value = str_replace("\n ", "\n", $value); - - // Microsoft products don't always correctly fold lines, they may be - // missing a whitespace. So if 'forgiving' is turned on, we will take - // those as well. - if ($this->options & self::OPTION_FORGIVING) { - while ('=' === substr($value, -1) && $this->lineBuffer) { - // Reading the line - $this->readLine(); - // Grabbing the raw form - $value .= "\n".$this->rawLine; - } - } - - return $value; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Parser/Parser.php b/lib/vendor/sabre/vobject/lib/Parser/Parser.php deleted file mode 100644 index b7b6114..0000000 --- a/lib/vendor/sabre/vobject/lib/Parser/Parser.php +++ /dev/null @@ -1,75 +0,0 @@ -setInput($input); - } - $this->options = $options; - } - - /** - * This method starts the parsing process. - * - * If the input was not supplied during construction, it's possible to pass - * it here instead. - * - * If either input or options are not supplied, the defaults will be used. - * - * @param mixed $input - * @param int $options - * - * @return array - */ - abstract public function parse($input = null, $options = 0); - - /** - * Sets the input data. - * - * @param mixed $input - */ - abstract public function setInput($input); -} diff --git a/lib/vendor/sabre/vobject/lib/Parser/XML.php b/lib/vendor/sabre/vobject/lib/Parser/XML.php deleted file mode 100644 index 7877317..0000000 --- a/lib/vendor/sabre/vobject/lib/Parser/XML.php +++ /dev/null @@ -1,377 +0,0 @@ -setInput($input); - } - - if (0 !== $options) { - $this->options = $options; - } - - if (is_null($this->input)) { - throw new EofException('End of input stream, or no input supplied'); - } - - switch ($this->input['name']) { - case '{'.self::XCAL_NAMESPACE.'}icalendar': - $this->root = new VCalendar([], false); - $this->pointer = &$this->input['value'][0]; - $this->parseVCalendarComponents($this->root); - break; - - case '{'.self::XCARD_NAMESPACE.'}vcards': - foreach ($this->input['value'] as &$vCard) { - $this->root = new VCard(['version' => '4.0'], false); - $this->pointer = &$vCard; - $this->parseVCardComponents($this->root); - - // We just parse the first element. - break; - } - break; - - default: - throw new ParseException('Unsupported XML standard'); - } - - return $this->root; - } - - /** - * Parse a xCalendar component. - */ - protected function parseVCalendarComponents(Component $parentComponent) - { - foreach ($this->pointer['value'] ?: [] as $children) { - switch (static::getTagName($children['name'])) { - case 'properties': - $this->pointer = &$children['value']; - $this->parseProperties($parentComponent); - break; - - case 'components': - $this->pointer = &$children; - $this->parseComponent($parentComponent); - break; - } - } - } - - /** - * Parse a xCard component. - */ - protected function parseVCardComponents(Component $parentComponent) - { - $this->pointer = &$this->pointer['value']; - $this->parseProperties($parentComponent); - } - - /** - * Parse xCalendar and xCard properties. - * - * @param string $propertyNamePrefix - */ - protected function parseProperties(Component $parentComponent, $propertyNamePrefix = '') - { - foreach ($this->pointer ?: [] as $xmlProperty) { - list($namespace, $tagName) = SabreXml\Service::parseClarkNotation($xmlProperty['name']); - - $propertyName = $tagName; - $propertyValue = []; - $propertyParameters = []; - $propertyType = 'text'; - - // A property which is not part of the standard. - if (self::XCAL_NAMESPACE !== $namespace - && self::XCARD_NAMESPACE !== $namespace) { - $propertyName = 'xml'; - $value = '<'.$tagName.' xmlns="'.$namespace.'"'; - - foreach ($xmlProperty['attributes'] as $attributeName => $attributeValue) { - $value .= ' '.$attributeName.'="'.str_replace('"', '\"', $attributeValue).'"'; - } - - $value .= '>'.$xmlProperty['value'].''; - - $propertyValue = [$value]; - - $this->createProperty( - $parentComponent, - $propertyName, - $propertyParameters, - $propertyType, - $propertyValue - ); - - continue; - } - - // xCard group. - if ('group' === $propertyName) { - if (!isset($xmlProperty['attributes']['name'])) { - continue; - } - - $this->pointer = &$xmlProperty['value']; - $this->parseProperties( - $parentComponent, - strtoupper($xmlProperty['attributes']['name']).'.' - ); - - continue; - } - - // Collect parameters. - foreach ($xmlProperty['value'] as $i => $xmlPropertyChild) { - if (!is_array($xmlPropertyChild) - || 'parameters' !== static::getTagName($xmlPropertyChild['name'])) { - continue; - } - - $xmlParameters = $xmlPropertyChild['value']; - - foreach ($xmlParameters as $xmlParameter) { - $propertyParameterValues = []; - - foreach ($xmlParameter['value'] as $xmlParameterValues) { - $propertyParameterValues[] = $xmlParameterValues['value']; - } - - $propertyParameters[static::getTagName($xmlParameter['name'])] - = implode(',', $propertyParameterValues); - } - - array_splice($xmlProperty['value'], $i, 1); - } - - $propertyNameExtended = ($this->root instanceof VCalendar - ? 'xcal' - : 'xcard').':'.$propertyName; - - switch ($propertyNameExtended) { - case 'xcal:geo': - $propertyType = 'float'; - $propertyValue['latitude'] = 0; - $propertyValue['longitude'] = 0; - - foreach ($xmlProperty['value'] as $xmlRequestChild) { - $propertyValue[static::getTagName($xmlRequestChild['name'])] - = $xmlRequestChild['value']; - } - break; - - case 'xcal:request-status': - $propertyType = 'text'; - - foreach ($xmlProperty['value'] as $xmlRequestChild) { - $propertyValue[static::getTagName($xmlRequestChild['name'])] - = $xmlRequestChild['value']; - } - break; - - case 'xcal:freebusy': - $propertyType = 'freebusy'; - // We don't break because we only want to set - // another property type. - - // no break - case 'xcal:categories': - case 'xcal:resources': - case 'xcal:exdate': - foreach ($xmlProperty['value'] as $specialChild) { - $propertyValue[static::getTagName($specialChild['name'])] - = $specialChild['value']; - } - break; - - case 'xcal:rdate': - $propertyType = 'date-time'; - - foreach ($xmlProperty['value'] as $specialChild) { - $tagName = static::getTagName($specialChild['name']); - - if ('period' === $tagName) { - $propertyParameters['value'] = 'PERIOD'; - $propertyValue[] = implode('/', $specialChild['value']); - } else { - $propertyValue[] = $specialChild['value']; - } - } - break; - - default: - $propertyType = static::getTagName($xmlProperty['value'][0]['name']); - - foreach ($xmlProperty['value'] as $value) { - $propertyValue[] = $value['value']; - } - - if ('date' === $propertyType) { - $propertyParameters['value'] = 'DATE'; - } - break; - } - - $this->createProperty( - $parentComponent, - $propertyNamePrefix.$propertyName, - $propertyParameters, - $propertyType, - $propertyValue - ); - } - } - - /** - * Parse a component. - */ - protected function parseComponent(Component $parentComponent) - { - $components = $this->pointer['value'] ?: []; - - foreach ($components as $component) { - $componentName = static::getTagName($component['name']); - $currentComponent = $this->root->createComponent( - $componentName, - null, - false - ); - - $this->pointer = &$component; - $this->parseVCalendarComponents($currentComponent); - - $parentComponent->add($currentComponent); - } - } - - /** - * Create a property. - * - * @param string $name - * @param array $parameters - * @param string $type - * @param mixed $value - */ - protected function createProperty(Component $parentComponent, $name, $parameters, $type, $value) - { - $property = $this->root->createProperty( - $name, - null, - $parameters, - $type - ); - $parentComponent->add($property); - $property->setXmlValue($value); - } - - /** - * Sets the input data. - * - * @param resource|string $input - */ - public function setInput($input) - { - if (is_resource($input)) { - $input = stream_get_contents($input); - } - - if (is_string($input)) { - $reader = new SabreXml\Reader(); - $reader->elementMap['{'.self::XCAL_NAMESPACE.'}period'] - = XML\Element\KeyValue::class; - $reader->elementMap['{'.self::XCAL_NAMESPACE.'}recur'] - = XML\Element\KeyValue::class; - $reader->xml($input); - $input = $reader->parse(); - } - - $this->input = $input; - } - - /** - * Get tag name from a Clark notation. - * - * @param string $clarkedTagName - * - * @return string - */ - protected static function getTagName($clarkedTagName) - { - list(, $tagName) = SabreXml\Service::parseClarkNotation($clarkedTagName); - - return $tagName; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Parser/XML/Element/KeyValue.php b/lib/vendor/sabre/vobject/lib/Parser/XML/Element/KeyValue.php deleted file mode 100644 index e017725..0000000 --- a/lib/vendor/sabre/vobject/lib/Parser/XML/Element/KeyValue.php +++ /dev/null @@ -1,63 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - * - * @param XML\Reader $reader - */ - public static function xmlDeserialize(SabreXml\Reader $reader): array - { - // If there's no children, we don't do anything. - if ($reader->isEmptyElement) { - $reader->next(); - - return []; - } - - $values = []; - $reader->read(); - - do { - if (SabreXml\Reader::ELEMENT === $reader->nodeType) { - $name = $reader->localName; - $values[$name] = $reader->parseCurrentElement()['value']; - } else { - $reader->read(); - } - } while (SabreXml\Reader::END_ELEMENT !== $reader->nodeType); - - $reader->read(); - - return $values; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property.php b/lib/vendor/sabre/vobject/lib/Property.php deleted file mode 100644 index 7cf5914..0000000 --- a/lib/vendor/sabre/vobject/lib/Property.php +++ /dev/null @@ -1,646 +0,0 @@ -value syntax. - * - * @param Component $root The root document - * @param string $name - * @param string|array|null $value - * @param array $parameters List of parameters - * @param string $group The vcard property group - */ - public function __construct(Component $root, $name, $value = null, array $parameters = [], $group = null, ?int $lineIndex = null, ?string $lineString = null) - { - $this->name = $name; - $this->group = $group; - - $this->root = $root; - - foreach ($parameters as $k => $v) { - $this->add($k, $v); - } - - if (!is_null($value)) { - $this->setValue($value); - } - - if (!is_null($lineIndex)) { - $this->lineIndex = $lineIndex; - } - - if (!is_null($lineString)) { - $this->lineString = $lineString; - } - } - - /** - * Updates the current value. - * - * This may be either a single, or multiple strings in an array. - * - * @param string|array $value - */ - public function setValue($value) - { - $this->value = $value; - } - - /** - * Returns the current value. - * - * This method will always return a singular value. If this was a - * multi-value object, some decision will be made first on how to represent - * it as a string. - * - * To get the correct multi-value version, use getParts. - * - * @return string - */ - public function getValue() - { - if (is_array($this->value)) { - if (0 == count($this->value)) { - return; - } elseif (1 === count($this->value)) { - return $this->value[0]; - } else { - return $this->getRawMimeDirValue(); - } - } else { - return $this->value; - } - } - - /** - * Sets a multi-valued property. - */ - public function setParts(array $parts) - { - $this->value = $parts; - } - - /** - * Returns a multi-valued property. - * - * This method always returns an array, if there was only a single value, - * it will still be wrapped in an array. - * - * @return array - */ - public function getParts() - { - if (is_null($this->value)) { - return []; - } elseif (is_array($this->value)) { - return $this->value; - } else { - return [$this->value]; - } - } - - /** - * Adds a new parameter. - * - * If a parameter with same name already existed, the values will be - * combined. - * If nameless parameter is added, we try to guess its name. - * - * @param string $name - * @param string|array|null $value - */ - public function add($name, $value = null) - { - $noName = false; - if (null === $name) { - $name = Parameter::guessParameterNameByValue($value); - $noName = true; - } - - if (isset($this->parameters[strtoupper($name)])) { - $this->parameters[strtoupper($name)]->addValue($value); - } else { - $param = new Parameter($this->root, $name, $value); - $param->noName = $noName; - $this->parameters[$param->name] = $param; - } - } - - /** - * Returns an iterable list of children. - * - * @return array - */ - public function parameters() - { - return $this->parameters; - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - abstract public function getValueType(); - - /** - * Sets a raw value coming from a mimedir (iCalendar/vCard) file. - * - * This has been 'unfolded', so only 1 line will be passed. Unescaping is - * not yet done, but parameters are not included. - * - * @param string $val - */ - abstract public function setRawMimeDirValue($val); - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - abstract public function getRawMimeDirValue(); - - /** - * Turns the object back into a serialized blob. - * - * @return string - */ - public function serialize() - { - $str = $this->name; - if ($this->group) { - $str = $this->group.'.'.$this->name; - } - - foreach ($this->parameters() as $param) { - $str .= ';'.$param->serialize(); - } - - $str .= ':'.$this->getRawMimeDirValue(); - - $str = \preg_replace( - '/( - (?:^.)? # 1 additional byte in first line because of missing single space (see next line) - .{1,74} # max 75 bytes per line (1 byte is used for a single space added after every CRLF) - (?![\x80-\xbf]) # prevent splitting multibyte characters - )/x', - "$1\r\n ", - $str - ); - - // remove single space after last CRLF - return \substr($str, 0, -1); - } - - /** - * Returns the value, in the format it should be encoded for JSON. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - return $this->getParts(); - } - - /** - * Sets the JSON value, as it would appear in a jCard or jCal object. - * - * The value must always be an array. - */ - public function setJsonValue(array $value) - { - if (1 === count($value)) { - $this->setValue(reset($value)); - } else { - $this->setValue($value); - } - } - - /** - * This method returns an array, with the representation as it should be - * encoded in JSON. This is used to create jCard or jCal documents. - * - * @return array - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - $parameters = []; - - foreach ($this->parameters as $parameter) { - if ('VALUE' === $parameter->name) { - continue; - } - $parameters[strtolower($parameter->name)] = $parameter->jsonSerialize(); - } - // In jCard, we need to encode the property-group as a separate 'group' - // parameter. - if ($this->group) { - $parameters['group'] = $this->group; - } - - return array_merge( - [ - strtolower($this->name), - (object) $parameters, - strtolower($this->getValueType()), - ], - $this->getJsonValue() - ); - } - - /** - * Hydrate data from a XML subtree, as it would appear in a xCard or xCal - * object. - */ - public function setXmlValue(array $value) - { - $this->setJsonValue($value); - } - - /** - * This method serializes the data into XML. This is used to create xCard or - * xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - public function xmlSerialize(Xml\Writer $writer): void - { - $parameters = []; - - foreach ($this->parameters as $parameter) { - if ('VALUE' === $parameter->name) { - continue; - } - - $parameters[] = $parameter; - } - - $writer->startElement(strtolower($this->name)); - - if (!empty($parameters)) { - $writer->startElement('parameters'); - - foreach ($parameters as $parameter) { - $writer->startElement(strtolower($parameter->name)); - $writer->write($parameter); - $writer->endElement(); - } - - $writer->endElement(); - } - - $this->xmlSerializeValue($writer); - $writer->endElement(); - } - - /** - * This method serializes only the value of a property. This is used to - * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - protected function xmlSerializeValue(Xml\Writer $writer) - { - $valueType = strtolower($this->getValueType()); - - foreach ($this->getJsonValue() as $values) { - foreach ((array) $values as $value) { - $writer->writeElement($valueType, $value); - } - } - } - - /** - * Called when this object is being cast to a string. - * - * If the property only had a single value, you will get just that. In the - * case the property had multiple values, the contents will be escaped and - * combined with ,. - * - * @return string - */ - public function __toString() - { - return (string) $this->getValue(); - } - - /* ArrayAccess interface {{{ */ - - /** - * Checks if an array element exists. - * - * @param mixed $name - * - * @return bool - */ - #[\ReturnTypeWillChange] - public function offsetExists($name) - { - if (is_int($name)) { - return parent::offsetExists($name); - } - - $name = strtoupper($name); - - foreach ($this->parameters as $parameter) { - if ($parameter->name == $name) { - return true; - } - } - - return false; - } - - /** - * Returns a parameter. - * - * If the parameter does not exist, null is returned. - * - * @param string $name - * - * @return Node - */ - #[\ReturnTypeWillChange] - public function offsetGet($name) - { - if (is_int($name)) { - return parent::offsetGet($name); - } - $name = strtoupper($name); - - if (!isset($this->parameters[$name])) { - return; - } - - return $this->parameters[$name]; - } - - /** - * Creates a new parameter. - * - * @param string $name - * @param mixed $value - * - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetSet($name, $value) - { - if (is_int($name)) { - parent::offsetSet($name, $value); - // @codeCoverageIgnoreStart - // This will never be reached, because an exception is always - // thrown. - return; - // @codeCoverageIgnoreEnd - } - - $param = new Parameter($this->root, $name, $value); - $this->parameters[$param->name] = $param; - } - - /** - * Removes one or more parameters with the specified name. - * - * @param string $name - * - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetUnset($name) - { - if (is_int($name)) { - parent::offsetUnset($name); - // @codeCoverageIgnoreStart - // This will never be reached, because an exception is always - // thrown. - return; - // @codeCoverageIgnoreEnd - } - - unset($this->parameters[strtoupper($name)]); - } - - /* }}} */ - - /** - * This method is automatically called when the object is cloned. - * Specifically, this will ensure all child elements are also cloned. - */ - public function __clone() - { - foreach ($this->parameters as $key => $child) { - $this->parameters[$key] = clone $child; - $this->parameters[$key]->parent = $this; - } - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * - Node::REPAIR - If something is broken, and automatic repair may - * be attempted. - * - * An array is returned with warnings. - * - * Every item in the array has the following properties: - * * level - (number between 1 and 3 with severity information) - * * message - (human readable message) - * * node - (reference to the offending node) - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $warnings = []; - - // Checking if our value is UTF-8 - if (!StringUtil::isUTF8($this->getRawMimeDirValue())) { - $oldValue = $this->getRawMimeDirValue(); - $level = 3; - if ($options & self::REPAIR) { - $newValue = StringUtil::convertToUTF8($oldValue); - if (true || StringUtil::isUTF8($newValue)) { - $this->setRawMimeDirValue($newValue); - $level = 1; - } - } - - if (preg_match('%([\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])%', $oldValue, $matches)) { - $message = 'Property contained a control character (0x'.bin2hex($matches[1]).')'; - } else { - $message = 'Property is not valid UTF-8! '.$oldValue; - } - - $warnings[] = [ - 'level' => $level, - 'message' => $message, - 'node' => $this, - ]; - } - - // Checking if the propertyname does not contain any invalid bytes. - if (!preg_match('/^([A-Z0-9-]+)$/', $this->name)) { - $warnings[] = [ - 'level' => $options & self::REPAIR ? 1 : 3, - 'message' => 'The propertyname: '.$this->name.' contains invalid characters. Only A-Z, 0-9 and - are allowed', - 'node' => $this, - ]; - if ($options & self::REPAIR) { - // Uppercasing and converting underscores to dashes. - $this->name = strtoupper( - str_replace('_', '-', $this->name) - ); - // Removing every other invalid character - $this->name = preg_replace('/([^A-Z0-9-])/u', '', $this->name); - } - } - - if ($encoding = $this->offsetGet('ENCODING')) { - if (Document::VCARD40 === $this->root->getDocumentType()) { - $warnings[] = [ - 'level' => 3, - 'message' => 'ENCODING parameter is not valid in vCard 4.', - 'node' => $this, - ]; - } else { - $encoding = (string) $encoding; - - $allowedEncoding = []; - - switch ($this->root->getDocumentType()) { - case Document::ICALENDAR20: - $allowedEncoding = ['8BIT', 'BASE64']; - break; - case Document::VCARD21: - $allowedEncoding = ['QUOTED-PRINTABLE', 'BASE64', '8BIT']; - break; - case Document::VCARD30: - $allowedEncoding = ['B']; - //Repair vCard30 that use BASE64 encoding - if ($options & self::REPAIR) { - if ('BASE64' === strtoupper($encoding)) { - $encoding = 'B'; - $this['ENCODING'] = $encoding; - $warnings[] = [ - 'level' => 1, - 'message' => 'ENCODING=BASE64 has been transformed to ENCODING=B.', - 'node' => $this, - ]; - } - } - break; - } - if ($allowedEncoding && !in_array(strtoupper($encoding), $allowedEncoding)) { - $warnings[] = [ - 'level' => 3, - 'message' => 'ENCODING='.strtoupper($encoding).' is not valid for this document type.', - 'node' => $this, - ]; - } - } - } - - // Validating inner parameters - foreach ($this->parameters as $param) { - $warnings = array_merge($warnings, $param->validate($options)); - } - - return $warnings; - } - - /** - * Call this method on a document if you're done using it. - * - * It's intended to remove all circular references, so PHP can easily clean - * it up. - */ - public function destroy() - { - parent::destroy(); - foreach ($this->parameters as $param) { - $param->destroy(); - } - $this->parameters = []; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/Binary.php b/lib/vendor/sabre/vobject/lib/Property/Binary.php deleted file mode 100644 index 1262dd0..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/Binary.php +++ /dev/null @@ -1,109 +0,0 @@ -value = $value[0]; - } else { - throw new \InvalidArgumentException('The argument must either be a string or an array with only one child'); - } - } else { - $this->value = $value; - } - } - - /** - * Sets a raw value coming from a mimedir (iCalendar/vCard) file. - * - * This has been 'unfolded', so only 1 line will be passed. Unescaping is - * not yet done, but parameters are not included. - * - * @param string $val - */ - public function setRawMimeDirValue($val) - { - $this->value = base64_decode($val); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return base64_encode($this->value); - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'BINARY'; - } - - /** - * Returns the value, in the format it should be encoded for json. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - return [base64_encode($this->getValue())]; - } - - /** - * Sets the json value, as it would appear in a jCard or jCal object. - * - * The value must always be an array. - */ - public function setJsonValue(array $value) - { - $value = array_map('base64_decode', $value); - parent::setJsonValue($value); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/Boolean.php b/lib/vendor/sabre/vobject/lib/Property/Boolean.php deleted file mode 100644 index 4bd6ffd..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/Boolean.php +++ /dev/null @@ -1,72 +0,0 @@ -setValue($val); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return $this->value ? 'TRUE' : 'FALSE'; - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'BOOLEAN'; - } - - /** - * Hydrate data from a XML subtree, as it would appear in a xCard or xCal - * object. - */ - public function setXmlValue(array $value) - { - $value = array_map( - function ($value) { - return 'true' === $value; - }, - $value - ); - parent::setXmlValue($value); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/FlatText.php b/lib/vendor/sabre/vobject/lib/Property/FlatText.php deleted file mode 100644 index d15cfe0..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/FlatText.php +++ /dev/null @@ -1,46 +0,0 @@ -setValue($val); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/FloatValue.php b/lib/vendor/sabre/vobject/lib/Property/FloatValue.php deleted file mode 100644 index e780ae6..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/FloatValue.php +++ /dev/null @@ -1,124 +0,0 @@ -delimiter, $val); - foreach ($val as &$item) { - $item = (float) $item; - } - $this->setParts($val); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return implode( - $this->delimiter, - $this->getParts() - ); - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'FLOAT'; - } - - /** - * Returns the value, in the format it should be encoded for JSON. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - $val = array_map('floatval', $this->getParts()); - - // Special-casing the GEO property. - // - // See: - // http://tools.ietf.org/html/draft-ietf-jcardcal-jcal-04#section-3.4.1.2 - if ('GEO' === $this->name) { - return [$val]; - } - - return $val; - } - - /** - * Hydrate data from a XML subtree, as it would appear in a xCard or xCal - * object. - */ - public function setXmlValue(array $value) - { - $value = array_map('floatval', $value); - parent::setXmlValue($value); - } - - /** - * This method serializes only the value of a property. This is used to - * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - protected function xmlSerializeValue(Xml\Writer $writer) - { - // Special-casing the GEO property. - // - // See: - // http://tools.ietf.org/html/rfc6321#section-3.4.1.2 - if ('GEO' === $this->name) { - $value = array_map('floatval', $this->getParts()); - - $writer->writeElement('latitude', $value[0]); - $writer->writeElement('longitude', $value[1]); - } else { - parent::xmlSerializeValue($writer); - } - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php b/lib/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php deleted file mode 100644 index c90967d..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php +++ /dev/null @@ -1,63 +0,0 @@ -getValue(); - if (!strpos($input, ':')) { - return $input; - } - list($schema, $everythingElse) = explode(':', $input, 2); - $schema = strtolower($schema); - if ('mailto' === $schema) { - $everythingElse = strtolower($everythingElse); - } - - return $schema.':'.$everythingElse; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Date.php b/lib/vendor/sabre/vobject/lib/Property/ICalendar/Date.php deleted file mode 100644 index d8e86d1..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Date.php +++ /dev/null @@ -1,18 +0,0 @@ -setDateTimes($parts); - } else { - parent::setParts($parts); - } - } - - /** - * Updates the current value. - * - * This may be either a single, or multiple strings in an array. - * - * Instead of strings, you may also use DateTime here. - * - * @param string|array|DateTimeInterface $value - */ - public function setValue($value) - { - if (is_array($value) && isset($value[0]) && $value[0] instanceof DateTimeInterface) { - $this->setDateTimes($value); - } elseif ($value instanceof DateTimeInterface) { - $this->setDateTimes([$value]); - } else { - parent::setValue($value); - } - } - - /** - * Sets a raw value coming from a mimedir (iCalendar/vCard) file. - * - * This has been 'unfolded', so only 1 line will be passed. Unescaping is - * not yet done, but parameters are not included. - * - * @param string $val - */ - public function setRawMimeDirValue($val) - { - $this->setValue(explode($this->delimiter, $val)); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return implode($this->delimiter, $this->getParts()); - } - - /** - * Returns true if this is a DATE-TIME value, false if it's a DATE. - * - * @return bool - */ - public function hasTime() - { - return 'DATE' !== strtoupper((string) $this['VALUE']); - } - - /** - * Returns true if this is a floating DATE or DATE-TIME. - * - * Note that DATE is always floating. - */ - public function isFloating() - { - return - !$this->hasTime() || - ( - !isset($this['TZID']) && - false === strpos($this->getValue(), 'Z') - ); - } - - /** - * Returns a date-time value. - * - * Note that if this property contained more than 1 date-time, only the - * first will be returned. To get an array with multiple values, call - * getDateTimes. - * - * If no timezone information is known, because it's either an all-day - * property or floating time, we will use the DateTimeZone argument to - * figure out the exact date. - * - * @param DateTimeZone $timeZone - * - * @return \DateTimeImmutable - */ - public function getDateTime(?DateTimeZone $timeZone = null) - { - $dt = $this->getDateTimes($timeZone); - if (!$dt) { - return; - } - - return $dt[0]; - } - - /** - * Returns multiple date-time values. - * - * If no timezone information is known, because it's either an all-day - * property or floating time, we will use the DateTimeZone argument to - * figure out the exact date. - * - * @param DateTimeZone $timeZone - * - * @return \DateTimeImmutable[] - * @return \DateTime[] - */ - public function getDateTimes(?DateTimeZone $timeZone = null) - { - // Does the property have a TZID? - $tzid = $this['TZID']; - - if ($tzid) { - $timeZone = TimeZoneUtil::getTimeZone((string) $tzid, $this->root); - } - - $dts = []; - foreach ($this->getParts() as $part) { - $dts[] = DateTimeParser::parse($part, $timeZone); - } - - return $dts; - } - - /** - * Sets the property as a DateTime object. - * - * @param bool isFloating If set to true, timezones will be ignored - */ - public function setDateTime(DateTimeInterface $dt, $isFloating = false) - { - $this->setDateTimes([$dt], $isFloating); - } - - /** - * Sets the property as multiple date-time objects. - * - * The first value will be used as a reference for the timezones, and all - * the other values will be adjusted for that timezone - * - * @param DateTimeInterface[] $dt - * @param bool isFloating If set to true, timezones will be ignored - */ - public function setDateTimes(array $dt, $isFloating = false) - { - $values = []; - - if ($this->hasTime()) { - $tz = null; - $isUtc = false; - - foreach ($dt as $d) { - if ($isFloating) { - $values[] = $d->format('Ymd\\THis'); - continue; - } - if (is_null($tz)) { - $tz = $d->getTimeZone(); - $isUtc = in_array($tz->getName(), ['UTC', 'GMT', 'Z', '+00:00']); - if (!$isUtc) { - $this->offsetSet('TZID', $tz->getName()); - } - } else { - $d = $d->setTimeZone($tz); - } - - if ($isUtc) { - $values[] = $d->format('Ymd\\THis\\Z'); - } else { - $values[] = $d->format('Ymd\\THis'); - } - } - if ($isUtc || $isFloating) { - $this->offsetUnset('TZID'); - } - } else { - foreach ($dt as $d) { - $values[] = $d->format('Ymd'); - } - $this->offsetUnset('TZID'); - } - - $this->value = $values; - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return $this->hasTime() ? 'DATE-TIME' : 'DATE'; - } - - /** - * Returns the value, in the format it should be encoded for JSON. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - $dts = $this->getDateTimes(); - $hasTime = $this->hasTime(); - $isFloating = $this->isFloating(); - - $tz = $dts[0]->getTimeZone(); - $isUtc = $isFloating ? false : in_array($tz->getName(), ['UTC', 'GMT', 'Z']); - - return array_map( - function (DateTimeInterface $dt) use ($hasTime, $isUtc) { - if ($hasTime) { - return $dt->format('Y-m-d\\TH:i:s').($isUtc ? 'Z' : ''); - } else { - return $dt->format('Y-m-d'); - } - }, - $dts - ); - } - - /** - * Sets the json value, as it would appear in a jCard or jCal object. - * - * The value must always be an array. - */ - public function setJsonValue(array $value) - { - // dates and times in jCal have one difference to dates and times in - // iCalendar. In jCal date-parts are separated by dashes, and - // time-parts are separated by colons. It makes sense to just remove - // those. - $this->setValue( - array_map( - function ($item) { - return strtr($item, [':' => '', '-' => '']); - }, - $value - ) - ); - } - - /** - * We need to intercept offsetSet, because it may be used to alter the - * VALUE from DATE-TIME to DATE or vice-versa. - * - * @param string $name - * @param mixed $value - * - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetSet($name, $value) - { - parent::offsetSet($name, $value); - if ('VALUE' !== strtoupper($name)) { - return; - } - - // This will ensure that dates are correctly encoded. - $this->setDateTimes($this->getDateTimes()); - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on) - * 2 - An inconsequential issue - * 3 - A severe issue. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $messages = parent::validate($options); - $valueType = $this->getValueType(); - $values = $this->getParts(); - foreach ($values as $value) { - try { - switch ($valueType) { - case 'DATE': - DateTimeParser::parseDate($value); - break; - case 'DATE-TIME': - DateTimeParser::parseDateTime($value); - break; - } - } catch (InvalidDataException $e) { - $messages[] = [ - 'level' => 3, - 'message' => 'The supplied value ('.$value.') is not a correct '.$valueType, - 'node' => $this, - ]; - break; - } - } - - return $messages; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Duration.php b/lib/vendor/sabre/vobject/lib/Property/ICalendar/Duration.php deleted file mode 100644 index e18fe19..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Duration.php +++ /dev/null @@ -1,79 +0,0 @@ -setValue(explode($this->delimiter, $val)); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return implode($this->delimiter, $this->getParts()); - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'DURATION'; - } - - /** - * Returns a DateInterval representation of the Duration property. - * - * If the property has more than one value, only the first is returned. - * - * @return \DateInterval - */ - public function getDateInterval() - { - $parts = $this->getParts(); - $value = $parts[0]; - - return DateTimeParser::parseDuration($value); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Period.php b/lib/vendor/sabre/vobject/lib/Property/ICalendar/Period.php deleted file mode 100644 index ae8a789..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Period.php +++ /dev/null @@ -1,135 +0,0 @@ -setValue(explode($this->delimiter, $val)); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return implode($this->delimiter, $this->getParts()); - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'PERIOD'; - } - - /** - * Sets the json value, as it would appear in a jCard or jCal object. - * - * The value must always be an array. - */ - public function setJsonValue(array $value) - { - $value = array_map( - function ($item) { - return strtr(implode('/', $item), [':' => '', '-' => '']); - }, - $value - ); - parent::setJsonValue($value); - } - - /** - * Returns the value, in the format it should be encoded for json. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - $return = []; - foreach ($this->getParts() as $item) { - list($start, $end) = explode('/', $item, 2); - - $start = DateTimeParser::parseDateTime($start); - - // This is a duration value. - if ('P' === $end[0]) { - $return[] = [ - $start->format('Y-m-d\\TH:i:s'), - $end, - ]; - } else { - $end = DateTimeParser::parseDateTime($end); - $return[] = [ - $start->format('Y-m-d\\TH:i:s'), - $end->format('Y-m-d\\TH:i:s'), - ]; - } - } - - return $return; - } - - /** - * This method serializes only the value of a property. This is used to - * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - protected function xmlSerializeValue(Xml\Writer $writer) - { - $writer->startElement(strtolower($this->getValueType())); - $value = $this->getJsonValue(); - $writer->writeElement('start', $value[0][0]); - - if ('P' === $value[0][1][0]) { - $writer->writeElement('duration', $value[0][1]); - } else { - $writer->writeElement('end', $value[0][1]); - } - - $writer->endElement(); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Recur.php b/lib/vendor/sabre/vobject/lib/Property/ICalendar/Recur.php deleted file mode 100644 index cd3d7a5..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/ICalendar/Recur.php +++ /dev/null @@ -1,344 +0,0 @@ -value array that is accessible using - * getParts, and may be set using setParts. - * - * @copyright Copyright (C) fruux GmbH (https://fruux.com/) - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class Recur extends Property -{ - /** - * Updates the current value. - * - * This may be either a single, or multiple strings in an array. - * - * @param string|array $value - */ - public function setValue($value) - { - // If we're getting the data from json, we'll be receiving an object - if ($value instanceof \StdClass) { - $value = (array) $value; - } - - if (is_array($value)) { - $newVal = []; - foreach ($value as $k => $v) { - if (is_string($v)) { - $v = strtoupper($v); - - // The value had multiple sub-values - if (false !== strpos($v, ',')) { - $v = explode(',', $v); - } - if (0 === strcmp($k, 'until')) { - $v = strtr($v, [':' => '', '-' => '']); - } - } elseif (is_array($v)) { - $v = array_map('strtoupper', $v); - } - - $newVal[strtoupper($k)] = $v; - } - $this->value = $newVal; - } elseif (is_string($value)) { - $this->value = self::stringToArray($value); - } else { - throw new \InvalidArgumentException('You must either pass a string, or a key=>value array'); - } - } - - /** - * Returns the current value. - * - * This method will always return a singular value. If this was a - * multi-value object, some decision will be made first on how to represent - * it as a string. - * - * To get the correct multi-value version, use getParts. - * - * @return string - */ - public function getValue() - { - $out = []; - foreach ($this->value as $key => $value) { - $out[] = $key.'='.(is_array($value) ? implode(',', $value) : $value); - } - - return strtoupper(implode(';', $out)); - } - - /** - * Sets a multi-valued property. - */ - public function setParts(array $parts) - { - $this->setValue($parts); - } - - /** - * Returns a multi-valued property. - * - * This method always returns an array, if there was only a single value, - * it will still be wrapped in an array. - * - * @return array - */ - public function getParts() - { - return $this->value; - } - - /** - * Sets a raw value coming from a mimedir (iCalendar/vCard) file. - * - * This has been 'unfolded', so only 1 line will be passed. Unescaping is - * not yet done, but parameters are not included. - * - * @param string $val - */ - public function setRawMimeDirValue($val) - { - $this->setValue($val); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return $this->getValue(); - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'RECUR'; - } - - /** - * Returns the value, in the format it should be encoded for json. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - $values = []; - foreach ($this->getParts() as $k => $v) { - if (0 === strcmp($k, 'UNTIL')) { - $date = new DateTime($this->root, null, $v); - $values[strtolower($k)] = $date->getJsonValue()[0]; - } elseif (0 === strcmp($k, 'COUNT')) { - $values[strtolower($k)] = intval($v); - } else { - $values[strtolower($k)] = $v; - } - } - - return [$values]; - } - - /** - * This method serializes only the value of a property. This is used to - * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - protected function xmlSerializeValue(Xml\Writer $writer) - { - $valueType = strtolower($this->getValueType()); - - foreach ($this->getJsonValue() as $value) { - $writer->writeElement($valueType, $value); - } - } - - /** - * Parses an RRULE value string, and turns it into a struct-ish array. - * - * @param string $value - * - * @return array - */ - public static function stringToArray($value) - { - $value = strtoupper($value); - $newValue = []; - foreach (explode(';', $value) as $part) { - // Skipping empty parts. - if (empty($part)) { - continue; - } - - $parts = explode('=', $part); - - if (2 !== count($parts)) { - throw new InvalidDataException('The supplied iCalendar RRULE part is incorrect: '.$part); - } - - list($partName, $partValue) = $parts; - - // The value itself had multiple values.. - if (false !== strpos($partValue, ',')) { - $partValue = explode(',', $partValue); - } - $newValue[$partName] = $partValue; - } - - return $newValue; - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on) - * 2 - An inconsequential issue - * 3 - A severe issue. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $repair = ($options & self::REPAIR); - - $warnings = parent::validate($options); - $values = $this->getParts(); - - foreach ($values as $key => $value) { - if ('' === $value) { - $warnings[] = [ - 'level' => $repair ? 1 : 3, - 'message' => 'Invalid value for '.$key.' in '.$this->name, - 'node' => $this, - ]; - if ($repair) { - unset($values[$key]); - } - } elseif ('BYMONTH' == $key) { - $byMonth = (array) $value; - foreach ($byMonth as $i => $v) { - if (!is_numeric($v) || (int) $v < 1 || (int) $v > 12) { - $warnings[] = [ - 'level' => $repair ? 1 : 3, - 'message' => 'BYMONTH in RRULE must have value(s) between 1 and 12!', - 'node' => $this, - ]; - if ($repair) { - if (is_array($value)) { - unset($values[$key][$i]); - } else { - unset($values[$key]); - } - } - } - } - // if there is no valid entry left, remove the whole value - if (is_array($value) && empty($values[$key])) { - unset($values[$key]); - } - } elseif ('BYWEEKNO' == $key) { - $byWeekNo = (array) $value; - foreach ($byWeekNo as $i => $v) { - if (!is_numeric($v) || (int) $v < -53 || 0 == (int) $v || (int) $v > 53) { - $warnings[] = [ - 'level' => $repair ? 1 : 3, - 'message' => 'BYWEEKNO in RRULE must have value(s) from -53 to -1, or 1 to 53!', - 'node' => $this, - ]; - if ($repair) { - if (is_array($value)) { - unset($values[$key][$i]); - } else { - unset($values[$key]); - } - } - } - } - // if there is no valid entry left, remove the whole value - if (is_array($value) && empty($values[$key])) { - unset($values[$key]); - } - } elseif ('BYYEARDAY' == $key) { - $byYearDay = (array) $value; - foreach ($byYearDay as $i => $v) { - if (!is_numeric($v) || (int) $v < -366 || 0 == (int) $v || (int) $v > 366) { - $warnings[] = [ - 'level' => $repair ? 1 : 3, - 'message' => 'BYYEARDAY in RRULE must have value(s) from -366 to -1, or 1 to 366!', - 'node' => $this, - ]; - if ($repair) { - if (is_array($value)) { - unset($values[$key][$i]); - } else { - unset($values[$key]); - } - } - } - } - // if there is no valid entry left, remove the whole value - if (is_array($value) && empty($values[$key])) { - unset($values[$key]); - } - } - } - if (!isset($values['FREQ'])) { - $warnings[] = [ - 'level' => $repair ? 1 : 3, - 'message' => 'FREQ is required in '.$this->name, - 'node' => $this, - ]; - if ($repair) { - $this->parent->remove($this); - } - } - if ($repair) { - $this->setValue($values); - } - - return $warnings; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/IntegerValue.php b/lib/vendor/sabre/vobject/lib/Property/IntegerValue.php deleted file mode 100644 index 3ae7752..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/IntegerValue.php +++ /dev/null @@ -1,76 +0,0 @@ -setValue((int) $val); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return $this->value; - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'INTEGER'; - } - - /** - * Returns the value, in the format it should be encoded for json. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - return [(int) $this->getValue()]; - } - - /** - * Hydrate data from a XML subtree, as it would appear in a xCard or xCal - * object. - */ - public function setXmlValue(array $value) - { - $value = array_map('intval', $value); - parent::setXmlValue($value); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/Text.php b/lib/vendor/sabre/vobject/lib/Property/Text.php deleted file mode 100644 index 16d2c07..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/Text.php +++ /dev/null @@ -1,392 +0,0 @@ - 5, - 'ADR' => 7, - ]; - - /** - * Creates the property. - * - * You can specify the parameters either in key=>value syntax, in which case - * parameters will automatically be created, or you can just pass a list of - * Parameter objects. - * - * @param Component $root The root document - * @param string $name - * @param string|array|null $value - * @param array $parameters List of parameters - * @param string $group The vcard property group - */ - public function __construct(Component $root, $name, $value = null, array $parameters = [], $group = null) - { - // There's two types of multi-valued text properties: - // 1. multivalue properties. - // 2. structured value properties - // - // The former is always separated by a comma, the latter by semi-colon. - if (in_array($name, $this->structuredValues)) { - $this->delimiter = ';'; - } - - parent::__construct($root, $name, $value, $parameters, $group); - } - - /** - * Sets a raw value coming from a mimedir (iCalendar/vCard) file. - * - * This has been 'unfolded', so only 1 line will be passed. Unescaping is - * not yet done, but parameters are not included. - * - * @param string $val - */ - public function setRawMimeDirValue($val) - { - $this->setValue(MimeDir::unescapeValue($val, $this->delimiter)); - } - - /** - * Sets the value as a quoted-printable encoded string. - * - * @param string $val - */ - public function setQuotedPrintableValue($val) - { - $val = quoted_printable_decode($val); - - // Quoted printable only appears in vCard 2.1, and the only character - // that may be escaped there is ;. So we are simply splitting on just - // that. - // - // We also don't have to unescape \\, so all we need to look for is a ; - // that's not preceded with a \. - $regex = '# (?setValue($matches); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - $val = $this->getParts(); - - if (isset($this->minimumPropertyValues[$this->name])) { - $val = array_pad($val, $this->minimumPropertyValues[$this->name], ''); - } - - foreach ($val as &$item) { - if (!is_array($item)) { - $item = [$item]; - } - - foreach ($item as &$subItem) { - if (!is_null($subItem)) { - $subItem = strtr( - $subItem, - [ - '\\' => '\\\\', - ';' => '\;', - ',' => '\,', - "\n" => '\n', - "\r" => '', - ] - ); - } - } - $item = implode(',', $item); - } - - return implode($this->delimiter, $val); - } - - /** - * Returns the value, in the format it should be encoded for json. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - // Structured text values should always be returned as a single - // array-item. Multi-value text should be returned as multiple items in - // the top-array. - if (in_array($this->name, $this->structuredValues)) { - return [$this->getParts()]; - } - - return $this->getParts(); - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'TEXT'; - } - - /** - * Turns the object back into a serialized blob. - * - * @return string - */ - public function serialize() - { - // We need to kick in a special type of encoding, if it's a 2.1 vcard. - if (Document::VCARD21 !== $this->root->getDocumentType()) { - return parent::serialize(); - } - - $val = $this->getParts(); - - if (isset($this->minimumPropertyValues[$this->name])) { - $val = \array_pad($val, $this->minimumPropertyValues[$this->name], ''); - } - - // Imploding multiple parts into a single value, and splitting the - // values with ;. - if (\count($val) > 1) { - foreach ($val as $k => $v) { - $val[$k] = \str_replace(';', '\;', $v); - } - $val = \implode(';', $val); - } else { - $val = $val[0]; - } - - $str = $this->name; - if ($this->group) { - $str = $this->group.'.'.$this->name; - } - foreach ($this->parameters as $param) { - if ('QUOTED-PRINTABLE' === $param->getValue()) { - continue; - } - $str .= ';'.$param->serialize(); - } - - // If the resulting value contains a \n, we must encode it as - // quoted-printable. - if (false !== \strpos($val, "\n")) { - $str .= ';ENCODING=QUOTED-PRINTABLE:'; - $lastLine = $str; - $out = null; - - // The PHP built-in quoted-printable-encode does not correctly - // encode newlines for us. Specifically, the \r\n sequence must in - // vcards be encoded as =0D=OA and we must insert soft-newlines - // every 75 bytes. - for ($ii = 0; $ii < \strlen($val); ++$ii) { - $ord = \ord($val[$ii]); - // These characters are encoded as themselves. - if ($ord >= 32 && $ord <= 126) { - $lastLine .= $val[$ii]; - } else { - $lastLine .= '='.\strtoupper(\bin2hex($val[$ii])); - } - if (\strlen($lastLine) >= 75) { - // Soft line break - $out .= $lastLine."=\r\n "; - $lastLine = null; - } - } - if (!\is_null($lastLine)) { - $out .= $lastLine."\r\n"; - } - - return $out; - } else { - $str .= ':'.$val; - - $str = \preg_replace( - '/( - (?:^.)? # 1 additional byte in first line because of missing single space (see next line) - .{1,74} # max 75 bytes per line (1 byte is used for a single space added after every CRLF) - (?![\x80-\xbf]) # prevent splitting multibyte characters - )/x', - "$1\r\n ", - $str - ); - - // remove single space after last CRLF - return \substr($str, 0, -1); - } - } - - /** - * This method serializes only the value of a property. This is used to - * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - protected function xmlSerializeValue(Xml\Writer $writer) - { - $values = $this->getParts(); - - $map = function ($items) use ($values, $writer) { - foreach ($items as $i => $item) { - $writer->writeElement( - $item, - !empty($values[$i]) ? $values[$i] : null - ); - } - }; - - switch ($this->name) { - // Special-casing the REQUEST-STATUS property. - // - // See: - // http://tools.ietf.org/html/rfc6321#section-3.4.1.3 - case 'REQUEST-STATUS': - $writer->writeElement('code', $values[0]); - $writer->writeElement('description', $values[1]); - - if (isset($values[2])) { - $writer->writeElement('data', $values[2]); - } - break; - - case 'N': - $map([ - 'surname', - 'given', - 'additional', - 'prefix', - 'suffix', - ]); - break; - - case 'GENDER': - $map([ - 'sex', - 'text', - ]); - break; - - case 'ADR': - $map([ - 'pobox', - 'ext', - 'street', - 'locality', - 'region', - 'code', - 'country', - ]); - break; - - case 'CLIENTPIDMAP': - $map([ - 'sourceid', - 'uri', - ]); - break; - - default: - parent::xmlSerializeValue($writer); - } - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * - Node::REPAIR - If something is broken, and automatic repair may - * be attempted. - * - * An array is returned with warnings. - * - * Every item in the array has the following properties: - * * level - (number between 1 and 3 with severity information) - * * message - (human readable message) - * * node - (reference to the offending node) - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $warnings = parent::validate($options); - - if (isset($this->minimumPropertyValues[$this->name])) { - $minimum = $this->minimumPropertyValues[$this->name]; - $parts = $this->getParts(); - if (count($parts) < $minimum) { - $warnings[] = [ - 'level' => $options & self::REPAIR ? 1 : 3, - 'message' => 'The '.$this->name.' property must have at least '.$minimum.' values. It only has '.count($parts), - 'node' => $this, - ]; - if ($options & self::REPAIR) { - $parts = array_pad($parts, $minimum, ''); - $this->setParts($parts); - } - } - } - - return $warnings; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/Time.php b/lib/vendor/sabre/vobject/lib/Property/Time.php deleted file mode 100644 index 1b81609..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/Time.php +++ /dev/null @@ -1,131 +0,0 @@ -setValue(reset($value)); - } else { - $this->setValue($value); - } - } - - /** - * Returns the value, in the format it should be encoded for json. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - $parts = DateTimeParser::parseVCardTime($this->getValue()); - $timeStr = ''; - - // Hour - if (!is_null($parts['hour'])) { - $timeStr .= $parts['hour']; - - if (!is_null($parts['minute'])) { - $timeStr .= ':'; - } - } else { - // We know either minute or second _must_ be set, so we insert a - // dash for an empty value. - $timeStr .= '-'; - } - - // Minute - if (!is_null($parts['minute'])) { - $timeStr .= $parts['minute']; - - if (!is_null($parts['second'])) { - $timeStr .= ':'; - } - } else { - if (isset($parts['second'])) { - // Dash for empty minute - $timeStr .= '-'; - } - } - - // Second - if (!is_null($parts['second'])) { - $timeStr .= $parts['second']; - } - - // Timezone - if (!is_null($parts['timezone'])) { - if ('Z' === $parts['timezone']) { - $timeStr .= 'Z'; - } else { - $timeStr .= - preg_replace('/([0-9]{2})([0-9]{2})$/', '$1:$2', $parts['timezone']); - } - } - - return [$timeStr]; - } - - /** - * Hydrate data from a XML subtree, as it would appear in a xCard or xCal - * object. - */ - public function setXmlValue(array $value) - { - $value = array_map( - function ($value) { - return str_replace(':', '', $value); - }, - $value - ); - parent::setXmlValue($value); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/Unknown.php b/lib/vendor/sabre/vobject/lib/Property/Unknown.php deleted file mode 100644 index 6f404c2..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/Unknown.php +++ /dev/null @@ -1,41 +0,0 @@ -getRawMimeDirValue()]; - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'UNKNOWN'; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/Uri.php b/lib/vendor/sabre/vobject/lib/Property/Uri.php deleted file mode 100644 index 1ad1fb1..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/Uri.php +++ /dev/null @@ -1,116 +0,0 @@ -name, ['URL', 'PHOTO'])) { - // If we are encoding a URI value, and this URI value has no - // VALUE=URI parameter, we add it anyway. - // - // This is not required by any spec, but both Apple iCal and Apple - // AddressBook (at least in version 10.8) will trip over this if - // this is not set, and so it improves compatibility. - // - // See Issue #227 and #235 - $parameters['VALUE'] = new Parameter($this->root, 'VALUE', 'URI'); - } - - return $parameters; - } - - /** - * Sets a raw value coming from a mimedir (iCalendar/vCard) file. - * - * This has been 'unfolded', so only 1 line will be passed. Unescaping is - * not yet done, but parameters are not included. - * - * @param string $val - */ - public function setRawMimeDirValue($val) - { - // Normally we don't need to do any type of unescaping for these - // properties, however.. we've noticed that Google Contacts - // specifically escapes the colon (:) with a backslash. While I have - // no clue why they thought that was a good idea, I'm unescaping it - // anyway. - // - // Good thing backslashes are not allowed in urls. Makes it easy to - // assume that a backslash is always intended as an escape character. - if ('URL' === $this->name) { - $regex = '# (?: (\\\\ (?: \\\\ | : ) ) ) #x'; - $matches = preg_split($regex, $val, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); - $newVal = ''; - foreach ($matches as $match) { - switch ($match) { - case '\:': - $newVal .= ':'; - break; - default: - $newVal .= $match; - break; - } - } - $this->value = $newVal; - } else { - $this->value = strtr($val, ['\,' => ',']); - } - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - if (is_array($this->value)) { - $value = $this->value[0]; - } else { - $value = $this->value; - } - - return strtr($value, [',' => '\,']); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/UtcOffset.php b/lib/vendor/sabre/vobject/lib/Property/UtcOffset.php deleted file mode 100644 index 04b8844..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/UtcOffset.php +++ /dev/null @@ -1,70 +0,0 @@ -value = $dt->format('Ymd'); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/VCard/DateAndOrTime.php b/lib/vendor/sabre/vobject/lib/Property/VCard/DateAndOrTime.php deleted file mode 100644 index 7bf79c4..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/VCard/DateAndOrTime.php +++ /dev/null @@ -1,367 +0,0 @@ - 1) { - throw new \InvalidArgumentException('Only one value allowed'); - } - if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) { - $this->setDateTime($parts[0]); - } else { - parent::setParts($parts); - } - } - - /** - * Updates the current value. - * - * This may be either a single, or multiple strings in an array. - * - * Instead of strings, you may also use DateTimeInterface here. - * - * @param string|array|DateTimeInterface $value - */ - public function setValue($value) - { - if ($value instanceof DateTimeInterface) { - $this->setDateTime($value); - } else { - parent::setValue($value); - } - } - - /** - * Sets the property as a DateTime object. - */ - public function setDateTime(DateTimeInterface $dt) - { - $tz = $dt->getTimeZone(); - $isUtc = in_array($tz->getName(), ['UTC', 'GMT', 'Z']); - - if ($isUtc) { - $value = $dt->format('Ymd\\THis\\Z'); - } else { - // Calculating the offset. - $value = $dt->format('Ymd\\THisO'); - } - - $this->value = $value; - } - - /** - * Returns a date-time value. - * - * Note that if this property contained more than 1 date-time, only the - * first will be returned. To get an array with multiple values, call - * getDateTimes. - * - * If no time was specified, we will always use midnight (in the default - * timezone) as the time. - * - * If parts of the date were omitted, such as the year, we will grab the - * current values for those. So at the time of writing, if the year was - * omitted, we would have filled in 2014. - * - * @return DateTimeImmutable - */ - public function getDateTime() - { - $now = new DateTime(); - - $tzFormat = 0 === $now->getTimezone()->getOffset($now) ? '\\Z' : 'O'; - $nowParts = DateTimeParser::parseVCardDateTime($now->format('Ymd\\This'.$tzFormat)); - - $dateParts = DateTimeParser::parseVCardDateTime($this->getValue()); - - // This sets all the missing parts to the current date/time. - // So if the year was missing for a birthday, we're making it 'this - // year'. - foreach ($dateParts as $k => $v) { - if (is_null($v)) { - $dateParts[$k] = $nowParts[$k]; - } - } - - return new DateTimeImmutable("$dateParts[year]-$dateParts[month]-$dateParts[date] $dateParts[hour]:$dateParts[minute]:$dateParts[second] $dateParts[timezone]"); - } - - /** - * Returns the value, in the format it should be encoded for json. - * - * This method must always return an array. - * - * @return array - */ - public function getJsonValue() - { - $parts = DateTimeParser::parseVCardDateTime($this->getValue()); - - $dateStr = ''; - - // Year - if (!is_null($parts['year'])) { - $dateStr .= $parts['year']; - - if (!is_null($parts['month'])) { - // If a year and a month is set, we need to insert a separator - // dash. - $dateStr .= '-'; - } - } else { - if (!is_null($parts['month']) || !is_null($parts['date'])) { - // Inserting two dashes - $dateStr .= '--'; - } - } - - // Month - if (!is_null($parts['month'])) { - $dateStr .= $parts['month']; - - if (isset($parts['date'])) { - // If month and date are set, we need the separator dash. - $dateStr .= '-'; - } - } elseif (isset($parts['date'])) { - // If the month is empty, and a date is set, we need a 'empty - // dash' - $dateStr .= '-'; - } - - // Date - if (!is_null($parts['date'])) { - $dateStr .= $parts['date']; - } - - // Early exit if we don't have a time string. - if (is_null($parts['hour']) && is_null($parts['minute']) && is_null($parts['second'])) { - return [$dateStr]; - } - - $dateStr .= 'T'; - - // Hour - if (!is_null($parts['hour'])) { - $dateStr .= $parts['hour']; - - if (!is_null($parts['minute'])) { - $dateStr .= ':'; - } - } else { - // We know either minute or second _must_ be set, so we insert a - // dash for an empty value. - $dateStr .= '-'; - } - - // Minute - if (!is_null($parts['minute'])) { - $dateStr .= $parts['minute']; - - if (!is_null($parts['second'])) { - $dateStr .= ':'; - } - } elseif (isset($parts['second'])) { - // Dash for empty minute - $dateStr .= '-'; - } - - // Second - if (!is_null($parts['second'])) { - $dateStr .= $parts['second']; - } - - // Timezone - if (!is_null($parts['timezone'])) { - $dateStr .= $parts['timezone']; - } - - return [$dateStr]; - } - - /** - * This method serializes only the value of a property. This is used to - * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - protected function xmlSerializeValue(Xml\Writer $writer) - { - $valueType = strtolower($this->getValueType()); - $parts = DateTimeParser::parseVCardDateAndOrTime($this->getValue()); - $value = ''; - - // $d = defined - $d = function ($part) use ($parts) { - return !is_null($parts[$part]); - }; - - // $r = read - $r = function ($part) use ($parts) { - return $parts[$part]; - }; - - // From the Relax NG Schema. - // - // # 4.3.1 - // value-date = element date { - // xsd:string { pattern = "\d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d" } - // } - if (($d('year') || $d('month') || $d('date')) - && (!$d('hour') && !$d('minute') && !$d('second') && !$d('timezone'))) { - if ($d('year') && $d('month') && $d('date')) { - $value .= $r('year').$r('month').$r('date'); - } elseif ($d('year') && $d('month') && !$d('date')) { - $value .= $r('year').'-'.$r('month'); - } elseif (!$d('year') && $d('month')) { - $value .= '--'.$r('month').$r('date'); - } elseif (!$d('year') && !$d('month') && $d('date')) { - $value .= '---'.$r('date'); - } - - // # 4.3.2 - // value-time = element time { - // xsd:string { pattern = "(\d\d(\d\d(\d\d)?)?|-\d\d(\d\d?)|--\d\d)" - // ~ "(Z|[+\-]\d\d(\d\d)?)?" } - // } - } elseif ((!$d('year') && !$d('month') && !$d('date')) - && ($d('hour') || $d('minute') || $d('second'))) { - if ($d('hour')) { - $value .= $r('hour').$r('minute').$r('second'); - } elseif ($d('minute')) { - $value .= '-'.$r('minute').$r('second'); - } elseif ($d('second')) { - $value .= '--'.$r('second'); - } - - $value .= $r('timezone'); - - // # 4.3.3 - // value-date-time = element date-time { - // xsd:string { pattern = "(\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?" - // ~ "(Z|[+\-]\d\d(\d\d)?)?" } - // } - } elseif ($d('date') && $d('hour')) { - if ($d('year') && $d('month') && $d('date')) { - $value .= $r('year').$r('month').$r('date'); - } elseif (!$d('year') && $d('month') && $d('date')) { - $value .= '--'.$r('month').$r('date'); - } elseif (!$d('year') && !$d('month') && $d('date')) { - $value .= '---'.$r('date'); - } - - $value .= 'T'.$r('hour').$r('minute').$r('second'). - $r('timezone'); - } - - $writer->writeElement($valueType, $value); - } - - /** - * Sets a raw value coming from a mimedir (iCalendar/vCard) file. - * - * This has been 'unfolded', so only 1 line will be passed. Unescaping is - * not yet done, but parameters are not included. - * - * @param string $val - */ - public function setRawMimeDirValue($val) - { - $this->setValue($val); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return implode($this->delimiter, $this->getParts()); - } - - /** - * Validates the node for correctness. - * - * The following options are supported: - * Node::REPAIR - May attempt to automatically repair the problem. - * - * This method returns an array with detected problems. - * Every element has the following properties: - * - * * level - problem level. - * * message - A human-readable string describing the issue. - * * node - A reference to the problematic node. - * - * The level means: - * 1 - The issue was repaired (only happens if REPAIR was turned on) - * 2 - An inconsequential issue - * 3 - A severe issue. - * - * @param int $options - * - * @return array - */ - public function validate($options = 0) - { - $messages = parent::validate($options); - $value = $this->getValue(); - - try { - DateTimeParser::parseVCardDateTime($value); - } catch (InvalidDataException $e) { - $messages[] = [ - 'level' => 3, - 'message' => 'The supplied value ('.$value.') is not a correct DATE-AND-OR-TIME property', - 'node' => $this, - ]; - } - - return $messages; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/VCard/DateTime.php b/lib/vendor/sabre/vobject/lib/Property/VCard/DateTime.php deleted file mode 100644 index 49c1f35..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/VCard/DateTime.php +++ /dev/null @@ -1,28 +0,0 @@ -setValue($val); - } - - /** - * Returns a raw mime-dir representation of the value. - * - * @return string - */ - public function getRawMimeDirValue() - { - return $this->getValue(); - } - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'LANGUAGE-TAG'; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/VCard/PhoneNumber.php b/lib/vendor/sabre/vobject/lib/Property/VCard/PhoneNumber.php deleted file mode 100644 index b714ffd..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/VCard/PhoneNumber.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ -class PhoneNumber extends Property\Text -{ - protected $structuredValues = []; - - /** - * Returns the type of value. - * - * This corresponds to the VALUE= parameter. Every property also has a - * 'default' valueType. - * - * @return string - */ - public function getValueType() - { - return 'PHONE-NUMBER'; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Property/VCard/TimeStamp.php b/lib/vendor/sabre/vobject/lib/Property/VCard/TimeStamp.php deleted file mode 100644 index da6ea3d..0000000 --- a/lib/vendor/sabre/vobject/lib/Property/VCard/TimeStamp.php +++ /dev/null @@ -1,81 +0,0 @@ -getValue()); - - $dateStr = - $parts['year'].'-'. - $parts['month'].'-'. - $parts['date'].'T'. - $parts['hour'].':'. - $parts['minute'].':'. - $parts['second']; - - // Timezone - if (!is_null($parts['timezone'])) { - $dateStr .= $parts['timezone']; - } - - return [$dateStr]; - } - - /** - * This method serializes only the value of a property. This is used to - * create xCard or xCal documents. - * - * @param Xml\Writer $writer XML writer - */ - protected function xmlSerializeValue(Xml\Writer $writer) - { - // xCard is the only XML and JSON format that has the same date and time - // format than vCard. - $valueType = strtolower($this->getValueType()); - $writer->writeElement($valueType, $this->getValue()); - } -} diff --git a/lib/vendor/sabre/vobject/lib/Reader.php b/lib/vendor/sabre/vobject/lib/Reader.php deleted file mode 100644 index 055d546..0000000 --- a/lib/vendor/sabre/vobject/lib/Reader.php +++ /dev/null @@ -1,95 +0,0 @@ -setCharset($charset); - $result = $parser->parse($data, $options); - - return $result; - } - - /** - * Parses a jCard or jCal object, and returns the top component. - * - * The options argument is a bitfield. Pass any of the OPTIONS constant to - * alter the parsers' behaviour. - * - * You can either a string, a readable stream, or an array for its input. - * Specifying the array is useful if json_decode was already called on the - * input. - * - * @param string|resource|array $data - * @param int $options - * - * @return Document - */ - public static function readJson($data, $options = 0) - { - $parser = new Parser\Json(); - $result = $parser->parse($data, $options); - - return $result; - } - - /** - * Parses a xCard or xCal object, and returns the top component. - * - * The options argument is a bitfield. Pass any of the OPTIONS constant to - * alter the parsers' behaviour. - * - * You can either supply a string, or a readable stream for input. - * - * @param string|resource $data - * @param int $options - * - * @return Document - */ - public static function readXML($data, $options = 0) - { - $parser = new Parser\XML(); - $result = $parser->parse($data, $options); - - return $result; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Recur/EventIterator.php b/lib/vendor/sabre/vobject/lib/Recur/EventIterator.php deleted file mode 100644 index 212c147..0000000 --- a/lib/vendor/sabre/vobject/lib/Recur/EventIterator.php +++ /dev/null @@ -1,501 +0,0 @@ -timeZone = $timeZone; - - if (is_array($input)) { - $events = $input; - } elseif ($input instanceof VEvent) { - // Single instance mode. - $events = [$input]; - } else { - // Calendar + UID mode. - $uid = (string) $uid; - if (!$uid) { - throw new InvalidArgumentException('The UID argument is required when a VCALENDAR is passed to this constructor'); - } - if (!isset($input->VEVENT)) { - throw new InvalidArgumentException('No events found in this calendar'); - } - $events = $input->getByUID($uid); - } - - foreach ($events as $vevent) { - if (!isset($vevent->{'RECURRENCE-ID'})) { - $this->masterEvent = $vevent; - } else { - $this->exceptions[ - $vevent->{'RECURRENCE-ID'}->getDateTime($this->timeZone)->getTimeStamp() - ] = true; - $this->overriddenEvents[] = $vevent; - } - } - - if (!$this->masterEvent) { - // No base event was found. CalDAV does allow cases where only - // overridden instances are stored. - // - // In this particular case, we're just going to grab the first - // event and use that instead. This may not always give the - // desired result. - if (!count($this->overriddenEvents)) { - throw new InvalidArgumentException('This VCALENDAR did not have an event with UID: '.$uid); - } - $this->masterEvent = array_shift($this->overriddenEvents); - } - - $this->startDate = $this->masterEvent->DTSTART->getDateTime($this->timeZone); - $this->allDay = !$this->masterEvent->DTSTART->hasTime(); - - if (isset($this->masterEvent->EXDATE)) { - foreach ($this->masterEvent->EXDATE as $exDate) { - foreach ($exDate->getDateTimes($this->timeZone) as $dt) { - $this->exceptions[$dt->getTimeStamp()] = true; - } - } - } - - if (isset($this->masterEvent->DTEND)) { - $this->eventDuration = - $this->masterEvent->DTEND->getDateTime($this->timeZone)->getTimeStamp() - - $this->startDate->getTimeStamp(); - } elseif (isset($this->masterEvent->DURATION)) { - $duration = $this->masterEvent->DURATION->getDateInterval(); - $end = clone $this->startDate; - $end = $end->add($duration); - $this->eventDuration = $end->getTimeStamp() - $this->startDate->getTimeStamp(); - } elseif ($this->allDay) { - $this->eventDuration = 3600 * 24; - } else { - $this->eventDuration = 0; - } - - if (isset($this->masterEvent->RDATE)) { - $rdateValues = []; - foreach ($this->masterEvent->RDATE as $rdate) { - $rdateValues = array_merge($rdateValues, $rdate->getParts()); - } - $this->recurIterator = new RDateIterator( - $rdateValues, - $this->startDate - ); - } elseif (isset($this->masterEvent->RRULE)) { - $this->recurIterator = new RRuleIterator( - $this->masterEvent->RRULE->getParts(), - $this->startDate - ); - } else { - $this->recurIterator = new RRuleIterator( - [ - 'FREQ' => 'DAILY', - 'COUNT' => 1, - ], - $this->startDate - ); - } - - $this->rewind(); - if (!$this->valid()) { - throw new NoInstancesException('This recurrence rule does not generate any valid instances'); - } - } - - /** - * Returns the date for the current position of the iterator. - * - * @return DateTimeImmutable - */ - #[\ReturnTypeWillChange] - public function current() - { - if ($this->currentDate) { - return clone $this->currentDate; - } - } - - /** - * This method returns the start date for the current iteration of the - * event. - * - * @return DateTimeImmutable - */ - public function getDtStart() - { - if ($this->currentDate) { - return clone $this->currentDate; - } - } - - /** - * This method returns the end date for the current iteration of the - * event. - * - * @return DateTimeImmutable - */ - public function getDtEnd() - { - if (!$this->valid()) { - return; - } - if ($this->currentOverriddenEvent && $this->currentOverriddenEvent->DTEND) { - return $this->currentOverriddenEvent->DTEND->getDateTime($this->timeZone); - } else { - $end = clone $this->currentDate; - - return $end->modify('+'.$this->eventDuration.' seconds'); - } - } - - /** - * Returns a VEVENT for the current iterations of the event. - * - * This VEVENT will have a recurrence id, and its DTSTART and DTEND - * altered. - * - * @return VEvent - */ - public function getEventObject() - { - if ($this->currentOverriddenEvent) { - return $this->currentOverriddenEvent; - } - - $event = clone $this->masterEvent; - - // Ignoring the following block, because PHPUnit's code coverage - // ignores most of these lines, and this messes with our stats. - // - // @codeCoverageIgnoreStart - unset( - $event->RRULE, - $event->EXDATE, - $event->RDATE, - $event->EXRULE, - $event->{'RECURRENCE-ID'} - ); - // @codeCoverageIgnoreEnd - - $event->DTSTART->setDateTime($this->getDtStart(), $event->DTSTART->isFloating()); - if (isset($event->DTEND)) { - $event->DTEND->setDateTime($this->getDtEnd(), $event->DTEND->isFloating()); - } - $recurid = clone $event->DTSTART; - $recurid->name = 'RECURRENCE-ID'; - $event->add($recurid); - - return $event; - } - - /** - * Returns the current position of the iterator. - * - * This is for us simply a 0-based index. - * - * @return int - */ - #[\ReturnTypeWillChange] - public function key() - { - // The counter is always 1 ahead. - return $this->counter - 1; - } - - /** - * This is called after next, to see if the iterator is still at a valid - * position, or if it's at the end. - * - * @return bool - */ - #[\ReturnTypeWillChange] - public function valid() - { - if ($this->counter > Settings::$maxRecurrences && -1 !== Settings::$maxRecurrences) { - throw new MaxInstancesExceededException('Recurring events are only allowed to generate '.Settings::$maxRecurrences); - } - - return (bool) $this->currentDate; - } - - /** - * Sets the iterator back to the starting point. - * - * @return void - */ - #[\ReturnTypeWillChange] - public function rewind() - { - $this->recurIterator->rewind(); - // re-creating overridden event index. - $index = []; - foreach ($this->overriddenEvents as $key => $event) { - $stamp = $event->DTSTART->getDateTime($this->timeZone)->getTimeStamp(); - $index[$stamp][] = $key; - } - krsort($index); - $this->counter = 0; - $this->overriddenEventsIndex = $index; - $this->currentOverriddenEvent = null; - - $this->nextDate = null; - $this->currentDate = clone $this->startDate; - - $this->next(); - } - - /** - * Advances the iterator with one step. - * - * @return void - */ - #[\ReturnTypeWillChange] - public function next() - { - $this->currentOverriddenEvent = null; - ++$this->counter; - if ($this->nextDate) { - // We had a stored value. - $nextDate = $this->nextDate; - $this->nextDate = null; - } else { - // We need to ask rruleparser for the next date. - // We need to do this until we find a date that's not in the - // exception list. - do { - if (!$this->recurIterator->valid()) { - $nextDate = null; - break; - } - $nextDate = $this->recurIterator->current(); - $this->recurIterator->next(); - } while (isset($this->exceptions[$nextDate->getTimeStamp()])); - } - - // $nextDate now contains what rrule thinks is the next one, but an - // overridden event may cut ahead. - if ($this->overriddenEventsIndex) { - $offsets = end($this->overriddenEventsIndex); - $timestamp = key($this->overriddenEventsIndex); - $offset = end($offsets); - if (!$nextDate || $timestamp < $nextDate->getTimeStamp()) { - // Overridden event comes first. - $this->currentOverriddenEvent = $this->overriddenEvents[$offset]; - - // Putting the rrule next date aside. - $this->nextDate = $nextDate; - $this->currentDate = $this->currentOverriddenEvent->DTSTART->getDateTime($this->timeZone); - - // Ensuring that this item will only be used once. - array_pop($this->overriddenEventsIndex[$timestamp]); - if (!$this->overriddenEventsIndex[$timestamp]) { - array_pop($this->overriddenEventsIndex); - } - - // Exit point! - return; - } - } - - $this->currentDate = $nextDate; - } - - /** - * Quickly jump to a date in the future. - */ - public function fastForward(DateTimeInterface $dateTime) - { - while ($this->valid() && $this->getDtEnd() <= $dateTime) { - $this->next(); - } - } - - /** - * Returns true if this recurring event never ends. - * - * @return bool - */ - public function isInfinite() - { - return $this->recurIterator->isInfinite(); - } - - /** - * RRULE parser. - * - * @var RRuleIterator - */ - protected $recurIterator; - - /** - * The duration, in seconds, of the master event. - * - * We use this to calculate the DTEND for subsequent events. - */ - protected $eventDuration; - - /** - * A reference to the main (master) event. - * - * @var VEVENT - */ - protected $masterEvent; - - /** - * List of overridden events. - * - * @var array - */ - protected $overriddenEvents = []; - - /** - * Overridden event index. - * - * Key is timestamp, value is the list of indexes of the item in the $overriddenEvent - * property. - * - * @var array - */ - protected $overriddenEventsIndex; - - /** - * A list of recurrence-id's that are either part of EXDATE, or are - * overridden. - * - * @var array - */ - protected $exceptions = []; - - /** - * Internal event counter. - * - * @var int - */ - protected $counter; - - /** - * The very start of the iteration process. - * - * @var DateTimeImmutable - */ - protected $startDate; - - /** - * Where we are currently in the iteration process. - * - * @var DateTimeImmutable - */ - protected $currentDate; - - /** - * The next date from the rrule parser. - * - * Sometimes we need to temporary store the next date, because an - * overridden event came before. - * - * @var DateTimeImmutable - */ - protected $nextDate; - - /** - * The event that overwrites the current iteration. - * - * @var VEVENT - */ - protected $currentOverriddenEvent; -} diff --git a/lib/vendor/sabre/vobject/lib/Recur/MaxInstancesExceededException.php b/lib/vendor/sabre/vobject/lib/Recur/MaxInstancesExceededException.php deleted file mode 100644 index cb08358..0000000 --- a/lib/vendor/sabre/vobject/lib/Recur/MaxInstancesExceededException.php +++ /dev/null @@ -1,17 +0,0 @@ -startDate = $start; - $this->parseRDate($rrule); - $this->currentDate = clone $this->startDate; - } - - /* Implementation of the Iterator interface {{{ */ - - #[\ReturnTypeWillChange] - public function current() - { - if (!$this->valid()) { - return; - } - - return clone $this->currentDate; - } - - /** - * Returns the current item number. - * - * @return int - */ - #[\ReturnTypeWillChange] - public function key() - { - return $this->counter; - } - - /** - * Returns whether the current item is a valid item for the recurrence - * iterator. - * - * @return bool - */ - #[\ReturnTypeWillChange] - public function valid() - { - return $this->counter <= count($this->dates); - } - - /** - * Resets the iterator. - * - * @return void - */ - #[\ReturnTypeWillChange] - public function rewind() - { - $this->currentDate = clone $this->startDate; - $this->counter = 0; - } - - /** - * Goes on to the next iteration. - * - * @return void - */ - #[\ReturnTypeWillChange] - public function next() - { - ++$this->counter; - if (!$this->valid()) { - return; - } - - $this->currentDate = - DateTimeParser::parse( - $this->dates[$this->counter - 1], - $this->startDate->getTimezone() - ); - } - - /* End of Iterator implementation }}} */ - - /** - * Returns true if this recurring event never ends. - * - * @return bool - */ - public function isInfinite() - { - return false; - } - - /** - * This method allows you to quickly go to the next occurrence after the - * specified date. - */ - public function fastForward(DateTimeInterface $dt) - { - while ($this->valid() && $this->currentDate < $dt) { - $this->next(); - } - } - - /** - * The reference start date/time for the rrule. - * - * All calculations are based on this initial date. - * - * @var DateTimeInterface - */ - protected $startDate; - - /** - * The date of the current iteration. You can get this by calling - * ->current(). - * - * @var DateTimeInterface - */ - protected $currentDate; - - /** - * The current item in the list. - * - * You can get this number with the key() method. - * - * @var int - */ - protected $counter = 0; - - /* }}} */ - - /** - * This method receives a string from an RRULE property, and populates this - * class with all the values. - * - * @param string|array $rrule - */ - protected function parseRDate($rdate) - { - if (is_string($rdate)) { - $rdate = explode(',', $rdate); - } - - $this->dates = $rdate; - } - - /** - * Array with the RRULE dates. - * - * @var array - */ - protected $dates = []; -} diff --git a/lib/vendor/sabre/vobject/lib/Recur/RRuleIterator.php b/lib/vendor/sabre/vobject/lib/Recur/RRuleIterator.php deleted file mode 100644 index ca53b63..0000000 --- a/lib/vendor/sabre/vobject/lib/Recur/RRuleIterator.php +++ /dev/null @@ -1,1079 +0,0 @@ -startDate = $start; - $this->parseRRule($rrule); - $this->currentDate = clone $this->startDate; - } - - /* Implementation of the Iterator interface {{{ */ - - #[\ReturnTypeWillChange] - public function current() - { - if (!$this->valid()) { - return; - } - - return clone $this->currentDate; - } - - /** - * Returns the current item number. - * - * @return int - */ - #[\ReturnTypeWillChange] - public function key() - { - return $this->counter; - } - - /** - * Returns whether the current item is a valid item for the recurrence - * iterator. This will return false if we've gone beyond the UNTIL or COUNT - * statements. - * - * @return bool - */ - #[\ReturnTypeWillChange] - public function valid() - { - if (null === $this->currentDate) { - return false; - } - if (!is_null($this->count)) { - return $this->counter < $this->count; - } - - return is_null($this->until) || $this->currentDate <= $this->until; - } - - /** - * Resets the iterator. - * - * @return void - */ - #[\ReturnTypeWillChange] - public function rewind() - { - $this->currentDate = clone $this->startDate; - $this->counter = 0; - } - - /** - * Goes on to the next iteration. - * - * @return void - */ - #[\ReturnTypeWillChange] - public function next() - { - // Otherwise, we find the next event in the normal RRULE - // sequence. - switch ($this->frequency) { - case 'hourly': - $this->nextHourly(); - break; - - case 'daily': - $this->nextDaily(); - break; - - case 'weekly': - $this->nextWeekly(); - break; - - case 'monthly': - $this->nextMonthly(); - break; - - case 'yearly': - $this->nextYearly(); - break; - } - ++$this->counter; - } - - /* End of Iterator implementation }}} */ - - /** - * Returns true if this recurring event never ends. - * - * @return bool - */ - public function isInfinite() - { - return !$this->count && !$this->until; - } - - /** - * This method allows you to quickly go to the next occurrence after the - * specified date. - */ - public function fastForward(DateTimeInterface $dt) - { - while ($this->valid() && $this->currentDate < $dt) { - $this->next(); - } - } - - /** - * The reference start date/time for the rrule. - * - * All calculations are based on this initial date. - * - * @var DateTimeInterface - */ - protected $startDate; - - /** - * The date of the current iteration. You can get this by calling - * ->current(). - * - * @var DateTimeInterface - */ - protected $currentDate; - - /** - * The number of hours that the next occurrence of an event - * jumped forward, usually because summer time started and - * the requested time-of-day like 0230 did not exist on that - * day. And so the event was scheduled 1 hour later at 0330. - */ - protected $hourJump = 0; - - /** - * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly, - * yearly. - * - * @var string - */ - protected $frequency; - - /** - * The number of recurrences, or 'null' if infinitely recurring. - * - * @var int - */ - protected $count; - - /** - * The interval. - * - * If for example frequency is set to daily, interval = 2 would mean every - * 2 days. - * - * @var int - */ - protected $interval = 1; - - /** - * The last instance of this recurrence, inclusively. - * - * @var DateTimeInterface|null - */ - protected $until; - - /** - * Which seconds to recur. - * - * This is an array of integers (between 0 and 60) - * - * @var array - */ - protected $bySecond; - - /** - * Which minutes to recur. - * - * This is an array of integers (between 0 and 59) - * - * @var array - */ - protected $byMinute; - - /** - * Which hours to recur. - * - * This is an array of integers (between 0 and 23) - * - * @var array - */ - protected $byHour; - - /** - * The current item in the list. - * - * You can get this number with the key() method. - * - * @var int - */ - protected $counter = 0; - - /** - * Which weekdays to recur. - * - * This is an array of weekdays - * - * This may also be preceded 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 - */ - protected $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 - */ - protected $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 - */ - protected $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 - */ - protected $byWeekNo; - - /** - * Which months to recur. - * - * This is an array of integers from 1 to 12. - * - * @var array - */ - protected $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 - */ - protected $bySetPos; - - /** - * When the week starts. - * - * @var string - */ - protected $weekStart = 'MO'; - - /* Functions that advance the iterator {{{ */ - - /** - * Gets the original start time of the RRULE. - * - * The value is formatted as a string with 24-hour:minute:second - */ - protected function startTime(): string - { - return $this->startDate->format('H:i:s'); - } - - /** - * Advances currentDate by the interval. - * The time is set from the original startDate. - * If the recurrence is on a day when summer time started, then the - * time on that day may have jumped forward, for example, from 0230 to 0330. - * Using the original time means that the next recurrence will be calculated - * based on the original start time and the day/week/month/year interval. - * So the start time of the next occurrence can correctly revert to 0230. - */ - protected function advanceTheDate(string $interval): void - { - $this->currentDate = $this->currentDate->modify($interval.' '.$this->startTime()); - } - - /** - * Does the processing for adjusting the time of multi-hourly events when summer time starts. - */ - protected function adjustForTimeJumpsOfHourlyEvent(DateTimeInterface $previousEventDateTime): void - { - if (0 === $this->hourJump) { - // Remember if the clock time jumped forward on the next occurrence. - // That happens if the next event time is on a day when summer time starts - // and the event time is in the non-existent hour of the day. - // For example, an event that normally starts at 02:30 will - // have to start at 03:30 on that day. - // If the interval is just 1 hour, then there is no "jumping back" to do. - // The events that day will happen, for example, at 0030 0130 0330 0430 0530... - if ($this->interval > 1) { - $expectedHourOfNextDate = ((int) $previousEventDateTime->format('G') + $this->interval) % 24; - $actualHourOfNextDate = (int) $this->currentDate->format('G'); - $this->hourJump = $actualHourOfNextDate - $expectedHourOfNextDate; - } - } else { - // The hour "jumped" for the previous occurrence, to avoid the non-existent time. - // currentDate got set ahead by (usually) 1 hour on that day. - // Adjust it back for this next occurrence. - $this->currentDate = $this->currentDate->sub(new \DateInterval('PT'.$this->hourJump.'H')); - $this->hourJump = 0; - } - } - - /** - * Does the processing for advancing the iterator for hourly frequency. - */ - protected function nextHourly() - { - $previousEventDateTime = clone $this->currentDate; - $this->currentDate = $this->currentDate->modify('+'.$this->interval.' hours'); - $this->adjustForTimeJumpsOfHourlyEvent($previousEventDateTime); - } - - /** - * Does the processing for advancing the iterator for daily frequency. - */ - protected function nextDaily() - { - if (!$this->byHour && !$this->byDay) { - $this->advanceTheDate('+'.$this->interval.' days'); - - return; - } - - $recurrenceHours = []; - if (!empty($this->byHour)) { - $recurrenceHours = $this->getHours(); - } - - $recurrenceDays = []; - if (!empty($this->byDay)) { - $recurrenceDays = $this->getDays(); - } - - $recurrenceMonths = []; - if (!empty($this->byMonth)) { - $recurrenceMonths = $this->getMonths(); - } - - do { - if ($this->byHour) { - if ('23' == $this->currentDate->format('G')) { - // to obey the interval rule - $this->currentDate = $this->currentDate->modify('+'.($this->interval - 1).' days'); - } - - $this->currentDate = $this->currentDate->modify('+1 hours'); - } else { - $this->currentDate = $this->currentDate->modify('+'.$this->interval.' days'); - } - - // Current month of the year - $currentMonth = $this->currentDate->format('n'); - - // Current day of the week - $currentDay = $this->currentDate->format('w'); - - // Current hour of the day - $currentHour = $this->currentDate->format('G'); - - if ($this->currentDate->getTimestamp() > self::dateUpperLimit) { - $this->currentDate = null; - - return; - } - } while ( - ($this->byDay && !in_array($currentDay, $recurrenceDays)) || - ($this->byHour && !in_array($currentHour, $recurrenceHours)) || - ($this->byMonth && !in_array($currentMonth, $recurrenceMonths)) - ); - } - - /** - * Does the processing for advancing the iterator for weekly frequency. - */ - protected function nextWeekly() - { - if (!$this->byHour && !$this->byDay) { - $this->advanceTheDate('+'.$this->interval.' weeks'); - - return; - } - - $recurrenceHours = []; - if ($this->byHour) { - $recurrenceHours = $this->getHours(); - } - - $recurrenceDays = []; - if ($this->byDay) { - $recurrenceDays = $this->getDays(); - } - - // First day of the week: - $firstDay = $this->dayMap[$this->weekStart]; - - do { - if ($this->byHour) { - $this->currentDate = $this->currentDate->modify('+1 hours'); - } else { - $this->advanceTheDate('+1 days'); - } - - // Current day of the week - $currentDay = (int) $this->currentDate->format('w'); - - // Current hour of the day - $currentHour = (int) $this->currentDate->format('G'); - - // We need to roll over to the next week - if ($currentDay === $firstDay && (!$this->byHour || '0' == $currentHour)) { - $this->currentDate = $this->currentDate->modify('+'.($this->interval - 1).' 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 = $this->currentDate->modify('last '.$this->dayNames[$this->dayMap[$this->weekStart]]); - } - } - - // We have a match - } while (($this->byDay && !in_array($currentDay, $recurrenceDays)) || ($this->byHour && !in_array($currentHour, $recurrenceHours))); - } - - /** - * Does the processing for advancing the iterator for monthly frequency. - */ - 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->advanceTheDate('+'.$this->interval.' months'); - } else { - $increase = 0; - do { - ++$increase; - $tempDate = clone $this->currentDate; - $tempDate = $tempDate->modify('+ '.($this->interval * $increase).' months '.$this->startTime()); - } while ($tempDate->format('j') != $currentDayOfMonth); - $this->currentDate = $tempDate; - } - - return; - } - - $occurrence = -1; - 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 line does not currently work in hhvm. Temporary workaround - // follows: - // $this->currentDate->modify('first day of this month'); - $this->currentDate = new DateTimeImmutable($this->currentDate->format('Y-m-1 H:i:s'), $this->currentDate->getTimezone()); - // end of workaround - $this->currentDate = $this->currentDate->modify('+ '.$this->interval.' months'); - - // This goes to 0 because we need to start counting at the - // beginning. - $currentDayOfMonth = 0; - - // For some reason the "until" parameter was not being used here, - // that's why the workaround of the 10000 year bug was needed at all - // let's stop it before the "until" parameter date - if ($this->until && $this->currentDate->getTimestamp() >= $this->until->getTimestamp()) { - return; - } - - // To prevent running this forever (better: until we hit the max date of DateTimeImmutable) we simply - // stop at 9999-12-31. Looks like the year 10000 problem is not solved in php .... - if ($this->currentDate->getTimestamp() > self::dateUpperLimit) { - $this->currentDate = null; - - return; - } - } - - // Set the currentDate to the year and month that we are in, and the day of the month that we have selected. - // That day could be a day when summer time starts, and if the time of the event is, for example, 0230, - // then 0230 will not be a valid time on that day. So always apply the start time from the original startDate. - // The "modify" method will set the time forward to 0330, for example, if needed. - $this->currentDate = $this->currentDate->setDate( - (int) $this->currentDate->format('Y'), - (int) $this->currentDate->format('n'), - (int) $occurrence - )->modify($this->startTime()); - } - - /** - * Does the processing for advancing the iterator for yearly frequency. - */ - protected function nextYearly() - { - $currentMonth = $this->currentDate->format('n'); - $currentYear = $this->currentDate->format('Y'); - $currentDayOfMonth = $this->currentDate->format('j'); - - // No sub-rules, so we just advance by year - if (empty($this->byMonth)) { - // Unless it was a leap day! - if (2 == $currentMonth && 29 == $currentDayOfMonth) { - $counter = 0; - do { - ++$counter; - // Here we increase the year count by the interval, until - // we hit a date that's also in a leap year. - // - // We could just find the next interval that's dividable by - // 4, but that would ignore the rule that there's no leap - // year every year that's dividable by a 100, but not by - // 400. (1800, 1900, 2100). So we just rely on the datetime - // functions instead. - $nextDate = clone $this->currentDate; - $nextDate = $nextDate->modify('+ '.($this->interval * $counter).' years'); - } while (2 != $nextDate->format('n')); - - $this->currentDate = $nextDate; - - return; - } - - if (null !== $this->byWeekNo) { // byWeekNo is an array with values from -53 to -1, or 1 to 53 - $dayOffsets = []; - if ($this->byDay) { - foreach ($this->byDay as $byDay) { - $dayOffsets[] = $this->dayMap[$byDay]; - } - } else { // default is Monday - $dayOffsets[] = 1; - } - - $currentYear = $this->currentDate->format('Y'); - - while (true) { - $checkDates = []; - - // loop through all WeekNo and Days to check all the combinations - foreach ($this->byWeekNo as $byWeekNo) { - foreach ($dayOffsets as $dayOffset) { - $date = clone $this->currentDate; - $date = $date->setISODate($currentYear, $byWeekNo, $dayOffset); - - if ($date > $this->currentDate) { - $checkDates[] = $date; - } - } - } - - if (count($checkDates) > 0) { - $this->currentDate = min($checkDates); - - return; - } - - // if there is no date found, check the next year - $currentYear += $this->interval; - } - } - - if (null !== $this->byYearDay) { // byYearDay is an array with values from -366 to -1, or 1 to 366 - $dayOffsets = []; - if ($this->byDay) { - foreach ($this->byDay as $byDay) { - $dayOffsets[] = $this->dayMap[$byDay]; - } - } else { // default is Monday-Sunday - $dayOffsets = [1, 2, 3, 4, 5, 6, 7]; - } - - $currentYear = $this->currentDate->format('Y'); - - while (true) { - $checkDates = []; - - // loop through all YearDay and Days to check all the combinations - foreach ($this->byYearDay as $byYearDay) { - $date = clone $this->currentDate; - if ($byYearDay > 0) { - $date = $date->setDate($currentYear, 1, 1); - $date = $date->add(new \DateInterval('P'.($byYearDay - 1).'D')); - } else { - $date = $date->setDate($currentYear, 12, 31); - $date = $date->sub(new \DateInterval('P'.abs($byYearDay + 1).'D')); - } - - if ($date > $this->currentDate && in_array($date->format('N'), $dayOffsets)) { - $checkDates[] = $date; - } - } - - if (count($checkDates) > 0) { - $this->currentDate = min($checkDates); - - return; - } - - // if there is no date found, check the next year - $currentYear += $this->interval; - } - } - - // The easiest form - $this->advanceTheDate('+'.$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) { - $occurrence = -1; - 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 - // occurrence is always correct. - if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) { - // only consider byMonth matches, - // otherwise, we don't follow RRule correctly - if (in_array($currentMonth, $this->byMonth)) { - 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 = $this->currentDate->setDate( - (int) $currentYear, - (int) $currentMonth, - (int) $currentDayOfMonth - ); - - // To prevent running this forever (better: until we hit the max date of DateTimeImmutable) we simply - // stop at 9999-12-31. Looks like the year 10000 problem is not solved in php .... - if ($this->currentDate->getTimestamp() > self::dateUpperLimit) { - $this->currentDate = null; - - return; - } - } - - // If we made it here, it means we got a valid occurrence - $this->currentDate = $this->currentDate->setDate( - (int) $currentYear, - (int) $currentMonth, - (int) $occurrence - )->modify($this->startTime()); - - return; - } else { - // These are the 'byMonth' rules, if there are no byDay or - // byMonthDay sub-rules. - do { - ++$currentMonth; - if ($currentMonth > 12) { - $currentYear += $this->interval; - $currentMonth = 1; - } - } while (!in_array($currentMonth, $this->byMonth)); - $this->currentDate = $this->currentDate->setDate( - (int) $currentYear, - (int) $currentMonth, - (int) $currentDayOfMonth - )->modify($this->startTime()); - - return; - } - } - - /* }}} */ - - /** - * This method receives a string from an RRULE property, and populates this - * class with all the values. - * - * @param string|array $rrule - */ - protected function parseRRule($rrule) - { - if (is_string($rrule)) { - $rrule = Property\ICalendar\Recur::stringToArray($rrule); - } - - foreach ($rrule as $key => $value) { - $key = strtoupper($key); - switch ($key) { - case 'FREQ': - $value = strtolower($value); - if (!in_array( - $value, - ['secondly', 'minutely', 'hourly', 'daily', 'weekly', 'monthly', 'yearly'] - )) { - throw new InvalidDataException('Unknown value for FREQ='.strtoupper($value)); - } - $this->frequency = $value; - break; - - case 'UNTIL': - $this->until = DateTimeParser::parse($value, $this->startDate->getTimezone()); - - // In some cases events are generated with an UNTIL= - // parameter before the actual start of the event. - // - // Not sure why this is happening. We assume that the - // intention was that the event only recurs once. - // - // So we are modifying the parameter so our code doesn't - // break. - if ($this->until < $this->startDate) { - $this->until = $this->startDate; - } - break; - - case 'INTERVAL': - case 'COUNT': - $val = (int) $value; - if ($val < 1) { - throw new InvalidDataException(strtoupper($key).' in RRULE must be a positive integer!'); - } - $key = strtolower($key); - $this->$key = $val; - break; - - case 'BYSECOND': - $this->bySecond = (array) $value; - break; - - case 'BYMINUTE': - $this->byMinute = (array) $value; - break; - - case 'BYHOUR': - $this->byHour = (array) $value; - break; - - case 'BYDAY': - $value = (array) $value; - foreach ($value as $part) { - if (!preg_match('#^ (-|\+)? ([1-5])? (MO|TU|WE|TH|FR|SA|SU) $# xi', $part)) { - throw new InvalidDataException('Invalid part in BYDAY clause: '.$part); - } - } - $this->byDay = $value; - break; - - case 'BYMONTHDAY': - $this->byMonthDay = (array) $value; - break; - - case 'BYYEARDAY': - $this->byYearDay = (array) $value; - foreach ($this->byYearDay as $byYearDay) { - if (!is_numeric($byYearDay) || (int) $byYearDay < -366 || 0 == (int) $byYearDay || (int) $byYearDay > 366) { - throw new InvalidDataException('BYYEARDAY in RRULE must have value(s) from 1 to 366, or -366 to -1!'); - } - } - break; - - case 'BYWEEKNO': - $this->byWeekNo = (array) $value; - foreach ($this->byWeekNo as $byWeekNo) { - if (!is_numeric($byWeekNo) || (int) $byWeekNo < -53 || 0 == (int) $byWeekNo || (int) $byWeekNo > 53) { - throw new InvalidDataException('BYWEEKNO in RRULE must have value(s) from 1 to 53, or -53 to -1!'); - } - } - break; - - case 'BYMONTH': - $this->byMonth = (array) $value; - foreach ($this->byMonth as $byMonth) { - if (!is_numeric($byMonth) || (int) $byMonth < 1 || (int) $byMonth > 12) { - throw new InvalidDataException('BYMONTH in RRULE must have value(s) between 1 and 12!'); - } - } - break; - - case 'BYSETPOS': - $this->bySetPos = (array) $value; - break; - - case 'WKST': - $this->weekStart = strtoupper($value); - break; - - default: - throw new InvalidDataException('Not supported: '.strtoupper($key)); - } - } - } - - /** - * Mappings between the day number and english day name. - * - * @var array - */ - protected $dayNames = [ - 0 => 'Sunday', - 1 => 'Monday', - 2 => 'Tuesday', - 3 => 'Wednesday', - 4 => 'Thursday', - 5 => 'Friday', - 6 => 'Saturday', - ]; - - /** - * 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 = []; - - // 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 = []; - - // workaround for missing 'first day of the month' support in hhvm - $checkDate = new \DateTime($startDate->format('Y-m-1')); - // workaround modify always advancing the date even if the current day is a $dayName in hhvm - if ($checkDate->format('l') !== $dayName) { - $checkDate = $checkDate->modify($dayName); - } - - do { - $dayHits[] = $checkDate->format('j'); - $checkDate = $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 - // might not exist, fx. -5th tuesday - if (isset($dayHits[count($dayHits) + $offset])) { - $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 = []; - 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 = []; - 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; - } - - /** - * Simple mapping from iCalendar day names to day numbers. - * - * @var array - */ - protected $dayMap = [ - 'SU' => 0, - 'MO' => 1, - 'TU' => 2, - 'WE' => 3, - 'TH' => 4, - 'FR' => 5, - 'SA' => 6, - ]; - - protected function getHours() - { - $recurrenceHours = []; - foreach ($this->byHour as $byHour) { - $recurrenceHours[] = $byHour; - } - - return $recurrenceHours; - } - - protected function getDays() - { - $recurrenceDays = []; - foreach ($this->byDay as $byDay) { - // The day may be preceded 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)]; - } - - return $recurrenceDays; - } - - protected function getMonths() - { - $recurrenceMonths = []; - foreach ($this->byMonth as $byMonth) { - $recurrenceMonths[] = $byMonth; - } - - return $recurrenceMonths; - } -} diff --git a/lib/vendor/sabre/vobject/lib/Settings.php b/lib/vendor/sabre/vobject/lib/Settings.php deleted file mode 100644 index b0bb80a..0000000 --- a/lib/vendor/sabre/vobject/lib/Settings.php +++ /dev/null @@ -1,55 +0,0 @@ -children() as $component) { - if (!$component instanceof VObject\Component) { - continue; - } - - // Get all timezones - if ('VTIMEZONE' === $component->name) { - $this->vtimezones[(string) $component->TZID] = $component; - continue; - } - - // Get component UID for recurring Events search - if (!$component->UID) { - $component->UID = sha1(microtime()).'-vobjectimport'; - } - $uid = (string) $component->UID; - - // Take care of recurring events - if (!array_key_exists($uid, $this->objects)) { - $this->objects[$uid] = new VCalendar(); - } - - $this->objects[$uid]->add(clone $component); - } - } - - /** - * Every time getNext() is called, a new object will be parsed, until we - * hit the end of the stream. - * - * When the end is reached, null will be returned. - * - * @return \Sabre\VObject\Component|null - */ - public function getNext() - { - if ($object = array_shift($this->objects)) { - // create our baseobject - $object->version = '2.0'; - $object->prodid = '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN'; - $object->calscale = 'GREGORIAN'; - - // add vtimezone information to obj (if we have it) - foreach ($this->vtimezones as $vtimezone) { - $object->add($vtimezone); - } - - return $object; - } else { - return; - } - } -} diff --git a/lib/vendor/sabre/vobject/lib/Splitter/SplitterInterface.php b/lib/vendor/sabre/vobject/lib/Splitter/SplitterInterface.php deleted file mode 100644 index c845ac5..0000000 --- a/lib/vendor/sabre/vobject/lib/Splitter/SplitterInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -input = $input; - $this->parser = new MimeDir($input, $options); - } - - /** - * Every time getNext() is called, a new object will be parsed, until we - * hit the end of the stream. - * - * When the end is reached, null will be returned. - * - * @return \Sabre\VObject\Component|null - */ - public function getNext() - { - try { - $object = $this->parser->parse(); - - if (!$object instanceof VObject\Component\VCard) { - throw new VObject\ParseException('The supplied input contained non-VCARD data.'); - } - } catch (VObject\EofException $e) { - return; - } - - return $object; - } -} diff --git a/lib/vendor/sabre/vobject/lib/StringUtil.php b/lib/vendor/sabre/vobject/lib/StringUtil.php deleted file mode 100644 index b04539e..0000000 --- a/lib/vendor/sabre/vobject/lib/StringUtil.php +++ /dev/null @@ -1,50 +0,0 @@ -addGuesser('lic', new GuessFromLicEntry()); - $this->addGuesser('msTzId', new GuessFromMsTzId()); - $this->addFinder('tzid', new FindFromTimezoneIdentifier()); - $this->addFinder('tzmap', new FindFromTimezoneMap()); - $this->addFinder('offset', new FindFromOffset()); - } - - private static function getInstance(): self - { - if (null === self::$instance) { - self::$instance = new self(); - } - - return self::$instance; - } - - private function addGuesser(string $key, TimezoneGuesser $guesser): void - { - $this->timezoneGuessers[$key] = $guesser; - } - - private function addFinder(string $key, TimezoneFinder $finder): void - { - $this->timezoneFinders[$key] = $finder; - } - - /** - * This method will try to find out the correct timezone for an iCalendar - * date-time value. - * - * You must pass the contents of the TZID parameter, as well as the full - * calendar. - * - * If the lookup fails, this method will return the default PHP timezone - * (as configured using date_default_timezone_set, or the date.timezone ini - * setting). - * - * Alternatively, if $failIfUncertain is set to true, it will throw an - * exception if we cannot accurately determine the timezone. - */ - private function findTimeZone(string $tzid, ?Component $vcalendar = null, bool $failIfUncertain = false): DateTimeZone - { - foreach ($this->timezoneFinders as $timezoneFinder) { - $timezone = $timezoneFinder->find($tzid, $failIfUncertain); - if (!$timezone instanceof DateTimeZone) { - continue; - } - - return $timezone; - } - - if ($vcalendar) { - // If that didn't work, we will scan VTIMEZONE objects - foreach ($vcalendar->select('VTIMEZONE') as $vtimezone) { - if ((string) $vtimezone->TZID === $tzid) { - foreach ($this->timezoneGuessers as $timezoneGuesser) { - $timezone = $timezoneGuesser->guess($vtimezone, $failIfUncertain); - if (!$timezone instanceof DateTimeZone) { - continue; - } - - return $timezone; - } - } - } - } - - if ($failIfUncertain) { - throw new InvalidArgumentException('We were unable to determine the correct PHP timezone for tzid: '.$tzid); - } - - // If we got all the way here, we default to whatever has been set as the PHP default timezone. - return new DateTimeZone(date_default_timezone_get()); - } - - public static function addTimezoneGuesser(string $key, TimezoneGuesser $guesser): void - { - self::getInstance()->addGuesser($key, $guesser); - } - - public static function addTimezoneFinder(string $key, TimezoneFinder $finder): void - { - self::getInstance()->addFinder($key, $finder); - } - - /** - * @param string $tzid - * @param false $failIfUncertain - * - * @return DateTimeZone - */ - public static function getTimeZone($tzid, ?Component $vcalendar = null, $failIfUncertain = false) - { - return self::getInstance()->findTimeZone($tzid, $vcalendar, $failIfUncertain); - } - - public static function clean(): void - { - self::$instance = null; - } - - // Keeping things for backwards compatibility - /** - * @var array|null - * - * @deprecated - */ - public static $map = null; - - /** - * List of microsoft exchange timezone ids. - * - * Source: http://msdn.microsoft.com/en-us/library/aa563018(loband).aspx - * - * @deprecated - */ - public static $microsoftExchangeMap = [ - 0 => 'UTC', - 31 => 'Africa/Casablanca', - // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo. - // I'm not even kidding.. We handle this special case in the - // getTimeZone method. - 2 => 'Europe/Lisbon', - 1 => 'Europe/London', - 4 => 'Europe/Berlin', - 6 => 'Europe/Prague', - 3 => 'Europe/Paris', - 69 => 'Africa/Luanda', // This was a best guess - 7 => 'Europe/Athens', - 5 => 'Europe/Bucharest', - 49 => 'Africa/Cairo', - 50 => 'Africa/Harare', - 59 => 'Europe/Helsinki', - 27 => 'Asia/Jerusalem', - 26 => 'Asia/Baghdad', - 74 => 'Asia/Kuwait', - 51 => 'Europe/Moscow', - 56 => 'Africa/Nairobi', - 25 => 'Asia/Tehran', - 24 => 'Asia/Muscat', // Best guess - 54 => 'Asia/Baku', - 48 => 'Asia/Kabul', - 58 => 'Asia/Yekaterinburg', - 47 => 'Asia/Karachi', - 23 => 'Asia/Calcutta', - 62 => 'Asia/Kathmandu', - 46 => 'Asia/Almaty', - 71 => 'Asia/Dhaka', - 66 => 'Asia/Colombo', - 61 => 'Asia/Rangoon', - 22 => 'Asia/Bangkok', - 64 => 'Asia/Krasnoyarsk', - 45 => 'Asia/Shanghai', - 63 => 'Asia/Irkutsk', - 21 => 'Asia/Singapore', - 73 => 'Australia/Perth', - 75 => 'Asia/Taipei', - 20 => 'Asia/Tokyo', - 72 => 'Asia/Seoul', - 70 => 'Asia/Yakutsk', - 19 => 'Australia/Adelaide', - 44 => 'Australia/Darwin', - 18 => 'Australia/Brisbane', - 76 => 'Australia/Sydney', - 43 => 'Pacific/Guam', - 42 => 'Australia/Hobart', - 68 => 'Asia/Vladivostok', - 41 => 'Asia/Magadan', - 17 => 'Pacific/Auckland', - 40 => 'Pacific/Fiji', - 67 => 'Pacific/Tongatapu', - 29 => 'Atlantic/Azores', - 53 => 'Atlantic/Cape_Verde', - 30 => 'America/Noronha', - 8 => 'America/Sao_Paulo', // Best guess - 32 => 'America/Argentina/Buenos_Aires', - 60 => 'America/Godthab', - 28 => 'America/St_Johns', - 9 => 'America/Halifax', - 33 => 'America/Caracas', - 65 => 'America/Santiago', - 35 => 'America/Bogota', - 10 => 'America/New_York', - 34 => 'America/Indiana/Indianapolis', - 55 => 'America/Guatemala', - 11 => 'America/Chicago', - 37 => 'America/Mexico_City', - 36 => 'America/Edmonton', - 38 => 'America/Phoenix', - 12 => 'America/Denver', // Best guess - 13 => 'America/Los_Angeles', // Best guess - 14 => 'America/Anchorage', - 15 => 'Pacific/Honolulu', - 16 => 'Pacific/Midway', - 39 => 'Pacific/Kwajalein', - ]; - - /** - * This method will load in all the tz mapping information, if it's not yet - * done. - * - * @deprecated - */ - public static function loadTzMaps() - { - if (!is_null(self::$map)) { - return; - } - - self::$map = array_merge( - include __DIR__.'/timezonedata/windowszones.php', - include __DIR__.'/timezonedata/lotuszones.php', - include __DIR__.'/timezonedata/exchangezones.php', - include __DIR__.'/timezonedata/php-workaround.php' - ); - } - - /** - * This method returns an array of timezone identifiers, that are supported - * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers(). - * - * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because: - * - It's not supported by some PHP versions as well as HHVM. - * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. - * (See timezonedata/php-bc.php and timezonedata php-workaround.php) - * - * @return array - * - * @deprecated - */ - public static function getIdentifiersBC() - { - return include __DIR__.'/timezonedata/php-bc.php'; - } -} diff --git a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromOffset.php b/lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromOffset.php deleted file mode 100644 index 990ac96..0000000 --- a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromOffset.php +++ /dev/null @@ -1,31 +0,0 @@ -getIdentifiersBC())) - ) { - return new DateTimeZone($tzid); - } - } catch (Exception $e) { - } - - return null; - } - - /** - * This method returns an array of timezone identifiers, that are supported - * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers(). - * - * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because: - * - It's not supported by some PHP versions as well as HHVM. - * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. - * (See timezonedata/php-bc.php and timezonedata php-workaround.php) - * - * @return array - */ - private function getIdentifiersBC() - { - return include __DIR__.'/../timezonedata/php-bc.php'; - } -} diff --git a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneMap.php b/lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneMap.php deleted file mode 100644 index b52ba6a..0000000 --- a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/FindFromTimezoneMap.php +++ /dev/null @@ -1,78 +0,0 @@ -hasTzInMap($tzid)) { - return new DateTimeZone($this->getTzFromMap($tzid)); - } - - // Some Microsoft products prefix the offset first, so let's strip that off - // and see if it is our tzid map. We don't want to check for this first just - // in case there are overrides in our tzid map. - foreach ($this->patterns as $pattern) { - if (!preg_match($pattern, $tzid, $matches)) { - continue; - } - $tzidAlternate = $matches[3]; - if ($this->hasTzInMap($tzidAlternate)) { - return new DateTimeZone($this->getTzFromMap($tzidAlternate)); - } - } - - return null; - } - - /** - * This method returns an array of timezone identifiers, that are supported - * by DateTimeZone(), but not returned by DateTimeZone::listIdentifiers(). - * - * We're not using DateTimeZone::listIdentifiers(DateTimeZone::ALL_WITH_BC) because: - * - It's not supported by some PHP versions as well as HHVM. - * - It also returns identifiers, that are invalid values for new DateTimeZone() on some PHP versions. - * (See timezonedata/php-bc.php and timezonedata php-workaround.php) - * - * @return array - */ - private function getTzMaps() - { - if ([] === $this->map) { - $this->map = array_merge( - include __DIR__.'/../timezonedata/windowszones.php', - include __DIR__.'/../timezonedata/lotuszones.php', - include __DIR__.'/../timezonedata/exchangezones.php', - include __DIR__.'/../timezonedata/php-workaround.php' - ); - } - - return $this->map; - } - - private function getTzFromMap(string $tzid): string - { - return $this->getTzMaps()[$tzid]; - } - - private function hasTzInMap(string $tzid): bool - { - return isset($this->getTzMaps()[$tzid]); - } -} diff --git a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromLicEntry.php b/lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromLicEntry.php deleted file mode 100644 index f340a39..0000000 --- a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromLicEntry.php +++ /dev/null @@ -1,33 +0,0 @@ -{'X-LIC-LOCATION'})) { - return null; - } - - $lic = (string) $vtimezone->{'X-LIC-LOCATION'}; - - // Libical generators may specify strings like - // "SystemV/EST5EDT". For those we must remove the - // SystemV part. - if ('SystemV/' === substr($lic, 0, 8)) { - $lic = substr($lic, 8); - } - - return TimeZoneUtil::getTimeZone($lic, null, $failIfUncertain); - } -} diff --git a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromMsTzId.php b/lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromMsTzId.php deleted file mode 100644 index b11ce18..0000000 --- a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/GuessFromMsTzId.php +++ /dev/null @@ -1,119 +0,0 @@ - 'UTC', - 31 => 'Africa/Casablanca', - - // Insanely, id #2 is used for both Europe/Lisbon, and Europe/Sarajevo. - // I'm not even kidding.. We handle this special case in the - // getTimeZone method. - 2 => 'Europe/Lisbon', - 1 => 'Europe/London', - 4 => 'Europe/Berlin', - 6 => 'Europe/Prague', - 3 => 'Europe/Paris', - 69 => 'Africa/Luanda', // This was a best guess - 7 => 'Europe/Athens', - 5 => 'Europe/Bucharest', - 49 => 'Africa/Cairo', - 50 => 'Africa/Harare', - 59 => 'Europe/Helsinki', - 27 => 'Asia/Jerusalem', - 26 => 'Asia/Baghdad', - 74 => 'Asia/Kuwait', - 51 => 'Europe/Moscow', - 56 => 'Africa/Nairobi', - 25 => 'Asia/Tehran', - 24 => 'Asia/Muscat', // Best guess - 54 => 'Asia/Baku', - 48 => 'Asia/Kabul', - 58 => 'Asia/Yekaterinburg', - 47 => 'Asia/Karachi', - 23 => 'Asia/Calcutta', - 62 => 'Asia/Kathmandu', - 46 => 'Asia/Almaty', - 71 => 'Asia/Dhaka', - 66 => 'Asia/Colombo', - 61 => 'Asia/Rangoon', - 22 => 'Asia/Bangkok', - 64 => 'Asia/Krasnoyarsk', - 45 => 'Asia/Shanghai', - 63 => 'Asia/Irkutsk', - 21 => 'Asia/Singapore', - 73 => 'Australia/Perth', - 75 => 'Asia/Taipei', - 20 => 'Asia/Tokyo', - 72 => 'Asia/Seoul', - 70 => 'Asia/Yakutsk', - 19 => 'Australia/Adelaide', - 44 => 'Australia/Darwin', - 18 => 'Australia/Brisbane', - 76 => 'Australia/Sydney', - 43 => 'Pacific/Guam', - 42 => 'Australia/Hobart', - 68 => 'Asia/Vladivostok', - 41 => 'Asia/Magadan', - 17 => 'Pacific/Auckland', - 40 => 'Pacific/Fiji', - 67 => 'Pacific/Tongatapu', - 29 => 'Atlantic/Azores', - 53 => 'Atlantic/Cape_Verde', - 30 => 'America/Noronha', - 8 => 'America/Sao_Paulo', // Best guess - 32 => 'America/Argentina/Buenos_Aires', - 60 => 'America/Godthab', - 28 => 'America/St_Johns', - 9 => 'America/Halifax', - 33 => 'America/Caracas', - 65 => 'America/Santiago', - 35 => 'America/Bogota', - 10 => 'America/New_York', - 34 => 'America/Indiana/Indianapolis', - 55 => 'America/Guatemala', - 11 => 'America/Chicago', - 37 => 'America/Mexico_City', - 36 => 'America/Edmonton', - 38 => 'America/Phoenix', - 12 => 'America/Denver', // Best guess - 13 => 'America/Los_Angeles', // Best guess - 14 => 'America/Anchorage', - 15 => 'Pacific/Honolulu', - 16 => 'Pacific/Midway', - 39 => 'Pacific/Kwajalein', - ]; - - public function guess(VTimeZone $vtimezone, bool $throwIfUnsure = false): ?DateTimeZone - { - // Microsoft may add a magic number, which we also have an - // answer for. - if (!isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) { - return null; - } - $cdoId = (int) $vtimezone->{'X-MICROSOFT-CDO-TZID'}->getValue(); - - // 2 can mean both Europe/Lisbon and Europe/Sarajevo. - if (2 === $cdoId && false !== strpos((string) $vtimezone->TZID, 'Sarajevo')) { - return new DateTimeZone('Europe/Sarajevo'); - } - - if (isset(self::$microsoftExchangeMap[$cdoId])) { - return new DateTimeZone(self::$microsoftExchangeMap[$cdoId]); - } - - return null; - } -} diff --git a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/TimezoneFinder.php b/lib/vendor/sabre/vobject/lib/TimezoneGuesser/TimezoneFinder.php deleted file mode 100644 index 5aa880a..0000000 --- a/lib/vendor/sabre/vobject/lib/TimezoneGuesser/TimezoneFinder.php +++ /dev/null @@ -1,10 +0,0 @@ -getDocumentType(); - if ($inputVersion === $targetVersion) { - return clone $input; - } - - if (!in_array($inputVersion, [Document::VCARD21, Document::VCARD30, Document::VCARD40])) { - throw new \InvalidArgumentException('Only vCard 2.1, 3.0 and 4.0 are supported for the input data'); - } - if (!in_array($targetVersion, [Document::VCARD30, Document::VCARD40])) { - throw new \InvalidArgumentException('You can only use vCard 3.0 or 4.0 for the target version'); - } - - $newVersion = Document::VCARD40 === $targetVersion ? '4.0' : '3.0'; - - $output = new Component\VCard([ - 'VERSION' => $newVersion, - ]); - - // We might have generated a default UID. Remove it! - unset($output->UID); - - foreach ($input->children() as $property) { - $this->convertProperty($input, $output, $property, $targetVersion); - } - - return $output; - } - - /** - * Handles conversion of a single property. - * - * @param int $targetVersion - */ - protected function convertProperty(Component\VCard $input, Component\VCard $output, Property $property, $targetVersion) - { - // Skipping these, those are automatically added. - if (in_array($property->name, ['VERSION', 'PRODID'])) { - return; - } - - $parameters = $property->parameters(); - $valueType = null; - if (isset($parameters['VALUE'])) { - $valueType = $parameters['VALUE']->getValue(); - unset($parameters['VALUE']); - } - if (!$valueType) { - $valueType = $property->getValueType(); - } - if (Document::VCARD30 !== $targetVersion && 'PHONE-NUMBER' === $valueType) { - $valueType = null; - } - $newProperty = $output->createProperty( - $property->name, - $property->getParts(), - [], // parameters will get added a bit later. - $valueType - ); - - if (Document::VCARD30 === $targetVersion) { - if ($property instanceof Property\Uri && in_array($property->name, ['PHOTO', 'LOGO', 'SOUND'])) { - $newProperty = $this->convertUriToBinary($output, $newProperty); - } elseif ($property instanceof Property\VCard\DateAndOrTime) { - // In vCard 4, the birth year may be optional. This is not the - // case for vCard 3. Apple has a workaround for this that - // allows applications that support Apple's extension still - // omit birthyears in vCard 3, but applications that do not - // support this, will just use a random birthyear. We're - // choosing 1604 for the birthyear, because that's what apple - // uses. - $parts = DateTimeParser::parseVCardDateTime($property->getValue()); - if (is_null($parts['year'])) { - $newValue = '1604-'.$parts['month'].'-'.$parts['date']; - $newProperty->setValue($newValue); - $newProperty['X-APPLE-OMIT-YEAR'] = '1604'; - } - - if ('ANNIVERSARY' == $newProperty->name) { - // Microsoft non-standard anniversary - $newProperty->name = 'X-ANNIVERSARY'; - - // We also need to add a new apple property for the same - // purpose. This apple property needs a 'label' in the same - // group, so we first need to find a groupname that doesn't - // exist yet. - $x = 1; - while ($output->select('ITEM'.$x.'.')) { - ++$x; - } - $output->add('ITEM'.$x.'.X-ABDATE', $newProperty->getValue(), ['VALUE' => 'DATE-AND-OR-TIME']); - $output->add('ITEM'.$x.'.X-ABLABEL', '_$!!$_'); - } - } elseif ('KIND' === $property->name) { - switch (strtolower($property->getValue())) { - case 'org': - // vCard 3.0 does not have an equivalent to KIND:ORG, - // but apple has an extension that means the same - // thing. - $newProperty = $output->createProperty('X-ABSHOWAS', 'COMPANY'); - break; - - case 'individual': - // Individual is implicit, so we skip it. - return; - - case 'group': - // OS X addressbook property - $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-KIND', 'GROUP'); - break; - } - } elseif ('MEMBER' === $property->name) { - $newProperty = $output->createProperty('X-ADDRESSBOOKSERVER-MEMBER', $property->getValue()); - } - } elseif (Document::VCARD40 === $targetVersion) { - // These properties were removed in vCard 4.0 - if (in_array($property->name, ['NAME', 'MAILER', 'LABEL', 'CLASS'])) { - return; - } - - if ($property instanceof Property\Binary) { - $newProperty = $this->convertBinaryToUri($output, $newProperty, $parameters); - } elseif ($property instanceof Property\VCard\DateAndOrTime && isset($parameters['X-APPLE-OMIT-YEAR'])) { - // If a property such as BDAY contained 'X-APPLE-OMIT-YEAR', - // then we're stripping the year from the vcard 4 value. - $parts = DateTimeParser::parseVCardDateTime($property->getValue()); - if ($parts['year'] === $property['X-APPLE-OMIT-YEAR']->getValue()) { - $newValue = '--'.$parts['month'].'-'.$parts['date']; - $newProperty->setValue($newValue); - } - - // Regardless if the year matched or not, we do need to strip - // X-APPLE-OMIT-YEAR. - unset($parameters['X-APPLE-OMIT-YEAR']); - } - switch ($property->name) { - case 'X-ABSHOWAS': - if ('COMPANY' === strtoupper($property->getValue())) { - $newProperty = $output->createProperty('KIND', 'ORG'); - } - break; - case 'X-ADDRESSBOOKSERVER-KIND': - if ('GROUP' === strtoupper($property->getValue())) { - $newProperty = $output->createProperty('KIND', 'GROUP'); - } - break; - case 'X-ADDRESSBOOKSERVER-MEMBER': - $newProperty = $output->createProperty('MEMBER', $property->getValue()); - break; - case 'X-ANNIVERSARY': - $newProperty->name = 'ANNIVERSARY'; - // If we already have an anniversary property with the same - // value, ignore. - foreach ($output->select('ANNIVERSARY') as $anniversary) { - if ($anniversary->getValue() === $newProperty->getValue()) { - return; - } - } - break; - case 'X-ABDATE': - // Find out what the label was, if it exists. - if (!$property->group) { - break; - } - $label = $input->{$property->group.'.X-ABLABEL'}; - - // We only support converting anniversaries. - if (!$label || '_$!!$_' !== $label->getValue()) { - break; - } - - // If we already have an anniversary property with the same - // value, ignore. - foreach ($output->select('ANNIVERSARY') as $anniversary) { - if ($anniversary->getValue() === $newProperty->getValue()) { - return; - } - } - $newProperty->name = 'ANNIVERSARY'; - break; - // Apple's per-property label system. - case 'X-ABLABEL': - if ('_$!!$_' === $newProperty->getValue()) { - // We can safely remove these, as they are converted to - // ANNIVERSARY properties. - return; - } - break; - } - } - - // set property group - $newProperty->group = $property->group; - - if (Document::VCARD40 === $targetVersion) { - $this->convertParameters40($newProperty, $parameters); - } else { - $this->convertParameters30($newProperty, $parameters); - } - - // Lastly, we need to see if there's a need for a VALUE parameter. - // - // We can do that by instantiating a empty property with that name, and - // seeing if the default valueType is identical to the current one. - $tempProperty = $output->createProperty($newProperty->name); - if ($tempProperty->getValueType() !== $newProperty->getValueType()) { - $newProperty['VALUE'] = $newProperty->getValueType(); - } - - $output->add($newProperty); - } - - /** - * Converts a BINARY property to a URI property. - * - * vCard 4.0 no longer supports BINARY properties. - * - * @param Property\Uri $property the input property - * @param $parameters list of parameters that will eventually be added to - * the new property - * - * @return Property\Uri - */ - protected function convertBinaryToUri(Component\VCard $output, Property\Binary $newProperty, array &$parameters) - { - $value = $newProperty->getValue(); - $newProperty = $output->createProperty( - $newProperty->name, - null, // no value - [], // no parameters yet - 'URI' // Forcing the BINARY type - ); - - $mimeType = 'application/octet-stream'; - - // See if we can find a better mimetype. - if (isset($parameters['TYPE'])) { - $newTypes = []; - foreach ($parameters['TYPE']->getParts() as $typePart) { - if (in_array( - strtoupper($typePart), - ['JPEG', 'PNG', 'GIF'] - )) { - $mimeType = 'image/'.strtolower($typePart); - } else { - $newTypes[] = $typePart; - } - } - - // If there were any parameters we're not converting to a - // mime-type, we need to keep them. - if ($newTypes) { - $parameters['TYPE']->setParts($newTypes); - } else { - unset($parameters['TYPE']); - } - } - - $newProperty->setValue('data:'.$mimeType.';base64,'.base64_encode($value)); - - return $newProperty; - } - - /** - * Converts a URI property to a BINARY property. - * - * In vCard 4.0 attachments are encoded as data: uri. Even though these may - * be valid in vCard 3.0 as well, we should convert those to BINARY if - * possible, to improve compatibility. - * - * @param Property\Uri $property the input property - * - * @return Property\Binary|null - */ - protected function convertUriToBinary(Component\VCard $output, Property\Uri $newProperty) - { - $value = $newProperty->getValue(); - - // Only converting data: uris - if ('data:' !== substr($value, 0, 5)) { - return $newProperty; - } - - $newProperty = $output->createProperty( - $newProperty->name, - null, // no value - [], // no parameters yet - 'BINARY' - ); - - $mimeType = substr($value, 5, strpos($value, ',') - 5); - if (strpos($mimeType, ';')) { - $mimeType = substr($mimeType, 0, strpos($mimeType, ';')); - $newProperty->setValue(base64_decode(substr($value, strpos($value, ',') + 1))); - } else { - $newProperty->setValue(substr($value, strpos($value, ',') + 1)); - } - unset($value); - - $newProperty['ENCODING'] = 'b'; - switch ($mimeType) { - case 'image/jpeg': - $newProperty['TYPE'] = 'JPEG'; - break; - case 'image/png': - $newProperty['TYPE'] = 'PNG'; - break; - case 'image/gif': - $newProperty['TYPE'] = 'GIF'; - break; - } - - return $newProperty; - } - - /** - * Adds parameters to a new property for vCard 4.0. - */ - protected function convertParameters40(Property $newProperty, array $parameters) - { - // Adding all parameters. - foreach ($parameters as $param) { - // vCard 2.1 allowed parameters with no name - if ($param->noName) { - $param->noName = false; - } - - switch ($param->name) { - // We need to see if there's any TYPE=PREF, because in vCard 4 - // that's now PREF=1. - case 'TYPE': - foreach ($param->getParts() as $paramPart) { - if ('PREF' === strtoupper($paramPart)) { - $newProperty->add('PREF', '1'); - } else { - $newProperty->add($param->name, $paramPart); - } - } - break; - // These no longer exist in vCard 4 - case 'ENCODING': - case 'CHARSET': - break; - - default: - $newProperty->add($param->name, $param->getParts()); - break; - } - } - } - - /** - * Adds parameters to a new property for vCard 3.0. - */ - protected function convertParameters30(Property $newProperty, array $parameters) - { - // Adding all parameters. - foreach ($parameters as $param) { - // vCard 2.1 allowed parameters with no name - if ($param->noName) { - $param->noName = false; - } - - switch ($param->name) { - case 'ENCODING': - // This value only existed in vCard 2.1, and should be - // removed for anything else. - if ('QUOTED-PRINTABLE' !== strtoupper($param->getValue())) { - $newProperty->add($param->name, $param->getParts()); - } - break; - - /* - * Converting PREF=1 to TYPE=PREF. - * - * Any other PREF numbers we'll drop. - */ - case 'PREF': - if ('1' == $param->getValue()) { - $newProperty->add('TYPE', 'PREF'); - } - break; - - default: - $newProperty->add($param->name, $param->getParts()); - break; - } - } - } -} diff --git a/lib/vendor/sabre/vobject/lib/Version.php b/lib/vendor/sabre/vobject/lib/Version.php deleted file mode 100644 index decd424..0000000 --- a/lib/vendor/sabre/vobject/lib/Version.php +++ /dev/null @@ -1,18 +0,0 @@ -serialize(); - } - - /** - * Serializes a jCal or jCard object. - * - * @param int $options - * - * @return string - */ - public static function writeJson(Component $component, $options = 0) - { - return json_encode($component, $options); - } - - /** - * Serializes a xCal or xCard object. - * - * @return string - */ - public static function writeXml(Component $component) - { - $writer = new Xml\Writer(); - $writer->openMemory(); - $writer->setIndent(true); - - $writer->startDocument('1.0', 'utf-8'); - - if ($component instanceof Component\VCalendar) { - $writer->startElement('icalendar'); - $writer->writeAttribute('xmlns', Parser\XML::XCAL_NAMESPACE); - } else { - $writer->startElement('vcards'); - $writer->writeAttribute('xmlns', Parser\XML::XCARD_NAMESPACE); - } - - $component->xmlSerialize($writer); - - $writer->endElement(); - - return $writer->outputMemory(); - } -} diff --git a/lib/vendor/sabre/vobject/lib/timezonedata/exchangezones.php b/lib/vendor/sabre/vobject/lib/timezonedata/exchangezones.php deleted file mode 100644 index 3e7eace..0000000 --- a/lib/vendor/sabre/vobject/lib/timezonedata/exchangezones.php +++ /dev/null @@ -1,95 +0,0 @@ - 'UTC', - 'Casablanca, Monrovia' => 'Africa/Casablanca', - 'Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London' => 'Europe/Lisbon', - 'Greenwich Mean Time; Dublin, Edinburgh, London' => 'Europe/London', - 'Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin', - 'Amsterdam, Berlin, Bern, Rom, Stockholm, Wien' => 'Europe/Berlin', - 'Belgrade, Pozsony, Budapest, Ljubljana, Prague' => 'Europe/Prague', - 'Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris', - 'Paris, Madrid, Brussels, Copenhagen' => 'Europe/Paris', - 'Prague, Central Europe' => 'Europe/Prague', - 'Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb' => 'Europe/Sarajevo', - 'West Central Africa' => 'Africa/Luanda', // This was a best guess - 'Athens, Istanbul, Minsk' => 'Europe/Athens', - 'Bucharest' => 'Europe/Bucharest', - 'Cairo' => 'Africa/Cairo', - 'Harare, Pretoria' => 'Africa/Harare', - 'Helsinki, Riga, Tallinn' => 'Europe/Helsinki', - 'Israel, Jerusalem Standard Time' => 'Asia/Jerusalem', - 'Baghdad' => 'Asia/Baghdad', - 'Arab, Kuwait, Riyadh' => 'Asia/Kuwait', - 'Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow', - 'East Africa, Nairobi' => 'Africa/Nairobi', - 'Tehran' => 'Asia/Tehran', - 'Abu Dhabi, Muscat' => 'Asia/Muscat', // Best guess - 'Baku, Tbilisi, Yerevan' => 'Asia/Baku', - 'Kabul' => 'Asia/Kabul', - 'Ekaterinburg' => 'Asia/Yekaterinburg', - 'Islamabad, Karachi, Tashkent' => 'Asia/Karachi', - 'Kolkata, Chennai, Mumbai, New Delhi, India Standard Time' => 'Asia/Calcutta', - 'Kathmandu, Nepal' => 'Asia/Kathmandu', - 'Almaty, Novosibirsk, North Central Asia' => 'Asia/Almaty', - 'Astana, Dhaka' => 'Asia/Dhaka', - 'Sri Jayawardenepura, Sri Lanka' => 'Asia/Colombo', - 'Rangoon' => 'Asia/Rangoon', - 'Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok', - 'Krasnoyarsk' => 'Asia/Krasnoyarsk', - 'Beijing, Chongqing, Hong Kong SAR, Urumqi' => 'Asia/Shanghai', - 'Irkutsk, Ulaan Bataar' => 'Asia/Irkutsk', - 'Kuala Lumpur, Singapore' => 'Asia/Singapore', - 'Perth, Western Australia' => 'Australia/Perth', - 'Taipei' => 'Asia/Taipei', - 'Osaka, Sapporo, Tokyo' => 'Asia/Tokyo', - 'Seoul, Korea Standard time' => 'Asia/Seoul', - 'Yakutsk' => 'Asia/Yakutsk', - 'Adelaide, Central Australia' => 'Australia/Adelaide', - 'Darwin' => 'Australia/Darwin', - 'Brisbane, East Australia' => 'Australia/Brisbane', - 'Canberra, Melbourne, Sydney, Hobart (year 2000 only)' => 'Australia/Sydney', - 'Guam, Port Moresby' => 'Pacific/Guam', - 'Hobart, Tasmania' => 'Australia/Hobart', - 'Vladivostok' => 'Asia/Vladivostok', - 'Magadan, Solomon Is., New Caledonia' => 'Asia/Magadan', - 'Auckland, Wellington' => 'Pacific/Auckland', - 'Fiji Islands, Kamchatka, Marshall Is.' => 'Pacific/Fiji', - 'Nuku\'alofa, Tonga' => 'Pacific/Tongatapu', - 'Azores' => 'Atlantic/Azores', - 'Cape Verde Is.' => 'Atlantic/Cape_Verde', - 'Mid-Atlantic' => 'America/Noronha', - 'Brasilia' => 'America/Sao_Paulo', // Best guess - 'Buenos Aires' => 'America/Argentina/Buenos_Aires', - 'Greenland' => 'America/Godthab', - 'Newfoundland' => 'America/St_Johns', - 'Atlantic Time (Canada)' => 'America/Halifax', - 'Caracas, La Paz' => 'America/Caracas', - 'Santiago' => 'America/Santiago', - 'Bogota, Lima, Quito' => 'America/Bogota', - 'Eastern Time (US & Canada)' => 'America/New_York', - 'Indiana (East)' => 'America/Indiana/Indianapolis', - 'Central America' => 'America/Guatemala', - 'Central Time (US & Canada)' => 'America/Chicago', - 'Mexico City, Tegucigalpa' => 'America/Mexico_City', - 'Saskatchewan' => 'America/Edmonton', - 'Arizona' => 'America/Phoenix', - 'Mountain Time (US & Canada)' => 'America/Denver', // Best guess - 'Pacific Time (US & Canada)' => 'America/Los_Angeles', // Best guess - 'Pacific Time (US & Canada); Tijuana' => 'America/Los_Angeles', // Best guess - 'Alaska' => 'America/Anchorage', - 'Hawaii' => 'Pacific/Honolulu', - 'Midway Island, Samoa' => 'Pacific/Midway', - 'Eniwetok, Kwajalein, Dateline Time' => 'Pacific/Kwajalein', -]; diff --git a/lib/vendor/sabre/vobject/lib/timezonedata/lotuszones.php b/lib/vendor/sabre/vobject/lib/timezonedata/lotuszones.php deleted file mode 100644 index 4b50808..0000000 --- a/lib/vendor/sabre/vobject/lib/timezonedata/lotuszones.php +++ /dev/null @@ -1,101 +0,0 @@ - 'Etc/GMT-12', - 'Samoa' => 'Pacific/Apia', - 'Hawaiian' => 'Pacific/Honolulu', - 'Alaskan' => 'America/Anchorage', - 'Pacific' => 'America/Los_Angeles', - 'Pacific Standard Time' => 'America/Los_Angeles', - 'Mexico Standard Time 2' => 'America/Chihuahua', - 'Mountain' => 'America/Denver', - // 'Mountain Standard Time' => 'America/Chihuahua', // conflict with windows timezones. - 'US Mountain' => 'America/Phoenix', - 'Canada Central' => 'America/Edmonton', - 'Central America' => 'America/Guatemala', - 'Central' => 'America/Chicago', - // 'Central Standard Time' => 'America/Mexico_City', // conflict with windows timezones. - 'Mexico' => 'America/Mexico_City', - 'Eastern' => 'America/New_York', - 'SA Pacific' => 'America/Bogota', - 'US Eastern' => 'America/Indiana/Indianapolis', - 'Venezuela' => 'America/Caracas', - 'Atlantic' => 'America/Halifax', - 'Central Brazilian' => 'America/Manaus', - 'Pacific SA' => 'America/Santiago', - 'SA Western' => 'America/La_Paz', - 'Newfoundland' => 'America/St_Johns', - 'Argentina' => 'America/Argentina/Buenos_Aires', - 'E. South America' => 'America/Belem', - 'Greenland' => 'America/Godthab', - 'Montevideo' => 'America/Montevideo', - 'SA Eastern' => 'America/Belem', - // 'Mid-Atlantic' => 'Etc/GMT-2', // conflict with windows timezones. - 'Azores' => 'Atlantic/Azores', - 'Cape Verde' => 'Atlantic/Cape_Verde', - 'Greenwich' => 'Atlantic/Reykjavik', // No I'm serious.. Greenwich is not GMT. - 'Morocco' => 'Africa/Casablanca', - 'Central Europe' => 'Europe/Prague', - 'Central European' => 'Europe/Sarajevo', - 'Romance' => 'Europe/Paris', - 'W. Central Africa' => 'Africa/Lagos', // Best guess - 'W. Europe' => 'Europe/Amsterdam', - 'E. Europe' => 'Europe/Minsk', - 'Egypt' => 'Africa/Cairo', - 'FLE' => 'Europe/Helsinki', - 'GTB' => 'Europe/Athens', - 'Israel' => 'Asia/Jerusalem', - 'Jordan' => 'Asia/Amman', - 'Middle East' => 'Asia/Beirut', - 'Namibia' => 'Africa/Windhoek', - 'South Africa' => 'Africa/Harare', - 'Arab' => 'Asia/Kuwait', - 'Arabic' => 'Asia/Baghdad', - 'E. Africa' => 'Africa/Nairobi', - 'Georgian' => 'Asia/Tbilisi', - 'Russian' => 'Europe/Moscow', - 'Iran' => 'Asia/Tehran', - 'Arabian' => 'Asia/Muscat', - 'Armenian' => 'Asia/Yerevan', - 'Azerbijan' => 'Asia/Baku', - 'Caucasus' => 'Asia/Yerevan', - 'Mauritius' => 'Indian/Mauritius', - 'Afghanistan' => 'Asia/Kabul', - 'Ekaterinburg' => 'Asia/Yekaterinburg', - 'Pakistan' => 'Asia/Karachi', - 'West Asia' => 'Asia/Tashkent', - 'India' => 'Asia/Calcutta', - 'Sri Lanka' => 'Asia/Colombo', - 'Nepal' => 'Asia/Kathmandu', - 'Central Asia' => 'Asia/Dhaka', - 'N. Central Asia' => 'Asia/Almaty', - 'Myanmar' => 'Asia/Rangoon', - 'North Asia' => 'Asia/Krasnoyarsk', - 'SE Asia' => 'Asia/Bangkok', - 'China' => 'Asia/Shanghai', - 'North Asia East' => 'Asia/Irkutsk', - 'Singapore' => 'Asia/Singapore', - 'Taipei' => 'Asia/Taipei', - 'W. Australia' => 'Australia/Perth', - 'Korea' => 'Asia/Seoul', - 'Tokyo' => 'Asia/Tokyo', - 'Yakutsk' => 'Asia/Yakutsk', - 'AUS Central' => 'Australia/Darwin', - 'Cen. Australia' => 'Australia/Adelaide', - 'AUS Eastern' => 'Australia/Sydney', - 'E. Australia' => 'Australia/Brisbane', - 'Tasmania' => 'Australia/Hobart', - 'Vladivostok' => 'Asia/Vladivostok', - 'West Pacific' => 'Pacific/Guam', - 'Central Pacific' => 'Asia/Magadan', - 'Fiji' => 'Pacific/Fiji', - 'New Zealand' => 'Pacific/Auckland', - 'Tonga' => 'Pacific/Tongatapu', -]; diff --git a/lib/vendor/sabre/vobject/lib/timezonedata/php-bc.php b/lib/vendor/sabre/vobject/lib/timezonedata/php-bc.php deleted file mode 100644 index 3116c68..0000000 --- a/lib/vendor/sabre/vobject/lib/timezonedata/php-bc.php +++ /dev/null @@ -1,152 +0,0 @@ - 'America/Chicago', - 'Cuba' => 'America/Havana', - 'Egypt' => 'Africa/Cairo', - 'Eire' => 'Europe/Dublin', - 'EST5EDT' => 'America/New_York', - 'Factory' => 'UTC', - 'GB-Eire' => 'Europe/London', - 'GMT0' => 'UTC', - 'Greenwich' => 'UTC', - 'Hongkong' => 'Asia/Hong_Kong', - 'Iceland' => 'Atlantic/Reykjavik', - 'Iran' => 'Asia/Tehran', - 'Israel' => 'Asia/Jerusalem', - 'Jamaica' => 'America/Jamaica', - 'Japan' => 'Asia/Tokyo', - 'Kwajalein' => 'Pacific/Kwajalein', - 'Libya' => 'Africa/Tripoli', - 'MST7MDT' => 'America/Denver', - 'Navajo' => 'America/Denver', - 'NZ-CHAT' => 'Pacific/Chatham', - 'Poland' => 'Europe/Warsaw', - 'Portugal' => 'Europe/Lisbon', - 'PST8PDT' => 'America/Los_Angeles', - 'Singapore' => 'Asia/Singapore', - 'Turkey' => 'Europe/Istanbul', - 'Universal' => 'UTC', - 'W-SU' => 'Europe/Moscow', - 'Zulu' => 'UTC', -]; diff --git a/lib/vendor/sabre/vobject/lib/timezonedata/windowszones.php b/lib/vendor/sabre/vobject/lib/timezonedata/windowszones.php deleted file mode 100644 index 2049a95..0000000 --- a/lib/vendor/sabre/vobject/lib/timezonedata/windowszones.php +++ /dev/null @@ -1,152 +0,0 @@ - 'Australia/Darwin', - 'AUS Eastern Standard Time' => 'Australia/Sydney', - 'Afghanistan Standard Time' => 'Asia/Kabul', - 'Alaskan Standard Time' => 'America/Anchorage', - 'Aleutian Standard Time' => 'America/Adak', - 'Altai Standard Time' => 'Asia/Barnaul', - 'Arab Standard Time' => 'Asia/Riyadh', - 'Arabian Standard Time' => 'Asia/Dubai', - 'Arabic Standard Time' => 'Asia/Baghdad', - 'Argentina Standard Time' => 'America/Buenos_Aires', - 'Astrakhan Standard Time' => 'Europe/Astrakhan', - 'Atlantic Standard Time' => 'America/Halifax', - 'Aus Central W. Standard Time' => 'Australia/Eucla', - 'Azerbaijan Standard Time' => 'Asia/Baku', - 'Azores Standard Time' => 'Atlantic/Azores', - 'Bahia Standard Time' => 'America/Bahia', - 'Bangladesh Standard Time' => 'Asia/Dhaka', - 'Belarus Standard Time' => 'Europe/Minsk', - 'Bougainville Standard Time' => 'Pacific/Bougainville', - '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', - 'Chatham Islands Standard Time' => 'Pacific/Chatham', - 'China Standard Time' => 'Asia/Shanghai', - 'Cuba Standard Time' => 'America/Havana', - 'Dateline Standard Time' => 'Etc/GMT+12', - 'E. Africa Standard Time' => 'Africa/Nairobi', - 'E. Australia Standard Time' => 'Australia/Brisbane', - 'E. Europe Standard Time' => 'Europe/Chisinau', - 'E. South America Standard Time' => 'America/Sao_Paulo', - 'Easter Island Standard Time' => 'Pacific/Easter', - 'Eastern Standard Time' => 'America/New_York', - 'Eastern Standard Time (Mexico)' => 'America/Cancun', - '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/Bucharest', - 'Georgian Standard Time' => 'Asia/Tbilisi', - 'Greenland Standard Time' => 'America/Godthab', - 'Greenwich Standard Time' => 'Atlantic/Reykjavik', - 'Haiti Standard Time' => 'America/Port-au-Prince', - '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', - 'Kaliningrad Standard Time' => 'Europe/Kaliningrad', - 'Korea Standard Time' => 'Asia/Seoul', - 'Libya Standard Time' => 'Africa/Tripoli', - 'Line Islands Standard Time' => 'Pacific/Kiritimati', - 'Lord Howe Standard Time' => 'Australia/Lord_Howe', - 'Magadan Standard Time' => 'Asia/Magadan', - 'Magallanes Standard Time' => 'America/Punta_Arenas', - 'Marquesas Standard Time' => 'Pacific/Marquesas', - 'Mauritius Standard Time' => 'Indian/Mauritius', - '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', - 'Norfolk Standard Time' => 'Pacific/Norfolk', - 'North Asia East Standard Time' => 'Asia/Irkutsk', - 'North Asia Standard Time' => 'Asia/Krasnoyarsk', - 'North Korea Standard Time' => 'Asia/Pyongyang', - 'Omsk Standard Time' => 'Asia/Omsk', - 'Pacific SA Standard Time' => 'America/Santiago', - 'Pacific Standard Time' => 'America/Los_Angeles', - 'Pacific Standard Time (Mexico)' => 'America/Tijuana', - 'Pakistan Standard Time' => 'Asia/Karachi', - 'Paraguay Standard Time' => 'America/Asuncion', - 'Qyzylorda Standard Time' => 'Asia/Qyzylorda', - 'Romance Standard Time' => 'Europe/Paris', - 'Russia Time Zone 10' => 'Asia/Srednekolymsk', - 'Russia Time Zone 11' => 'Asia/Kamchatka', - 'Russia Time Zone 3' => 'Europe/Samara', - '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', - 'Saint Pierre Standard Time' => 'America/Miquelon', - 'Sakhalin Standard Time' => 'Asia/Sakhalin', - 'Samoa Standard Time' => 'Pacific/Apia', - 'Sao Tome Standard Time' => 'Africa/Sao_Tome', - 'Saratov Standard Time' => 'Europe/Saratov', - 'Singapore Standard Time' => 'Asia/Singapore', - 'South Africa Standard Time' => 'Africa/Johannesburg', - 'Sri Lanka Standard Time' => 'Asia/Colombo', - 'Sudan Standard Time' => 'Africa/Khartoum', - 'Syria Standard Time' => 'Asia/Damascus', - 'Taipei Standard Time' => 'Asia/Taipei', - 'Tasmania Standard Time' => 'Australia/Hobart', - 'Tocantins Standard Time' => 'America/Araguaina', - 'Tokyo Standard Time' => 'Asia/Tokyo', - 'Tomsk Standard Time' => 'Asia/Tomsk', - 'Tonga Standard Time' => 'Pacific/Tongatapu', - 'Transbaikal Standard Time' => 'Asia/Chita', - 'Turkey Standard Time' => 'Europe/Istanbul', - 'Turks And Caicos Standard Time' => 'America/Grand_Turk', - 'US Eastern Standard Time' => 'America/Indianapolis', - 'US Mountain Standard Time' => 'America/Phoenix', - 'UTC' => 'Etc/GMT', - 'UTC+12' => 'Etc/GMT-12', - 'UTC+13' => 'Etc/GMT-13', - 'UTC-02' => 'Etc/GMT+2', - 'UTC-08' => 'Etc/GMT+8', - 'UTC-09' => 'Etc/GMT+9', - 'UTC-11' => 'Etc/GMT+11', - 'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar', - 'Venezuela Standard Time' => 'America/Caracas', - 'Vladivostok Standard Time' => 'Asia/Vladivostok', - 'Volgograd Standard Time' => 'Europe/Volgograd', - 'W. Australia Standard Time' => 'Australia/Perth', - 'W. Central Africa Standard Time' => 'Africa/Lagos', - 'W. Europe Standard Time' => 'Europe/Berlin', - 'W. Mongolia Standard Time' => 'Asia/Hovd', - 'West Asia Standard Time' => 'Asia/Tashkent', - 'West Bank Standard Time' => 'Asia/Hebron', - 'West Pacific Standard Time' => 'Pacific/Port_Moresby', - 'Yakutsk Standard Time' => 'Asia/Yakutsk', - 'Yukon Standard Time' => 'America/Whitehorse', -]; diff --git a/lib/vendor/sabre/vobject/resources/schema/xcal.rng b/lib/vendor/sabre/vobject/resources/schema/xcal.rng deleted file mode 100644 index 4a51460..0000000 --- a/lib/vendor/sabre/vobject/resources/schema/xcal.rng +++ /dev/null @@ -1,1192 +0,0 @@ -# RELAX NG Schema for iCalendar in XML -# Extract from RFC6321. -# Erratum 3042 applied. -# Erratum 3050 applied. -# Erratum 3314 applied. - -default namespace = "urn:ietf:params:xml:ns:icalendar-2.0" - -# 3.2 Property Parameters - -# 3.2.1 Alternate Text Representation - -altrepparam = element altrep { - value-uri -} - -# 3.2.2 Common Name - -cnparam = element cn { - value-text -} - -# 3.2.3 Calendar User Type - -cutypeparam = element cutype { - element text { - "INDIVIDUAL" | - "GROUP" | - "RESOURCE" | - "ROOM" | - "UNKNOWN" - } -} - -# 3.2.4 Delegators - -delfromparam = element delegated-from { - value-cal-address+ -} - -# 3.2.5 Delegatees - -deltoparam = element delegated-to { - value-cal-address+ -} - -# 3.2.6 Directory Entry Reference - -dirparam = element dir { - value-uri -} - -# 3.2.7 Inline Encoding - -encodingparam = element encoding { - element text { - "8BIT" | - "BASE64" - } -} - -# 3.2.8 Format Type - -fmttypeparam = element fmttype { - value-text -} - -# 3.2.9 Free/Busy Time Type - -fbtypeparam = element fbtype { - element text { - "FREE" | - "BUSY" | - "BUSY-UNAVAILABLE" | - "BUSY-TENTATIVE" - } -} - -# 3.2.10 Language - -languageparam = element language { - value-text -} - -# 3.2.11 Group or List Membership - -memberparam = element member { - value-cal-address+ -} - -# 3.2.12 Participation Status - -partstatparam = element partstat { - type-partstat-event | - type-partstat-todo | - type-partstat-jour -} - -type-partstat-event = ( - element text { - "NEEDS-ACTION" | - "ACCEPTED" | - "DECLINED" | - "TENTATIVE" | - "DELEGATED" - } -) - -type-partstat-todo = ( - element text { - "NEEDS-ACTION" | - "ACCEPTED" | - "DECLINED" | - "TENTATIVE" | - "DELEGATED" | - "COMPLETED" | - "IN-PROCESS" - } -) - -type-partstat-jour = ( - element text { - "NEEDS-ACTION" | - "ACCEPTED" | - "DECLINED" - } -) - -# 3.2.13 Recurrence Identifier Range - -rangeparam = element range { - element text { - "THISANDFUTURE" - } -} - -# 3.2.14 Alarm Trigger Relationship - -trigrelparam = element related { - element text { - "START" | - "END" - } -} - -# 3.2.15 Relationship Type - -reltypeparam = element reltype { - element text { - "PARENT" | - "CHILD" | - "SIBLING" - } -} - -# 3.2.16 Participation Role - -roleparam = element role { - element text { - "CHAIR" | - "REQ-PARTICIPANT" | - "OPT-PARTICIPANT" | - "NON-PARTICIPANT" - } -} - -# 3.2.17 RSVP Expectation - -rsvpparam = element rsvp { - value-boolean -} - -# 3.2.18 Sent By - -sentbyparam = element sent-by { - value-cal-address -} - -# 3.2.19 Time Zone Identifier - -tzidparam = element tzid { - value-text -} - -# 3.3 Property Value Data Types - -# 3.3.1 BINARY - -value-binary = element binary { - xsd:string -} - -# 3.3.2 BOOLEAN - -value-boolean = element boolean { - xsd:boolean -} - -# 3.3.3 CAL-ADDRESS - -value-cal-address = element cal-address { - xsd:anyURI -} - -# 3.3.4 DATE - -pattern-date = xsd:string { - pattern = "\d\d\d\d-\d\d-\d\d" -} - -value-date = element date { - pattern-date -} - -# 3.3.5 DATE-TIME - -pattern-date-time = xsd:string { - pattern = "\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ?" -} - -value-date-time = element date-time { - pattern-date-time -} - -# 3.3.6 DURATION - -pattern-duration = xsd:string { - pattern = "(+|-)?P(\d+W)|(\d+D)?" - ~ "(T(\d+H(\d+M)?(\d+S)?)|" - ~ "(\d+M(\d+S)?)|" - ~ "(\d+S))?" -} - -value-duration = element duration { - pattern-duration -} - -# 3.3.7 FLOAT - -value-float = element float { - xsd:float -} - -# 3.3.8 INTEGER - -value-integer = element integer { - xsd:integer -} - -# 3.3.9 PERIOD - -value-period = element period { - element start { - pattern-date-time - }, - ( - element end { - pattern-date-time - } | - element duration { - pattern-duration - } - ) -} - -# 3.3.10 RECUR - -value-recur = element recur { - type-freq, - (type-until | type-count)?, - element interval { - xsd:positiveInteger - }?, - type-bysecond*, - type-byminute*, - type-byhour*, - type-byday*, - type-bymonthday*, - type-byyearday*, - type-byweekno*, - type-bymonth*, - type-bysetpos*, - element wkst { type-weekday }? -} - -type-freq = element freq { - "SECONDLY" | - "MINUTELY" | - "HOURLY" | - "DAILY" | - "WEEKLY" | - "MONTHLY" | - "YEARLY" -} - -type-until = element until { - type-date | - type-date-time -} - -type-count = element count { - xsd:positiveInteger -} - -type-bysecond = element bysecond { - xsd:nonNegativeInteger -} - -type-byminute = element byminute { - xsd:nonNegativeInteger -} - -type-byhour = element byhour { - xsd:nonNegativeInteger -} - -type-weekday = ( - "SU" | - "MO" | - "TU" | - "WE" | - "TH" | - "FR" | - "SA" -) - -type-byday = element byday { - xsd:integer?, - type-weekday -} - -type-bymonthday = element bymonthday { - xsd:integer -} - -type-byyearday = element byyearday { - xsd:integer -} - -type-byweekno = element byweekno { - xsd:integer -} - -type-bymonth = element bymonth { - xsd:positiveInteger -} - -type-bysetpos = element bysetpos { - xsd:integer -} - -# 3.3.11 TEXT - -value-text = element text { - xsd:string -} - -# 3.3.12 TIME - -pattern-time = xsd:string { - pattern = "\d\d:\d\d:\d\dZ?" -} - -value-time = element time { - pattern-time -} - -# 3.3.13 URI - -value-uri = element uri { - xsd:anyURI -} - -# 3.3.14 UTC-OFFSET - -value-utc-offset = element utc-offset { - xsd:string { pattern = "(+|-)\d\d:\d\d(:\d\d)?" } -} - -# UNKNOWN - -value-unknown = element unknown { - xsd:string -} - -# 3.4 iCalendar Stream - -start = element icalendar { - vcalendar+ -} - -# 3.6 Calendar Components - -vcalendar = element vcalendar { - type-calprops, - type-component -} - -type-calprops = element properties { - property-prodid & - property-version & - property-calscale? & - property-method? -} - -type-component = element components { - ( - component-vevent | - component-vtodo | - component-vjournal | - component-vfreebusy | - component-vtimezone - )* -} - -# 3.6.1 Event Component - -component-vevent = element vevent { - type-eventprop, - element components { - component-valarm+ - }? -} - -type-eventprop = element properties { - property-dtstamp & - property-dtstart & - property-uid & - - property-class? & - property-created? & - property-description? & - property-geo? & - property-last-mod? & - property-location? & - property-organizer? & - property-priority? & - property-seq? & - property-status-event? & - property-summary? & - property-transp? & - property-url? & - property-recurid? & - - property-rrule? & - - (property-dtend | property-duration)? & - - property-attach* & - property-attendee* & - property-categories* & - property-comment* & - property-contact* & - property-exdate* & - property-rstatus* & - property-related* & - property-resources* & - property-rdate* -} - -# 3.6.2 To-do Component - -component-vtodo = element vtodo { - type-todoprop, - element components { - component-valarm+ - }? -} - -type-todoprop = element properties { - property-dtstamp & - property-uid & - - property-class? & - property-completed? & - property-created? & - property-description? & - property-geo? & - property-last-mod? & - property-location? & - property-organizer? & - property-percent? & - property-priority? & - property-recurid? & - property-seq? & - property-status-todo? & - property-summary? & - property-url? & - - property-rrule? & - - ( - (property-dtstart?, property-dtend? ) | - (property-dtstart, property-duration)? - ) & - - property-attach* & - property-attendee* & - property-categories* & - property-comment* & - property-contact* & - property-exdate* & - property-rstatus* & - property-related* & - property-resources* & - property-rdate* -} - -# 3.6.3 Journal Component - -component-vjournal = element vjournal { - type-jourprop -} - -type-jourprop = element properties { - property-dtstamp & - property-uid & - - property-class? & - property-created? & - property-dtstart? & - property-last-mod? & - property-organizer? & - property-recurid? & - property-seq? & - property-status-jour? & - property-summary? & - property-url? & - - property-rrule? & - - property-attach* & - property-attendee* & - property-categories* & - property-comment* & - property-contact* & - property-description? & - property-exdate* & - property-related* & - property-rdate* & - property-rstatus* -} - -# 3.6.4 Free/Busy Component - -component-vfreebusy = element vfreebusy { - type-fbprop -} - -type-fbprop = element properties { - property-dtstamp & - property-uid & - - property-contact? & - property-dtstart? & - property-dtend? & - property-duration? & - property-organizer? & - property-url? & - - property-attendee* & - property-comment* & - property-freebusy* & - property-rstatus* -} - -# 3.6.5 Time Zone Component - -component-vtimezone = element vtimezone { - element properties { - property-tzid & - - property-last-mod? & - property-tzurl? - }, - element components { - (component-standard | component-daylight) & - component-standard* & - component-daylight* - } -} - -component-standard = element standard { - type-tzprop -} - -component-daylight = element daylight { - type-tzprop -} - -type-tzprop = element properties { - property-dtstart & - property-tzoffsetto & - property-tzoffsetfrom & - - property-rrule? & - - property-comment* & - property-rdate* & - property-tzname* -} - -# 3.6.6 Alarm Component - -component-valarm = element valarm { - type-audioprop | type-dispprop | type-emailprop -} - -type-audioprop = element properties { - property-action & - - property-trigger & - - (property-duration, property-repeat)? & - - property-attach? -} - -type-emailprop = element properties { - property-action & - property-description & - property-trigger & - property-summary & - - property-attendee+ & - - (property-duration, property-repeat)? & - - property-attach* -} - -type-dispprop = element properties { - property-action & - property-description & - property-trigger & - - (property-duration, property-repeat)? -} - -# 3.7 Calendar Properties - -# 3.7.1 Calendar Scale - -property-calscale = element calscale { - - element parameters { empty }?, - - element text { "GREGORIAN" } -} - -# 3.7.2 Method - -property-method = element method { - - element parameters { empty }?, - - value-text -} - -# 3.7.3 Product Identifier - -property-prodid = element prodid { - - element parameters { empty }?, - - value-text -} - -# 3.7.4 Version - -property-version = element version { - - element parameters { empty }?, - - element text { "2.0" } -} - -# 3.8 Component Properties - -# 3.8.1 Descriptive Component Properties - -# 3.8.1.1 Attachment - -property-attach = element attach { - - element parameters { - fmttypeparam? & - encodingparam? - }?, - - value-uri | value-binary -} - -# 3.8.1.2 Categories - -property-categories = element categories { - - element parameters { - languageparam? & - }?, - - value-text+ -} - -# 3.8.1.3 Classification - -property-class = element class { - - element parameters { empty }?, - - element text { - "PUBLIC" | - "PRIVATE" | - "CONFIDENTIAL" - } -} - -# 3.8.1.4 Comment - -property-comment = element comment { - - element parameters { - altrepparam? & - languageparam? - }?, - - value-text -} - -# 3.8.1.5 Description - -property-description = element description { - - element parameters { - altrepparam? & - languageparam? - }?, - - value-text -} - -# 3.8.1.6 Geographic Position - -property-geo = element geo { - - element parameters { empty }?, - - element latitude { xsd:float }, - element longitude { xsd:float } -} - -# 3.8.1.7 Location - -property-location = element location { - - element parameters { - - altrepparam? & - languageparam? - }?, - - value-text -} - -# 3.8.1.8 Percent Complete - -property-percent = element percent-complete { - - element parameters { empty }?, - - value-integer -} - -# 3.8.1.9 Priority - -property-priority = element priority { - - element parameters { empty }?, - - value-integer -} - -# 3.8.1.10 Resources - -property-resources = element resources { - - element parameters { - altrepparam? & - languageparam? - }?, - - value-text+ -} - -# 3.8.1.11 Status - -property-status-event = element status { - - element parameters { empty }?, - - element text { - "TENTATIVE" | - "CONFIRMED" | - "CANCELLED" - } -} - -property-status-todo = element status { - - element parameters { empty }?, - - element text { - "NEEDS-ACTION" | - "COMPLETED" | - "IN-PROCESS" | - "CANCELLED" - } -} - -property-status-jour = element status { - - element parameters { empty }?, - - element text { - "DRAFT" | - "FINAL" | - "CANCELLED" - } -} - -# 3.8.1.12 Summary - -property-summary = element summary { - - element parameters { - altrepparam? & - languageparam? - }?, - - value-text -} - -# 3.8.2 Date and Time Component Properties - -# 3.8.2.1 Date/Time Completed - -property-completed = element completed { - - element parameters { empty }?, - - value-date-time -} - -# 3.8.2.2 Date/Time End - -property-dtend = element dtend { - - element parameters { - tzidparam? - }?, - - value-date-time | - value-date -} - -# 3.8.2.3 Date/Time Due - -property-due = element due { - - element parameters { - tzidparam? - }?, - - value-date-time | - value-date -} - -# 3.8.2.4 Date/Time Start - -property-dtstart = element dtstart { - - element parameters { - tzidparam? - }?, - - value-date-time | - value-date -} - -# 3.8.2.5 Duration - -property-duration = element duration { - - element parameters { empty }?, - - value-duration -} - -# 3.8.2.6 Free/Busy Time - -property-freebusy = element freebusy { - - element parameters { - fbtypeparam? - }?, - - - value-period+ -} - -# 3.8.2.7 Time Transparency - -property-transp = element transp { - - element parameters { empty }?, - - element text { - "OPAQUE" | - "TRANSPARENT" - } -} - -# 3.8.3 Time Zone Component Properties - -# 3.8.3.1 Time Zone Identifier - -property-tzid = element tzid { - - element parameters { empty }?, - - value-text -} - -# 3.8.3.2 Time Zone Name - -property-tzname = element tzname { - - element parameters { - languageparam? - }?, - - value-text -} - -# 3.8.3.3 Time Zone Offset From - -property-tzoffsetfrom = element tzoffsetfrom { - - element parameters { empty }?, - - value-utc-offset -} - -# 3.8.3.4 Time Zone Offset To - -property-tzoffsetto = element tzoffsetto { - - element parameters { empty }?, - - value-utc-offset -} - -# 3.8.3.5 Time Zone URL - -property-tzurl = element tzurl { - - element parameters { empty }?, - - value-uri -} - -# 3.8.4 Relationship Component Properties - -# 3.8.4.1 Attendee - -property-attendee = element attendee { - - element parameters { - cutypeparam? & - memberparam? & - roleparam? & - partstatparam? & - rsvpparam? & - deltoparam? & - delfromparam? & - sentbyparam? & - cnparam? & - dirparam? & - languageparam? - }?, - - value-cal-address -} - -# 3.8.4.2 Contact - -property-contact = element contact { - - element parameters { - altrepparam? & - languageparam? - }?, - - value-text -} - -# 3.8.4.3 Organizer - -property-organizer = element organizer { - - element parameters { - cnparam? & - dirparam? & - sentbyparam? & - languageparam? - }?, - - value-cal-address -} - -# 3.8.4.4 Recurrence ID - -property-recurid = element recurrence-id { - - element parameters { - tzidparam? & - rangeparam? - }?, - - value-date-time | - value-date -} - -# 3.8.4.5 Related-To - -property-related = element related-to { - - element parameters { - reltypeparam? - }?, - - value-text -} - -# 3.8.4.6 Uniform Resource Locator - -property-url = element url { - - element parameters { empty }?, - - value-uri -} - -# 3.8.4.7 Unique Identifier - -property-uid = element uid { - - element parameters { empty }?, - - value-text -} - -# 3.8.5 Recurrence Component Properties - -# 3.8.5.1 Exception Date/Times - -property-exdate = element exdate { - - element parameters { - tzidparam? - }?, - - value-date-time+ | - value-date+ -} - -# 3.8.5.2 Recurrence Date/Times - -property-rdate = element rdate { - - element parameters { - tzidparam? - }?, - - value-date-time+ | - value-date+ | - value-period+ -} - -# 3.8.5.3 Recurrence Rule - -property-rrule = element rrule { - - element parameters { empty }?, - - value-recur -} - -# 3.8.6 Alarm Component Properties - -# 3.8.6.1 Action - -property-action = element action { - - element parameters { empty }?, - - element text { - "AUDIO" | - "DISPLAY" | - "EMAIL" - } -} - -# 3.8.6.2 Repeat Count - -property-repeat = element repeat { - - element parameters { empty }?, - - value-integer -} - -# 3.8.6.3 Trigger - -property-trigger = element trigger { - - ( - element parameters { - trigrelparam? - }?, - - value-duration - ) | - ( - element parameters { empty }?, - - value-date-time - ) -} - -# 3.8.7 Change Management Component Properties - -# 3.8.7.1 Date/Time Created - -property-created = element created { - - element parameters { empty }?, - - value-date-time -} - -# 3.8.7.2 Date/Time Stamp - -property-dtstamp = element dtstamp { - - element parameters { empty }?, - - value-date-time -} - -# 3.8.7.3 Last Modified - -property-last-mod = element last-modified { - - element parameters { empty }?, - - value-date-time -} - -# 3.8.7.4 Sequence Number - -property-seq = element sequence { - - element parameters { empty }?, - - value-integer -} - -# 3.8.8 Miscellaneous Component Properties - -# 3.8.8.3 Request Status - -property-rstatus = element request-status { - - element parameters { - languageparam? - }?, - - element code { xsd:string }, - element description { xsd:string }, - element data { xsd:string }? -} diff --git a/lib/vendor/sabre/vobject/resources/schema/xcard.rng b/lib/vendor/sabre/vobject/resources/schema/xcard.rng deleted file mode 100644 index c0b7cfb..0000000 --- a/lib/vendor/sabre/vobject/resources/schema/xcard.rng +++ /dev/null @@ -1,388 +0,0 @@ -# RELAX NG Schema for vCard in XML -# Extract from RFC6351. -# Erratum 2994 applied. -# Erratum 3047 applied. -# Erratum 3008 applied. -# Erratum 4247 applied. - -default namespace = "urn:ietf:params:xml:ns:vcard-4.0" - -### Section 3.3: vCard Format Specification -# -# 3.3 -iana-token = xsd:string { pattern = "[a-zA-Z0-9\-]+" } -x-name = xsd:string { pattern = "x-[a-zA-Z0-9\-]+" } - -### Section 4: Value types -# -# 4.1 -value-text = element text { text } -value-text-list = value-text+ - -# 4.2 -value-uri = element uri { xsd:anyURI } - -# 4.3.1 -value-date = element date { - xsd:string { pattern = "\d{8}|\d{4}-\d\d|--\d\d(\d\d)?|---\d\d" } - } - -# 4.3.2 -value-time = element time { - xsd:string { pattern = "(\d\d(\d\d(\d\d)?)?|-\d\d(\d\d)?|--\d\d)" - ~ "(Z|[+\-]\d\d(\d\d)?)?" } - } - -# 4.3.3 -value-date-time = element date-time { - xsd:string { pattern = "(\d{8}|--\d{4}|---\d\d)T\d\d(\d\d(\d\d)?)?" - ~ "(Z|[+\-]\d\d(\d\d)?)?" } - } - -# 4.3.4 -value-date-and-or-time = value-date | value-date-time | value-time - -# 4.3.5 -value-timestamp = element timestamp { - xsd:string { pattern = "\d{8}T\d{6}(Z|[+\-]\d\d(\d\d)?)?" } - } - -# 4.4 -value-boolean = element boolean { xsd:boolean } - -# 4.5 -value-integer = element integer { xsd:integer } - -# 4.6 -value-float = element float { xsd:float } - -# 4.7 -value-utc-offset = element utc-offset { - xsd:string { pattern = "[+\-]\d\d(\d\d)?" } - } - -# 4.8 -value-language-tag = element language-tag { - xsd:string { pattern = "([a-z]{2,3}((-[a-z]{3}){0,3})?|[a-z]{4,8})" - ~ "(-[a-z]{4})?(-([a-z]{2}|\d{3}))?" - ~ "(-([0-9a-z]{5,8}|\d[0-9a-z]{3}))*" - ~ "(-[0-9a-wyz](-[0-9a-z]{2,8})+)*" - ~ "(-x(-[0-9a-z]{1,8})+)?|x(-[0-9a-z]{1,8})+|" - ~ "[a-z]{1,3}(-[0-9a-z]{2,8}){1,2}" } - } - -### Section 5: Parameters -# -# 5.1 -param-language = element language { value-language-tag }? - -# 5.2 -param-pref = element pref { - element integer { - xsd:integer { minInclusive = "1" maxInclusive = "100" } - } - }? - -# 5.4 -param-altid = element altid { value-text }? - -# 5.5 -param-pid = element pid { - element text { xsd:string { pattern = "\d+(\.\d+)?" } }+ - }? - -# 5.6 -param-type = element type { element text { "work" | "home" }+ }? - -# 5.7 -param-mediatype = element mediatype { value-text }? - -# 5.8 -param-calscale = element calscale { element text { "gregorian" } }? - -# 5.9 -param-sort-as = element sort-as { value-text+ }? - -# 5.10 -param-geo = element geo { value-uri }? - -# 5.11 -param-tz = element tz { value-text | value-uri }? - -### Section 6: Properties -# -# 6.1.3 -property-source = element source { - element parameters { param-altid, param-pid, param-pref, - param-mediatype }?, - value-uri - } - -# 6.1.4 -property-kind = element kind { - element text { "individual" | "group" | "org" | "location" | - x-name | iana-token }* - } - -# 6.2.1 -property-fn = element fn { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type }?, - value-text - } - -# 6.2.2 -property-n = element n { - element parameters { param-language, param-sort-as, param-altid }?, - element surname { text }+, - element given { text }+, - element additional { text }+, - element prefix { text }+, - element suffix { text }+ - } - -# 6.2.3 -property-nickname = element nickname { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type }?, - value-text-list - } - -# 6.2.4 -property-photo = element photo { - element parameters { param-altid, param-pid, param-pref, param-type, - param-mediatype }?, - value-uri - } - -# 6.2.5 -property-bday = element bday { - element parameters { param-altid, param-calscale }?, - (value-date-and-or-time | value-text) - } - -# 6.2.6 -property-anniversary = element anniversary { - element parameters { param-altid, param-calscale }?, - (value-date-and-or-time | value-text) - } - -# 6.2.7 -property-gender = element gender { - element sex { "" | "M" | "F" | "O" | "N" | "U" }, - element identity { text }? - } - -# 6.3.1 -param-label = element label { value-text }? -property-adr = element adr { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type, param-geo, param-tz, - param-label }?, - element pobox { text }+, - element ext { text }+, - element street { text }+, - element locality { text }+, - element region { text }+, - element code { text }+, - element country { text }+ - } - -# 6.4.1 -property-tel = element tel { - element parameters { - param-altid, - param-pid, - param-pref, - element type { - element text { "work" | "home" | "text" | "voice" - | "fax" | "cell" | "video" | "pager" - | "textphone" | x-name | iana-token }+ - }?, - param-mediatype - }?, - (value-text | value-uri) - } - -# 6.4.2 -property-email = element email { - element parameters { param-altid, param-pid, param-pref, - param-type }?, - value-text - } - -# 6.4.3 -property-impp = element impp { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - value-uri - } - -# 6.4.4 -property-lang = element lang { - element parameters { param-altid, param-pid, param-pref, - param-type }?, - value-language-tag - } - -# 6.5.1 -property-tz = element tz { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - (value-text | value-uri | value-utc-offset) - } - -# 6.5.2 -property-geo = element geo { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - value-uri - } - -# 6.6.1 -property-title = element title { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type }?, - value-text - } - -# 6.6.2 -property-role = element role { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type }?, - value-text - } - -# 6.6.3 -property-logo = element logo { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type, param-mediatype }?, - value-uri - } - -# 6.6.4 -property-org = element org { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type, param-sort-as }?, - value-text-list - } - -# 6.6.5 -property-member = element member { - element parameters { param-altid, param-pid, param-pref, - param-mediatype }?, - value-uri - } - -# 6.6.6 -property-related = element related { - element parameters { - param-altid, - param-pid, - param-pref, - element type { - element text { - "work" | "home" | "contact" | "acquaintance" | - "friend" | "met" | "co-worker" | "colleague" | "co-resident" | - "neighbor" | "child" | "parent" | "sibling" | "spouse" | - "kin" | "muse" | "crush" | "date" | "sweetheart" | "me" | - "agent" | "emergency" - }+ - }?, - param-mediatype - }?, - (value-uri | value-text) - } - -# 6.7.1 -property-categories = element categories { - element parameters { param-altid, param-pid, param-pref, - param-type }?, - value-text-list - } - -# 6.7.2 -property-note = element note { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type }?, - value-text - } - -# 6.7.3 -property-prodid = element prodid { value-text } - -# 6.7.4 -property-rev = element rev { value-timestamp } - -# 6.7.5 -property-sound = element sound { - element parameters { param-language, param-altid, param-pid, - param-pref, param-type, param-mediatype }?, - value-uri - } - -# 6.7.6 -property-uid = element uid { value-uri } - -# 6.7.7 -property-clientpidmap = element clientpidmap { - element sourceid { xsd:positiveInteger }, - value-uri - } - -# 6.7.8 -property-url = element url { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - value-uri - } - -# 6.8.1 -property-key = element key { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - (value-uri | value-text) - } - -# 6.9.1 -property-fburl = element fburl { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - value-uri - } - -# 6.9.2 -property-caladruri = element caladruri { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - value-uri - } - -# 6.9.3 -property-caluri = element caluri { - element parameters { param-altid, param-pid, param-pref, - param-type, param-mediatype }?, - value-uri - } - -# Top-level grammar -property = property-adr | property-anniversary | property-bday - | property-caladruri | property-caluri | property-categories - | property-clientpidmap | property-email | property-fburl - | property-fn | property-geo | property-impp | property-key - | property-kind | property-lang | property-logo - | property-member | property-n | property-nickname - | property-note | property-org | property-photo - | property-prodid | property-related | property-rev - | property-role | property-gender | property-sound - | property-source | property-tel | property-title - | property-tz | property-uid | property-url -start = element vcards { - element vcard { - (property - | element group { - attribute name { text }, - property* - })+ - }+ - } diff --git a/lib/vendor/sabre/xml/.github/workflows/ci.yml b/lib/vendor/sabre/xml/.github/workflows/ci.yml deleted file mode 100644 index 5775aba..0000000 --- a/lib/vendor/sabre/xml/.github/workflows/ci.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: continuous-integration -on: - push: - branches: - - master - - release/* - pull_request: -jobs: - unit-testing: - name: PHPUnit (PHP ${{ matrix.php-versions }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] - coverage: ['pcov'] - code-style: ['yes'] - code-analysis: ['no'] - include: - - php-versions: '7.1' - coverage: 'none' - code-style: 'yes' - code-analysis: 'yes' - - php-versions: '8.4' - coverage: 'pcov' - code-style: 'yes' - code-analysis: 'yes' - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup PHP, with composer and extensions - uses: shivammathur/setup-php@v2 #https://github.com/shivammathur/setup-php - with: - php-version: ${{ matrix.php-versions }} - extensions: mbstring, dom, fileinfo, mysql, redis, opcache - coverage: ${{ matrix.coverage }} - tools: composer - - - name: Get composer cache directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache composer dependencies - uses: actions/cache@v3 - with: - path: ${{ steps.composer-cache.outputs.dir }} - # Use composer.json for key, if composer.lock is not committed. - # key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - - name: Install composer dependencies - run: composer install --no-progress --prefer-dist --optimize-autoloader - - - name: Code Analysis (PHP CS-Fixer) - if: matrix.code-style == 'yes' - run: PHP_CS_FIXER_IGNORE_ENV=true php vendor/bin/php-cs-fixer fix --dry-run --diff - - - name: Code Analysis (PHPStan) - if: matrix.code-analysis == 'yes' - run: composer phpstan - - - name: Test with phpunit - run: vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-clover clover.xml - - - name: Code Coverage - uses: codecov/codecov-action@v3 - if: matrix.coverage != 'none' diff --git a/lib/vendor/sabre/xml/.php-cs-fixer.dist.php b/lib/vendor/sabre/xml/.php-cs-fixer.dist.php deleted file mode 100644 index f9d4b7a..0000000 --- a/lib/vendor/sabre/xml/.php-cs-fixer.dist.php +++ /dev/null @@ -1,17 +0,0 @@ -exclude('vendor') - ->in(__DIR__); - -$config = new PhpCsFixer\Config(); -$config->setRules([ - '@PSR1' => true, - '@Symfony' => true, - 'nullable_type_declaration' => [ - 'syntax' => 'question_mark', - ], - 'nullable_type_declaration_for_default_null_value' => true, -]); -$config->setFinder($finder); -return $config; \ No newline at end of file diff --git a/lib/vendor/sabre/xml/LICENSE b/lib/vendor/sabre/xml/LICENSE deleted file mode 100644 index c9faf40..0000000 --- a/lib/vendor/sabre/xml/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/) - -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 Sabre 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/lib/vendor/sabre/xml/README.md b/lib/vendor/sabre/xml/README.md deleted file mode 100644 index 55af24f..0000000 --- a/lib/vendor/sabre/xml/README.md +++ /dev/null @@ -1,25 +0,0 @@ -sabre/xml -========= - -[![Build Status](https://secure.travis-ci.org/sabre-io/xml.svg?branch=master)](http://travis-ci.org/sabre-io/xml) - -The sabre/xml library is a specialized XML reader and writer. - -Documentation -------------- - -* [Introduction](http://sabre.io/xml/). -* [Installation](http://sabre.io/xml/install/). -* [Reading XML](http://sabre.io/xml/reading/). -* [Writing XML](http://sabre.io/xml/writing/). - - -Support -------- - -Head over to the [SabreDAV mailing list](http://groups.google.com/group/sabredav-discuss) for any questions. - -Made at fruux -------------- - -This library is being developed by [fruux](https://fruux.com/). Drop us a line for commercial services or enterprise support. diff --git a/lib/vendor/sabre/xml/bin/.empty b/lib/vendor/sabre/xml/bin/.empty deleted file mode 100644 index e69de29..0000000 diff --git a/lib/vendor/sabre/xml/composer.json b/lib/vendor/sabre/xml/composer.json deleted file mode 100644 index d7577c2..0000000 --- a/lib/vendor/sabre/xml/composer.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "sabre/xml", - "description" : "sabre/xml is an XML library that you may not hate.", - "keywords" : [ "XML", "XMLReader", "XMLWriter", "DOM" ], - "homepage" : "https://sabre.io/xml/", - "license" : "BSD-3-Clause", - "require" : { - "php" : "^7.1 || ^8.0", - "ext-xmlwriter" : "*", - "ext-xmlreader" : "*", - "ext-dom" : "*", - "lib-libxml" : ">=2.6.20", - "sabre/uri" : ">=1.0,<3.0.0" - }, - "authors" : [ - { - "name" : "Evert Pot", - "email" : "me@evertpot.com", - "homepage" : "http://evertpot.com/", - "role" : "Developer" - }, - { - "name": "Markus Staab", - "email": "markus.staab@redaxo.de", - "role" : "Developer" - } - ], - "support" : { - "forum" : "https://groups.google.com/group/sabredav-discuss", - "source" : "https://github.com/fruux/sabre-xml" - }, - "autoload" : { - "psr-4" : { - "Sabre\\Xml\\" : "lib/" - }, - "files": [ - "lib/Deserializer/functions.php", - "lib/Serializer/functions.php" - ] - }, - "autoload-dev" : { - "psr-4" : { - "Sabre\\Xml\\" : "tests/Sabre/Xml/" - } - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit" : "^7.5 || ^8.5 || ^9.6" - }, - "scripts": { - "phpstan": [ - "phpstan analyse lib tests" - ], - "cs-fixer": [ - "PHP_CS_FIXER_IGNORE_ENV=true php-cs-fixer fix" - ], - "phpunit": [ - "phpunit --configuration tests/phpunit.xml" - ], - "test": [ - "composer phpstan", - "composer cs-fixer", - "composer phpunit" - ] - } -} diff --git a/lib/vendor/sabre/xml/lib/ContextStackTrait.php b/lib/vendor/sabre/xml/lib/ContextStackTrait.php deleted file mode 100644 index 4e15bd4..0000000 --- a/lib/vendor/sabre/xml/lib/ContextStackTrait.php +++ /dev/null @@ -1,118 +0,0 @@ -contextStack[] = [ - $this->elementMap, - $this->contextUri, - $this->namespaceMap, - $this->classMap, - ]; - } - - /** - * Restore the previous "context". - */ - public function popContext() - { - list( - $this->elementMap, - $this->contextUri, - $this->namespaceMap, - $this->classMap - ) = array_pop($this->contextStack); - } -} diff --git a/lib/vendor/sabre/xml/lib/Deserializer/functions.php b/lib/vendor/sabre/xml/lib/Deserializer/functions.php deleted file mode 100644 index 5081809..0000000 --- a/lib/vendor/sabre/xml/lib/Deserializer/functions.php +++ /dev/null @@ -1,360 +0,0 @@ -value" array. - * - * For example, keyvalue will parse: - * - * - * - * value1 - * value2 - * - * - * - * Into: - * - * [ - * "{http://sabredav.org/ns}elem1" => "value1", - * "{http://sabredav.org/ns}elem2" => "value2", - * "{http://sabredav.org/ns}elem3" => null, - * ]; - * - * If you specify the 'namespace' argument, the deserializer will remove - * the namespaces of the keys that match that namespace. - * - * For example, if you call keyValue like this: - * - * keyValue($reader, 'http://sabredav.org/ns') - * - * it's output will instead be: - * - * [ - * "elem1" => "value1", - * "elem2" => "value2", - * "elem3" => null, - * ]; - * - * Attributes will be removed from the top-level elements. If elements with - * the same name appear twice in the list, only the last one will be kept. - */ -function keyValue(Reader $reader, ?string $namespace = null): array -{ - // If there's no children, we don't do anything. - if ($reader->isEmptyElement) { - $reader->next(); - - return []; - } - - if (!$reader->read()) { - $reader->next(); - - return []; - } - - if (Reader::END_ELEMENT === $reader->nodeType) { - $reader->next(); - - return []; - } - - $values = []; - - do { - if (Reader::ELEMENT === $reader->nodeType) { - if (null !== $namespace && $reader->namespaceURI === $namespace) { - $values[$reader->localName] = $reader->parseCurrentElement()['value']; - } else { - $clark = $reader->getClark(); - $values[$clark] = $reader->parseCurrentElement()['value']; - } - } else { - if (!$reader->read()) { - break; - } - } - } while (Reader::END_ELEMENT !== $reader->nodeType); - - $reader->read(); - - return $values; -} - -/** - * The 'enum' deserializer parses elements into a simple list - * without values or attributes. - * - * For example, Elements will parse: - * - * - * - * - * - * - * content - * - * - * - * Into: - * - * [ - * "{http://sabredav.org/ns}elem1", - * "{http://sabredav.org/ns}elem2", - * "{http://sabredav.org/ns}elem3", - * "{http://sabredav.org/ns}elem4", - * "{http://sabredav.org/ns}elem5", - * ]; - * - * This is useful for 'enum'-like structures. - * - * If the $namespace argument is specified, it will strip the namespace - * for all elements that match that. - * - * For example, - * - * enum($reader, 'http://sabredav.org/ns') - * - * would return: - * - * [ - * "elem1", - * "elem2", - * "elem3", - * "elem4", - * "elem5", - * ]; - * - * @return string[] - */ -function enum(Reader $reader, ?string $namespace = null): array -{ - // If there's no children, we don't do anything. - if ($reader->isEmptyElement) { - $reader->next(); - - return []; - } - if (!$reader->read()) { - $reader->next(); - - return []; - } - - if (Reader::END_ELEMENT === $reader->nodeType) { - $reader->next(); - - return []; - } - $currentDepth = $reader->depth; - - $values = []; - do { - if (Reader::ELEMENT !== $reader->nodeType) { - continue; - } - if (!is_null($namespace) && $namespace === $reader->namespaceURI) { - $values[] = $reader->localName; - } else { - $values[] = (string) $reader->getClark(); - } - } while ($reader->depth >= $currentDepth && $reader->next()); - - $reader->next(); - - return $values; -} - -/** - * The valueObject deserializer turns an xml element into a PHP object of - * a specific class. - * - * This is primarily used by the mapValueObject function from the Service - * class, but it can also easily be used for more specific situations. - * - * @return object - */ -function valueObject(Reader $reader, string $className, string $namespace) -{ - $valueObject = new $className(); - if ($reader->isEmptyElement) { - $reader->next(); - - return $valueObject; - } - - $defaultProperties = get_class_vars($className); - - $reader->read(); - do { - if (Reader::ELEMENT === $reader->nodeType && $reader->namespaceURI == $namespace) { - if (property_exists($valueObject, $reader->localName)) { - if (is_array($defaultProperties[$reader->localName])) { - $valueObject->{$reader->localName}[] = $reader->parseCurrentElement()['value']; - } else { - $valueObject->{$reader->localName} = $reader->parseCurrentElement()['value']; - } - } else { - // Ignore property - $reader->next(); - } - } elseif (Reader::ELEMENT === $reader->nodeType) { - // Skipping element from different namespace - $reader->next(); - } else { - if (Reader::END_ELEMENT !== $reader->nodeType && !$reader->read()) { - break; - } - } - } while (Reader::END_ELEMENT !== $reader->nodeType); - - $reader->read(); - - return $valueObject; -} - -/** - * This deserializer helps you deserialize xml structures that look like - * this:. - * - * - * ... - * ... - * ... - * - * - * Many XML documents use patterns like that, and this deserializer - * allow you to get all the 'items' as an array. - * - * In that previous example, you would register the deserializer as such: - * - * $reader->elementMap['{}collection'] = function($reader) { - * return repeatingElements($reader, '{}item'); - * } - * - * The repeatingElements deserializer simply returns everything as an array. - * - * $childElementName must either be a a clark-notation element name, or if no - * namespace is used, the bare element name. - */ -function repeatingElements(Reader $reader, string $childElementName): array -{ - if ('{' !== $childElementName[0]) { - $childElementName = '{}'.$childElementName; - } - $result = []; - - foreach ($reader->parseGetElements() as $element) { - if ($element['name'] === $childElementName) { - $result[] = $element['value']; - } - } - - return $result; -} - -/** - * This deserializer helps you to deserialize structures which contain mixed content like this:. - * - *

    some text and a inline tagand even more text

    - * - * The above example will return - * - * [ - * 'some text', - * [ - * 'name' => '{}extref', - * 'value' => 'and a inline tag', - * 'attributes' => [] - * ], - * 'and even more text' - * ] - * - * In strict XML documents you wont find this kind of markup but in html this is a quite common pattern. - */ -function mixedContent(Reader $reader): array -{ - // If there's no children, we don't do anything. - if ($reader->isEmptyElement) { - $reader->next(); - - return []; - } - - $previousDepth = $reader->depth; - - $content = []; - $reader->read(); - while (true) { - if (Reader::ELEMENT == $reader->nodeType) { - $content[] = $reader->parseCurrentElement(); - } elseif ($reader->depth >= $previousDepth && in_array($reader->nodeType, [Reader::TEXT, Reader::CDATA, Reader::WHITESPACE])) { - $content[] = $reader->value; - $reader->read(); - } elseif (Reader::END_ELEMENT == $reader->nodeType) { - // Ensuring we are moving the cursor after the end element. - $reader->read(); - break; - } else { - $reader->read(); - } - } - - return $content; -} - -/** - * The functionCaller deserializer turns an xml element into whatever your callable return. - * - * You can use, e.g., a named constructor (factory method) to create an object using - * this function. - */ -function functionCaller(Reader $reader, callable $func, string $namespace) -{ - if ($reader->isEmptyElement) { - $reader->next(); - - return null; - } - - $funcArgs = []; - $func = is_string($func) && false !== strpos($func, '::') ? explode('::', $func) : $func; - $ref = is_array($func) ? new \ReflectionMethod($func[0], $func[1]) : new \ReflectionFunction($func); - foreach ($ref->getParameters() as $parameter) { - $funcArgs[$parameter->getName()] = null; - } - - $reader->read(); - do { - if (Reader::ELEMENT === $reader->nodeType && $reader->namespaceURI == $namespace) { - if (array_key_exists($reader->localName, $funcArgs)) { - $funcArgs[$reader->localName] = $reader->parseCurrentElement()['value']; - } else { - // Ignore property - $reader->next(); - } - } else { - $reader->read(); - } - } while (Reader::END_ELEMENT !== $reader->nodeType); - $reader->read(); - - return $func(...array_values($funcArgs)); -} diff --git a/lib/vendor/sabre/xml/lib/Element.php b/lib/vendor/sabre/xml/lib/Element.php deleted file mode 100644 index 559eb54..0000000 --- a/lib/vendor/sabre/xml/lib/Element.php +++ /dev/null @@ -1,22 +0,0 @@ -value = $value; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Xml\Writer $writer) - { - $writer->write($this->value); - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - */ - public static function xmlDeserialize(Xml\Reader $reader) - { - $subTree = $reader->parseInnerTree(); - - return $subTree; - } -} diff --git a/lib/vendor/sabre/xml/lib/Element/Cdata.php b/lib/vendor/sabre/xml/lib/Element/Cdata.php deleted file mode 100644 index 1367343..0000000 --- a/lib/vendor/sabre/xml/lib/Element/Cdata.php +++ /dev/null @@ -1,59 +0,0 @@ -value = $value; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Xml\Writer $writer) - { - $writer->writeCData($this->value); - } -} diff --git a/lib/vendor/sabre/xml/lib/Element/Elements.php b/lib/vendor/sabre/xml/lib/Element/Elements.php deleted file mode 100644 index 6915fd4..0000000 --- a/lib/vendor/sabre/xml/lib/Element/Elements.php +++ /dev/null @@ -1,98 +0,0 @@ - - * - * - * - * - * content - * - * - * - * Into: - * - * [ - * "{http://sabredav.org/ns}elem1", - * "{http://sabredav.org/ns}elem2", - * "{http://sabredav.org/ns}elem3", - * "{http://sabredav.org/ns}elem4", - * "{http://sabredav.org/ns}elem5", - * ]; - * - * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/). - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class Elements implements Xml\Element -{ - /** - * Value to serialize. - * - * @var array - */ - protected $value; - - /** - * Constructor. - */ - public function __construct(array $value = []) - { - $this->value = $value; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Xml\Writer $writer) - { - Serializer\enum($writer, $this->value); - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseSubTree() will parse the entire sub-tree, and advance to - * the next element. - */ - public static function xmlDeserialize(Xml\Reader $reader) - { - return Deserializer\enum($reader); - } -} diff --git a/lib/vendor/sabre/xml/lib/Element/KeyValue.php b/lib/vendor/sabre/xml/lib/Element/KeyValue.php deleted file mode 100644 index 7d75a3a..0000000 --- a/lib/vendor/sabre/xml/lib/Element/KeyValue.php +++ /dev/null @@ -1,98 +0,0 @@ -value struct. - * - * Attributes will be removed, and duplicate child elements are discarded. - * Complex values within the elements will be parsed by the 'standard' parser. - * - * For example, KeyValue will parse: - * - * - * - * value1 - * value2 - * - * - * - * Into: - * - * [ - * "{http://sabredav.org/ns}elem1" => "value1", - * "{http://sabredav.org/ns}elem2" => "value2", - * "{http://sabredav.org/ns}elem3" => null, - * ]; - * - * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/). - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class KeyValue implements Xml\Element -{ - /** - * Value to serialize. - * - * @var array - */ - protected $value; - - /** - * Constructor. - */ - public function __construct(array $value = []) - { - $this->value = $value; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Xml\Writer $writer) - { - $writer->write($this->value); - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - */ - public static function xmlDeserialize(Xml\Reader $reader) - { - return Deserializer\keyValue($reader); - } -} diff --git a/lib/vendor/sabre/xml/lib/Element/Uri.php b/lib/vendor/sabre/xml/lib/Element/Uri.php deleted file mode 100644 index 6527638..0000000 --- a/lib/vendor/sabre/xml/lib/Element/Uri.php +++ /dev/null @@ -1,97 +0,0 @@ -/foo/bar - * http://example.org/hi - * - * If the uri is relative, it will be automatically expanded to an absolute - * url during writing and reading, if the contextUri property is set on the - * reader and/or writer. - * - * @copyright Copyright (C) 2009-2015 fruux GmbH (https://fruux.com/). - * @author Evert Pot (http://evertpot.com/) - * @license http://sabre.io/license/ Modified BSD License - */ -class Uri implements Xml\Element -{ - /** - * Uri element value. - * - * @var string - */ - protected $value; - - /** - * Constructor. - * - * @param string $value - */ - public function __construct($value) - { - $this->value = $value; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Xml\Writer $writer) - { - $writer->text( - \Sabre\Uri\resolve( - $writer->contextUri, - $this->value - ) - ); - } - - /** - * This method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * Important note 2: You are responsible for advancing the reader to the - * next element. Not doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseSubTree() will parse the entire sub-tree, and advance to - * the next element. - */ - public static function xmlDeserialize(Xml\Reader $reader) - { - return new self( - \Sabre\Uri\resolve( - (string) $reader->contextUri, - $reader->readText() - ) - ); - } -} diff --git a/lib/vendor/sabre/xml/lib/Element/XmlFragment.php b/lib/vendor/sabre/xml/lib/Element/XmlFragment.php deleted file mode 100644 index 99d1f87..0000000 --- a/lib/vendor/sabre/xml/lib/Element/XmlFragment.php +++ /dev/null @@ -1,146 +0,0 @@ -xml = $xml; - } - - /** - * Returns the inner XML document. - */ - public function getXml(): string - { - return $this->xml; - } - - /** - * The xmlSerialize method is called during xml writing. - * - * Use the $writer argument to write its own xml serialization. - * - * An important note: do _not_ create a parent element. Any element - * implementing XmlSerializable should only ever write what's considered - * its 'inner xml'. - * - * The parent of the current element is responsible for writing a - * containing element. - * - * This allows serializers to be re-used for different element names. - * - * If you are opening new elements, you must also close them again. - */ - public function xmlSerialize(Writer $writer) - { - $reader = new Reader(); - - // Wrapping the xml in a container, so root-less values can still be - // parsed. - $xml = << -{$this->getXml()} -XML; - - $reader->xml($xml); - - while ($reader->read()) { - if ($reader->depth < 1) { - // Skipping the root node. - continue; - } - - switch ($reader->nodeType) { - case Reader::ELEMENT: - $writer->startElement( - (string) $reader->getClark() - ); - $empty = $reader->isEmptyElement; - while ($reader->moveToNextAttribute()) { - switch ($reader->namespaceURI) { - case '': - $writer->writeAttribute($reader->localName, $reader->value); - break; - case 'http://www.w3.org/2000/xmlns/': - // Skip namespace declarations - break; - default: - $writer->writeAttribute((string) $reader->getClark(), $reader->value); - break; - } - } - if ($empty) { - $writer->endElement(); - } - break; - case Reader::CDATA: - case Reader::TEXT: - $writer->text( - $reader->value - ); - break; - case Reader::END_ELEMENT: - $writer->endElement(); - break; - } - } - } - - /** - * The deserialize method is called during xml parsing. - * - * This method is called statically, this is because in theory this method - * may be used as a type of constructor, or factory method. - * - * Often you want to return an instance of the current class, but you are - * free to return other data as well. - * - * You are responsible for advancing the reader to the next element. Not - * doing anything will result in a never-ending loop. - * - * If you just want to skip parsing for this element altogether, you can - * just call $reader->next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - */ - public static function xmlDeserialize(Reader $reader) - { - $result = new self($reader->readInnerXml()); - $reader->next(); - - return $result; - } -} diff --git a/lib/vendor/sabre/xml/lib/LibXMLException.php b/lib/vendor/sabre/xml/lib/LibXMLException.php deleted file mode 100644 index 993f95f..0000000 --- a/lib/vendor/sabre/xml/lib/LibXMLException.php +++ /dev/null @@ -1,47 +0,0 @@ -errors = $errors; - parent::__construct($errors[0]->message.' on line '.$errors[0]->line.', column '.$errors[0]->column, $code, $previousException); - } - - /** - * Returns the LibXML errors. - */ - public function getErrors(): array - { - return $this->errors; - } -} diff --git a/lib/vendor/sabre/xml/lib/ParseException.php b/lib/vendor/sabre/xml/lib/ParseException.php deleted file mode 100644 index 158cf01..0000000 --- a/lib/vendor/sabre/xml/lib/ParseException.php +++ /dev/null @@ -1,18 +0,0 @@ -localName) { - return null; - } - - return '{'.$this->namespaceURI.'}'.$this->localName; - } - - /** - * Reads the entire document. - * - * This function returns an array with the following three elements: - * * name - The root element name. - * * value - The value for the root element. - * * attributes - An array of attributes. - * - * This function will also disable the standard libxml error handler (which - * usually just results in PHP errors), and throw exceptions instead. - */ - public function parse(): array - { - $previousEntityState = null; - $shouldCallLibxmlDisableEntityLoader = (\LIBXML_VERSION < 20900); - if ($shouldCallLibxmlDisableEntityLoader) { - $previousEntityState = libxml_disable_entity_loader(true); - } - $previousSetting = libxml_use_internal_errors(true); - - try { - while (self::ELEMENT !== $this->nodeType) { - if (!$this->read()) { - $errors = libxml_get_errors(); - libxml_clear_errors(); - if ($errors) { - throw new LibXMLException($errors); - } - } - } - $result = $this->parseCurrentElement(); - - // last line of defense in case errors did occur above - $errors = libxml_get_errors(); - libxml_clear_errors(); - if ($errors) { - throw new LibXMLException($errors); - } - } finally { - libxml_use_internal_errors($previousSetting); - if ($shouldCallLibxmlDisableEntityLoader) { - libxml_disable_entity_loader($previousEntityState); - } - } - - return $result; - } - - /** - * parseGetElements parses everything in the current sub-tree, - * and returns an array of elements. - * - * Each element has a 'name', 'value' and 'attributes' key. - * - * If the element didn't contain sub-elements, an empty array is always - * returned. If there was any text inside the element, it will be - * discarded. - * - * If the $elementMap argument is specified, the existing elementMap will - * be overridden while parsing the tree, and restored after this process. - */ - public function parseGetElements(?array $elementMap = null): array - { - $result = $this->parseInnerTree($elementMap); - if (!is_array($result)) { - return []; - } - - return $result; - } - - /** - * Parses all elements below the current element. - * - * This method will return a string if this was a text-node, or an array if - * there were sub-elements. - * - * If there's both text and sub-elements, the text will be discarded. - * - * If the $elementMap argument is specified, the existing elementMap will - * be overridden while parsing the tree, and restored after this process. - * - * @return array|string|null - */ - public function parseInnerTree(?array $elementMap = null) - { - $text = null; - $elements = []; - - if (self::ELEMENT === $this->nodeType && $this->isEmptyElement) { - // Easy! - $this->next(); - - return null; - } - - if (!is_null($elementMap)) { - $this->pushContext(); - $this->elementMap = $elementMap; - } - - try { - if (!$this->read()) { - $errors = libxml_get_errors(); - libxml_clear_errors(); - if ($errors) { - throw new LibXMLException($errors); - } - throw new ParseException('This should never happen (famous last words)'); - } - - $keepOnParsing = true; - - while ($keepOnParsing) { - if (!$this->isValid()) { - $errors = libxml_get_errors(); - - if ($errors) { - libxml_clear_errors(); - throw new LibXMLException($errors); - } - } - - switch ($this->nodeType) { - case self::ELEMENT: - $elements[] = $this->parseCurrentElement(); - break; - case self::TEXT: - case self::CDATA: - $text .= $this->value; - $this->read(); - break; - case self::END_ELEMENT: - // Ensuring we are moving the cursor after the end element. - $this->read(); - $keepOnParsing = false; - break; - case self::NONE: - throw new ParseException('We hit the end of the document prematurely. This likely means that some parser "eats" too many elements. Do not attempt to continue parsing.'); - default: - // Advance to the next element - $this->read(); - break; - } - } - } finally { - if (!is_null($elementMap)) { - $this->popContext(); - } - } - - return $elements ? $elements : $text; - } - - /** - * Reads all text below the current element, and returns this as a string. - */ - public function readText(): string - { - $result = ''; - $previousDepth = $this->depth; - - while ($this->read() && $this->depth != $previousDepth) { - if (in_array($this->nodeType, [\XMLReader::TEXT, \XMLReader::CDATA, \XMLReader::WHITESPACE])) { - $result .= $this->value; - } - } - - return $result; - } - - /** - * Parses the current XML element. - * - * This method returns arn array with 3 properties: - * * name - A clark-notation XML element name. - * * value - The parsed value. - * * attributes - A key-value list of attributes. - */ - public function parseCurrentElement(): array - { - $name = $this->getClark(); - - $attributes = []; - - if ($this->hasAttributes) { - $attributes = $this->parseAttributes(); - } - - $value = call_user_func( - $this->getDeserializerForElementName((string) $name), - $this - ); - - return [ - 'name' => $name, - 'value' => $value, - 'attributes' => $attributes, - ]; - } - - /** - * Grabs all the attributes from the current element, and returns them as a - * key-value array. - * - * If the attributes are part of the same namespace, they will simply be - * short keys. If they are defined on a different namespace, the attribute - * name will be returned in clark-notation. - */ - public function parseAttributes(): array - { - $attributes = []; - - while ($this->moveToNextAttribute()) { - if ($this->namespaceURI) { - // Ignoring 'xmlns', it doesn't make any sense. - if ('http://www.w3.org/2000/xmlns/' === $this->namespaceURI) { - continue; - } - - $name = $this->getClark(); - $attributes[$name] = $this->value; - } else { - $attributes[$this->localName] = $this->value; - } - } - $this->moveToElement(); - - return $attributes; - } - - /** - * Returns the function that should be used to parse the element identified - * by its clark-notation name. - */ - public function getDeserializerForElementName(string $name): callable - { - if (!array_key_exists($name, $this->elementMap)) { - if ('{}' == substr($name, 0, 2) && array_key_exists(substr($name, 2), $this->elementMap)) { - $name = substr($name, 2); - } else { - return ['Sabre\\Xml\\Element\\Base', 'xmlDeserialize']; - } - } - - $deserializer = $this->elementMap[$name]; - if (is_subclass_of($deserializer, 'Sabre\\Xml\\XmlDeserializable')) { - return [$deserializer, 'xmlDeserialize']; - } - - if (is_callable($deserializer)) { - return $deserializer; - } - - $type = gettype($deserializer); - if ('string' === $type) { - $type .= ' ('.$deserializer.')'; - } elseif ('object' === $type) { - $type .= ' ('.get_class($deserializer).')'; - } - throw new \LogicException('Could not use this type as a deserializer: '.$type.' for element: '.$name); - } -} diff --git a/lib/vendor/sabre/xml/lib/Serializer/functions.php b/lib/vendor/sabre/xml/lib/Serializer/functions.php deleted file mode 100644 index 23f22d4..0000000 --- a/lib/vendor/sabre/xml/lib/Serializer/functions.php +++ /dev/null @@ -1,207 +0,0 @@ - - * - * - * content - * - * - * @param string[] $values - */ -function enum(Writer $writer, array $values) -{ - foreach ($values as $value) { - $writer->writeElement($value); - } -} - -/** - * The valueObject serializer turns a simple PHP object into a classname. - * - * Every public property will be encoded as an xml element with the same - * name, in the XML namespace as specified. - * - * Values that are set to null or an empty array are not serialized. To - * serialize empty properties, you must specify them as an empty string. - * - * @param object $valueObject - */ -function valueObject(Writer $writer, $valueObject, string $namespace) -{ - foreach (get_object_vars($valueObject) as $key => $val) { - if (is_array($val)) { - // If $val is an array, it has a special meaning. We need to - // generate one child element for each item in $val - foreach ($val as $child) { - $writer->writeElement('{'.$namespace.'}'.$key, $child); - } - } elseif (null !== $val) { - $writer->writeElement('{'.$namespace.'}'.$key, $val); - } - } -} - -/** - * This serializer helps you serialize xml structures that look like - * this:. - * - * - * ... - * ... - * ... - * - * - * In that previous example, this serializer just serializes the item element, - * and this could be called like this: - * - * repeatingElements($writer, $items, '{}item'); - */ -function repeatingElements(Writer $writer, array $items, string $childElementName) -{ - foreach ($items as $item) { - $writer->writeElement($childElementName, $item); - } -} - -/** - * This function is the 'default' serializer that is able to serialize most - * things, and delegates to other serializers if needed. - * - * The standardSerializer supports a wide-array of values. - * - * $value may be a string or integer, it will just write out the string as text. - * $value may be an instance of XmlSerializable or Element, in which case it - * calls it's xmlSerialize() method. - * $value may be a PHP callback/function/closure, in case we call the callback - * and give it the Writer as an argument. - * $value may be a an object, and if it's in the classMap we automatically call - * the correct serializer for it. - * $value may be null, in which case we do nothing. - * - * If $value is an array, the array must look like this: - * - * [ - * [ - * 'name' => '{namespaceUri}element-name', - * 'value' => '...', - * 'attributes' => [ 'attName' => 'attValue' ] - * ] - * [, - * 'name' => '{namespaceUri}element-name2', - * 'value' => '...', - * ] - * ] - * - * This would result in xml like: - * - * - * ... - * - * - * ... - * - * - * The value property may be any value standardSerializer supports, so you can - * nest data-structures this way. Both value and attributes are optional. - * - * Alternatively, you can also specify the array using this syntax: - * - * [ - * [ - * '{namespaceUri}element-name' => '...', - * '{namespaceUri}element-name2' => '...', - * ] - * ] - * - * This is excellent for simple key->value structures, and here you can also - * specify anything for the value. - * - * You can even mix the two array syntaxes. - * - * @param string|int|float|bool|array|object $value - */ -function standardSerializer(Writer $writer, $value) -{ - if (is_scalar($value)) { - // String, integer, float, boolean - $writer->text((string) $value); - } elseif ($value instanceof XmlSerializable) { - // XmlSerializable classes or Element classes. - $value->xmlSerialize($writer); - } elseif (is_object($value) && isset($writer->classMap[get_class($value)])) { - // It's an object which class appears in the classmap. - $writer->classMap[get_class($value)]($writer, $value); - } elseif (is_callable($value)) { - // A callback - $value($writer); - } elseif (is_array($value) && array_key_exists('name', $value)) { - // if the array had a 'name' element, we assume that this array - // describes a 'name' and optionally 'attributes' and 'value'. - - $name = $value['name']; - $attributes = isset($value['attributes']) ? $value['attributes'] : []; - $value = isset($value['value']) ? $value['value'] : null; - - $writer->startElement($name); - $writer->writeAttributes($attributes); - $writer->write($value); - $writer->endElement(); - } elseif (is_array($value)) { - foreach ($value as $name => $item) { - if (is_int($name)) { - // This item has a numeric index. We just loop through the - // array and throw it back in the writer. - standardSerializer($writer, $item); - } elseif (is_string($name) && is_array($item) && isset($item['attributes'])) { - // The key is used for a name, but $item has 'attributes' and - // possibly 'value' - $writer->startElement($name); - $writer->writeAttributes($item['attributes']); - if (isset($item['value'])) { - $writer->write($item['value']); - } - $writer->endElement(); - } elseif (is_string($name)) { - // This was a plain key-value array. - $writer->startElement($name); - $writer->write($item); - $writer->endElement(); - } else { - throw new \InvalidArgumentException('The writer does not know how to serialize arrays with keys of type: '.gettype($name)); - } - } - } elseif (is_object($value)) { - throw new \InvalidArgumentException('The writer cannot serialize objects of class: '.get_class($value)); - } elseif (!is_null($value)) { - throw new \InvalidArgumentException('The writer cannot serialize values of type: '.gettype($value)); - } -} diff --git a/lib/vendor/sabre/xml/lib/Service.php b/lib/vendor/sabre/xml/lib/Service.php deleted file mode 100644 index 6e52263..0000000 --- a/lib/vendor/sabre/xml/lib/Service.php +++ /dev/null @@ -1,326 +0,0 @@ -elementMap = $this->elementMap; - - return $r; - } - - /** - * Returns a fresh xml writer. - */ - public function getWriter(): Writer - { - $w = new Writer(); - $w->namespaceMap = $this->namespaceMap; - $w->classMap = $this->classMap; - - return $w; - } - - /** - * Parses a document in full. - * - * Input may be specified as a string or readable stream resource. - * The returned value is the value of the root document. - * - * Specifying the $contextUri allows the parser to figure out what the URI - * of the document was. This allows relative URIs within the document to be - * expanded easily. - * - * The $rootElementName is specified by reference and will be populated - * with the root element name of the document. - * - * @param string|resource $input - * - * @return array|object|string - * - * @throws ParseException - */ - public function parse($input, ?string $contextUri = null, ?string &$rootElementName = null) - { - if (!is_string($input)) { - // Unfortunately the XMLReader doesn't support streams. When it - // does, we can optimize this. - if (is_resource($input)) { - $input = (string) stream_get_contents($input); - } else { - // Input is not a string and not a resource. - // Therefore, it has to be a closed resource. - // Effectively empty input has been passed in. - $input = ''; - } - } - - // If input is empty, then it's safe to throw an exception - if (empty($input)) { - throw new ParseException('The input element to parse is empty. Do not attempt to parse'); - } - - $r = $this->getReader(); - $r->contextUri = $contextUri; - $r->XML($input, null, $this->options); - - $result = $r->parse(); - $rootElementName = $result['name']; - - return $result['value']; - } - - /** - * Parses a document in full, and specify what the expected root element - * name is. - * - * This function works similar to parse, but the difference is that the - * user can specify what the expected name of the root element should be, - * in clark notation. - * - * This is useful in cases where you expected a specific document to be - * passed, and reduces the amount of if statements. - * - * It's also possible to pass an array of expected rootElements if your - * code may expect more than one document type. - * - * @param string|string[] $rootElementName - * @param string|resource $input - * - * @return array|object|string - * - * @throws ParseException - */ - public function expect($rootElementName, $input, ?string $contextUri = null) - { - if (!is_string($input)) { - // Unfortunately the XMLReader doesn't support streams. When it - // does, we can optimize this. - if (is_resource($input)) { - $input = (string) stream_get_contents($input); - } else { - // Input is not a string and not a resource. - // Therefore, it has to be a closed resource. - // Effectively empty input has been passed in. - $input = ''; - } - } - - // If input is empty, then it's safe to throw an exception - if (empty($input)) { - throw new ParseException('The input element to parse is empty. Do not attempt to parse'); - } - - $r = $this->getReader(); - $r->contextUri = $contextUri; - $r->XML($input, null, $this->options); - - $rootElementName = (array) $rootElementName; - - foreach ($rootElementName as &$rEl) { - if ('{' !== $rEl[0]) { - $rEl = '{}'.$rEl; - } - } - - $result = $r->parse(); - if (!in_array($result['name'], $rootElementName, true)) { - throw new ParseException('Expected '.implode(' or ', $rootElementName).' but received '.$result['name'].' as the root element'); - } - - return $result['value']; - } - - /** - * Generates an XML document in one go. - * - * The $rootElement must be specified in clark notation. - * The value must be a string, an array or an object implementing - * XmlSerializable. Basically, anything that's supported by the Writer - * object. - * - * $contextUri can be used to specify a sort of 'root' of the PHP application, - * in case the xml document is used as a http response. - * - * This allows an implementor to easily create URI's relative to the root - * of the domain. - * - * @param string|array|object|XmlSerializable $value - * - * @return string - */ - public function write(string $rootElementName, $value, ?string $contextUri = null) - { - $w = $this->getWriter(); - $w->openMemory(); - $w->contextUri = $contextUri; - $w->setIndent(true); - $w->startDocument(); - $w->writeElement($rootElementName, $value); - - return $w->outputMemory(); - } - - /** - * Map an XML element to a PHP class. - * - * Calling this function will automatically set up the Reader and Writer - * classes to turn a specific XML element to a PHP class. - * - * For example, given a class such as : - * - * class Author { - * public $firstName; - * public $lastName; - * } - * - * and an XML element such as: - * - * - * ... - * ... - * - * - * These can easily be mapped by calling: - * - * $service->mapValueObject('{http://example.org}author', 'Author'); - */ - public function mapValueObject(string $elementName, string $className) - { - list($namespace) = self::parseClarkNotation($elementName); - - $this->elementMap[$elementName] = function (Reader $reader) use ($className, $namespace) { - return \Sabre\Xml\Deserializer\valueObject($reader, $className, $namespace); - }; - $this->classMap[$className] = function (Writer $writer, $valueObject) use ($namespace) { - return \Sabre\Xml\Serializer\valueObject($writer, $valueObject, $namespace); - }; - $this->valueObjectMap[$className] = $elementName; - } - - /** - * Writes a value object. - * - * This function largely behaves similar to write(), except that it's - * intended specifically to serialize a Value Object into an XML document. - * - * The ValueObject must have been previously registered using - * mapValueObject(). - * - * @param object $object - * - * @throws \InvalidArgumentException - */ - public function writeValueObject($object, ?string $contextUri = null) - { - if (!isset($this->valueObjectMap[get_class($object)])) { - throw new \InvalidArgumentException('"'.get_class($object).'" is not a registered value object class. Register your class with mapValueObject.'); - } - - return $this->write( - $this->valueObjectMap[get_class($object)], - $object, - $contextUri - ); - } - - /** - * Parses a clark-notation string, and returns the namespace and element - * name components. - * - * If the string was invalid, it will throw an InvalidArgumentException. - * - * @throws \InvalidArgumentException - */ - public static function parseClarkNotation(string $str): array - { - static $cache = []; - - if (!isset($cache[$str])) { - if (!preg_match('/^{([^}]*)}(.*)$/', $str, $matches)) { - throw new \InvalidArgumentException('\''.$str.'\' is not a valid clark-notation formatted string'); - } - - $cache[$str] = [ - $matches[1], - $matches[2], - ]; - } - - return $cache[$str]; - } - - /** - * A list of classes and which XML elements they map to. - */ - protected $valueObjectMap = []; -} diff --git a/lib/vendor/sabre/xml/lib/Version.php b/lib/vendor/sabre/xml/lib/Version.php deleted file mode 100644 index c2da842..0000000 --- a/lib/vendor/sabre/xml/lib/Version.php +++ /dev/null @@ -1,20 +0,0 @@ - "..", - * "{namespace}name2" => "..", - * ] - * - * One element will be created for each key in this array. The values of - * this array support any format this method supports (this method is - * called recursively). - * - * Array format 2: - * - * [ - * [ - * "name" => "{namespace}name1" - * "value" => "..", - * "attributes" => [ - * "attr" => "attribute value", - * ] - * ], - * [ - * "name" => "{namespace}name1" - * "value" => "..", - * "attributes" => [ - * "attr" => "attribute value", - * ] - * ] - * ] - */ - public function write($value) - { - Serializer\standardSerializer($this, $value); - } - - /** - * Opens a new element. - * - * You can either just use a local elementname, or you can use clark- - * notation to start a new element. - * - * Example: - * - * $writer->startElement('{http://www.w3.org/2005/Atom}entry'); - * - * Would result in something like: - * - * - * - * Note: this function doesn't have the string typehint, because PHP's - * XMLWriter::startElement doesn't either. - * - * @param string $name - */ - public function startElement($name): bool - { - if ('{' === $name[0]) { - list($namespace, $localName) = - Service::parseClarkNotation($name); - - if (array_key_exists($namespace, $this->namespaceMap)) { - $result = $this->startElementNS( - '' === $this->namespaceMap[$namespace] ? null : $this->namespaceMap[$namespace], - $localName, - null - ); - } else { - // An empty namespace means it's the global namespace. This is - // allowed, but it mustn't get a prefix. - if ('' === $namespace || null === $namespace) { - $result = $this->startElement($localName); - $this->writeAttribute('xmlns', ''); - } else { - if (!isset($this->adhocNamespaces[$namespace])) { - $this->adhocNamespaces[$namespace] = 'x'.(count($this->adhocNamespaces) + 1); - } - $result = $this->startElementNS($this->adhocNamespaces[$namespace], $localName, $namespace); - } - } - } else { - $result = parent::startElement($name); - } - - if (!$this->namespacesWritten) { - foreach ($this->namespaceMap as $namespace => $prefix) { - $this->writeAttribute($prefix ? 'xmlns:'.$prefix : 'xmlns', $namespace); - } - $this->namespacesWritten = true; - } - - return $result; - } - - /** - * Write a full element tag and it's contents. - * - * This method automatically closes the element as well. - * - * The element name may be specified in clark-notation. - * - * Examples: - * - * $writer->writeElement('{http://www.w3.org/2005/Atom}author',null); - * becomes: - * - * - * $writer->writeElement('{http://www.w3.org/2005/Atom}author', [ - * '{http://www.w3.org/2005/Atom}name' => 'Evert Pot', - * ]); - * becomes: - * Evert Pot - * - * Note: this function doesn't have the string typehint, because PHP's - * XMLWriter::startElement doesn't either. - * - * @param array|string|object|null $content - */ - public function writeElement($name, $content = null): bool - { - $this->startElement($name); - if (!is_null($content)) { - $this->write($content); - } - $this->endElement(); - - return true; - } - - /** - * Writes a list of attributes. - * - * Attributes are specified as a key->value array. - * - * The key is an attribute name. If the key is a 'localName', the current - * xml namespace is assumed. If it's a 'clark notation key', this namespace - * will be used instead. - */ - public function writeAttributes(array $attributes) - { - foreach ($attributes as $name => $value) { - $this->writeAttribute($name, $value); - } - } - - /** - * Writes a new attribute. - * - * The name may be specified in clark-notation. - * - * Returns true when successful. - * - * Note: this function doesn't have typehints, because for some reason - * PHP's XMLWriter::writeAttribute doesn't either. - * - * @param string $name - * @param string $value - */ - public function writeAttribute($name, $value): bool - { - if ('{' !== $name[0]) { - return parent::writeAttribute($name, $value); - } - - list( - $namespace, - $localName - ) = Service::parseClarkNotation($name); - - if (array_key_exists($namespace, $this->namespaceMap)) { - // It's an attribute with a namespace we know - return $this->writeAttribute( - $this->namespaceMap[$namespace].':'.$localName, - $value - ); - } - - // We don't know the namespace, we must add it in-line - if (!isset($this->adhocNamespaces[$namespace])) { - $this->adhocNamespaces[$namespace] = 'x'.(count($this->adhocNamespaces) + 1); - } - - return $this->writeAttributeNS( - $this->adhocNamespaces[$namespace], - $localName, - $namespace, - $value - ); - } -} diff --git a/lib/vendor/sabre/xml/lib/XmlDeserializable.php b/lib/vendor/sabre/xml/lib/XmlDeserializable.php deleted file mode 100644 index 0a57203..0000000 --- a/lib/vendor/sabre/xml/lib/XmlDeserializable.php +++ /dev/null @@ -1,36 +0,0 @@ -next(); - * - * $reader->parseInnerTree() will parse the entire sub-tree, and advance to - * the next element. - */ - public static function xmlDeserialize(Reader $reader); -} diff --git a/lib/vendor/sabre/xml/lib/XmlSerializable.php b/lib/vendor/sabre/xml/lib/XmlSerializable.php deleted file mode 100644 index 2affc33..0000000 --- a/lib/vendor/sabre/xml/lib/XmlSerializable.php +++ /dev/null @@ -1,34 +0,0 @@ -