From e7f0fe6d554e3de8cfd4b3d71ba99ddf6256cf9a Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 8 Dec 2016 17:51:47 +0100 Subject: [PATCH 01/32] add phpSPO lib Signed-off-by: Arthur Schiwon --- apps/files_external/3rdparty/composer.json | 2 +- apps/files_external/3rdparty/composer.lock | 48 +++- .../3rdparty/composer/autoload_classmap.php | 253 ++++++++++++++++++ .../3rdparty/composer/autoload_psr4.php | 1 + .../3rdparty/composer/installed.json | 46 ++++ apps/files_external/3rdparty/vgrem/php-spo | 1 + 6 files changed, 349 insertions(+), 2 deletions(-) create mode 160000 apps/files_external/3rdparty/vgrem/php-spo diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index 2eab8a8f7b41b..4bba089e3a891 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -10,6 +10,6 @@ "require": { "icewind/smb": "2.0.0", "icewind/streams": "0.5.2" + "vgrem/php-spo": "dev-master" } } - diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 99ef5f94871ce..7a138ecba142b 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -87,12 +87,58 @@ ], "description": "A set of generic stream wrappers", "time": "2016-12-02T14:21:23+00:00" + }, + { + "name": "vgrem/php-spo", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/vgrem/phpSPO.git", + "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/68413b42ff18c96a3a4e097b47c905eeab30305b", + "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Office365\\PHP\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0+" + ], + "authors": [ + { + "name": "Vadim Gremyachev", + "email": "vvgrem@gmail.com" + } + ], + "description": "The library provides a Office 365 REST client for PHP. It allows to performs CRUD operations against Office 365 resources via an REST/OData based API", + "keywords": [ + "Office365", + "api", + "curl", + "rest", + "sharepoint" + ], + "time": "2016-11-22 15:34:47" } ], "packages-dev": [], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "vgrem/php-spo": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": [], diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index 97f4ce99cda51..c96c7ae2e911e 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -83,4 +83,257 @@ 'Icewind\\Streams\\Url' => $vendorDir . '/icewind/streams/src/Url.php', 'Icewind\\Streams\\UrlCallback' => $vendorDir . '/icewind/streams/src/UrlCallBack.php', 'Icewind\\Streams\\Wrapper' => $vendorDir . '/icewind/streams/src/Wrapper.php', + 'Office365\\PHP\\Client\\FileServices\\IdentitySet' => $vendorDir . '/vgrem/php-spo/src/OneDrive/IdentitySet.php', + 'Office365\\PHP\\Client\\FileServices\\ImageFacet' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ImageFacet.php', + 'Office365\\PHP\\Client\\FileServices\\ItemReference' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ItemReference.php', + 'Office365\\PHP\\Client\\GraphClient\\ActiveDirectoryClient' => $vendorDir . '/vgrem/php-spo/src/GraphClient/ActiveDirectoryClient.php', + 'Office365\\PHP\\Client\\GraphClient\\Contact' => $vendorDir . '/vgrem/php-spo/src/GraphClient/Contact.php', + 'Office365\\PHP\\Client\\GraphClient\\ContactCollection' => $vendorDir . '/vgrem/php-spo/src/GraphClient/ContactCollection.php', + 'Office365\\PHP\\Client\\GraphClient\\Device' => $vendorDir . '/vgrem/php-spo/src/GraphClient/Device.php', + 'Office365\\PHP\\Client\\GraphClient\\DeviceCollection' => $vendorDir . '/vgrem/php-spo/src/GraphClient/DeviceCollection.php', + 'Office365\\PHP\\Client\\GraphClient\\DirectoryObject' => $vendorDir . '/vgrem/php-spo/src/GraphClient/DirectoryObject.php', + 'Office365\\PHP\\Client\\GraphClient\\DirectoryObjectCollection' => $vendorDir . '/vgrem/php-spo/src/GraphClient/DirectoryObjectCollection.php', + 'Office365\\PHP\\Client\\GraphClient\\GraphObject' => $vendorDir . '/vgrem/php-spo/src/GraphClient/GraphObject.php', + 'Office365\\PHP\\Client\\GraphClient\\TenantDetail' => $vendorDir . '/vgrem/php-spo/src/GraphClient/TenantDetail.php', + 'Office365\\PHP\\Client\\GraphClient\\TenantDetailCollection' => $vendorDir . '/vgrem/php-spo/src/GraphClient/TenantDetailCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\CurrentUserRequestContext' => $vendorDir . '/vgrem/php-spo/src/OneDrive/CurrentUserRequestContext.php', + 'Office365\\PHP\\Client\\OneDrive\\Drive' => $vendorDir . '/vgrem/php-spo/src/OneDrive/Drive.php', + 'Office365\\PHP\\Client\\OneDrive\\File' => $vendorDir . '/vgrem/php-spo/src/OneDrive/File.php', + 'Office365\\PHP\\Client\\OneDrive\\FileCollection' => $vendorDir . '/vgrem/php-spo/src/OneDrive/FileCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\Folder' => $vendorDir . '/vgrem/php-spo/src/OneDrive/Folder.php', + 'Office365\\PHP\\Client\\OneDrive\\FolderCollection' => $vendorDir . '/vgrem/php-spo/src/OneDrive/FolderCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\Identity' => $vendorDir . '/vgrem/php-spo/src/OneDrive/Identity.php', + 'Office365\\PHP\\Client\\OneDrive\\Item' => $vendorDir . '/vgrem/php-spo/src/OneDrive/Item.php', + 'Office365\\PHP\\Client\\OneDrive\\ItemCollection' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ItemCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\OneDriveClient' => $vendorDir . '/vgrem/php-spo/src/OneDrive/OneDriveClient.php', + 'Office365\\PHP\\Client\\OneDrive\\OneDriveErrorCode' => $vendorDir . '/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php', + 'Office365\\PHP\\Client\\OutlookServices\\Attachment' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Attachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\AttachmentCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/AttachmentCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Attendee' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Attendee.php', + 'Office365\\PHP\\Client\\OutlookServices\\AttendeeType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/AttendeeType.php', + 'Office365\\PHP\\Client\\OutlookServices\\BodyType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/BodyType.php', + 'Office365\\PHP\\Client\\OutlookServices\\Calendar' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Calendar.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/CalendarCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarColor' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/CalendarColor.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarGroup' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/CalendarGroup.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarGroupCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/CalendarGroupCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ChangeType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ChangeType.php', + 'Office365\\PHP\\Client\\OutlookServices\\Contact' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Contact.php', + 'Office365\\PHP\\Client\\OutlookServices\\ContactCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ContactCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ContactFolder' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ContactFolder.php', + 'Office365\\PHP\\Client\\OutlookServices\\Conversation' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Conversation.php', + 'Office365\\PHP\\Client\\OutlookServices\\ConversationCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ConversationCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ConversationThread' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ConversationThread.php', + 'Office365\\PHP\\Client\\OutlookServices\\DateTimeTimeZone' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/DateTimeTimeZone.php', + 'Office365\\PHP\\Client\\OutlookServices\\DayOfWeek' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/DayOfWeek.php', + 'Office365\\PHP\\Client\\OutlookServices\\EmailAddress' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/EmailAddress.php', + 'Office365\\PHP\\Client\\OutlookServices\\Event' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Event.php', + 'Office365\\PHP\\Client\\OutlookServices\\EventCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/EventCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\EventType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/EventType.php', + 'Office365\\PHP\\Client\\OutlookServices\\FileAttachment' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/FileAttachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\FileAttachmentCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/FileAttachmentCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\FreeBusyStatus' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/FreeBusyStatus.php', + 'Office365\\PHP\\Client\\OutlookServices\\GeoCoordinates' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/GeoCoordinates.php', + 'Office365\\PHP\\Client\\OutlookServices\\Group' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Group.php', + 'Office365\\PHP\\Client\\OutlookServices\\GroupCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/GroupCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Item' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Item.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemAttachment' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ItemAttachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemAttachmentCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ItemAttachmentCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemBody' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ItemBody.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ItemCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Location' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Location.php', + 'Office365\\PHP\\Client\\OutlookServices\\MailFolder' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/MailFolder.php', + 'Office365\\PHP\\Client\\OutlookServices\\MeetingMessageType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/MeetingMessageType.php', + 'Office365\\PHP\\Client\\OutlookServices\\Message' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Message.php', + 'Office365\\PHP\\Client\\OutlookServices\\MessageCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/MessageCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\OpenTypeExtension' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/OpenTypeExtension.php', + 'Office365\\PHP\\Client\\OutlookServices\\OutlookClient' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/OutlookClient.php', + 'Office365\\PHP\\Client\\OutlookServices\\OutlookEntity' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/OutlookEntity.php', + 'Office365\\PHP\\Client\\OutlookServices\\Photo' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Photo.php', + 'Office365\\PHP\\Client\\OutlookServices\\PhysicalAddress' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/PhysicalAddress.php', + 'Office365\\PHP\\Client\\OutlookServices\\Post' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Post.php', + 'Office365\\PHP\\Client\\OutlookServices\\PushSubscription' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/PushSubscription.php', + 'Office365\\PHP\\Client\\OutlookServices\\PushSubscriptionCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/PushSubscriptionCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Recipient' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Recipient.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrencePattern' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/RecurrencePattern.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrencePatternType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/RecurrencePatternType.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrenceRange' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/RecurrenceRange.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrenceRangeType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/RecurrenceRangeType.php', + 'Office365\\PHP\\Client\\OutlookServices\\ReferenceAttachment' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ReferenceAttachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\Reminder' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Reminder.php', + 'Office365\\PHP\\Client\\OutlookServices\\ResponseStatus' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/ResponseStatus.php', + 'Office365\\PHP\\Client\\OutlookServices\\Subscription' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Subscription.php', + 'Office365\\PHP\\Client\\OutlookServices\\SubscriptionCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/SubscriptionCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\User' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/User.php', + 'Office365\\PHP\\Client\\OutlookServices\\UserCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/UserCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\WeekIndex' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/WeekIndex.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\ACSTokenProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/ACSTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\AuthenticationContext' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/AuthenticationContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\BaseTokenProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\CookieCacheEntry' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/CookieCacheEntry.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\IAuthenticationContext' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\NetworkCredentialContext' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/NetworkCredentialContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\OAuthTokenProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\SamlTokenProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\ClientAction' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientAction.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionCreateEntity' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionCreateEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionDeleteEntity' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionDeleteEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionInvokeGetMethod' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionInvokeGetMethod.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionInvokeMethod' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionInvokeMethod.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionInvokePostMethod' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionInvokePostMethod.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionReadEntity' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionReadEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionType' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionType.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionUpdateEntity' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientActionUpdateEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientObject' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientObject.php', + 'Office365\\PHP\\Client\\Runtime\\ClientObjectCollection' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientObjectCollection.php', + 'Office365\\PHP\\Client\\Runtime\\ClientRequest' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientRequest.php', + 'Office365\\PHP\\Client\\Runtime\\ClientResult' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientResult.php', + 'Office365\\PHP\\Client\\Runtime\\ClientRuntimeContext' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php', + 'Office365\\PHP\\Client\\Runtime\\ClientValueObject' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientValueObject.php', + 'Office365\\PHP\\Client\\Runtime\\ClientValueObjectCollection' => $vendorDir . '/vgrem/php-spo/src/Runtime/ClientValueObjectCollection.php', + 'Office365\\PHP\\Client\\Runtime\\ContextWebInformation' => $vendorDir . '/vgrem/php-spo/src/Runtime/ContextWebInformation.php', + 'Office365\\PHP\\Client\\Runtime\\FormatType' => $vendorDir . '/vgrem/php-spo/src/Runtime/FormatType.php', + 'Office365\\PHP\\Client\\Runtime\\HttpMethod' => $vendorDir . '/vgrem/php-spo/src/Runtime/HttpMethod.php', + 'Office365\\PHP\\Client\\Runtime\\KeyValue' => $vendorDir . '/vgrem/php-spo/src/Runtime/KeyValue.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\AtomFormat' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/AtomFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\JsonFormat' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/JsonFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\JsonLightFormat' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/JsonLightFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\JsonPayloadSerializer' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/JsonPayloadSerializer.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataException' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataException.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataFormat' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataMetadataLevel' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataMetadataLevel.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPathParser' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataPathParser.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPayload' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataPayload.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPayloadKind' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataPayloadKind.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPrimitiveTypeKind' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataPrimitiveTypeKind.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataQueryOptions' => $vendorDir . '/vgrem/php-spo/src/Runtime/OData/ODataQueryOptions.php', + 'Office365\\PHP\\Client\\Runtime\\Office365Version' => $vendorDir . '/vgrem/php-spo/src/Runtime/Office365Version.php', + 'Office365\\PHP\\Client\\Runtime\\OperationParameterCollection' => $vendorDir . '/vgrem/php-spo/src/Runtime/OperationParameterCollection.php', + 'Office365\\PHP\\Client\\Runtime\\RequestContext' => $vendorDir . '/vgrem/php-spo/src/Runtime/RequestContext.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePath' => $vendorDir . '/vgrem/php-spo/src/Runtime/ResourcePath.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePathEntity' => $vendorDir . '/vgrem/php-spo/src/Runtime/ResourcePathEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePathLink' => $vendorDir . '/vgrem/php-spo/src/Runtime/ResourcePathLink.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePathServiceOperation' => $vendorDir . '/vgrem/php-spo/src/Runtime/ResourcePathServiceOperation.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\ClientCredential' => $vendorDir . '/vgrem/php-spo/src/Runtime/Utilities/ClientCredential.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\EnumType' => $vendorDir . '/vgrem/php-spo/src/Runtime/Utilities/EnumType.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\Guid' => $vendorDir . '/vgrem/php-spo/src/Runtime/Utilities/Guid.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\JsonConvert' => $vendorDir . '/vgrem/php-spo/src/Runtime/Utilities/JsonConvert.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\RequestOptions' => $vendorDir . '/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\Requests' => $vendorDir . '/vgrem/php-spo/src/Runtime/Utilities/Requests.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\UserCredentials' => $vendorDir . '/vgrem/php-spo/src/Runtime/Utilities/UserCredentials.php', + 'Office365\\PHP\\Client\\SharePoint\\AddFieldOptions' => $vendorDir . '/vgrem/php-spo/src/SharePoint/AddFieldOptions.php', + 'Office365\\PHP\\Client\\SharePoint\\AppInstance' => $vendorDir . '/vgrem/php-spo/src/SharePoint/AppInstance.php', + 'Office365\\PHP\\Client\\SharePoint\\Attachment' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Attachment.php', + 'Office365\\PHP\\Client\\SharePoint\\AttachmentCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/AttachmentCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\AttachmentCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/AttachmentCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\BasePermissions' => $vendorDir . '/vgrem/php-spo/src/SharePoint/BasePermissions.php', + 'Office365\\PHP\\Client\\SharePoint\\CamlQuery' => $vendorDir . '/vgrem/php-spo/src/SharePoint/CamlQuery.php', + 'Office365\\PHP\\Client\\SharePoint\\Change' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Change.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeField' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeField.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeFile' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeFile.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeFolder' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeFolder.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeItem' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeItem.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeList' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeList.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeLogItemQuery' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeLogItemQuery.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeQuery' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeQuery.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeSite' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeSite.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeToken' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeToken.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeType.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeUser' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeUser.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeView' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeView.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeWeb' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ChangeWeb.php', + 'Office365\\PHP\\Client\\SharePoint\\CheckOutType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/CheckOutType.php', + 'Office365\\PHP\\Client\\SharePoint\\ClientContext' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ClientContext.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ContentType.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentTypeCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ContentTypeCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentTypeCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ContentTypeCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentTypeId' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ContentTypeId.php', + 'Office365\\PHP\\Client\\SharePoint\\CustomActionElement' => $vendorDir . '/vgrem/php-spo/src/SharePoint/CustomActionElement.php', + 'Office365\\PHP\\Client\\SharePoint\\CustomActionElementCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/CustomActionElementCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\DocumentSet\\DocumentSet' => $vendorDir . '/vgrem/php-spo/src/SharePoint/DocumentManagement/DocumentSet/DocumentSet.php', + 'Office365\\PHP\\Client\\SharePoint\\Field' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Field.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldCalculated' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldCalculated.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldChoice' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldChoice.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldComputed' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldComputed.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldDateTime' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldDateTime.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldGeolocation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldGeolocation.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldGeolocationValue' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldGeolocationValue.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldGuid' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldGuid.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldLookup' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldLookup.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldLookupValue' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldLookupValue.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldMultiChoice' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldMultiChoice.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldMultiLineText' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldMultiLineText.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldNumber' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldNumber.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldText' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldText.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldType.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUrl' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldUrl.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUrlValue' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldUrlValue.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUser' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldUser.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUserValue' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FieldUserValue.php', + 'Office365\\PHP\\Client\\SharePoint\\File' => $vendorDir . '/vgrem/php-spo/src/SharePoint/File.php', + 'Office365\\PHP\\Client\\SharePoint\\FileCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FileCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\FileCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FileCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\FileVersion' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FileVersion.php', + 'Office365\\PHP\\Client\\SharePoint\\FileVersionCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FileVersionCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Folder' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Folder.php', + 'Office365\\PHP\\Client\\SharePoint\\FolderCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/FolderCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Group' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Group.php', + 'Office365\\PHP\\Client\\SharePoint\\GroupCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/GroupCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\GroupCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/GroupCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\InformationRightsManagementSettings' => $vendorDir . '/vgrem/php-spo/src/SharePoint/InformationRightsManagementSettings.php', + 'Office365\\PHP\\Client\\SharePoint\\ListCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ListCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ListCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ListCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItem' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ListItem.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItemCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ListItemCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItemCollectionPosition' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ListItemCollectionPosition.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItemCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ListItemCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ListTemplateType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ListTemplateType.php', + 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ObjectSharingInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingSettings' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ObjectSharingSettings.php', + 'Office365\\PHP\\Client\\SharePoint\\PermissionKind' => $vendorDir . '/vgrem/php-spo/src/SharePoint/PermissionKind.php', + 'Office365\\PHP\\Client\\SharePoint\\Principal' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Principal.php', + 'Office365\\PHP\\Client\\SharePoint\\PrincipalType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/PrincipalType.php', + 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItem' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RecycleBinItem.php', + 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItemCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RecycleBinItemCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleAssignment' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RoleAssignment.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleAssignmentCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RoleAssignmentCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleDefinition' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RoleDefinition.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleDefinitionCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RoleDefinitionCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleDefinitionCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RoleDefinitionCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\SPList' => $vendorDir . '/vgrem/php-spo/src/SharePoint/SPList.php', + 'Office365\\PHP\\Client\\SharePoint\\SecurableObject' => $vendorDir . '/vgrem/php-spo/src/SharePoint/SecurableObject.php', + 'Office365\\PHP\\Client\\SharePoint\\Site' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Site.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialActor' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Social/SocialActor.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialRestActor' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Social/SocialRestActor.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialRestFeedManager' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Social/SocialRestFeedManager.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialRestFollowingManager' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Social/SocialRestFollowingManager.php', + 'Office365\\PHP\\Client\\SharePoint\\Taxonomy\\TaxonomyField' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Taxonomy/TaxonomyField.php', + 'Office365\\PHP\\Client\\SharePoint\\Taxonomy\\TaxonomySession' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Taxonomy/TaxonomySession.php', + 'Office365\\PHP\\Client\\SharePoint\\TemplateFileType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/TemplateFileType.php', + 'Office365\\PHP\\Client\\SharePoint\\User' => $vendorDir . '/vgrem/php-spo/src/SharePoint/User.php', + 'Office365\\PHP\\Client\\SharePoint\\UserCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\UserCustomAction' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserCustomAction.php', + 'Office365\\PHP\\Client\\SharePoint\\UserCustomActionCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserCustomActionCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\UserIdInfo' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserIdInfo.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\PeopleManager' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserProfiles/PeopleManager.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\PersonProperties' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserProfiles/PersonProperties.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\PersonPropertiesCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserProfiles/PersonPropertiesCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\ProfileLoader' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserProfiles/ProfileLoader.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\UserProfile' => $vendorDir . '/vgrem/php-spo/src/SharePoint/UserProfiles/UserProfile.php', + 'Office365\\PHP\\Client\\SharePoint\\Utilities\\Utility' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Utilities/Utility.php', + 'Office365\\PHP\\Client\\SharePoint\\View' => $vendorDir . '/vgrem/php-spo/src/SharePoint/View.php', + 'Office365\\PHP\\Client\\SharePoint\\ViewCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ViewCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ViewCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ViewCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ViewFieldCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ViewFieldCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Web' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Web.php', + 'Office365\\PHP\\Client\\SharePoint\\WebCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/WebCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\WebCreationInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/WebCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\LimitedWebPartManager' => $vendorDir . '/vgrem/php-spo/src/SharePoint/WebParts/LimitedWebPartManager.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\PersonalizationScope' => $vendorDir . '/vgrem/php-spo/src/SharePoint/WebParts/PersonalizationScope.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\WebPart' => $vendorDir . '/vgrem/php-spo/src/SharePoint/WebParts/WebPart.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\WebPartDefinition' => $vendorDir . '/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinition.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\WebPartDefinitionCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinitionCollection.php', ); diff --git a/apps/files_external/3rdparty/composer/autoload_psr4.php b/apps/files_external/3rdparty/composer/autoload_psr4.php index 7cfe0f1c46dc0..4d8d20f45ab8b 100644 --- a/apps/files_external/3rdparty/composer/autoload_psr4.php +++ b/apps/files_external/3rdparty/composer/autoload_psr4.php @@ -6,6 +6,7 @@ $baseDir = $vendorDir; return array( + 'Office365\\PHP\\Client\\' => array($vendorDir . '/vgrem/php-spo/src'), 'Icewind\\Streams\\Tests\\' => array($vendorDir . '/icewind/streams/tests'), 'Icewind\\Streams\\' => array($vendorDir . '/icewind/streams/src'), 'Icewind\\SMB\\Test\\' => array($vendorDir . '/icewind/smb/tests'), diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index 8e065858d02ca..cb2e12618ab74 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -84,5 +84,51 @@ } ], "description": "A set of generic stream wrappers" + }, + { + "name": "vgrem/php-spo", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/vgrem/phpSPO.git", + "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/68413b42ff18c96a3a4e097b47c905eeab30305b", + "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.4" + }, + "time": "2016-11-22 15:34:47", + "type": "library", + "installation-source": "source", + "autoload": { + "psr-4": { + "Office365\\PHP\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0+" + ], + "authors": [ + { + "name": "Vadim Gremyachev", + "email": "vvgrem@gmail.com" + } + ], + "description": "The library provides a Office 365 REST client for PHP. It allows to performs CRUD operations against Office 365 resources via an REST/OData based API", + "keywords": [ + "Office365", + "api", + "curl", + "rest", + "sharepoint" + ] } ] diff --git a/apps/files_external/3rdparty/vgrem/php-spo b/apps/files_external/3rdparty/vgrem/php-spo new file mode 160000 index 0000000000000..68413b42ff18c --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo @@ -0,0 +1 @@ +Subproject commit 68413b42ff18c96a3a4e097b47c905eeab30305b From 943d99071500197f005b1b8667c8f06a58077d1f Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 2 Dec 2016 18:04:25 +0100 Subject: [PATCH 02/32] initial Backend and Storage class Signed-off-by: Arthur Schiwon --- .../lib/AppInfo/Application.php | 40 ++-- .../lib/Lib/Backend/SharePoint.php | 48 +++++ .../lib/Lib/Storage/SharePoint.php | 188 ++++++++++++++++++ 3 files changed, 262 insertions(+), 14 deletions(-) create mode 100644 apps/files_external/lib/Lib/Backend/SharePoint.php create mode 100644 apps/files_external/lib/Lib/Storage/SharePoint.php diff --git a/apps/files_external/lib/AppInfo/Application.php b/apps/files_external/lib/AppInfo/Application.php index fcf10adb3755b..ea8fbf5956ffb 100644 --- a/apps/files_external/lib/AppInfo/Application.php +++ b/apps/files_external/lib/AppInfo/Application.php @@ -29,10 +29,21 @@ namespace OCA\Files_External\AppInfo; +use OCA\Files_External\Lib\Backend\AmazonS3; +use OCA\Files_External\Lib\Backend\DAV; +use OCA\Files_External\Lib\Backend\Dropbox; +use OCA\Files_External\Lib\Backend\FTP; +use OCA\Files_External\Lib\Backend\Google; +use OCA\Files_External\Lib\Backend\Local; +use OCA\Files_External\Lib\Backend\OwnCloud; +use OCA\Files_External\Lib\Backend\SFTP; +use OCA\Files_External\Lib\Backend\SFTP_Key; +use OCA\Files_External\Lib\Backend\SharePoint; +use OCA\Files_External\Lib\Backend\SMB; +use OCA\Files_External\Lib\Backend\SMB_OC; +use OCA\Files_External\Lib\Backend\Swift; use \OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; -use \OCP\IContainer; -use \OCA\Files_External\Service\BackendService; use \OCA\Files_External\Lib\Config\IBackendProvider; use \OCA\Files_External\Lib\Config\IAuthMechanismProvider; @@ -89,18 +100,19 @@ public function getBackends() { $container = $this->getContainer(); $backends = [ - $container->query('OCA\Files_External\Lib\Backend\Local'), - $container->query('OCA\Files_External\Lib\Backend\FTP'), - $container->query('OCA\Files_External\Lib\Backend\DAV'), - $container->query('OCA\Files_External\Lib\Backend\OwnCloud'), - $container->query('OCA\Files_External\Lib\Backend\SFTP'), - $container->query('OCA\Files_External\Lib\Backend\AmazonS3'), - $container->query('OCA\Files_External\Lib\Backend\Dropbox'), - $container->query('OCA\Files_External\Lib\Backend\Google'), - $container->query('OCA\Files_External\Lib\Backend\Swift'), - $container->query('OCA\Files_External\Lib\Backend\SFTP_Key'), - $container->query('OCA\Files_External\Lib\Backend\SMB'), - $container->query('OCA\Files_External\Lib\Backend\SMB_OC'), + $container->query(Local::class), + $container->query(FTP::class), + $container->query(DAV::class), + $container->query(OwnCloud::class), + $container->query(SFTP::class), + $container->query(AmazonS3::class), + $container->query(Dropbox::class), + $container->query(Google::class), + $container->query(Swift::class), + $container->query(SFTP_Key::class), + $container->query(SMB::class), + $container->query(SMB_OC::class), + $container->query(SharePoint::class), ]; return $backends; diff --git a/apps/files_external/lib/Lib/Backend/SharePoint.php b/apps/files_external/lib/Lib/Backend/SharePoint.php new file mode 100644 index 0000000000000..f1bd6d6d63208 --- /dev/null +++ b/apps/files_external/lib/Lib/Backend/SharePoint.php @@ -0,0 +1,48 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Lib\Backend; + +use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCA\Files_External\Lib\Auth\Password\Password; +use OCA\Files_External\Lib\DefinitionParameter; +use OCA\Files_External\Lib\Storage\SharePoint as SharePointStorage; +use OCP\IL10N; + +class SharePoint extends Backend { + + public function __construct(IL10N $l, Password $legacyAuth) { + $this + ->setIdentifier('sharepoint') + ->setStorageClass(SharePointStorage::class) + ->setText($l->t('SharePoint')) + ->addParameters([ + (new DefinitionParameter('host', $l->t('Host'))), + (new DefinitionParameter('root', $l->t('Document Library'))), + ]) + ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) + ->setLegacyAuthMechanism($legacyAuth) + ; + } + +} diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php new file mode 100644 index 0000000000000..1925a8cc39ccd --- /dev/null +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -0,0 +1,188 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Lib\Storage; + +use OC\Files\Storage\Common; +use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; +use Office365\PHP\Client\SharePoint\ClientContext; + +class SharePoint extends Common { + + protected $server; + + protected $documentLibrary; + + protected $authUser; + + protected $authPwd; + + protected $context; + + public function __construct($parameters) { + $s = 'sadf'; + $this->server = $parameters['host']; + $this->documentLibrary = $parameters['root']; + + // FIXME: perhaps not set + $this->authUser = $parameters['user']; + $this->authPwd = $parameters['password']; + + $authContext = new AuthenticationContext($this->server); + $authContext->acquireTokenForUser($this->authUser, $this->authPwd); + $this->context = new ClientContext($this->server, $authContext); + + $web = $this->context->getWeb(); + $list = $web->getLists()->getByTitle($this->documentLibrary); + $s = 'asdf'; + + # TODO: test this ^ + } + + /** + * Get the identifier for the storage, + * the returned id should be the same for every storage object that is created with the same parameters + * and two storage objects with the same id should refer to two storages that display the same files. + * + * @return string + * @since 6.0.0 + */ + public function getId() { + return 'SharePoint::' . $this->server . '::' . $this->documentLibrary . '::' . $this->authUser; + } + + /** + * see http://php.net/manual/en/function.mkdir.php + * implementations need to implement a recursive mkdir + * + * @param string $path + * @return bool + * @since 6.0.0 + */ + public function mkdir($path) { + // TODO: Implement mkdir() method. + return true; + } + + /** + * see http://php.net/manual/en/function.rmdir.php + * + * @param string $path + * @return bool + * @since 6.0.0 + */ + public function rmdir($path) { + // TODO: Implement rmdir() method. + return true; + } + + /** + * see http://php.net/manual/en/function.opendir.php + * + * @param string $path + * @return resource|false + * @since 6.0.0 + */ + public function opendir($path) { + // TODO: Implement opendir() method. + return false; + } + + /** + * see http://php.net/manual/en/function.stat.php + * only the following keys are required in the result: size and mtime + * + * @param string $path + * @return array|false + * @since 6.0.0 + */ + public function stat($path) { + // TODO: Implement stat() method. + $path = trim($path, '/'); + + return false; + } + + /** + * see http://php.net/manual/en/function.filetype.php + * + * @param string $path + * @return string|false + * @since 6.0.0 + */ + public function filetype($path) { + // TODO: Implement filetype() method. + return false; + } + + /** + * see http://php.net/manual/en/function.file_exists.php + * + * @param string $path + * @return bool + * @since 6.0.0 + */ + public function file_exists($path) { + // TODO: Implement file_exists() method. + return true; + } + + /** + * see http://php.net/manual/en/function.unlink.php + * + * @param string $path + * @return bool + * @since 6.0.0 + */ + public function unlink($path) { + // TODO: Implement unlink() method. + return true; + } + + /** + * see http://php.net/manual/en/function.fopen.php + * + * @param string $path + * @param string $mode + * @return resource|false + * @since 6.0.0 + */ + public function fopen($path, $mode) { + // TODO: Implement fopen() method. + return false; + } + + /** + * see http://php.net/manual/en/function.touch.php + * If the backend does not support the operation, false should be returned + * + * @param string $path + * @param int $mtime + * @return bool + * @since 6.0.0 + */ + public function touch($path, $mtime = null) { + // TODO: Implement touch() method. + return true; + } +} From 0729e0514940445063b8a6eab5f8a0eb5e682e1c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 12 Dec 2016 17:28:39 +0100 Subject: [PATCH 03/32] WIP changes Signed-off-by: Arthur Schiwon --- .../3rdparty/composer/autoload_real.php | 17 +++++------------ .../lib/Lib/Backend/SharePoint.php | 6 ++++-- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/apps/files_external/3rdparty/composer/autoload_real.php b/apps/files_external/3rdparty/composer/autoload_real.php index 4ac68127fea9d..d5f334739d9fa 100644 --- a/apps/files_external/3rdparty/composer/autoload_real.php +++ b/apps/files_external/3rdparty/composer/autoload_real.php @@ -23,19 +23,12 @@ public static function getLoader() self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3::getInitializer($loader)); - } else { - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } - $loader->setClassMapAuthoritative(true); + $loader->setClassMapAuthoritative(true); $loader->register(true); return $loader; diff --git a/apps/files_external/lib/Lib/Backend/SharePoint.php b/apps/files_external/lib/Lib/Backend/SharePoint.php index f1bd6d6d63208..6dc57606d9e25 100644 --- a/apps/files_external/lib/Lib/Backend/SharePoint.php +++ b/apps/files_external/lib/Lib/Backend/SharePoint.php @@ -24,6 +24,7 @@ namespace OCA\Files_External\Lib\Backend; use OCA\Files_External\Lib\Auth\AuthMechanism; +use OCA\Files_External\Lib\Auth\OAuth2\OAuth2; use OCA\Files_External\Lib\Auth\Password\Password; use OCA\Files_External\Lib\DefinitionParameter; use OCA\Files_External\Lib\Storage\SharePoint as SharePointStorage; @@ -31,7 +32,7 @@ class SharePoint extends Backend { - public function __construct(IL10N $l, Password $legacyAuth) { + public function __construct(IL10N $l, OAuth2 $legacyAuth, Password $legacyAuth2) { $this ->setIdentifier('sharepoint') ->setStorageClass(SharePointStorage::class) @@ -40,8 +41,9 @@ public function __construct(IL10N $l, Password $legacyAuth) { (new DefinitionParameter('host', $l->t('Host'))), (new DefinitionParameter('root', $l->t('Document Library'))), ]) + ->addAuthScheme(AuthMechanism::SCHEME_OAUTH2) ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) - ->setLegacyAuthMechanism($legacyAuth) + ->setLegacyAuthMechanism($legacyAuth2) ; } From 04472b1d9b7068cfbfff68f0db4ce5a7aff02202 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 20 Dec 2016 17:34:12 +0100 Subject: [PATCH 04/32] DI and init methods, we go for basic auth until we here anything else Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/ContextsFactory.php | 41 +++++++++++++++++ .../lib/Lib/Storage/SharePoint.php | 45 ++++++++++++++++--- 2 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 apps/files_external/lib/Lib/SharePoint/ContextsFactory.php diff --git a/apps/files_external/lib/Lib/SharePoint/ContextsFactory.php b/apps/files_external/lib/Lib/SharePoint/ContextsFactory.php new file mode 100644 index 0000000000000..a679da7ce442f --- /dev/null +++ b/apps/files_external/lib/Lib/SharePoint/ContextsFactory.php @@ -0,0 +1,41 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Lib\SharePoint; + +use Office365\PHP\Client\Runtime\Auth\IAuthenticationContext; +use Office365\PHP\Client\Runtime\Auth\NetworkCredentialContext; +use Office365\PHP\Client\SharePoint\ClientContext; + +class ContextsFactory { + + public function getAuthContext($user, $password) { + return new NetworkCredentialContext($user, $password); + } + + public function getClientContext($server, IAuthenticationContext $authContext) { + return new ClientContext($server, $authContext); + } + +} diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 1925a8cc39ccd..209b78983a7c4 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -24,7 +24,7 @@ namespace OCA\Files_External\Lib\Storage; use OC\Files\Storage\Common; -use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; +use OCA\Files_External\Lib\SharePoint\ContextsFactory; use Office365\PHP\Client\SharePoint\ClientContext; class SharePoint extends Common { @@ -37,10 +37,13 @@ class SharePoint extends Common { protected $authPwd; + /** @var ClientContext */ protected $context; + /** @var ContextsFactory */ + protected $contextsFactory; + public function __construct($parameters) { - $s = 'sadf'; $this->server = $parameters['host']; $this->documentLibrary = $parameters['root']; @@ -48,9 +51,8 @@ public function __construct($parameters) { $this->authUser = $parameters['user']; $this->authPwd = $parameters['password']; - $authContext = new AuthenticationContext($this->server); - $authContext->acquireTokenForUser($this->authUser, $this->authPwd); - $this->context = new ClientContext($this->server, $authContext); + $this->fixDI($parameters); + $this->initConnection($this->authUser, $this->authPwd); $web = $this->context->getWeb(); $list = $web->getLists()->getByTitle($this->documentLibrary); @@ -185,4 +187,37 @@ public function touch($path, $mtime = null) { // TODO: Implement touch() method. return true; } + + /** + * work around dependency injection issues so we can test this class properly + * + * @param array $parameters + */ + private function fixDI(array $parameters) { + if(isset($parameters['authContextFactory']) + && $parameters['authContextFactory'] instanceof ContextsFactory) + { + $this->contextsFactory = $parameters['authContextFactory']; + } else { + $this->contextsFactory = new ContextsFactory(); + } + } + + /** + * Set up necessary contexts for authentication and access to SharePoint + * + * @param string $user + * @param string $password + * @throws \InvalidArgumentException + */ + private function initConnection($user, $password) { + if(!is_string($user) || empty($user)) { + throw new \InvalidArgumentException('No user given'); + } + if(!is_string($password) || empty($password)) { + throw new \InvalidArgumentException('No password given'); + } + $authContext = $this->contextsFactory ->getAuthContext($user, $password); + $this->context = $this->contextsFactory->getClientContext($this->server, $authContext); + } } From 2a282481e449d0c72dbb372bf0ddfe7113aacc40 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 21 Dec 2016 10:04:33 +0100 Subject: [PATCH 05/32] work on stat Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/NotFoundException.php | 28 +++++++++++++ .../lib/Lib/Storage/SharePoint.php | 41 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 apps/files_external/lib/Lib/SharePoint/NotFoundException.php diff --git a/apps/files_external/lib/Lib/SharePoint/NotFoundException.php b/apps/files_external/lib/Lib/SharePoint/NotFoundException.php new file mode 100644 index 0000000000000..ef4c9cb760a09 --- /dev/null +++ b/apps/files_external/lib/Lib/SharePoint/NotFoundException.php @@ -0,0 +1,28 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Lib\SharePoint; + +class NotFoundException extends \Exception { + +} diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 209b78983a7c4..c4127e8fb351a 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -25,7 +25,10 @@ use OC\Files\Storage\Common; use OCA\Files_External\Lib\SharePoint\ContextsFactory; +use OCA\Files_External\Lib\SharePoint\NotFoundException; use Office365\PHP\Client\SharePoint\ClientContext; +use Office365\PHP\Client\SharePoint\ListItem; +use Office365\PHP\Client\SharePoint\SPList; class SharePoint extends Common { @@ -33,6 +36,9 @@ class SharePoint extends Common { protected $documentLibrary; + /** @var SPList */ + protected $documentLibraryItem; + protected $authUser; protected $authPwd; @@ -122,6 +128,21 @@ public function stat($path) { // TODO: Implement stat() method. $path = trim($path, '/'); + $rootFolder = $documentLibrary = $this->getDocumentLibrary()->getRootFolder(); + if($path === '/' || $path === '') { + $properties = $rootFolder->getProperties(); + $stat = [ + 'size' => $rootFolder->getProperty('Size'), // int32 + 'mtime' => $rootFolder->getProperty('TimeLastModified'), // returns DateTime + 'atime' => time(), // other storages do the same :speak_no_evil: + ]; + } + + + if(isset($stat)) { + return $stat; + } + return false; } @@ -188,6 +209,26 @@ public function touch($path, $mtime = null) { return true; } + /** + * @return SPList + * @throws NotFoundException + */ + private function getDocumentLibrary() { + if(!is_null($this->documentLibraryItem)) { + return $this->documentLibraryItem; + } + + //FIXME: ensure documentLibrary is not evil + $lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibrary . '\'')->top(1); + $this->context->load($lists)->executeQuery(); + if ($lists->getCount() == 1) { + $this->documentLibraryItem = $lists->getData()[0]; + return $this->documentLibraryItem; + } + + throw new NotFoundException('List not found'); + } + /** * work around dependency injection issues so we can test this class properly * From 2c181b4de6c756a8e9f01be8269a5fd52f4199bb Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 21 Dec 2016 20:00:49 +0100 Subject: [PATCH 06/32] work on stat and tests Signed-off-by: Arthur Schiwon --- .../lib/Lib/Backend/SharePoint.php | 7 +- .../lib/Lib/Storage/SharePoint.php | 69 ++++--- .../tests/Storage/SharePointTest.php | 172 ++++++++++++++++++ 3 files changed, 214 insertions(+), 34 deletions(-) create mode 100644 apps/files_external/tests/Storage/SharePointTest.php diff --git a/apps/files_external/lib/Lib/Backend/SharePoint.php b/apps/files_external/lib/Lib/Backend/SharePoint.php index 6dc57606d9e25..f96a57b28ebe1 100644 --- a/apps/files_external/lib/Lib/Backend/SharePoint.php +++ b/apps/files_external/lib/Lib/Backend/SharePoint.php @@ -32,18 +32,17 @@ class SharePoint extends Backend { - public function __construct(IL10N $l, OAuth2 $legacyAuth, Password $legacyAuth2) { + public function __construct(IL10N $l, Password $legacyAuth) { $this ->setIdentifier('sharepoint') ->setStorageClass(SharePointStorage::class) ->setText($l->t('SharePoint')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), - (new DefinitionParameter('root', $l->t('Document Library'))), + (new DefinitionParameter('documentLibrary', $l->t('Document Library'))), ]) - ->addAuthScheme(AuthMechanism::SCHEME_OAUTH2) ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD) - ->setLegacyAuthMechanism($legacyAuth2) + ->setLegacyAuthMechanism($legacyAuth) ; } diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index c4127e8fb351a..00bd3264e098c 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -27,7 +27,6 @@ use OCA\Files_External\Lib\SharePoint\ContextsFactory; use OCA\Files_External\Lib\SharePoint\NotFoundException; use Office365\PHP\Client\SharePoint\ClientContext; -use Office365\PHP\Client\SharePoint\ListItem; use Office365\PHP\Client\SharePoint\SPList; class SharePoint extends Common { @@ -51,20 +50,22 @@ class SharePoint extends Common { public function __construct($parameters) { $this->server = $parameters['host']; - $this->documentLibrary = $parameters['root']; + $this->documentLibrary = $parameters['documentLibrary']; - // FIXME: perhaps not set + if(strpos($this->documentLibrary, '"') !== false) { + // they are, amongst others, not allowed and we use it in the filter + // cf. https://support.microsoft.com/en-us/kb/2933738 + // TODO: verify, it talks about files and folders mostly + throw new \InvalidArgumentException('Illegal character in Document Library Name'); + } + + if(!isset($parameters['user']) || !isset($parameters['password'])) { + throw new \UnexpectedValueException('No user or password given'); + } $this->authUser = $parameters['user']; - $this->authPwd = $parameters['password']; + $this->authPwd = $parameters['password']; $this->fixDI($parameters); - $this->initConnection($this->authUser, $this->authPwd); - - $web = $this->context->getWeb(); - $list = $web->getLists()->getByTitle($this->documentLibrary); - $s = 'asdf'; - - # TODO: test this ^ } /** @@ -125,24 +126,31 @@ public function opendir($path) { * @since 6.0.0 */ public function stat($path) { - // TODO: Implement stat() method. + $this->ensureConnection(); + $path = trim($path, '/'); - $rootFolder = $documentLibrary = $this->getDocumentLibrary()->getRootFolder(); + $rootFolder = $this->getDocumentLibrary()->getRootFolder(); if($path === '/' || $path === '') { - $properties = $rootFolder->getProperties(); + $properties = $rootFolder->getProperties(); // TODO: see what we retrieve here + // FIXME: getProperty may return null + // FIXME: Folder does not have such properties, according to doc $stat = [ - 'size' => $rootFolder->getProperty('Size'), // int32 - 'mtime' => $rootFolder->getProperty('TimeLastModified'), // returns DateTime - 'atime' => time(), // other storages do the same :speak_no_evil: + // int64, size in bytes, excluding the size of any Web Parts that are used in the file. + 'size' => $rootFolder->getProperty('Length'), + 'mtime' => $rootFolder->getProperty('TimeLastModified'), + // no property in SP 2013, other storages do the same :speak_no_evil: + 'atime' => time(), ]; } + // TODO handle path cases - - if(isset($stat)) { + if(isset($stat) && !is_null($stat['size']) && !is_null($stat['mtime'])) { return $stat; } + // If we do not get a size or mtime from SP, we treat it as an error + // thus returning false, according to PHP documentation on stat() return false; } @@ -218,8 +226,7 @@ private function getDocumentLibrary() { return $this->documentLibraryItem; } - //FIXME: ensure documentLibrary is not evil - $lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibrary . '\'')->top(1); + $lists = $this->context->getWeb()->getLists()->filter('Title eq "' . $this->documentLibrary . '"')->top(1); $this->context->load($lists)->executeQuery(); if ($lists->getCount() == 1) { $this->documentLibraryItem = $lists->getData()[0]; @@ -235,10 +242,10 @@ private function getDocumentLibrary() { * @param array $parameters */ private function fixDI(array $parameters) { - if(isset($parameters['authContextFactory']) - && $parameters['authContextFactory'] instanceof ContextsFactory) + if(isset($parameters['contextFactory']) + && $parameters['contextFactory'] instanceof ContextsFactory) { - $this->contextsFactory = $parameters['authContextFactory']; + $this->contextsFactory = $parameters['contextFactory']; } else { $this->contextsFactory = new ContextsFactory(); } @@ -247,18 +254,20 @@ private function fixDI(array $parameters) { /** * Set up necessary contexts for authentication and access to SharePoint * - * @param string $user - * @param string $password * @throws \InvalidArgumentException */ - private function initConnection($user, $password) { - if(!is_string($user) || empty($user)) { + private function ensureConnection() { + if($this->context instanceof ClientContext) { + return; + } + + if(!is_string($this->authUser) || empty($this->authUser)) { throw new \InvalidArgumentException('No user given'); } - if(!is_string($password) || empty($password)) { + if(!is_string($this->authPwd) || empty($this->authPwd)) { throw new \InvalidArgumentException('No password given'); } - $authContext = $this->contextsFactory ->getAuthContext($user, $password); + $authContext = $this->contextsFactory->getAuthContext($this->authUser, $this->authPwd); $this->context = $this->contextsFactory->getClientContext($this->server, $authContext); } } diff --git a/apps/files_external/tests/Storage/SharePointTest.php b/apps/files_external/tests/Storage/SharePointTest.php new file mode 100644 index 0000000000000..a9165d16134c9 --- /dev/null +++ b/apps/files_external/tests/Storage/SharePointTest.php @@ -0,0 +1,172 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Tests\Storage; + +use OCA\Files_External\Lib\SharePoint\ContextsFactory; +use OCA\Files_External\Lib\Storage\SharePoint; +use Office365\PHP\Client\Runtime\Auth\IAuthenticationContext; +use Office365\PHP\Client\Runtime\ClientObjectCollection; +use Office365\PHP\Client\SharePoint\ClientContext; +use Office365\PHP\Client\SharePoint\Folder; +use Office365\PHP\Client\SharePoint\ListCollection; +use Office365\PHP\Client\SharePoint\SPList; +use Office365\PHP\Client\SharePoint\Web; +use Test\TestCase; + +class SharePointTest extends TestCase { + + /** @var SharePoint */ + protected $storage; + + /** @var ContextsFactory|\PHPUnit_Framework_MockObject_MockObject */ + protected $factory; + + /** @var ClientContext|\PHPUnit_Framework_MockObject_MockObject */ + protected $clientContextMock; + + /** @var string */ + protected $documentLibraryName = 'Fancy Documents'; + + /** @var SPList|\PHPUnit_Framework_MockObject_MockObject */ + protected $sharePointList; + + /** @var string */ + protected $exampleHost = 'example.foo'; + + /** @var string */ + protected $exampleUser = 'alice'; + + /** @var string */ + protected $examplePwd = 'a123456'; + + public function setUp() { + parent::setUp(); + + $this->factory = $this->createMock(ContextsFactory::class); + + $parameters = [ + 'host' => $this->exampleHost, + 'documentLibrary' => $this->documentLibraryName, + 'user' => $this->exampleUser, + 'password' => $this->examplePwd, + 'contextFactory' => $this->factory, + ]; + + $this->storage = new SharePoint($parameters); + } + + private function prepareFactoryMocks() { + $authContextMock = $this->createMock(IAuthenticationContext::class); + $this->clientContextMock = $this->createMock(ClientContext::class); + + $this->factory->expects($this->once()) + ->method('getAuthContext') + ->with($this->exampleUser, $this->examplePwd) + ->willReturn($authContextMock); + $this->factory->expects($this->once()) + ->method('getClientContext') + ->with($this->exampleHost, $authContextMock) + ->willReturn($this->clientContextMock); + } + + /** + * prepare Mocks for SharePoint::getDocumentLibrary() call + */ + private function prepareMockForGetDocumentLibrary() { + $this->prepareFactoryMocks(); // precondition + + $this->sharePointList = $this->createMock(SPList::class); + + $clientObjectCollectionMock = $this->createMock(ClientObjectCollection::class); + $clientObjectCollectionMock->expects($this->once()) + ->method('top') + ->with(1) + ->willReturnSelf(); + $clientObjectCollectionMock->expects($this->once()) + ->method('getCount') + ->willReturn(1); + $clientObjectCollectionMock->expects($this->once()) + ->method('getData') + ->willReturn([$this->sharePointList]); + + $listCollectionMock = $this->createMock(ListCollection::class); + $listCollectionMock->expects($this->once()) + ->method('filter') + ->with('Title eq "' . $this->documentLibraryName . '"') + ->willReturn($clientObjectCollectionMock); + + $webMock = $this->createMock(Web::class); + $webMock->expects($this->once()) + ->method('getLists') + ->willReturn($listCollectionMock); + + $this->clientContextMock->expects($this->once()) + ->method('getWeb') + ->willReturn($webMock); + $this->clientContextMock->expects($this->once()) + ->method('load') + ->with($clientObjectCollectionMock) + ->willReturnSelf(); + $this->clientContextMock->expects($this->once()) + ->method('executeQuery'); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testBadDocumentLibraryName() { + $parameters = [ + 'host' => 'example.foo', + 'documentLibrary' => 'foo" or bar eq 42', + 'user' => 'alicce', + 'password' => 'asdf', + ]; + + new SharePoint($parameters); + } + + public function testStat() { + $this->prepareMockForGetDocumentLibrary(); + + $mtime = new \DateTime('yesterday'); + $size = 4096; + + $folderMock = $this->createMock(Folder::class); + $folderMock->expects($this->exactly(2)) + ->method('getProperty') + ->withConsecutive(['Length'], ['TimeLastModified']) + ->willReturnOnConsecutiveCalls($size, $mtime); + + $this->sharePointList->expects($this->once()) + ->method('getRootFolder') + ->willReturn($folderMock); + + $rootData = $this->storage->stat('/'); + + $this->assertSame($mtime, $rootData['mtime']); + $this->assertSame($size, $rootData['size']); + $this->assertTrue($mtime->getTimestamp() < $rootData['atime']); + } + +} From b0d8a7a76f554a2c77eb386ba0bee87050e373d1 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Dec 2016 23:32:53 +0100 Subject: [PATCH 07/32] complete stat(), implement filetype() Signed-off-by: Arthur Schiwon --- .../lib/Lib/Storage/SharePoint.php | 62 +++++++++++++++---- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 00bd3264e098c..540c5aaf1eacb 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -27,6 +27,8 @@ use OCA\Files_External\Lib\SharePoint\ContextsFactory; use OCA\Files_External\Lib\SharePoint\NotFoundException; use Office365\PHP\Client\SharePoint\ClientContext; +use Office365\PHP\Client\SharePoint\File; +use Office365\PHP\Client\SharePoint\Folder; use Office365\PHP\Client\SharePoint\SPList; class SharePoint extends Common { @@ -130,20 +132,27 @@ public function stat($path) { $path = trim($path, '/'); - $rootFolder = $this->getDocumentLibrary()->getRootFolder(); if($path === '/' || $path === '') { - $properties = $rootFolder->getProperties(); // TODO: see what we retrieve here - // FIXME: getProperty may return null - // FIXME: Folder does not have such properties, according to doc - $stat = [ - // int64, size in bytes, excluding the size of any Web Parts that are used in the file. - 'size' => $rootFolder->getProperty('Length'), - 'mtime' => $rootFolder->getProperty('TimeLastModified'), - // no property in SP 2013, other storages do the same :speak_no_evil: - 'atime' => time(), - ]; + $fsObject = $this->getDocumentLibrary()->getRootFolder(); + $properties = $fsObject->getProperties(); // TODO: see what we retrieve here + } else { + // TODO: verify that try-catch approach works + try { + $fsObject = $this->fetchFileOrFolder($path, true); // likely we need to modify path since we are not operating on the document library + } catch (\Exception $e) { + // it can be a folder, too + $fsObject = $this->fetchFileOrFolder($path, false); + } } - // TODO handle path cases + // FIXME: getProperty may return null + // FIXME: Folder does not have such properties, according to doc – traversing through all files needed + $stat = [ + // int64, size in bytes, excluding the size of any Web Parts that are used in the file. + 'size' => $fsObject->getProperty('Length'), + 'mtime' => $fsObject->getProperty('TimeLastModified'), + // no property in SP 2013, other storages do the same :speak_no_evil: + 'atime' => time(), + ]; if(isset($stat) && !is_null($stat['size']) && !is_null($stat['mtime'])) { return $stat; @@ -154,6 +163,19 @@ public function stat($path) { return false; } + /** + * @param string $path + * @param bool $tryFile + * @return File|Folder + */ + private function fetchFileOrFolder($path, $tryFile) { + if($tryFile) { + return $this->context->getWeb()->getFileByServerRelativeUrl($path); + } else { + return $this->context->getWeb()->getFolderByServerRelativeUrl($path); + } + } + /** * see http://php.net/manual/en/function.filetype.php * @@ -162,7 +184,21 @@ public function stat($path) { * @since 6.0.0 */ public function filetype($path) { - // TODO: Implement filetype() method. + $path = trim($path); + if($path === '/' || $path === '') { + return 'dir'; + } + try { + $this->fetchFileOrFolder($path, true); + return 'file'; + } catch(\Exception $e) { + try { + $this->fetchFileOrFolder($path, false); + return 'dir'; + } catch (\Exception $e) { + // NOOP + } + } return false; } From a44f37b00a9d48f5cda64a61d2fe853f6664c66f Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 23 Dec 2016 23:39:28 +0100 Subject: [PATCH 08/32] implement fileExists() and unlink() Signed-off-by: Arthur Schiwon --- .../lib/Lib/Storage/SharePoint.php | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 540c5aaf1eacb..0506735f7a436 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -210,7 +210,9 @@ public function filetype($path) { * @since 6.0.0 */ public function file_exists($path) { - // TODO: Implement file_exists() method. + if($this->filetype($path) === false) { + return false; + } return true; } @@ -222,8 +224,20 @@ public function file_exists($path) { * @since 6.0.0 */ public function unlink($path) { - // TODO: Implement unlink() method. - return true; + $path = trim($path); + if($path === '/' || $path === '') { + return false; + } + foreach([true, false] as $asFile) { + try { + $fsObject = $this->fetchFileOrFolder($path, $asFile); + $fsObject->deleteObject(); + return true; + } catch(\Exception $e) { + // NOOP + } + } + return false; } /** From d895e71ed94709e695f8bc4f58750d44319c799b Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 9 Mar 2017 12:08:52 +0100 Subject: [PATCH 09/32] update php-spo Signed-off-by: Arthur Schiwon --- apps/files_external/3rdparty/composer.json | 2 +- apps/files_external/3rdparty/composer.lock | 10 +- .../3rdparty/composer/autoload_classmap.php | 25 +- .../3rdparty/composer/autoload_real.php | 17 +- .../3rdparty/composer/autoload_static.php | 286 ++++++++++++++++-- .../3rdparty/composer/installed.json | 8 +- apps/files_external/3rdparty/vgrem/php-spo | 2 +- 7 files changed, 290 insertions(+), 60 deletions(-) diff --git a/apps/files_external/3rdparty/composer.json b/apps/files_external/3rdparty/composer.json index 4bba089e3a891..67f5a8cef7bc1 100644 --- a/apps/files_external/3rdparty/composer.json +++ b/apps/files_external/3rdparty/composer.json @@ -9,7 +9,7 @@ }, "require": { "icewind/smb": "2.0.0", - "icewind/streams": "0.5.2" + "icewind/streams": "0.5.2", "vgrem/php-spo": "dev-master" } } diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 7a138ecba142b..6d08a1c168934 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "0bbca3fe2d180fbc5681985bdf6b22e7", + "content-hash": "687c46336601ae737f169ba14a534bdb", "packages": [ { "name": "icewind/smb", @@ -94,12 +94,12 @@ "source": { "type": "git", "url": "https://github.com/vgrem/phpSPO.git", - "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b" + "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/68413b42ff18c96a3a4e097b47c905eeab30305b", - "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b", + "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/59a2956f94f694592e3d3c6252f0e753f73a1686", + "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686", "shasum": "" }, "require": { @@ -130,7 +130,7 @@ "rest", "sharepoint" ], - "time": "2016-11-22 15:34:47" + "time": "2017-02-22 10:52:00" } ], "packages-dev": [], diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index c96c7ae2e911e..5bdff2e38bdfd 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -46,14 +46,6 @@ 'Icewind\\SMB\\Server' => $vendorDir . '/icewind/smb/src/Server.php', 'Icewind\\SMB\\Share' => $vendorDir . '/icewind/smb/src/Share.php', 'Icewind\\SMB\\System' => $vendorDir . '/icewind/smb/src/System.php', - 'Icewind\\SMB\\Test\\AbstractShare' => $vendorDir . '/icewind/smb/tests/AbstractShare.php', - 'Icewind\\SMB\\Test\\NativeShare' => $vendorDir . '/icewind/smb/tests/NativeShare.php', - 'Icewind\\SMB\\Test\\NativeStream' => $vendorDir . '/icewind/smb/tests/NativeStream.php', - 'Icewind\\SMB\\Test\\NotifyHandlerTest' => $vendorDir . '/icewind/smb/tests/NotifyHandlerTest.php', - 'Icewind\\SMB\\Test\\Parser' => $vendorDir . '/icewind/smb/tests/Parser.php', - 'Icewind\\SMB\\Test\\Server' => $vendorDir . '/icewind/smb/tests/Server.php', - 'Icewind\\SMB\\Test\\Share' => $vendorDir . '/icewind/smb/tests/Share.php', - 'Icewind\\SMB\\Test\\TestCase' => $vendorDir . '/icewind/smb/tests/TestCase.php', 'Icewind\\SMB\\TimeZoneProvider' => $vendorDir . '/icewind/smb/src/TimeZoneProvider.php', 'Icewind\\Streams\\CallbackWrapper' => $vendorDir . '/icewind/streams/src/CallbackWrapper.php', 'Icewind\\Streams\\Directory' => $vendorDir . '/icewind/streams/src/Directory.php', @@ -66,23 +58,11 @@ 'Icewind\\Streams\\PathWrapper' => $vendorDir . '/icewind/streams/src/PathWrapper.php', 'Icewind\\Streams\\RetryWrapper' => $vendorDir . '/icewind/streams/src/RetryWrapper.php', 'Icewind\\Streams\\SeekableWrapper' => $vendorDir . '/icewind/streams/src/SeekableWrapper.php', - 'Icewind\\Streams\\Tests\\CallbackWrapper' => $vendorDir . '/icewind/streams/tests/CallbackWrapper.php', - 'Icewind\\Streams\\Tests\\DirectoryFilter' => $vendorDir . '/icewind/streams/tests/DirectoryFilter.php', - 'Icewind\\Streams\\Tests\\DirectoryWrapper' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', - 'Icewind\\Streams\\Tests\\DirectoryWrapperDummy' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', - 'Icewind\\Streams\\Tests\\DirectoryWrapperNull' => $vendorDir . '/icewind/streams/tests/DirectoryWrapper.php', - 'Icewind\\Streams\\Tests\\FailWrapper' => $vendorDir . '/icewind/streams/tests/RetryWrapper.php', - 'Icewind\\Streams\\Tests\\IteratorDirectory' => $vendorDir . '/icewind/streams/tests/IteratorDirectory.php', - 'Icewind\\Streams\\Tests\\NullWrapper' => $vendorDir . '/icewind/streams/tests/NullWrapper.php', - 'Icewind\\Streams\\Tests\\PartialWrapper' => $vendorDir . '/icewind/streams/tests/RetryWrapper.php', - 'Icewind\\Streams\\Tests\\PathWrapper' => $vendorDir . '/icewind/streams/tests/PathWrapper.php', - 'Icewind\\Streams\\Tests\\RetryWrapper' => $vendorDir . '/icewind/streams/tests/RetryWrapper.php', - 'Icewind\\Streams\\Tests\\SeekableWrapper' => $vendorDir . '/icewind/streams/tests/SeekableWrapper.php', - 'Icewind\\Streams\\Tests\\UrlCallBack' => $vendorDir . '/icewind/streams/tests/UrlCallBack.php', - 'Icewind\\Streams\\Tests\\Wrapper' => $vendorDir . '/icewind/streams/tests/Wrapper.php', 'Icewind\\Streams\\Url' => $vendorDir . '/icewind/streams/src/Url.php', 'Icewind\\Streams\\UrlCallback' => $vendorDir . '/icewind/streams/src/UrlCallBack.php', 'Icewind\\Streams\\Wrapper' => $vendorDir . '/icewind/streams/src/Wrapper.php', + 'Office365\\PHP\\Client\\Discovery\\CapabilityDiscoveryResult' => $vendorDir . '/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php', + 'Office365\\PHP\\Client\\Discovery\\DiscoveryClient' => $vendorDir . '/vgrem/php-spo/src/Discovery/DiscoveryClient.php', 'Office365\\PHP\\Client\\FileServices\\IdentitySet' => $vendorDir . '/vgrem/php-spo/src/OneDrive/IdentitySet.php', 'Office365\\PHP\\Client\\FileServices\\ImageFacet' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ImageFacet.php', 'Office365\\PHP\\Client\\FileServices\\ItemReference' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ItemReference.php', @@ -132,6 +112,7 @@ 'Office365\\PHP\\Client\\OutlookServices\\EventType' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/EventType.php', 'Office365\\PHP\\Client\\OutlookServices\\FileAttachment' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/FileAttachment.php', 'Office365\\PHP\\Client\\OutlookServices\\FileAttachmentCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/FileAttachmentCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\FolderCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/FolderCollection.php', 'Office365\\PHP\\Client\\OutlookServices\\FreeBusyStatus' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/FreeBusyStatus.php', 'Office365\\PHP\\Client\\OutlookServices\\GeoCoordinates' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/GeoCoordinates.php', 'Office365\\PHP\\Client\\OutlookServices\\Group' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Group.php', diff --git a/apps/files_external/3rdparty/composer/autoload_real.php b/apps/files_external/3rdparty/composer/autoload_real.php index d5f334739d9fa..4ac68127fea9d 100644 --- a/apps/files_external/3rdparty/composer/autoload_real.php +++ b/apps/files_external/3rdparty/composer/autoload_real.php @@ -23,12 +23,19 @@ public static function getLoader() self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit98fe9b281934250b3a93f69a5ce843b3', 'loadClassLoader')); - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3::getInitializer($loader)); + } else { + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } - $loader->setClassMapAuthoritative(true); + $loader->setClassMapAuthoritative(true); $loader->register(true); return $loader; diff --git a/apps/files_external/3rdparty/composer/autoload_static.php b/apps/files_external/3rdparty/composer/autoload_static.php index c1a3a0492d091..eb1f56aa483d0 100644 --- a/apps/files_external/3rdparty/composer/autoload_static.php +++ b/apps/files_external/3rdparty/composer/autoload_static.php @@ -7,6 +7,10 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 { public static $prefixLengthsPsr4 = array ( + 'O' => + array ( + 'Office365\\PHP\\Client\\' => 21, + ), 'I' => array ( 'Icewind\\Streams\\Tests\\' => 22, @@ -17,6 +21,10 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 ); public static $prefixDirsPsr4 = array ( + 'Office365\\PHP\\Client\\' => + array ( + 0 => __DIR__ . '/..' . '/vgrem/php-spo/src', + ), 'Icewind\\Streams\\Tests\\' => array ( 0 => __DIR__ . '/..' . '/icewind/streams/tests', @@ -76,14 +84,6 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\SMB\\Server' => __DIR__ . '/..' . '/icewind/smb/src/Server.php', 'Icewind\\SMB\\Share' => __DIR__ . '/..' . '/icewind/smb/src/Share.php', 'Icewind\\SMB\\System' => __DIR__ . '/..' . '/icewind/smb/src/System.php', - 'Icewind\\SMB\\Test\\AbstractShare' => __DIR__ . '/..' . '/icewind/smb/tests/AbstractShare.php', - 'Icewind\\SMB\\Test\\NativeShare' => __DIR__ . '/..' . '/icewind/smb/tests/NativeShare.php', - 'Icewind\\SMB\\Test\\NativeStream' => __DIR__ . '/..' . '/icewind/smb/tests/NativeStream.php', - 'Icewind\\SMB\\Test\\NotifyHandlerTest' => __DIR__ . '/..' . '/icewind/smb/tests/NotifyHandlerTest.php', - 'Icewind\\SMB\\Test\\Parser' => __DIR__ . '/..' . '/icewind/smb/tests/Parser.php', - 'Icewind\\SMB\\Test\\Server' => __DIR__ . '/..' . '/icewind/smb/tests/Server.php', - 'Icewind\\SMB\\Test\\Share' => __DIR__ . '/..' . '/icewind/smb/tests/Share.php', - 'Icewind\\SMB\\Test\\TestCase' => __DIR__ . '/..' . '/icewind/smb/tests/TestCase.php', 'Icewind\\SMB\\TimeZoneProvider' => __DIR__ . '/..' . '/icewind/smb/src/TimeZoneProvider.php', 'Icewind\\Streams\\CallbackWrapper' => __DIR__ . '/..' . '/icewind/streams/src/CallbackWrapper.php', 'Icewind\\Streams\\Directory' => __DIR__ . '/..' . '/icewind/streams/src/Directory.php', @@ -96,23 +96,265 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\Streams\\PathWrapper' => __DIR__ . '/..' . '/icewind/streams/src/PathWrapper.php', 'Icewind\\Streams\\RetryWrapper' => __DIR__ . '/..' . '/icewind/streams/src/RetryWrapper.php', 'Icewind\\Streams\\SeekableWrapper' => __DIR__ . '/..' . '/icewind/streams/src/SeekableWrapper.php', - 'Icewind\\Streams\\Tests\\CallbackWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/CallbackWrapper.php', - 'Icewind\\Streams\\Tests\\DirectoryFilter' => __DIR__ . '/..' . '/icewind/streams/tests/DirectoryFilter.php', - 'Icewind\\Streams\\Tests\\DirectoryWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/DirectoryWrapper.php', - 'Icewind\\Streams\\Tests\\DirectoryWrapperDummy' => __DIR__ . '/..' . '/icewind/streams/tests/DirectoryWrapper.php', - 'Icewind\\Streams\\Tests\\DirectoryWrapperNull' => __DIR__ . '/..' . '/icewind/streams/tests/DirectoryWrapper.php', - 'Icewind\\Streams\\Tests\\FailWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/RetryWrapper.php', - 'Icewind\\Streams\\Tests\\IteratorDirectory' => __DIR__ . '/..' . '/icewind/streams/tests/IteratorDirectory.php', - 'Icewind\\Streams\\Tests\\NullWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/NullWrapper.php', - 'Icewind\\Streams\\Tests\\PartialWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/RetryWrapper.php', - 'Icewind\\Streams\\Tests\\PathWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/PathWrapper.php', - 'Icewind\\Streams\\Tests\\RetryWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/RetryWrapper.php', - 'Icewind\\Streams\\Tests\\SeekableWrapper' => __DIR__ . '/..' . '/icewind/streams/tests/SeekableWrapper.php', - 'Icewind\\Streams\\Tests\\UrlCallBack' => __DIR__ . '/..' . '/icewind/streams/tests/UrlCallBack.php', - 'Icewind\\Streams\\Tests\\Wrapper' => __DIR__ . '/..' . '/icewind/streams/tests/Wrapper.php', 'Icewind\\Streams\\Url' => __DIR__ . '/..' . '/icewind/streams/src/Url.php', 'Icewind\\Streams\\UrlCallback' => __DIR__ . '/..' . '/icewind/streams/src/UrlCallBack.php', 'Icewind\\Streams\\Wrapper' => __DIR__ . '/..' . '/icewind/streams/src/Wrapper.php', + 'Office365\\PHP\\Client\\Discovery\\CapabilityDiscoveryResult' => __DIR__ . '/..' . '/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php', + 'Office365\\PHP\\Client\\Discovery\\DiscoveryClient' => __DIR__ . '/..' . '/vgrem/php-spo/src/Discovery/DiscoveryClient.php', + 'Office365\\PHP\\Client\\FileServices\\IdentitySet' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/IdentitySet.php', + 'Office365\\PHP\\Client\\FileServices\\ImageFacet' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/ImageFacet.php', + 'Office365\\PHP\\Client\\FileServices\\ItemReference' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/ItemReference.php', + 'Office365\\PHP\\Client\\GraphClient\\ActiveDirectoryClient' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/ActiveDirectoryClient.php', + 'Office365\\PHP\\Client\\GraphClient\\Contact' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/Contact.php', + 'Office365\\PHP\\Client\\GraphClient\\ContactCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/ContactCollection.php', + 'Office365\\PHP\\Client\\GraphClient\\Device' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/Device.php', + 'Office365\\PHP\\Client\\GraphClient\\DeviceCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/DeviceCollection.php', + 'Office365\\PHP\\Client\\GraphClient\\DirectoryObject' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/DirectoryObject.php', + 'Office365\\PHP\\Client\\GraphClient\\DirectoryObjectCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/DirectoryObjectCollection.php', + 'Office365\\PHP\\Client\\GraphClient\\GraphObject' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/GraphObject.php', + 'Office365\\PHP\\Client\\GraphClient\\TenantDetail' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/TenantDetail.php', + 'Office365\\PHP\\Client\\GraphClient\\TenantDetailCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/GraphClient/TenantDetailCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\CurrentUserRequestContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/CurrentUserRequestContext.php', + 'Office365\\PHP\\Client\\OneDrive\\Drive' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/Drive.php', + 'Office365\\PHP\\Client\\OneDrive\\File' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/File.php', + 'Office365\\PHP\\Client\\OneDrive\\FileCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/FileCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\Folder' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/Folder.php', + 'Office365\\PHP\\Client\\OneDrive\\FolderCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/FolderCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\Identity' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/Identity.php', + 'Office365\\PHP\\Client\\OneDrive\\Item' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/Item.php', + 'Office365\\PHP\\Client\\OneDrive\\ItemCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/ItemCollection.php', + 'Office365\\PHP\\Client\\OneDrive\\OneDriveClient' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/OneDriveClient.php', + 'Office365\\PHP\\Client\\OneDrive\\OneDriveErrorCode' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php', + 'Office365\\PHP\\Client\\OutlookServices\\Attachment' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Attachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\AttachmentCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/AttachmentCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Attendee' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Attendee.php', + 'Office365\\PHP\\Client\\OutlookServices\\AttendeeType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/AttendeeType.php', + 'Office365\\PHP\\Client\\OutlookServices\\BodyType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/BodyType.php', + 'Office365\\PHP\\Client\\OutlookServices\\Calendar' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Calendar.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/CalendarCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarColor' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/CalendarColor.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarGroup' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/CalendarGroup.php', + 'Office365\\PHP\\Client\\OutlookServices\\CalendarGroupCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/CalendarGroupCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ChangeType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ChangeType.php', + 'Office365\\PHP\\Client\\OutlookServices\\Contact' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Contact.php', + 'Office365\\PHP\\Client\\OutlookServices\\ContactCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ContactCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ContactFolder' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ContactFolder.php', + 'Office365\\PHP\\Client\\OutlookServices\\Conversation' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Conversation.php', + 'Office365\\PHP\\Client\\OutlookServices\\ConversationCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ConversationCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ConversationThread' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ConversationThread.php', + 'Office365\\PHP\\Client\\OutlookServices\\DateTimeTimeZone' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/DateTimeTimeZone.php', + 'Office365\\PHP\\Client\\OutlookServices\\DayOfWeek' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/DayOfWeek.php', + 'Office365\\PHP\\Client\\OutlookServices\\EmailAddress' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/EmailAddress.php', + 'Office365\\PHP\\Client\\OutlookServices\\Event' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Event.php', + 'Office365\\PHP\\Client\\OutlookServices\\EventCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/EventCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\EventType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/EventType.php', + 'Office365\\PHP\\Client\\OutlookServices\\FileAttachment' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/FileAttachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\FileAttachmentCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/FileAttachmentCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\FolderCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/FolderCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\FreeBusyStatus' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/FreeBusyStatus.php', + 'Office365\\PHP\\Client\\OutlookServices\\GeoCoordinates' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/GeoCoordinates.php', + 'Office365\\PHP\\Client\\OutlookServices\\Group' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Group.php', + 'Office365\\PHP\\Client\\OutlookServices\\GroupCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/GroupCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Item' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Item.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemAttachment' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ItemAttachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemAttachmentCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ItemAttachmentCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemBody' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ItemBody.php', + 'Office365\\PHP\\Client\\OutlookServices\\ItemCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ItemCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Location' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Location.php', + 'Office365\\PHP\\Client\\OutlookServices\\MailFolder' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/MailFolder.php', + 'Office365\\PHP\\Client\\OutlookServices\\MeetingMessageType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/MeetingMessageType.php', + 'Office365\\PHP\\Client\\OutlookServices\\Message' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Message.php', + 'Office365\\PHP\\Client\\OutlookServices\\MessageCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/MessageCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\OpenTypeExtension' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/OpenTypeExtension.php', + 'Office365\\PHP\\Client\\OutlookServices\\OutlookClient' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/OutlookClient.php', + 'Office365\\PHP\\Client\\OutlookServices\\OutlookEntity' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/OutlookEntity.php', + 'Office365\\PHP\\Client\\OutlookServices\\Photo' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Photo.php', + 'Office365\\PHP\\Client\\OutlookServices\\PhysicalAddress' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/PhysicalAddress.php', + 'Office365\\PHP\\Client\\OutlookServices\\Post' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Post.php', + 'Office365\\PHP\\Client\\OutlookServices\\PushSubscription' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/PushSubscription.php', + 'Office365\\PHP\\Client\\OutlookServices\\PushSubscriptionCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/PushSubscriptionCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\Recipient' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Recipient.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrencePattern' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/RecurrencePattern.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrencePatternType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/RecurrencePatternType.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrenceRange' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/RecurrenceRange.php', + 'Office365\\PHP\\Client\\OutlookServices\\RecurrenceRangeType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/RecurrenceRangeType.php', + 'Office365\\PHP\\Client\\OutlookServices\\ReferenceAttachment' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ReferenceAttachment.php', + 'Office365\\PHP\\Client\\OutlookServices\\Reminder' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Reminder.php', + 'Office365\\PHP\\Client\\OutlookServices\\ResponseStatus' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/ResponseStatus.php', + 'Office365\\PHP\\Client\\OutlookServices\\Subscription' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Subscription.php', + 'Office365\\PHP\\Client\\OutlookServices\\SubscriptionCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/SubscriptionCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\User' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/User.php', + 'Office365\\PHP\\Client\\OutlookServices\\UserCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/UserCollection.php', + 'Office365\\PHP\\Client\\OutlookServices\\WeekIndex' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/WeekIndex.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\ACSTokenProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/ACSTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\AuthenticationContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/AuthenticationContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\BaseTokenProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\CookieCacheEntry' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/CookieCacheEntry.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\IAuthenticationContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\NetworkCredentialContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/NetworkCredentialContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\OAuthTokenProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\SamlTokenProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php', + 'Office365\\PHP\\Client\\Runtime\\ClientAction' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientAction.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionCreateEntity' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionCreateEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionDeleteEntity' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionDeleteEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionInvokeGetMethod' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionInvokeGetMethod.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionInvokeMethod' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionInvokeMethod.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionInvokePostMethod' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionInvokePostMethod.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionReadEntity' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionReadEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionType' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionType.php', + 'Office365\\PHP\\Client\\Runtime\\ClientActionUpdateEntity' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientActionUpdateEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ClientObject' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientObject.php', + 'Office365\\PHP\\Client\\Runtime\\ClientObjectCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientObjectCollection.php', + 'Office365\\PHP\\Client\\Runtime\\ClientRequest' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientRequest.php', + 'Office365\\PHP\\Client\\Runtime\\ClientResult' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientResult.php', + 'Office365\\PHP\\Client\\Runtime\\ClientRuntimeContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php', + 'Office365\\PHP\\Client\\Runtime\\ClientValueObject' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientValueObject.php', + 'Office365\\PHP\\Client\\Runtime\\ClientValueObjectCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ClientValueObjectCollection.php', + 'Office365\\PHP\\Client\\Runtime\\ContextWebInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ContextWebInformation.php', + 'Office365\\PHP\\Client\\Runtime\\FormatType' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/FormatType.php', + 'Office365\\PHP\\Client\\Runtime\\HttpMethod' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/HttpMethod.php', + 'Office365\\PHP\\Client\\Runtime\\KeyValue' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/KeyValue.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\AtomFormat' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/AtomFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\JsonFormat' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/JsonFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\JsonLightFormat' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/JsonLightFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\JsonPayloadSerializer' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/JsonPayloadSerializer.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataException' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataException.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataFormat' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataFormat.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataMetadataLevel' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataMetadataLevel.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPathParser' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataPathParser.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPayload' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataPayload.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPayloadKind' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataPayloadKind.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataPrimitiveTypeKind' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataPrimitiveTypeKind.php', + 'Office365\\PHP\\Client\\Runtime\\OData\\ODataQueryOptions' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OData/ODataQueryOptions.php', + 'Office365\\PHP\\Client\\Runtime\\Office365Version' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Office365Version.php', + 'Office365\\PHP\\Client\\Runtime\\OperationParameterCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/OperationParameterCollection.php', + 'Office365\\PHP\\Client\\Runtime\\RequestContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/RequestContext.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePath' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ResourcePath.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePathEntity' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ResourcePathEntity.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePathLink' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ResourcePathLink.php', + 'Office365\\PHP\\Client\\Runtime\\ResourcePathServiceOperation' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/ResourcePathServiceOperation.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\ClientCredential' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Utilities/ClientCredential.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\EnumType' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Utilities/EnumType.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\Guid' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Utilities/Guid.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\JsonConvert' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Utilities/JsonConvert.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\RequestOptions' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\Requests' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Utilities/Requests.php', + 'Office365\\PHP\\Client\\Runtime\\Utilities\\UserCredentials' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Utilities/UserCredentials.php', + 'Office365\\PHP\\Client\\SharePoint\\AddFieldOptions' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/AddFieldOptions.php', + 'Office365\\PHP\\Client\\SharePoint\\AppInstance' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/AppInstance.php', + 'Office365\\PHP\\Client\\SharePoint\\Attachment' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Attachment.php', + 'Office365\\PHP\\Client\\SharePoint\\AttachmentCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/AttachmentCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\AttachmentCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/AttachmentCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\BasePermissions' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/BasePermissions.php', + 'Office365\\PHP\\Client\\SharePoint\\CamlQuery' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/CamlQuery.php', + 'Office365\\PHP\\Client\\SharePoint\\Change' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Change.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeField' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeField.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeFile' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeFile.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeFolder' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeFolder.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeItem' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeItem.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeList' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeList.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeLogItemQuery' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeLogItemQuery.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeQuery' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeQuery.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeSite' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeSite.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeToken' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeToken.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeType.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeUser' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeUser.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeView' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeView.php', + 'Office365\\PHP\\Client\\SharePoint\\ChangeWeb' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ChangeWeb.php', + 'Office365\\PHP\\Client\\SharePoint\\CheckOutType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/CheckOutType.php', + 'Office365\\PHP\\Client\\SharePoint\\ClientContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ClientContext.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ContentType.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentTypeCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ContentTypeCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentTypeCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ContentTypeCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ContentTypeId' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ContentTypeId.php', + 'Office365\\PHP\\Client\\SharePoint\\CustomActionElement' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/CustomActionElement.php', + 'Office365\\PHP\\Client\\SharePoint\\CustomActionElementCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/CustomActionElementCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\DocumentSet\\DocumentSet' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/DocumentManagement/DocumentSet/DocumentSet.php', + 'Office365\\PHP\\Client\\SharePoint\\Field' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Field.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldCalculated' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldCalculated.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldChoice' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldChoice.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldComputed' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldComputed.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldDateTime' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldDateTime.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldGeolocation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldGeolocation.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldGeolocationValue' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldGeolocationValue.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldGuid' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldGuid.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldLookup' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldLookup.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldLookupValue' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldLookupValue.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldMultiChoice' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldMultiChoice.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldMultiLineText' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldMultiLineText.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldNumber' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldNumber.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldText' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldText.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldType.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUrl' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldUrl.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUrlValue' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldUrlValue.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUser' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldUser.php', + 'Office365\\PHP\\Client\\SharePoint\\FieldUserValue' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FieldUserValue.php', + 'Office365\\PHP\\Client\\SharePoint\\File' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/File.php', + 'Office365\\PHP\\Client\\SharePoint\\FileCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FileCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\FileCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FileCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\FileVersion' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FileVersion.php', + 'Office365\\PHP\\Client\\SharePoint\\FileVersionCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FileVersionCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Folder' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Folder.php', + 'Office365\\PHP\\Client\\SharePoint\\FolderCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/FolderCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Group' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Group.php', + 'Office365\\PHP\\Client\\SharePoint\\GroupCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/GroupCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\GroupCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/GroupCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\InformationRightsManagementSettings' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/InformationRightsManagementSettings.php', + 'Office365\\PHP\\Client\\SharePoint\\ListCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ListCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ListCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ListCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItem' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ListItem.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItemCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ListItemCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItemCollectionPosition' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ListItemCollectionPosition.php', + 'Office365\\PHP\\Client\\SharePoint\\ListItemCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ListItemCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ListTemplateType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ListTemplateType.php', + 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ObjectSharingInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingSettings' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ObjectSharingSettings.php', + 'Office365\\PHP\\Client\\SharePoint\\PermissionKind' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/PermissionKind.php', + 'Office365\\PHP\\Client\\SharePoint\\Principal' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Principal.php', + 'Office365\\PHP\\Client\\SharePoint\\PrincipalType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/PrincipalType.php', + 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItem' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RecycleBinItem.php', + 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItemCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RecycleBinItemCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleAssignment' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RoleAssignment.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleAssignmentCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RoleAssignmentCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleDefinition' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RoleDefinition.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleDefinitionCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RoleDefinitionCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\RoleDefinitionCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RoleDefinitionCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\SPList' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/SPList.php', + 'Office365\\PHP\\Client\\SharePoint\\SecurableObject' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/SecurableObject.php', + 'Office365\\PHP\\Client\\SharePoint\\Site' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Site.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialActor' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Social/SocialActor.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialRestActor' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Social/SocialRestActor.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialRestFeedManager' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Social/SocialRestFeedManager.php', + 'Office365\\PHP\\Client\\SharePoint\\Social\\SocialRestFollowingManager' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Social/SocialRestFollowingManager.php', + 'Office365\\PHP\\Client\\SharePoint\\Taxonomy\\TaxonomyField' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Taxonomy/TaxonomyField.php', + 'Office365\\PHP\\Client\\SharePoint\\Taxonomy\\TaxonomySession' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Taxonomy/TaxonomySession.php', + 'Office365\\PHP\\Client\\SharePoint\\TemplateFileType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/TemplateFileType.php', + 'Office365\\PHP\\Client\\SharePoint\\User' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/User.php', + 'Office365\\PHP\\Client\\SharePoint\\UserCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\UserCustomAction' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserCustomAction.php', + 'Office365\\PHP\\Client\\SharePoint\\UserCustomActionCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserCustomActionCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\UserIdInfo' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserIdInfo.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\PeopleManager' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserProfiles/PeopleManager.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\PersonProperties' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserProfiles/PersonProperties.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\PersonPropertiesCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserProfiles/PersonPropertiesCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\ProfileLoader' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserProfiles/ProfileLoader.php', + 'Office365\\PHP\\Client\\SharePoint\\UserProfiles\\UserProfile' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/UserProfiles/UserProfile.php', + 'Office365\\PHP\\Client\\SharePoint\\Utilities\\Utility' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Utilities/Utility.php', + 'Office365\\PHP\\Client\\SharePoint\\View' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/View.php', + 'Office365\\PHP\\Client\\SharePoint\\ViewCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ViewCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\ViewCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ViewCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\ViewFieldCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ViewFieldCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Web' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Web.php', + 'Office365\\PHP\\Client\\SharePoint\\WebCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/WebCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\WebCreationInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/WebCreationInformation.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\LimitedWebPartManager' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/WebParts/LimitedWebPartManager.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\PersonalizationScope' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/WebParts/PersonalizationScope.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\WebPart' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/WebParts/WebPart.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\WebPartDefinition' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinition.php', + 'Office365\\PHP\\Client\\SharePoint\\WebParts\\WebPartDefinitionCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinitionCollection.php', ); public static function getInitializer(ClassLoader $loader) diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index cb2e12618ab74..0f2475d0fe83a 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -92,19 +92,19 @@ "source": { "type": "git", "url": "https://github.com/vgrem/phpSPO.git", - "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b" + "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/68413b42ff18c96a3a4e097b47c905eeab30305b", - "reference": "68413b42ff18c96a3a4e097b47c905eeab30305b", + "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/59a2956f94f694592e3d3c6252f0e753f73a1686", + "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686", "shasum": "" }, "require": { "ext-curl": "*", "php": ">=5.4" }, - "time": "2016-11-22 15:34:47", + "time": "2017-02-22T10:52:00+00:00", "type": "library", "installation-source": "source", "autoload": { diff --git a/apps/files_external/3rdparty/vgrem/php-spo b/apps/files_external/3rdparty/vgrem/php-spo index 68413b42ff18c..59a2956f94f69 160000 --- a/apps/files_external/3rdparty/vgrem/php-spo +++ b/apps/files_external/3rdparty/vgrem/php-spo @@ -1 +1 @@ -Subproject commit 68413b42ff18c96a3a4e097b47c905eeab30305b +Subproject commit 59a2956f94f694592e3d3c6252f0e753f73a1686 From 9be6573016ab8dff3e7a3c59e14fe80c929a16ae Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Sat, 11 Mar 2017 01:38:58 +0100 Subject: [PATCH 10/32] first testing and fixes * use NTLM Login only for now * fix fetching Document Library * fix retrieve root folder info Signed-off-by: Arthur Schiwon --- .../lib/Lib/Storage/SharePoint.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 0506735f7a436..5f55a09aaf00b 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -131,10 +131,15 @@ public function stat($path) { $this->ensureConnection(); $path = trim($path, '/'); + $sizeProperty = 'Length'; if($path === '/' || $path === '') { - $fsObject = $this->getDocumentLibrary()->getRootFolder(); - $properties = $fsObject->getProperties(); // TODO: see what we retrieve here + $sizeProperty = 'ItemCount'; // FIXME: temporary, since SP does not return a size for folders + $docLib = $this->getDocumentLibrary(); + $fsObject = $docLib->getRootFolder(); // TODO: save one line, now it's easier for debugging + $this->context->load($fsObject, ['Length', 'TimeLastModified', 'ItemCount']); + $this->context->executeQuery(); + $properties = $fsObject->getProperties(); // FIXME: dev shortcut, remove when not needed anymore } else { // TODO: verify that try-catch approach works try { @@ -148,7 +153,7 @@ public function stat($path) { // FIXME: Folder does not have such properties, according to doc – traversing through all files needed $stat = [ // int64, size in bytes, excluding the size of any Web Parts that are used in the file. - 'size' => $fsObject->getProperty('Length'), + 'size' => $fsObject->getProperty($sizeProperty), 'mtime' => $fsObject->getProperty('TimeLastModified'), // no property in SP 2013, other storages do the same :speak_no_evil: 'atime' => time(), @@ -276,7 +281,7 @@ private function getDocumentLibrary() { return $this->documentLibraryItem; } - $lists = $this->context->getWeb()->getLists()->filter('Title eq "' . $this->documentLibrary . '"')->top(1); + $lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibrary . '\'')->top(1); $this->context->load($lists)->executeQuery(); if ($lists->getCount() == 1) { $this->documentLibraryItem = $lists->getData()[0]; @@ -318,6 +323,11 @@ private function ensureConnection() { throw new \InvalidArgumentException('No password given'); } $authContext = $this->contextsFactory->getAuthContext($this->authUser, $this->authPwd); + $authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow… $this->context = $this->contextsFactory->getClientContext($this->server, $authContext); + # Auth is not triggered yet. This will happen when something is requested from Sharepoint (on demand), e.g.: + #$site = $this->context->getSite(); + #$this->context->load($site); + #$this->context->executeQuery(); } } From 2991f39781e1e3da0ade3b463a5db8947e17bb6c Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 13 Mar 2017 12:47:45 +0100 Subject: [PATCH 11/32] polish stat() Signed-off-by: Arthur Schiwon --- .../lib/Lib/Storage/SharePoint.php | 90 ++++++++++++------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 5f55a09aaf00b..61d9f2bb5a6e3 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -26,24 +26,36 @@ use OC\Files\Storage\Common; use OCA\Files_External\Lib\SharePoint\ContextsFactory; use OCA\Files_External\Lib\SharePoint\NotFoundException; +use OCP\Files\FileInfo; +use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; +use Office365\PHP\Client\Runtime\ClientObject; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; use Office365\PHP\Client\SharePoint\SPList; class SharePoint extends Common { + const SP_PROPERTY_SIZE = 'Length'; + const SP_PROPERTY_MTIME = 'TimeLastModified'; + /** @var string */ protected $server; + /** @var string */ protected $documentLibrary; /** @var SPList */ protected $documentLibraryItem; + /** @var string */ protected $authUser; + /** @var string */ protected $authPwd; + /** @var AuthenticationContext */ + protected $authContext; + /** @var ClientContext */ protected $context; @@ -131,35 +143,21 @@ public function stat($path) { $this->ensureConnection(); $path = trim($path, '/'); - $sizeProperty = 'Length'; - - if($path === '/' || $path === '') { - $sizeProperty = 'ItemCount'; // FIXME: temporary, since SP does not return a size for folders - $docLib = $this->getDocumentLibrary(); - $fsObject = $docLib->getRootFolder(); // TODO: save one line, now it's easier for debugging - $this->context->load($fsObject, ['Length', 'TimeLastModified', 'ItemCount']); - $this->context->executeQuery(); - $properties = $fsObject->getProperties(); // FIXME: dev shortcut, remove when not needed anymore - } else { - // TODO: verify that try-catch approach works - try { - $fsObject = $this->fetchFileOrFolder($path, true); // likely we need to modify path since we are not operating on the document library - } catch (\Exception $e) { - // it can be a folder, too - $fsObject = $this->fetchFileOrFolder($path, false); - } + $serverUrl = '/' . $this->documentLibrary; + if($path !== '') { + $serverUrl .= '/' . $path; } - // FIXME: getProperty may return null - // FIXME: Folder does not have such properties, according to doc – traversing through all files needed + + $file = $this->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); $stat = [ // int64, size in bytes, excluding the size of any Web Parts that are used in the file. - 'size' => $fsObject->getProperty($sizeProperty), - 'mtime' => $fsObject->getProperty('TimeLastModified'), - // no property in SP 2013, other storages do the same :speak_no_evil: + 'size' => $file->getProperty(self::SP_PROPERTY_SIZE) ?: FileInfo::SPACE_UNKNOWN, + 'mtime' => $file->getProperty(self::SP_PROPERTY_MTIME), + // no property in SP 2013 & 2016, other storages do the same :speak_no_evil: 'atime' => time(), ]; - if(isset($stat) && !is_null($stat['size']) && !is_null($stat['mtime'])) { + if(!is_null($stat['mtime'])) { return $stat; } @@ -170,17 +168,40 @@ public function stat($path) { /** * @param string $path + * @param array $properties * @param bool $tryFile * @return File|Folder + * @throws \Exception */ - private function fetchFileOrFolder($path, $tryFile) { + private function fetchFileOrFolder($path, array $properties = null, $tryFile = true) { if($tryFile) { - return $this->context->getWeb()->getFileByServerRelativeUrl($path); + try { + $file = $this->context->getWeb()->getFileByServerRelativeUrl($path); + $this->loadAndExecute($file, $properties); + return $file; + } catch (\Exception $e) { + if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1) { + throw $e; + } + $this->createClientContext(); // otherwise the old query will be repeated + return $this->fetchFolder($path, $properties); + } } else { - return $this->context->getWeb()->getFolderByServerRelativeUrl($path); + return $this->fetchFolder($path, $properties); } } + private function fetchFolder($relativeServerPath, array $properties = null) { + $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); + $this->loadAndExecute($folder, $properties); + return $folder; + } + + private function loadAndExecute(ClientObject $object, array $properties = null) { + $this->context->load($object, $properties); + $this->context->executeQuery(); + } + /** * see http://php.net/manual/en/function.filetype.php * @@ -322,12 +343,17 @@ private function ensureConnection() { if(!is_string($this->authPwd) || empty($this->authPwd)) { throw new \InvalidArgumentException('No password given'); } - $authContext = $this->contextsFactory->getAuthContext($this->authUser, $this->authPwd); - $authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow… - $this->context = $this->contextsFactory->getClientContext($this->server, $authContext); + $this->authContext = $this->contextsFactory->getAuthContext($this->authUser, $this->authPwd); + $this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow… + $this->createClientContext(); # Auth is not triggered yet. This will happen when something is requested from Sharepoint (on demand), e.g.: - #$site = $this->context->getSite(); - #$this->context->load($site); - #$this->context->executeQuery(); + } + + /** + * (re)creates the sharepoint client context + */ + private function createClientContext() { + $this->context = null; + $this->context = $this->contextsFactory->getClientContext($this->server, $this->authContext); } } From 61298bf646abc11edd3a8da056fc5c92850539c8 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 14 Mar 2017 12:06:49 +0100 Subject: [PATCH 12/32] rework file_type() and file_exists() also simplifies and improves internal fetchFileOrFolder method Signed-off-by: Arthur Schiwon --- .../lib/Lib/Storage/SharePoint.php | 102 +++++++++++------- 1 file changed, 64 insertions(+), 38 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 61d9f2bb5a6e3..afb8556c0512c 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -80,6 +80,7 @@ public function __construct($parameters) { $this->authPwd = $parameters['password']; $this->fixDI($parameters); + $this->ensureConnection(); } /** @@ -140,14 +141,7 @@ public function opendir($path) { * @since 6.0.0 */ public function stat($path) { - $this->ensureConnection(); - - $path = trim($path, '/'); - $serverUrl = '/' . $this->documentLibrary; - if($path !== '') { - $serverUrl .= '/' . $path; - } - + $serverUrl = $this->formatPath($path); $file = $this->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); $stat = [ // int64, size in bytes, excluding the size of any Web Parts that are used in the file. @@ -169,26 +163,37 @@ public function stat($path) { /** * @param string $path * @param array $properties - * @param bool $tryFile * @return File|Folder * @throws \Exception */ - private function fetchFileOrFolder($path, array $properties = null, $tryFile = true) { - if($tryFile) { - try { - $file = $this->context->getWeb()->getFileByServerRelativeUrl($path); - $this->loadAndExecute($file, $properties); - return $file; - } catch (\Exception $e) { - if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1) { - throw $e; - } - $this->createClientContext(); // otherwise the old query will be repeated - return $this->fetchFolder($path, $properties); + private function fetchFileOrFolder($path, array $properties = null) { + # room for optimization: if "." present in path, try file first, + # otherwise folder + + # Attempt 1: fetch a file + try { + $file = $this->context->getWeb()->getFileByServerRelativeUrl($path); + $this->loadAndExecute($file, $properties); + return $file; + } catch (\Exception $e) { + if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1) { + # Unexpected Exception, pass it on + throw $e; } - } else { + } + + # Attempt 2: fetch a folder + try { + $this->createClientContext(); // otherwise the old query will be repeated return $this->fetchFolder($path, $properties); + } catch (\Exception $e) { + if($e->getMessage() !== 'Unknown Error') { // yes, SP returns this + throw $e; + } } + + # Nothing succeeded, quit with not found + throw new NotFoundException('File or Folder not found'); } private function fetchFolder($relativeServerPath, array $properties = null) { @@ -206,26 +211,24 @@ private function loadAndExecute(ClientObject $object, array $properties = null) * see http://php.net/manual/en/function.filetype.php * * @param string $path - * @return string|false + * @return false|string + * @throws \Exception * @since 6.0.0 */ public function filetype($path) { - $path = trim($path); - if($path === '/' || $path === '') { - return 'dir'; - } try { - $this->fetchFileOrFolder($path, true); + $serverUrl = $this->formatPath($path); + $object = $this->fetchFileOrFolder($serverUrl, []); + } catch (NotFoundException $e) { + return false; + } + if($object instanceof File) { return 'file'; - } catch(\Exception $e) { - try { - $this->fetchFileOrFolder($path, false); - return 'dir'; - } catch (\Exception $e) { - // NOOP - } + } else if($object instanceof Folder) { + return 'dir'; + } else { + return false; } - return false; } /** @@ -236,10 +239,17 @@ public function filetype($path) { * @since 6.0.0 */ public function file_exists($path) { - if($this->filetype($path) === false) { + try { + $serverUrl = $this->formatPath($path); + // alternative approach is to use a CAML query instead of querying + // for file and folder. It is not necessarily faster, though. + // Would need evaluation of typical use cases (I assume most often + // exisiting files are checked) and measurements. + $this->fetchFileOrFolder($serverUrl); + return true; + } catch (NotFoundException $e) { return false; } - return true; } /** @@ -356,4 +366,20 @@ private function createClientContext() { $this->context = null; $this->context = $this->contextsFactory->getClientContext($this->server, $this->authContext); } + + /** + * creates the relative server "url" out of the provided path + * + * @param $path + * @return string + */ + private function formatPath($path) { + $path = trim($path, '/'); + $serverUrl = '/' . $this->documentLibrary; + if($path !== '') { + $serverUrl .= '/' . $path; + } + return $serverUrl; + } + } From 89d48f8072bb8c39d6123266f82daa82a68e2b57 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 15 Mar 2017 14:09:07 +0100 Subject: [PATCH 13/32] Split SharePoint Backend in two classes * seperates direct backend code and API handling * an awful lot easier to unit test Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 162 ++++++++++++++ .../SharePoint/SharePointClientFactory.php | 42 ++++ .../lib/Lib/Storage/SharePoint.php | 142 +++---------- .../tests/SharePoint/SharePointClientTest.php | 186 ++++++++++++++++ .../tests/Storage/SharePointTest.php | 199 ++++++++++++------ 5 files changed, 557 insertions(+), 174 deletions(-) create mode 100644 apps/files_external/lib/Lib/SharePoint/SharePointClient.php create mode 100644 apps/files_external/lib/Lib/SharePoint/SharePointClientFactory.php create mode 100644 apps/files_external/tests/SharePoint/SharePointClientTest.php diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php new file mode 100644 index 0000000000000..d27779c157823 --- /dev/null +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -0,0 +1,162 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Lib\SharePoint; + + +use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; +use Office365\PHP\Client\Runtime\ClientObject; +use Office365\PHP\Client\SharePoint\ClientContext; +use Office365\PHP\Client\SharePoint\File; +use Office365\PHP\Client\SharePoint\Folder; +use Office365\PHP\Client\SharePoint\SPList; + +class SharePointClient { + /** @var ClientContext */ + protected $context; + + /** @var AuthenticationContext */ + protected $authContext; + + /** @var SPList */ + protected $documentLibrary; + + /** @var ContextsFactory */ + private $contextsFactory; + + /** @var string */ + private $sharePointUrl; + + /** @var string[] */ + private $credentials; + + /** @var string */ + private $documentLibraryTitle; + + public function __construct(ContextsFactory $contextsFactory, $sharePointUrl, array $credentials, $documentLibraryTitle) { + $this->contextsFactory = $contextsFactory; + $this->sharePointUrl = $sharePointUrl; + $this->credentials = $credentials; + $this->documentLibraryTitle = $documentLibraryTitle; + } + + /** + * @param string $path + * @param array $properties + * @return File|Folder + * @throws \Exception + */ + public function fetchFileOrFolder($path, array $properties = null) { + $this->ensureConnection(); + + # room for optimization: if "." present in path, try file first, + # otherwise folder + + # Attempt 1: fetch a file + try { + $file = $this->context->getWeb()->getFileByServerRelativeUrl($path); + $this->loadAndExecute($file, $properties); + return $file; + } catch (\Exception $e) { + if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1) { + # Unexpected Exception, pass it on + throw $e; + } + } + + # Attempt 2: fetch a folder + try { + $this->createClientContext(); // otherwise the old query will be repeated + return $this->fetchFolder($path, $properties); + } catch (\Exception $e) { + if($e->getMessage() !== 'Unknown Error') { // yes, SP returns this + throw $e; + } + } + + # Nothing succeeded, quit with not found + $this->createClientContext(); // otherwise the old query will be repeated + throw new NotFoundException('File or Folder not found'); + } + + public function fetchFolder($relativeServerPath, array $properties = null) { + $this->ensureConnection(); + $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); + $this->loadAndExecute($folder, $properties); + return $folder; + } + + private function loadAndExecute(ClientObject $object, array $properties = null) { + $this->context->load($object, $properties); + $this->context->executeQuery(); + } + + /** + * @return SPList + * @throws NotFoundException + */ + private function getDocumentLibrary() { + if(!is_null($this->documentLibrary)) { + return $this->documentLibrary; + } + + $lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibraryTitle . '\'')->top(1); + $this->context->load($lists)->executeQuery(); + if ($lists->getCount() === 1 && $lists->getData()[0] instanceof SPList) { + $this->documentLibrary = $lists->getData()[0]; + return $this->documentLibrary; + } + + throw new NotFoundException('List not found'); + } + + /** + * Set up necessary contexts for authentication and access to SharePoint + * + * @throws \InvalidArgumentException + */ + private function ensureConnection() { + if($this->context instanceof ClientContext) { + return; + } + + if(!is_string($this->credentials['user']) || empty($this->credentials['user'])) { + throw new \InvalidArgumentException('No user given'); + } + if(!is_string($this->credentials['password']) || empty($this->credentials['password'])) { + throw new \InvalidArgumentException('No password given'); + } + $this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']); + $this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow… + $this->createClientContext(); + # Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand), e.g.: + } + + /** + * (re)creates the sharepoint client context + */ + private function createClientContext() { + $this->context = null; + $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext); + } +} diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClientFactory.php b/apps/files_external/lib/Lib/SharePoint/SharePointClientFactory.php new file mode 100644 index 0000000000000..60ccd18d72d6b --- /dev/null +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClientFactory.php @@ -0,0 +1,42 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Lib\SharePoint; + +class SharePointClientFactory { + /** + * @param ContextsFactory $contextsFactory + * @param string $sharePointUrl + * @param array $credentials + * @param string $documentLibraryTitle + * @return SharePointClient + */ + public function getClient( + ContextsFactory $contextsFactory, + $sharePointUrl, + array $credentials, + $documentLibraryTitle) + { + return new SharePointClient($contextsFactory, $sharePointUrl, $credentials, $documentLibraryTitle); + } +} diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index afb8556c0512c..31e71b3c3ab7d 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -26,13 +26,11 @@ use OC\Files\Storage\Common; use OCA\Files_External\Lib\SharePoint\ContextsFactory; use OCA\Files_External\Lib\SharePoint\NotFoundException; +use OCA\Files_External\Lib\SharePoint\SharePointClient; +use OCA\Files_External\Lib\SharePoint\SharePointClientFactory; use OCP\Files\FileInfo; -use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; -use Office365\PHP\Client\Runtime\ClientObject; -use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; -use Office365\PHP\Client\SharePoint\SPList; class SharePoint extends Common { const SP_PROPERTY_SIZE = 'Length'; @@ -44,23 +42,17 @@ class SharePoint extends Common { /** @var string */ protected $documentLibrary; - /** @var SPList */ - protected $documentLibraryItem; - /** @var string */ protected $authUser; /** @var string */ protected $authPwd; - /** @var AuthenticationContext */ - protected $authContext; - - /** @var ClientContext */ - protected $context; + /** @var SharePointClient */ + protected $spClient; - /** @var ContextsFactory */ - protected $contextsFactory; + /** @var ContextsFactory */ + private $contextsFactory; public function __construct($parameters) { $this->server = $parameters['host']; @@ -80,7 +72,6 @@ public function __construct($parameters) { $this->authPwd = $parameters['password']; $this->fixDI($parameters); - $this->ensureConnection(); } /** @@ -142,7 +133,11 @@ public function opendir($path) { */ public function stat($path) { $serverUrl = $this->formatPath($path); - $file = $this->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); + try { + $file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); + } catch (\Exception $e) { + return false; + } $stat = [ // int64, size in bytes, excluding the size of any Web Parts that are used in the file. 'size' => $file->getProperty(self::SP_PROPERTY_SIZE) ?: FileInfo::SPACE_UNKNOWN, @@ -155,58 +150,11 @@ public function stat($path) { return $stat; } - // If we do not get a size or mtime from SP, we treat it as an error + // If we do not get a mtime from SP, we treat it as an error // thus returning false, according to PHP documentation on stat() return false; } - /** - * @param string $path - * @param array $properties - * @return File|Folder - * @throws \Exception - */ - private function fetchFileOrFolder($path, array $properties = null) { - # room for optimization: if "." present in path, try file first, - # otherwise folder - - # Attempt 1: fetch a file - try { - $file = $this->context->getWeb()->getFileByServerRelativeUrl($path); - $this->loadAndExecute($file, $properties); - return $file; - } catch (\Exception $e) { - if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1) { - # Unexpected Exception, pass it on - throw $e; - } - } - - # Attempt 2: fetch a folder - try { - $this->createClientContext(); // otherwise the old query will be repeated - return $this->fetchFolder($path, $properties); - } catch (\Exception $e) { - if($e->getMessage() !== 'Unknown Error') { // yes, SP returns this - throw $e; - } - } - - # Nothing succeeded, quit with not found - throw new NotFoundException('File or Folder not found'); - } - - private function fetchFolder($relativeServerPath, array $properties = null) { - $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); - $this->loadAndExecute($folder, $properties); - return $folder; - } - - private function loadAndExecute(ClientObject $object, array $properties = null) { - $this->context->load($object, $properties); - $this->context->executeQuery(); - } - /** * see http://php.net/manual/en/function.filetype.php * @@ -218,7 +166,7 @@ private function loadAndExecute(ClientObject $object, array $properties = null) public function filetype($path) { try { $serverUrl = $this->formatPath($path); - $object = $this->fetchFileOrFolder($serverUrl, []); + $object = $this->spClient->fetchFileOrFolder($serverUrl, []); } catch (NotFoundException $e) { return false; } @@ -244,8 +192,8 @@ public function file_exists($path) { // alternative approach is to use a CAML query instead of querying // for file and folder. It is not necessarily faster, though. // Would need evaluation of typical use cases (I assume most often - // exisiting files are checked) and measurements. - $this->fetchFileOrFolder($serverUrl); + // existing files are checked) and measurements. + $this->spClient->fetchFileOrFolder($serverUrl, []); return true; } catch (NotFoundException $e) { return false; @@ -266,7 +214,7 @@ public function unlink($path) { } foreach([true, false] as $asFile) { try { - $fsObject = $this->fetchFileOrFolder($path, $asFile); + $fsObject = $this->spClient->fetchFileOrFolder($path, $asFile); $fsObject->deleteObject(); return true; } catch(\Exception $e) { @@ -303,24 +251,6 @@ public function touch($path, $mtime = null) { return true; } - /** - * @return SPList - * @throws NotFoundException - */ - private function getDocumentLibrary() { - if(!is_null($this->documentLibraryItem)) { - return $this->documentLibraryItem; - } - - $lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibrary . '\'')->top(1); - $this->context->load($lists)->executeQuery(); - if ($lists->getCount() == 1) { - $this->documentLibraryItem = $lists->getData()[0]; - return $this->documentLibraryItem; - } - - throw new NotFoundException('List not found'); - } /** * work around dependency injection issues so we can test this class properly @@ -335,36 +265,20 @@ private function fixDI(array $parameters) { } else { $this->contextsFactory = new ContextsFactory(); } - } - /** - * Set up necessary contexts for authentication and access to SharePoint - * - * @throws \InvalidArgumentException - */ - private function ensureConnection() { - if($this->context instanceof ClientContext) { - return; - } - - if(!is_string($this->authUser) || empty($this->authUser)) { - throw new \InvalidArgumentException('No user given'); - } - if(!is_string($this->authPwd) || empty($this->authPwd)) { - throw new \InvalidArgumentException('No password given'); + if(isset($parameters['sharePointClientFactory']) + && $parameters['sharePointClientFactory'] instanceof SharePointClientFactory) + { + $spcFactory = $parameters['sharePointClientFactory']; + } else { + $spcFactory = new SharePointClientFactory(); } - $this->authContext = $this->contextsFactory->getAuthContext($this->authUser, $this->authPwd); - $this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow… - $this->createClientContext(); - # Auth is not triggered yet. This will happen when something is requested from Sharepoint (on demand), e.g.: - } - - /** - * (re)creates the sharepoint client context - */ - private function createClientContext() { - $this->context = null; - $this->context = $this->contextsFactory->getClientContext($this->server, $this->authContext); + $this->spClient = $spcFactory->getClient( + $this->contextsFactory, + $this->server, + [ 'user' => $this->authUser, 'password' => $this->authPwd], + $this->documentLibrary + ); } /** diff --git a/apps/files_external/tests/SharePoint/SharePointClientTest.php b/apps/files_external/tests/SharePoint/SharePointClientTest.php new file mode 100644 index 0000000000000..9cf37fed55eaa --- /dev/null +++ b/apps/files_external/tests/SharePoint/SharePointClientTest.php @@ -0,0 +1,186 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Files_External\Tests\SharePoint; + + +use OCA\Files_External\Lib\SharePoint\ContextsFactory; +use OCA\Files_External\Lib\SharePoint\NotFoundException; +use OCA\Files_External\Lib\SharePoint\SharePointClient; +use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; +use Office365\PHP\Client\SharePoint\ClientContext; +use Office365\PHP\Client\SharePoint\File; +use Office365\PHP\Client\SharePoint\Folder; +use Office365\PHP\Client\SharePoint\Web; +use Test\TestCase; + +class SharePointClientTest extends TestCase { + /** @var ContextsFactory|\PHPUnit_Framework_MockObject_MockObject */ + protected $contextsFactory; + + /** @var string */ + protected $documentLibraryTitle; + + /** @var SharePointClient */ + protected $client; + + public function setUp() { + parent::setUp(); + + $this->contextsFactory = $this->createMock(ContextsFactory::class); + $credentials = ['user' => 'foobar', 'password' => 'barfoo']; + $this->documentLibraryTitle = 'Our Docs'; + + $this->client = new SharePointClient( + $this->contextsFactory, + 'my.sp.server', + $credentials, + $this->documentLibraryTitle + ); + } + + public function testFetchFileByFileOrFolder() { + $path = '/' . $this->documentLibraryTitle . '/OurFile.txt'; + $properties = ['Length', 'TimeLastModified']; + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); + + $fileMock = $this->createMock(File::class); + + $webMock = $this->createMock(Web::class); + $webMock->expects($this->once()) + ->method('getFileByServerRelativeUrl') + ->with($path) + ->willReturn($fileMock); + + $clientContextMock = $this->createMock(ClientContext::class); + $clientContextMock->expects($this->once()) + ->method('getWeb') + ->willReturn($webMock); + $clientContextMock->expects($this->once()) + ->method('load') + ->with($fileMock, $properties); + $clientContextMock->expects($this->once()) + ->method('executeQuery'); + + $this->contextsFactory->expects($this->once()) + ->method('getClientContext') + ->willReturn($clientContextMock); + + $fileObject = $this->client->fetchFileOrFolder($path, $properties); + $this->assertSame($fileMock, $fileObject); + } + + public function testFetchFolderByFileOrFolder() { + $path = '/' . $this->documentLibraryTitle . '/Our Directory'; + $properties = ['Length', 'TimeLastModified']; + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); + + $fileMock = $this->createMock(File::class); + $folderMock = $this->createMock(Folder::class); + + $webMock = $this->createMock(Web::class); + $webMock->expects($this->once()) + ->method('getFileByServerRelativeUrl') + ->with($path) + ->willReturn($fileMock); + $webMock->expects($this->once()) + ->method('getFolderByServerRelativeUrl') + ->with($path) + ->willReturn($folderMock); + + $clientContextMock = $this->createMock(ClientContext::class); + $clientContextMock->expects($this->exactly(2)) + ->method('getWeb') + ->willReturn($webMock); + $clientContextMock->expects($this->exactly(2)) + ->method('load') + ->withConsecutive([$fileMock, $properties], [$folderMock, $properties]); + $clientContextMock->expects($this->at(2)) + ->method('executeQuery') + ->willThrowException(new \Exception('The file /whatwasitsname does not exist.')); + $clientContextMock->expects($this->at(5)) + ->method('executeQuery'); + + + $this->contextsFactory->expects($this->exactly(2)) + ->method('getClientContext') + ->willReturn($clientContextMock); + + $folderObject = $this->client->fetchFileOrFolder($path, $properties); + $this->assertSame($folderMock, $folderObject); + } + + /** + * @expectedException \OCA\Files_External\Lib\SharePoint\NotFoundException + * + * also fully covers fetchFolder(), loadAndExecute(), createClientContext() + */ + public function testFetchNotExistingByFileOrFolder() { + $path = '/' . $this->documentLibraryTitle . '/Our Directory/not-here.pdf'; + $properties = ['Length', 'TimeLastModified']; + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); + + $fileMock = $this->createMock(File::class); + $folderMock = $this->createMock(Folder::class); + + $webMock = $this->createMock(Web::class); + $webMock->expects($this->once()) + ->method('getFileByServerRelativeUrl') + ->with($path) + ->willReturn($fileMock); + $webMock->expects($this->once()) + ->method('getFolderByServerRelativeUrl') + ->with($path) + ->willReturn($folderMock); + + $clientContextMock = $this->createMock(ClientContext::class); + $clientContextMock->expects($this->exactly(2)) + ->method('getWeb') + ->willReturn($webMock); + $clientContextMock->expects($this->exactly(2)) + ->method('load') + ->withConsecutive([$fileMock, $properties], [$folderMock, $properties]); + $clientContextMock->expects($this->at(2)) + ->method('executeQuery') + ->willThrowException(new \Exception('The file /whatwasitsname does not exist.')); + $clientContextMock->expects($this->at(5)) + ->method('executeQuery') + ->willThrowException(new \Exception('Unknown Error')); + + + $this->contextsFactory->expects($this->exactly(3)) + ->method('getClientContext') + ->willReturn($clientContextMock); + + $this->client->fetchFileOrFolder($path, $properties); + } +} diff --git a/apps/files_external/tests/Storage/SharePointTest.php b/apps/files_external/tests/Storage/SharePointTest.php index a9165d16134c9..92b70f0b1051a 100644 --- a/apps/files_external/tests/Storage/SharePointTest.php +++ b/apps/files_external/tests/Storage/SharePointTest.php @@ -23,15 +23,17 @@ namespace OCA\Files_External\Tests\Storage; +use OCA\Files_External\Lib\SharePoint\NotFoundException; +use OCP\Files\FileInfo; use OCA\Files_External\Lib\SharePoint\ContextsFactory; +use OCA\Files_External\Lib\SharePoint\SharePointClient; +use OCA\Files_External\Lib\SharePoint\SharePointClientFactory; use OCA\Files_External\Lib\Storage\SharePoint; use Office365\PHP\Client\Runtime\Auth\IAuthenticationContext; -use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\SharePoint\ClientContext; +use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; -use Office365\PHP\Client\SharePoint\ListCollection; use Office365\PHP\Client\SharePoint\SPList; -use Office365\PHP\Client\SharePoint\Web; use Test\TestCase; class SharePointTest extends TestCase { @@ -46,7 +48,7 @@ class SharePointTest extends TestCase { protected $clientContextMock; /** @var string */ - protected $documentLibraryName = 'Fancy Documents'; + protected $documentLibraryTitle = 'Fancy Documents'; /** @var SPList|\PHPUnit_Framework_MockObject_MockObject */ protected $sharePointList; @@ -60,17 +62,30 @@ class SharePointTest extends TestCase { /** @var string */ protected $examplePwd = 'a123456'; + /** @var SharePointClientFactory|\PHPUnit_Framework_MockObject_MockObject */ + protected $clientFactory; + + /** @var SharePointClient|\PHPUnit_Framework_MockObject_MockObject */ + protected $client; + public function setUp() { parent::setUp(); $this->factory = $this->createMock(ContextsFactory::class); + $this->clientFactory = $this->createMock(SharePointClientFactory::class); + $this->client = $this->createMock(SharePointClient::class); + + $this->clientFactory->expects($this->any()) + ->method('getClient') + ->willReturn($this->client); $parameters = [ - 'host' => $this->exampleHost, - 'documentLibrary' => $this->documentLibraryName, - 'user' => $this->exampleUser, - 'password' => $this->examplePwd, - 'contextFactory' => $this->factory, + 'host' => $this->exampleHost, + 'documentLibrary' => $this->documentLibraryTitle, + 'user' => $this->exampleUser, + 'password' => $this->examplePwd, + 'contextFactory' => $this->factory, + 'sharePointClientFactory' => $this->clientFactory, ]; $this->storage = new SharePoint($parameters); @@ -88,48 +103,7 @@ private function prepareFactoryMocks() { ->method('getClientContext') ->with($this->exampleHost, $authContextMock) ->willReturn($this->clientContextMock); - } - /** - * prepare Mocks for SharePoint::getDocumentLibrary() call - */ - private function prepareMockForGetDocumentLibrary() { - $this->prepareFactoryMocks(); // precondition - - $this->sharePointList = $this->createMock(SPList::class); - - $clientObjectCollectionMock = $this->createMock(ClientObjectCollection::class); - $clientObjectCollectionMock->expects($this->once()) - ->method('top') - ->with(1) - ->willReturnSelf(); - $clientObjectCollectionMock->expects($this->once()) - ->method('getCount') - ->willReturn(1); - $clientObjectCollectionMock->expects($this->once()) - ->method('getData') - ->willReturn([$this->sharePointList]); - - $listCollectionMock = $this->createMock(ListCollection::class); - $listCollectionMock->expects($this->once()) - ->method('filter') - ->with('Title eq "' . $this->documentLibraryName . '"') - ->willReturn($clientObjectCollectionMock); - - $webMock = $this->createMock(Web::class); - $webMock->expects($this->once()) - ->method('getLists') - ->willReturn($listCollectionMock); - - $this->clientContextMock->expects($this->once()) - ->method('getWeb') - ->willReturn($webMock); - $this->clientContextMock->expects($this->once()) - ->method('load') - ->with($clientObjectCollectionMock) - ->willReturnSelf(); - $this->clientContextMock->expects($this->once()) - ->method('executeQuery'); } /** @@ -146,27 +120,132 @@ public function testBadDocumentLibraryName() { new SharePoint($parameters); } - public function testStat() { - $this->prepareMockForGetDocumentLibrary(); + public function pathProvider() { + return [ + ['/', null], + ['', null], + ['Paperwork', null], + ['Paperwork/', null], + ['/Paperwork/', null], + ['My Documents', null], + ['Paperwork/This and That/Bills/', null], + ['Textfile.txt', 26624], + ['Paperwork/Letter Template.ott', 26624], + ['Paperwork/This and That/Foobar.ora', 26624], + ]; + } + /** + * @dataProvider pathProvider + */ + public function testStatExisting($path, $returnSize) { $mtime = new \DateTime('yesterday'); - $size = 4096; + $size = $returnSize ?: FileInfo::SPACE_UNKNOWN; $folderMock = $this->createMock(Folder::class); $folderMock->expects($this->exactly(2)) ->method('getProperty') ->withConsecutive(['Length'], ['TimeLastModified']) - ->willReturnOnConsecutiveCalls($size, $mtime); + ->willReturnOnConsecutiveCalls($returnSize, $mtime); - $this->sharePointList->expects($this->once()) - ->method('getRootFolder') + $serverPath = '/' . $this->documentLibraryTitle; + if(trim($path, '/') !== '') { + $serverPath .= '/' . trim($path, '/'); + } + + $this->client->expects($this->once()) + ->method('fetchFileOrFolder') + ->with($serverPath, [SharePoint::SP_PROPERTY_SIZE, SharePoint::SP_PROPERTY_MTIME]) ->willReturn($folderMock); - $rootData = $this->storage->stat('/'); + $data = $this->storage->stat($path); + + $this->assertSame($mtime, $data['mtime']); + $this->assertSame($size, $data['size']); + $this->assertTrue($mtime->getTimestamp() < $data['atime']); + } + + public function testStatNotExisting() { + $path = '/foobar/bar.foo'; + $serverPath = '/' . $this->documentLibraryTitle . '/' . trim($path, '/'); - $this->assertSame($mtime, $rootData['mtime']); - $this->assertSame($size, $rootData['size']); - $this->assertTrue($mtime->getTimestamp() < $rootData['atime']); + $this->client->expects($this->once()) + ->method('fetchFileOrFolder') + ->with($serverPath, [SharePoint::SP_PROPERTY_SIZE, SharePoint::SP_PROPERTY_MTIME]) + ->willThrowException(new NotFoundException()); + + $this->assertFalse($this->storage->stat($path)); + } + + /** + * @dataProvider pathProvider + */ + public function testFileType($path, $returnSize) { + if($returnSize === null) { + $return = $this->createMock(Folder::class); + $expectedType = 'dir'; + } else { + $return = $this->createMock(File::class); + $expectedType = 'file'; + } + + $serverPath = '/' . $this->documentLibraryTitle; + if(trim($path, '/') !== '') { + $serverPath .= '/' . trim($path, '/'); + } + + $this->client->expects($this->once()) + ->method('fetchFileOrFolder') + ->with($serverPath, []) + ->willReturn($return); + + $this->assertSame($expectedType, $this->storage->filetype($path)); + } + + public function testFileTypeNotExisting() { + $path = '/dingdong/nothing.sh'; + + $serverPath = '/' . $this->documentLibraryTitle; + if(trim($path, '/') !== '') { + $serverPath .= '/' . trim($path, '/'); + } + + $this->client->expects($this->once()) + ->method('fetchFileOrFolder') + ->with($serverPath, []) + ->willThrowException(new NotFoundException()); + + $this->assertFalse($this->storage->filetype($path)); + } + + public function boolProvider() { + return [ + [ true ], + [ false ] + ]; + } + + /** + * @dataProvider boolProvider + */ + public function testFileExists($exists) { + $path = '/dingdong/nothing.sh'; + + $serverPath = '/' . $this->documentLibraryTitle; + if(trim($path, '/') !== '') { + $serverPath .= '/' . trim($path, '/'); + } + + $invocationMocker = $this->client->expects($this->once()) + ->method('fetchFileOrFolder') + ->with($serverPath, []); + if($exists) { + $invocationMocker->willReturn($this->createMock(File::class)); + } else { + $invocationMocker->willThrowException(new NotFoundException()); + } + + $this->assertSame($exists, $this->storage->file_exists($path)); } } From ab1a54fbc62c956e58f07c25bb034279548b0926 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 17 Mar 2017 01:16:37 +0100 Subject: [PATCH 14/32] implement opendir() it appears awefully slow, mostly because of yet missing caching, as other storage backends deal with that. To be added later. Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 31 ++++++++++++++++++- .../lib/Lib/Storage/SharePoint.php | 31 +++++++++++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index d27779c157823..bf576d8449317 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -26,6 +26,7 @@ use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; use Office365\PHP\Client\Runtime\ClientObject; +use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; @@ -106,7 +107,35 @@ public function fetchFolder($relativeServerPath, array $properties = null) { return $folder; } - private function loadAndExecute(ClientObject $object, array $properties = null) { + /** + * @param $relativeServerPath + * @param null $properties + * @return ClientObjectCollection[] + */ + public function fetchFolderContents($relativeServerPath, $properties = null) { + $this->ensureConnection(); + $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); + $folderCollection = $folder->getFolders(); + $fileCollection = $folder->getFiles(); + $this->context->load($folderCollection, $properties); + $this->context->load($fileCollection, $properties); + $this->context->executeQuery(); + + $collections = ['folders' => $folderCollection, 'files' => $fileCollection]; + + foreach ($collections as $collection) { + foreach ($collection->getData() as $item) { + /** @var File|Folder $item */ + $fields = $item->getListItemAllFields(); + $this->context->load($fields, ['Id', 'Hidden']); + } + } + $this->context->executeQuery(); + + return $collections; + } + + public function loadAndExecute(ClientObject $object, array $properties = null) { $this->context->load($object, $properties); $this->context->executeQuery(); } diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 31e71b3c3ab7d..60d8f8dcebf8f 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -23,6 +23,7 @@ namespace OCA\Files_External\Lib\Storage; +use Icewind\Streams\IteratorDirectory; use OC\Files\Storage\Common; use OCA\Files_External\Lib\SharePoint\ContextsFactory; use OCA\Files_External\Lib\SharePoint\NotFoundException; @@ -31,6 +32,7 @@ use OCP\Files\FileInfo; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; +use Office365\PHP\Client\SharePoint\ListItem; class SharePoint extends Common { const SP_PROPERTY_SIZE = 'Length'; @@ -119,8 +121,33 @@ public function rmdir($path) { * @since 6.0.0 */ public function opendir($path) { - // TODO: Implement opendir() method. - return false; + try { + $serverUrl = $this->formatPath($path); + //$collections = $this->spClient->fetchFolderContents($serverUrl, ['Name', 'ListItemAllFields']); // does not work for some reason :( + $collections = $this->spClient->fetchFolderContents($serverUrl); + $files = []; + + foreach ($collections as $collection) { + /** @var File[]|Folder[] $items */ + $items = $collection->getData(); + foreach ($items as $item) { + /** @var ListItem $fields */ + $id = $item->getListItemAllFields()->getProperty('Id'); + $hidden = $item->getListItemAllFields()->getProperty('Hidden'); // TODO: get someone to test this in SP 2013 + if($hidden === false || $id !== null) { + // avoids listing hidden "Forms" folder (and its contents). + // Have not found a different mechanism to detect whether + // a file or folder is hidden. There used to be a Hidden + // field, but seems to have gone (since SP 2016?). + $files[] = $item->getProperty('Name'); + } + } + } + + return IteratorDirectory::wrap($files); + } catch (NotFoundException $e) { + return false; + } } /** From c1952c004613f853f76422b6c5ddc3447c624a16 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 22 Mar 2017 16:20:32 +0100 Subject: [PATCH 15/32] fix interpreting mtime from SP Signed-off-by: Arthur Schiwon --- apps/files_external/lib/Lib/Storage/SharePoint.php | 9 +++++++-- apps/files_external/tests/Storage/SharePointTest.php | 9 ++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 60d8f8dcebf8f..fb401128ff69a 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -165,10 +165,15 @@ public function stat($path) { } catch (\Exception $e) { return false; } + + $size = $file->getProperty(self::SP_PROPERTY_SIZE) ?: FileInfo::SPACE_UNKNOWN; + $mtimeValue = $file->getProperty(self::SP_PROPERTY_MTIME); + $mtime = $mtimeValue ? new \DateTime($mtimeValue) : null; + $stat = [ // int64, size in bytes, excluding the size of any Web Parts that are used in the file. - 'size' => $file->getProperty(self::SP_PROPERTY_SIZE) ?: FileInfo::SPACE_UNKNOWN, - 'mtime' => $file->getProperty(self::SP_PROPERTY_MTIME), + 'size' => $size, + 'mtime' => $mtime->getTimestamp(), // no property in SP 2013 & 2016, other storages do the same :speak_no_evil: 'atime' => time(), ]; diff --git a/apps/files_external/tests/Storage/SharePointTest.php b/apps/files_external/tests/Storage/SharePointTest.php index 92b70f0b1051a..11c3fe9130e1b 100644 --- a/apps/files_external/tests/Storage/SharePointTest.php +++ b/apps/files_external/tests/Storage/SharePointTest.php @@ -139,14 +139,17 @@ public function pathProvider() { * @dataProvider pathProvider */ public function testStatExisting($path, $returnSize) { - $mtime = new \DateTime('yesterday'); + $mtime = new \DateTime(null, new \DateTimeZone('Z')); + $mtime->sub(new \DateInterval('P2D')); + // a SP time string looks like: 2017-03-22T16:17:23Z + $returnMTime = $mtime->format('o-m-d\TH:i:se'); $size = $returnSize ?: FileInfo::SPACE_UNKNOWN; $folderMock = $this->createMock(Folder::class); $folderMock->expects($this->exactly(2)) ->method('getProperty') ->withConsecutive(['Length'], ['TimeLastModified']) - ->willReturnOnConsecutiveCalls($returnSize, $mtime); + ->willReturnOnConsecutiveCalls($returnSize, $returnMTime); $serverPath = '/' . $this->documentLibraryTitle; if(trim($path, '/') !== '') { @@ -160,7 +163,7 @@ public function testStatExisting($path, $returnSize) { $data = $this->storage->stat($path); - $this->assertSame($mtime, $data['mtime']); + $this->assertSame($mtime->getTimestamp(), $data['mtime']); $this->assertSame($size, $data['size']); $this->assertTrue($mtime->getTimestamp() < $data['atime']); } From 1f254159c4aca9d4f78cb46a177ec3b22010b547 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 22 Mar 2017 22:29:33 +0100 Subject: [PATCH 16/32] performance tuning part 1: add cache, saves 80% time still takes too long though Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 26 ++++++--- .../lib/Lib/Storage/SharePoint.php | 55 +++++++++++++++++-- .../tests/SharePoint/SharePointClientTest.php | 29 ++++++++-- .../tests/Storage/SharePointTest.php | 6 +- 4 files changed, 96 insertions(+), 20 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index bf576d8449317..73d306bfdc5a3 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -103,7 +103,12 @@ public function fetchFileOrFolder($path, array $properties = null) { public function fetchFolder($relativeServerPath, array $properties = null) { $this->ensureConnection(); $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); - $this->loadAndExecute($folder, $properties); + $folderCollection = $folder->getFolders(); + $fileCollection = $folder->getFiles(); + $this->context->load($folder, $properties); + $this->context->load($folderCollection, null); + $this->context->load($fileCollection, null); + $this->context->executeQuery(); return $folder; } @@ -112,14 +117,19 @@ public function fetchFolder($relativeServerPath, array $properties = null) { * @param null $properties * @return ClientObjectCollection[] */ - public function fetchFolderContents($relativeServerPath, $properties = null) { + public function fetchFolderContents($relativeServerPath, $properties = null, Folder $folder = null) { $this->ensureConnection(); - $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); - $folderCollection = $folder->getFolders(); - $fileCollection = $folder->getFiles(); - $this->context->load($folderCollection, $properties); - $this->context->load($fileCollection, $properties); - $this->context->executeQuery(); + if($folder === null) { + $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); + $folderCollection = $folder->getFolders(); + $fileCollection = $folder->getFiles(); + $this->context->load($folderCollection, $properties); + $this->context->load($fileCollection, $properties); + $this->context->executeQuery(); + } else { + $folderCollection = $folder->getFolders(); + $fileCollection = $folder->getFiles(); + } $collections = ['folders' => $folderCollection, 'files' => $fileCollection]; diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index fb401128ff69a..b9a4062ab0824 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -24,12 +24,14 @@ namespace OCA\Files_External\Lib\Storage; use Icewind\Streams\IteratorDirectory; +use OC\Cache\CappedMemoryCache; use OC\Files\Storage\Common; use OCA\Files_External\Lib\SharePoint\ContextsFactory; use OCA\Files_External\Lib\SharePoint\NotFoundException; use OCA\Files_External\Lib\SharePoint\SharePointClient; use OCA\Files_External\Lib\SharePoint\SharePointClientFactory; use OCP\Files\FileInfo; +use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; use Office365\PHP\Client\SharePoint\ListItem; @@ -53,6 +55,9 @@ class SharePoint extends Common { /** @var SharePointClient */ protected $spClient; + /** @var CappedMemoryCache */ + protected $fileCache; + /** @var ContextsFactory */ private $contextsFactory; @@ -124,7 +129,7 @@ public function opendir($path) { try { $serverUrl = $this->formatPath($path); //$collections = $this->spClient->fetchFolderContents($serverUrl, ['Name', 'ListItemAllFields']); // does not work for some reason :( - $collections = $this->spClient->fetchFolderContents($serverUrl); + $collections = $this->getFolderContents($serverUrl); $files = []; foreach ($collections as $collection) { @@ -161,7 +166,7 @@ public function opendir($path) { public function stat($path) { $serverUrl = $this->formatPath($path); try { - $file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); + $file = $this->getFileOrFolder($serverUrl); } catch (\Exception $e) { return false; } @@ -198,7 +203,7 @@ public function stat($path) { public function filetype($path) { try { $serverUrl = $this->formatPath($path); - $object = $this->spClient->fetchFileOrFolder($serverUrl, []); + $object = $this->getFileOrFolder($serverUrl); } catch (NotFoundException $e) { return false; } @@ -225,7 +230,7 @@ public function file_exists($path) { // for file and folder. It is not necessarily faster, though. // Would need evaluation of typical use cases (I assume most often // existing files are checked) and measurements. - $this->spClient->fetchFileOrFolder($serverUrl, []); + $this->getFileOrFolder($serverUrl); return true; } catch (NotFoundException $e) { return false; @@ -240,6 +245,7 @@ public function file_exists($path) { * @since 6.0.0 */ public function unlink($path) { + // FIXME:: all is totally wrong $path = trim($path); if($path === '/' || $path === '') { return false; @@ -311,6 +317,47 @@ private function fixDI(array $parameters) { [ 'user' => $this->authUser, 'password' => $this->authPwd], $this->documentLibrary ); + + if(isset($parameters['cappedMemoryCache'])) { + $this->fileCache = $parameters['cappedMemoryCache']; + } else { + $this->fileCache = new CappedMemoryCache('256'); + } + } + + /** + * @param $serverUrl + * @return ClientObjectCollection[] + */ + private function getFolderContents($serverUrl) { + $entry = $this->fileCache->get($serverUrl); + if($entry === null || !isset($entry['children'])) { + $folder = isset($entry['instance']) ? $entry['instance'] : null; + $contents = $this->spClient->fetchFolderContents($serverUrl, null, $folder); + $cacheItem = $entry ?: []; + $cacheItem['children'] = $contents; + $this->fileCache->set($serverUrl, $cacheItem); + } else { + $contents = $entry['children']; + } + return $contents; + } + + /** + * @param $serverUrl + * @return File|Folder + */ + private function getFileOrFolder($serverUrl) { + $entry = $this->fileCache->get($serverUrl); + if($entry === null || !isset($entry['instance'])) { + $file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); + $cacheItem = $entry ?: []; + $cacheItem['instance'] = $file; + $this->fileCache->set($serverUrl, $cacheItem); + } else { + $file = $entry['instance']; + } + return $file; } /** diff --git a/apps/files_external/tests/SharePoint/SharePointClientTest.php b/apps/files_external/tests/SharePoint/SharePointClientTest.php index 9cf37fed55eaa..e2ced5e9918a8 100644 --- a/apps/files_external/tests/SharePoint/SharePointClientTest.php +++ b/apps/files_external/tests/SharePoint/SharePointClientTest.php @@ -30,7 +30,9 @@ use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; +use Office365\PHP\Client\SharePoint\FileCollection; use Office365\PHP\Client\SharePoint\Folder; +use Office365\PHP\Client\SharePoint\FolderCollection; use Office365\PHP\Client\SharePoint\Web; use Test\TestCase; @@ -102,7 +104,16 @@ public function testFetchFolderByFileOrFolder() { ->willReturn($this->createMock(AuthenticationContext::class)); $fileMock = $this->createMock(File::class); + $folderCollectionMock = $this->createMock(FolderCollection::class); + $fileCollectionMock = $this->createMock(FileCollection::class); + $folderMock = $this->createMock(Folder::class); + $folderMock->expects($this->once()) + ->method('getFolders') + ->willReturn($folderCollectionMock); + $folderMock->expects($this->once()) + ->method('getFiles') + ->willReturn($fileCollectionMock); $webMock = $this->createMock(Web::class); $webMock->expects($this->once()) @@ -118,16 +129,15 @@ public function testFetchFolderByFileOrFolder() { $clientContextMock->expects($this->exactly(2)) ->method('getWeb') ->willReturn($webMock); - $clientContextMock->expects($this->exactly(2)) + $clientContextMock->expects($this->exactly(4)) ->method('load') ->withConsecutive([$fileMock, $properties], [$folderMock, $properties]); $clientContextMock->expects($this->at(2)) ->method('executeQuery') ->willThrowException(new \Exception('The file /whatwasitsname does not exist.')); - $clientContextMock->expects($this->at(5)) + $clientContextMock->expects($this->at(7)) ->method('executeQuery'); - $this->contextsFactory->expects($this->exactly(2)) ->method('getClientContext') ->willReturn($clientContextMock); @@ -150,7 +160,16 @@ public function testFetchNotExistingByFileOrFolder() { ->willReturn($this->createMock(AuthenticationContext::class)); $fileMock = $this->createMock(File::class); + $folderCollectionMock = $this->createMock(FolderCollection::class); + $fileCollectionMock = $this->createMock(FileCollection::class); + $folderMock = $this->createMock(Folder::class); + $folderMock->expects($this->once()) + ->method('getFolders') + ->willReturn($folderCollectionMock); + $folderMock->expects($this->once()) + ->method('getFiles') + ->willReturn($fileCollectionMock); $webMock = $this->createMock(Web::class); $webMock->expects($this->once()) @@ -166,13 +185,13 @@ public function testFetchNotExistingByFileOrFolder() { $clientContextMock->expects($this->exactly(2)) ->method('getWeb') ->willReturn($webMock); - $clientContextMock->expects($this->exactly(2)) + $clientContextMock->expects($this->exactly(4)) ->method('load') ->withConsecutive([$fileMock, $properties], [$folderMock, $properties]); $clientContextMock->expects($this->at(2)) ->method('executeQuery') ->willThrowException(new \Exception('The file /whatwasitsname does not exist.')); - $clientContextMock->expects($this->at(5)) + $clientContextMock->expects($this->at(7)) ->method('executeQuery') ->willThrowException(new \Exception('Unknown Error')); diff --git a/apps/files_external/tests/Storage/SharePointTest.php b/apps/files_external/tests/Storage/SharePointTest.php index 11c3fe9130e1b..b4781e059af7d 100644 --- a/apps/files_external/tests/Storage/SharePointTest.php +++ b/apps/files_external/tests/Storage/SharePointTest.php @@ -199,7 +199,7 @@ public function testFileType($path, $returnSize) { $this->client->expects($this->once()) ->method('fetchFileOrFolder') - ->with($serverPath, []) + ->with($serverPath) ->willReturn($return); $this->assertSame($expectedType, $this->storage->filetype($path)); @@ -215,7 +215,7 @@ public function testFileTypeNotExisting() { $this->client->expects($this->once()) ->method('fetchFileOrFolder') - ->with($serverPath, []) + ->with($serverPath) ->willThrowException(new NotFoundException()); $this->assertFalse($this->storage->filetype($path)); @@ -241,7 +241,7 @@ public function testFileExists($exists) { $invocationMocker = $this->client->expects($this->once()) ->method('fetchFileOrFolder') - ->with($serverPath, []); + ->with($serverPath); if($exists) { $invocationMocker->willReturn($this->createMock(File::class)); } else { From e072312c1895fc4fa3b0467f88e3d7e28e04c56e Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 23 Mar 2017 21:16:43 +0100 Subject: [PATCH 17/32] properly add php-spo Signed-off-by: Arthur Schiwon --- apps/files_external/3rdparty/.gitignore | 7 + apps/files_external/3rdparty/vgrem/php-spo | 1 - .../3rdparty/vgrem/php-spo/.gitattributes | 63 ++++ .../3rdparty/vgrem/php-spo/.gitignore | 165 +++++++++++ .../3rdparty/vgrem/php-spo/LICENSE.md | 21 ++ .../3rdparty/vgrem/php-spo/README.md | 181 ++++++++++++ .../3rdparty/vgrem/php-spo/composer.json | 23 ++ .../3rdparty/vgrem/php-spo/composer.lock | 21 ++ .../Discovery/CapabilityDiscoveryResult.php | 39 +++ .../php-spo/src/Discovery/DiscoveryClient.php | 34 +++ .../src/GraphClient/ActiveDirectoryClient.php | 58 ++++ .../vgrem/php-spo/src/GraphClient/Contact.php | 10 + .../src/GraphClient/ContactCollection.php | 12 + .../vgrem/php-spo/src/GraphClient/Device.php | 10 + .../src/GraphClient/DeviceCollection.php | 11 + .../src/GraphClient/DirectoryObject.php | 10 + .../GraphClient/DirectoryObjectCollection.php | 11 + .../php-spo/src/GraphClient/GraphObject.php | 12 + .../php-spo/src/GraphClient/TenantDetail.php | 10 + .../GraphClient/TenantDetailCollection.php | 12 + .../OneDrive/CurrentUserRequestContext.php | 45 +++ .../vgrem/php-spo/src/OneDrive/Drive.php | 55 ++++ .../vgrem/php-spo/src/OneDrive/File.php | 52 ++++ .../php-spo/src/OneDrive/FileCollection.php | 10 + .../vgrem/php-spo/src/OneDrive/Folder.php | 30 ++ .../php-spo/src/OneDrive/FolderCollection.php | 9 + .../vgrem/php-spo/src/OneDrive/Identity.php | 12 + .../php-spo/src/OneDrive/IdentitySet.php | 12 + .../vgrem/php-spo/src/OneDrive/ImageFacet.php | 12 + .../vgrem/php-spo/src/OneDrive/Item.php | 49 ++++ .../php-spo/src/OneDrive/ItemCollection.php | 22 ++ .../php-spo/src/OneDrive/ItemReference.php | 12 + .../php-spo/src/OneDrive/OneDriveClient.php | 47 +++ .../src/OneDrive/OneDriveErrorCode.php | 25 ++ .../src/OutlookServices/Attachment.php | 51 ++++ .../OutlookServices/AttachmentCollection.php | 12 + .../php-spo/src/OutlookServices/Attendee.php | 24 ++ .../src/OutlookServices/AttendeeType.php | 12 + .../php-spo/src/OutlookServices/BodyType.php | 15 + .../php-spo/src/OutlookServices/Calendar.php | 59 ++++ .../OutlookServices/CalendarCollection.php | 12 + .../src/OutlookServices/CalendarColor.php | 20 ++ .../src/OutlookServices/CalendarGroup.php | 13 + .../CalendarGroupCollection.php | 11 + .../src/OutlookServices/ChangeType.php | 14 + .../php-spo/src/OutlookServices/Contact.php | 131 +++++++++ .../src/OutlookServices/ContactCollection.php | 39 +++ .../src/OutlookServices/ContactFolder.php | 41 +++ .../src/OutlookServices/Conversation.php | 12 + .../ConversationCollection.php | 11 + .../OutlookServices/ConversationThread.php | 10 + .../src/OutlookServices/DateTimeTimeZone.php | 15 + .../php-spo/src/OutlookServices/DayOfWeek.php | 16 + .../src/OutlookServices/EmailAddress.php | 37 +++ .../php-spo/src/OutlookServices/Event.php | 66 +++++ .../src/OutlookServices/EventCollection.php | 23 ++ .../php-spo/src/OutlookServices/EventType.php | 14 + .../src/OutlookServices/FileAttachment.php | 32 ++ .../FileAttachmentCollection.php | 10 + .../src/OutlookServices/FolderCollection.php | 26 ++ .../src/OutlookServices/FreeBusyStatus.php | 17 ++ .../src/OutlookServices/GeoCoordinates.php | 46 +++ .../php-spo/src/OutlookServices/Group.php | 10 + .../src/OutlookServices/GroupCollection.php | 12 + .../php-spo/src/OutlookServices/Item.php | 38 +++ .../src/OutlookServices/ItemAttachment.php | 19 ++ .../ItemAttachmentCollection.php | 12 + .../php-spo/src/OutlookServices/ItemBody.php | 36 +++ .../src/OutlookServices/ItemCollection.php | 12 + .../php-spo/src/OutlookServices/Location.php | 34 +++ .../src/OutlookServices/MailFolder.php | 49 ++++ .../OutlookServices/MeetingMessageType.php | 15 + .../php-spo/src/OutlookServices/Message.php | 240 +++++++++++++++ .../src/OutlookServices/MessageCollection.php | 42 +++ .../src/OutlookServices/OpenTypeExtension.php | 12 + .../src/OutlookServices/OutlookClient.php | 117 ++++++++ .../src/OutlookServices/OutlookEntity.php | 91 ++++++ .../php-spo/src/OutlookServices/Photo.php | 12 + .../src/OutlookServices/PhysicalAddress.php | 48 +++ .../php-spo/src/OutlookServices/Post.php | 10 + .../src/OutlookServices/PushSubscription.php | 10 + .../PushSubscriptionCollection.php | 11 + .../php-spo/src/OutlookServices/Recipient.php | 28 ++ .../src/OutlookServices/RecurrencePattern.php | 63 ++++ .../OutlookServices/RecurrencePatternType.php | 15 + .../src/OutlookServices/RecurrenceRange.php | 41 +++ .../OutlookServices/RecurrenceRangeType.php | 12 + .../OutlookServices/ReferenceAttachment.php | 10 + .../php-spo/src/OutlookServices/Reminder.php | 63 ++++ .../src/OutlookServices/ResponseStatus.php | 28 ++ .../src/OutlookServices/Subscription.php | 27 ++ .../SubscriptionCollection.php | 11 + .../php-spo/src/OutlookServices/User.php | 230 +++++++++++++++ .../src/OutlookServices/UserCollection.php | 11 + .../php-spo/src/OutlookServices/WeekIndex.php | 14 + .../src/Runtime/Auth/ACSTokenProvider.php | 139 +++++++++ .../Runtime/Auth/AuthenticationContext.php | 186 ++++++++++++ .../src/Runtime/Auth/BaseTokenProvider.php | 11 + .../src/Runtime/Auth/CookieCacheEntry.php | 26 ++ .../Runtime/Auth/IAuthenticationContext.php | 10 + .../Runtime/Auth/NetworkCredentialContext.php | 47 +++ .../src/Runtime/Auth/OAuthTokenProvider.php | 116 ++++++++ .../src/Runtime/Auth/SamlTokenProvider.php | 142 +++++++++ .../php-spo/src/Runtime/Auth/xml/SAML.xml | 30 ++ .../php-spo/src/Runtime/ClientAction.php | 56 ++++ .../src/Runtime/ClientActionCreateEntity.php | 19 ++ .../src/Runtime/ClientActionDeleteEntity.php | 18 ++ .../Runtime/ClientActionInvokeGetMethod.php | 23 ++ .../src/Runtime/ClientActionInvokeMethod.php | 41 +++ .../Runtime/ClientActionInvokePostMethod.php | 22 ++ .../src/Runtime/ClientActionReadEntity.php | 16 + .../php-spo/src/Runtime/ClientActionType.php | 15 + .../src/Runtime/ClientActionUpdateEntity.php | 18 ++ .../php-spo/src/Runtime/ClientObject.php | 254 ++++++++++++++++ .../src/Runtime/ClientObjectCollection.php | 275 ++++++++++++++++++ .../php-spo/src/Runtime/ClientRequest.php | 233 +++++++++++++++ .../php-spo/src/Runtime/ClientResult.php | 36 +++ .../src/Runtime/ClientRuntimeContext.php | 166 +++++++++++ .../php-spo/src/Runtime/ClientValueObject.php | 66 +++++ .../Runtime/ClientValueObjectCollection.php | 89 ++++++ .../src/Runtime/ContextWebInformation.php | 53 ++++ .../vgrem/php-spo/src/Runtime/FormatType.php | 12 + .../vgrem/php-spo/src/Runtime/HttpMethod.php | 15 + .../vgrem/php-spo/src/Runtime/KeyValue.php | 27 ++ .../php-spo/src/Runtime/OData/AtomFormat.php | 17 ++ .../php-spo/src/Runtime/OData/JsonFormat.php | 43 +++ .../src/Runtime/OData/JsonLightFormat.php | 21 ++ .../Runtime/OData/JsonPayloadSerializer.php | 81 ++++++ .../src/Runtime/OData/ODataException.php | 10 + .../php-spo/src/Runtime/OData/ODataFormat.php | 48 +++ .../src/Runtime/OData/ODataMetadataLevel.php | 12 + .../src/Runtime/OData/ODataPathParser.php | 85 ++++++ .../src/Runtime/OData/ODataPayload.php | 121 ++++++++ .../src/Runtime/OData/ODataPayloadKind.php | 46 +++ .../Runtime/OData/ODataPrimitiveTypeKind.php | 114 ++++++++ .../src/Runtime/OData/ODataQueryOptions.php | 46 +++ .../php-spo/src/Runtime/Office365Version.php | 12 + .../Runtime/OperationParameterCollection.php | 53 ++++ .../php-spo/src/Runtime/RequestContext.php | 55 ++++ .../php-spo/src/Runtime/ResourcePath.php | 107 +++++++ .../src/Runtime/ResourcePathEntity.php | 41 +++ .../php-spo/src/Runtime/ResourcePathLink.php | 16 + .../Runtime/ResourcePathServiceOperation.php | 42 +++ .../src/Runtime/Soap/SoapClientRequest.php | 43 +++ .../Runtime/Utilities/ClientCredential.php | 28 ++ .../src/Runtime/Utilities/EnumType.php | 29 ++ .../php-spo/src/Runtime/Utilities/Guid.php | 78 +++++ .../src/Runtime/Utilities/JsonConvert.php | 54 ++++ .../src/Runtime/Utilities/RequestOptions.php | 130 +++++++++ .../src/Runtime/Utilities/Requests.php | 131 +++++++++ .../src/Runtime/Utilities/UserCredentials.php | 31 ++ .../src/SharePoint/AddFieldOptions.php | 18 ++ .../php-spo/src/SharePoint/AppInstance.php | 12 + .../php-spo/src/SharePoint/Attachment.php | 19 ++ .../src/SharePoint/AttachmentCollection.php | 39 +++ .../AttachmentCreationInformation.php | 23 ++ .../src/SharePoint/BasePermissions.php | 69 +++++ .../php-spo/src/SharePoint/CamlQuery.php | 54 ++++ .../vgrem/php-spo/src/SharePoint/Change.php | 19 ++ .../src/SharePoint/ChangeCollection.php | 11 + .../php-spo/src/SharePoint/ChangeField.php | 18 ++ .../php-spo/src/SharePoint/ChangeFile.php | 18 ++ .../php-spo/src/SharePoint/ChangeFolder.php | 16 + .../php-spo/src/SharePoint/ChangeItem.php | 22 ++ .../php-spo/src/SharePoint/ChangeList.php | 17 ++ .../src/SharePoint/ChangeLogItemQuery.php | 61 ++++ .../php-spo/src/SharePoint/ChangeQuery.php | 252 ++++++++++++++++ .../php-spo/src/SharePoint/ChangeSite.php | 10 + .../php-spo/src/SharePoint/ChangeToken.php | 13 + .../php-spo/src/SharePoint/ChangeType.php | 14 + .../php-spo/src/SharePoint/ChangeUser.php | 18 ++ .../php-spo/src/SharePoint/ChangeView.php | 24 ++ .../php-spo/src/SharePoint/ChangeWeb.php | 12 + .../php-spo/src/SharePoint/CheckOutType.php | 26 ++ .../php-spo/src/SharePoint/ClientContext.php | 134 +++++++++ .../php-spo/src/SharePoint/ContentType.php | 37 +++ .../src/SharePoint/ContentTypeCollection.php | 43 +++ .../ContentTypeCreationInformation.php | 71 +++++ .../php-spo/src/SharePoint/ContentTypeId.php | 18 ++ .../src/SharePoint/CustomActionElement.php | 12 + .../CustomActionElementCollection.php | 12 + .../DocumentSet/DocumentSet.php | 12 + .../vgrem/php-spo/src/SharePoint/Field.php | 40 +++ .../src/SharePoint/FieldCalculated.php | 10 + .../php-spo/src/SharePoint/FieldChoice.php | 10 + .../src/SharePoint/FieldCollection.php | 55 ++++ .../php-spo/src/SharePoint/FieldComputed.php | 10 + .../SharePoint/FieldCreationInformation.php | 44 +++ .../php-spo/src/SharePoint/FieldDateTime.php | 9 + .../src/SharePoint/FieldGeolocation.php | 9 + .../src/SharePoint/FieldGeolocationValue.php | 32 ++ .../php-spo/src/SharePoint/FieldGuid.php | 10 + .../php-spo/src/SharePoint/FieldLookup.php | 9 + .../src/SharePoint/FieldLookupValue.php | 26 ++ .../src/SharePoint/FieldMultiChoice.php | 10 + .../src/SharePoint/FieldMultiLineText.php | 10 + .../php-spo/src/SharePoint/FieldNumber.php | 10 + .../php-spo/src/SharePoint/FieldText.php | 9 + .../php-spo/src/SharePoint/FieldType.php | 45 +++ .../vgrem/php-spo/src/SharePoint/FieldUrl.php | 9 + .../php-spo/src/SharePoint/FieldUrlValue.php | 26 ++ .../php-spo/src/SharePoint/FieldUser.php | 10 + .../php-spo/src/SharePoint/FieldUserValue.php | 12 + .../vgrem/php-spo/src/SharePoint/File.php | 248 ++++++++++++++++ .../php-spo/src/SharePoint/FileCollection.php | 58 ++++ .../SharePoint/FileCreationInformation.php | 37 +++ .../php-spo/src/SharePoint/FileVersion.php | 13 + .../src/SharePoint/FileVersionCollection.php | 12 + .../vgrem/php-spo/src/SharePoint/Folder.php | 100 +++++++ .../src/SharePoint/FolderCollection.php | 22 ++ .../vgrem/php-spo/src/SharePoint/Group.php | 24 ++ .../src/SharePoint/GroupCollection.php | 84 ++++++ .../SharePoint/GroupCreationInformation.php | 30 ++ .../InformationRightsManagementSettings.php | 38 +++ .../php-spo/src/SharePoint/ListCollection.php | 63 ++++ .../SharePoint/ListCreationInformation.php | 46 +++ .../vgrem/php-spo/src/SharePoint/ListItem.php | 94 ++++++ .../src/SharePoint/ListItemCollection.php | 33 +++ .../SharePoint/ListItemCollectionPosition.php | 17 ++ .../ListItemCreationInformation.php | 29 ++ .../src/SharePoint/ListTemplateType.php | 66 +++++ .../SharePoint/ObjectSharingInformation.php | 12 + .../src/SharePoint/ObjectSharingSettings.php | 11 + .../php-spo/src/SharePoint/PermissionKind.php | 48 +++ .../php-spo/src/SharePoint/Principal.php | 22 ++ .../php-spo/src/SharePoint/PrincipalType.php | 17 ++ .../php-spo/src/SharePoint/RecycleBinItem.php | 12 + .../SharePoint/RecycleBinItemCollection.php | 12 + .../php-spo/src/SharePoint/RoleAssignment.php | 57 ++++ .../SharePoint/RoleAssignmentCollection.php | 24 ++ .../php-spo/src/SharePoint/RoleDefinition.php | 19 ++ .../SharePoint/RoleDefinitionCollection.php | 12 + .../RoleDefinitionCreationInformation.php | 13 + .../vgrem/php-spo/src/SharePoint/SPList.php | 222 ++++++++++++++ .../src/SharePoint/SecurableObject.php | 49 ++++ .../vgrem/php-spo/src/SharePoint/Site.php | 50 ++++ .../src/SharePoint/Social/SocialActor.php | 12 + .../src/SharePoint/Social/SocialRestActor.php | 25 ++ .../Social/SocialRestFeedManager.php | 13 + .../Social/SocialRestFollowingManager.php | 12 + .../src/SharePoint/Taxonomy/TaxonomyField.php | 12 + .../SharePoint/Taxonomy/TaxonomySession.php | 12 + .../src/SharePoint/TemplateFileType.php | 13 + .../vgrem/php-spo/src/SharePoint/User.php | 31 ++ .../php-spo/src/SharePoint/UserCollection.php | 71 +++++ .../src/SharePoint/UserCustomAction.php | 12 + .../SharePoint/UserCustomActionCollection.php | 13 + .../php-spo/src/SharePoint/UserIdInfo.php | 12 + .../SharePoint/UserProfiles/PeopleManager.php | 147 ++++++++++ .../UserProfiles/PersonProperties.php | 93 ++++++ .../PersonPropertiesCollection.php | 11 + .../SharePoint/UserProfiles/ProfileLoader.php | 24 ++ .../SharePoint/UserProfiles/UserProfile.php | 31 ++ .../src/SharePoint/Utilities/Utility.php | 77 +++++ .../vgrem/php-spo/src/SharePoint/View.php | 60 ++++ .../php-spo/src/SharePoint/ViewCollection.php | 55 ++++ .../SharePoint/ViewCreationInformation.php | 59 ++++ .../src/SharePoint/ViewFieldCollection.php | 13 + .../vgrem/php-spo/src/SharePoint/Web.php | 251 ++++++++++++++++ .../php-spo/src/SharePoint/WebCollection.php | 33 +++ .../src/SharePoint/WebCreationInformation.php | 64 ++++ .../WebParts/LimitedWebPartManager.php | 50 ++++ .../WebParts/PersonalizationScope.php | 12 + .../src/SharePoint/WebParts/WebPart.php | 9 + .../SharePoint/WebParts/WebPartDefinition.php | 42 +++ .../WebParts/WebPartDefinitionCollection.php | 31 ++ 266 files changed, 11352 insertions(+), 1 deletion(-) delete mode 160000 apps/files_external/3rdparty/vgrem/php-spo create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/.gitattributes create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/.gitignore create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/LICENSE.md create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/README.md create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/composer.json create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/composer.lock create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/DiscoveryClient.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/ActiveDirectoryClient.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/Contact.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/ContactCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/Device.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/DeviceCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/DirectoryObject.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/DirectoryObjectCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/GraphObject.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/TenantDetail.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/TenantDetailCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/CurrentUserRequestContext.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/Drive.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/File.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FileCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/Folder.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FolderCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/Identity.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/IdentitySet.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ImageFacet.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/Item.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemReference.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/OneDriveClient.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Attachment.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/AttachmentCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Attendee.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/AttendeeType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/BodyType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Calendar.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/CalendarCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/CalendarColor.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/CalendarGroup.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/CalendarGroupCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ChangeType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Contact.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ContactCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ContactFolder.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Conversation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ConversationCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ConversationThread.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/DateTimeTimeZone.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/DayOfWeek.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/EmailAddress.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Event.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/EventCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/EventType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/FileAttachment.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/FileAttachmentCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/FolderCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/FreeBusyStatus.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/GeoCoordinates.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Group.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/GroupCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Item.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ItemAttachment.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ItemAttachmentCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ItemBody.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ItemCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Location.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MailFolder.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MeetingMessageType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Message.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MessageCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OpenTypeExtension.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OutlookClient.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OutlookEntity.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Photo.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/PhysicalAddress.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Post.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/PushSubscription.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/PushSubscriptionCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Recipient.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/RecurrencePattern.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/RecurrencePatternType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/RecurrenceRange.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/RecurrenceRangeType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ReferenceAttachment.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Reminder.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ResponseStatus.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Subscription.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/SubscriptionCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/User.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/UserCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/WeekIndex.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/ACSTokenProvider.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/AuthenticationContext.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/CookieCacheEntry.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/NetworkCredentialContext.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/xml/SAML.xml create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientAction.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionCreateEntity.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionDeleteEntity.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokeGetMethod.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokeMethod.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokePostMethod.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionReadEntity.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionUpdateEntity.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObject.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObjectCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRequest.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientResult.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObject.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObjectCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ContextWebInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/FormatType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/HttpMethod.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/KeyValue.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/AtomFormat.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonFormat.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonLightFormat.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonPayloadSerializer.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataException.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataFormat.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataMetadataLevel.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataPathParser.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataPayload.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataPayloadKind.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataPrimitiveTypeKind.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataQueryOptions.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Office365Version.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OperationParameterCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/RequestContext.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePath.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathEntity.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathLink.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathServiceOperation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Soap/SoapClientRequest.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/ClientCredential.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/EnumType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Guid.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/JsonConvert.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/UserCredentials.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AddFieldOptions.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AppInstance.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Attachment.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/BasePermissions.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/CamlQuery.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Change.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeField.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeFile.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeFolder.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeItem.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeList.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeLogItemQuery.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeQuery.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeSite.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeToken.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeUser.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeView.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeWeb.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/CheckOutType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ClientContext.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeId.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/CustomActionElement.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/CustomActionElementCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/DocumentManagement/DocumentSet/DocumentSet.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Field.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldCalculated.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldChoice.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldComputed.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldDateTime.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldGeolocation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldGeolocationValue.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldGuid.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldLookup.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldLookupValue.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldMultiChoice.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldMultiLineText.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldNumber.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldText.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldUrl.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldUrlValue.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldUser.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldUserValue.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/File.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileVersion.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileVersionCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Folder.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FolderCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Group.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/InformationRightsManagementSettings.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItem.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollectionPosition.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListTemplateType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ObjectSharingInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ObjectSharingSettings.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/PermissionKind.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Principal.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/PrincipalType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RecycleBinItem.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RecycleBinItemCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleAssignment.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleAssignmentCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinition.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinitionCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinitionCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/SPList.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/SecurableObject.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Site.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Social/SocialActor.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Social/SocialRestActor.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Social/SocialRestFeedManager.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Social/SocialRestFollowingManager.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Taxonomy/TaxonomyField.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Taxonomy/TaxonomySession.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/TemplateFileType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/User.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCustomAction.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCustomActionCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserIdInfo.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/PeopleManager.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/PersonProperties.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/PersonPropertiesCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/ProfileLoader.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/UserProfile.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Utilities/Utility.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/View.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewFieldCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Web.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCreationInformation.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/LimitedWebPartManager.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/PersonalizationScope.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/WebPart.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinition.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinitionCollection.php diff --git a/apps/files_external/3rdparty/.gitignore b/apps/files_external/3rdparty/.gitignore index b56af237c35bb..ae7073a2bb44c 100644 --- a/apps/files_external/3rdparty/.gitignore +++ b/apps/files_external/3rdparty/.gitignore @@ -3,3 +3,10 @@ icewind/smb/tests icewind/smb/install_libsmbclient.sh icewind/smb/.travis.yml icewind/streams/tests + +vgrem/php-spo/examples +vgrem/php-spo/tests +vgrem/php-spo/vendor +vgrem/php-spo/.git +vgrem/php-spo/.travis.yml +vgrem/php-spo/phpunit_o365.xml diff --git a/apps/files_external/3rdparty/vgrem/php-spo b/apps/files_external/3rdparty/vgrem/php-spo deleted file mode 160000 index 59a2956f94f69..0000000000000 --- a/apps/files_external/3rdparty/vgrem/php-spo +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 59a2956f94f694592e3d3c6252f0e753f73a1686 diff --git a/apps/files_external/3rdparty/vgrem/php-spo/.gitattributes b/apps/files_external/3rdparty/vgrem/php-spo/.gitattributes new file mode 100644 index 0000000000000..1ff0c423042b4 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/apps/files_external/3rdparty/vgrem/php-spo/.gitignore b/apps/files_external/3rdparty/vgrem/php-spo/.gitignore new file mode 100644 index 0000000000000..821719b92568b --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/.gitignore @@ -0,0 +1,165 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets +!packages/*/build/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac desktop service store files +.DS_Store +*.phpproj +*.sln +.idea/ +examples/SharePoint/todoapp/ +src/ExcelServices/ +src/SharePoint/DocumentManagement/Video/ +src/SharePoint/Publishing/ +src/VideoService/ +examples/GraphExplorer/bower_components +vendor \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/LICENSE.md b/apps/files_external/3rdparty/vgrem/php-spo/LICENSE.md new file mode 100644 index 0000000000000..fd783c175f1a4 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Vadim Gremyachev + +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/apps/files_external/3rdparty/vgrem/php-spo/README.md b/apps/files_external/3rdparty/vgrem/php-spo/README.md new file mode 100644 index 0000000000000..76e41b05e7317 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/README.md @@ -0,0 +1,181 @@ +### About +The library provides a Office 365 REST client for PHP applications. It allows to performs CRUD operations against Office 365 resources via an REST/OData based API. + +#### The list of supported Office 365 REST APIs: + +- [SharePoint REST API](https://msdn.microsoft.com/en-us/library/office/jj860569.aspx) (_supported_ versions: [SharePoint 2013](https://msdn.microsoft.com/library/office/jj860569(v=office.15).aspx), SharePoint 2016, SharePoint Online and OneDrive for Business) +- [Outlook REST API](https://msdn.microsoft.com/en-us/office/office365/api/use-outlook-rest-api#DefineOutlookRESTAPI) + - [Outlook Contacts REST API](https://msdn.microsoft.com/en-us/office/office365/api/contacts-rest-operations) + - [Outlook Calendar REST API](https://msdn.microsoft.com/en-us/office/office365/api/calendar-rest-operations) + - [Outlook Mail REST API](https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations) + +### Status + +[![Build Status](https://travis-ci.org/vgrem/phpSPO.svg?branch=master)](https://travis-ci.org/vgrem/phpSPO) + +### Installation + +You can use **Composer** or simply **Download the Release** + +#### Composer + +The preferred method is via [composer](https://getcomposer.org). Follow the +[installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have +composer installed. + +Once composer is installed, execute the following command in your project root to install this library: + +```sh +composer require vgrem/php-spo:dev-master -n --no-progress +``` + +Finally, be sure to include the autoloader: + +```php +require_once '/path/to/your-project/vendor/autoload.php'; +``` + + + +### PHP version +- [PHP 5.4 or later](https://secure.php.net/) + + +### API + +- PHP:cURL underlying library is used to perform HTTP requests +- `ClientContext` - represents a SharePoint client context to performs CRUD operations against SharePoint resources via SharePoint Online REST API +- `OutlookClient` - represents a client context to performs CRUD operations against Office resources such as Outlook resources +- `ClientRequest` - represents a client request (more low level compared to `ClientContext`) to to performs CRUD operations against SharePoint resources via SharePoint Online REST API +- `AuthenticationContext` - represents an object that provides credentials to access SharePoint Online resources. +- `NetworkCredentialContext` - provides credentials for password-based authentication schemes such as Basic. + + +There are **two** approaches available to perform REST based queries: + +- via `ClientRequest` class where you need to construct REST queries by specifying endpoint url, headers if required and payload (low level approach), see [renameFolder.php](https://github.com/vgrem/phpSPO/blob/master/examples/renameFolder.php) for a more details +- via `ClientContext` class where you target client object resources such as Web, ListItem and etc., see [list_examples.php](https://github.com/vgrem/phpSPO/blob/master/examples/list_examples.php) for a more details + + +### Usage + + +#### Using SharePoint REST API + + +The following examples demonstrates how to perform basic CRUD operations against **SharePoint** list item resources. + +Example 1. How to read SharePoint list items + +```` + +$authCtx = new AuthenticationContext($Url); +$authCtx->acquireTokenForUser($UserName,$Password); //authenticate + +$ctx = new ClientContext($Url,$authCtx); //initialize REST client +$web = $ctx->getWeb(); +$list = $web->getLists()->getByTitle($listTitle); //init List resource +$items = $list->getItems(); //prepare a query to retrieve from the +$ctx->load($items); //save a query to retrieve list items from the server +$ctx->executeQuery(); //submit query to SharePoint Online REST service +foreach( $items->getData() as $item ) { + print "Task: '{$item->Title}'\r\n"; +} +```` + + +Example 2. How to create SharePoint list item: +```` +$listTitle = 'Tasks'; +$list = $ctx->getWeb()->getLists()->getByTitle($listTitle); +$itemProperties = array('Title' => 'Order Approval', 'Body' => 'Order approval task','__metadata' => array('type' => 'SP.Data.TasksListItem')); +$item = $list->addItem($itemProperties); +$ctx->executeQuery(); +print "Task '{$item->Title}' has been created.\r\n"; +```` + +Example 3. How to delete a SharePoint list item: +```` +$listTitle = 'Tasks'; +$itemToDeleteId = 1; +$list = $ctx->getWeb()->getLists()->getByTitle($listTitle); +$listItem = $list->getItemById($itemToDeleteId); +$listItem->deleteObject(); +$ctx->executeQuery(); +```` + +Example 4. How to update SharePoint list item: +```` +$listTitle = 'Tasks'; +$itemToUpdateId = 1; +$list = $ctx->getWeb()->getLists()->getByTitle($listTitle); +$listItem = $list->getItemById($itemId); +$itemProperties = array('PercentComplete' => 1); +$listItem->update($itemProperties); +$ctx->executeQuery(); +```` + + + +#### Using Outlook REST API + +The following examples demonstrates how to read, create and send messages via Outlook Mail API. + +Example 1. How to create a draft message + +```` + +$authCtx = new NetworkCredentialContext($UserName,$Password); //using Basic Auth scheme (for v1 API only) +$ctx = new OutlookClient($authCtx); //initialize OutlookServices client +$message = $ctx->getMe()->getMessages()->createMessage(); //create a Message resource +//set Message properties +$message->Subject = "--subject--"; +$message->Body = new ItemBody(BodyType::Text,"--Content goes here--"); +$message->ToRecipients = array( + new Recipient(new EmailAddress("Jon Doe","jdoe@contoso.onmicrosoft.com")) +); +$ctx->executeQuery(); +```` + + +Example 2. How to get messages + +```` + +$authCtx = new NetworkCredentialContext($UserName,$Password); //using Basic Auth scheme (for v1 API only) +$ctx = new OutlookClient($authCtx); //initialize OutlookServices client +$messages = $ctx->getMe()->getMessages(); +$ctx->load($messages); +$ctx->executeQuery(); +//print messages subjects +foreach ($messages->getData() as $curMessage){ + print $curMessage->Subject; +} +```` + + +Example 3. How to send a message + +```` + +$authCtx = new NetworkCredentialContext($UserName,$Password); //using Basic Auth scheme (for v1 API only) +$ctx = new OutlookClient($authCtx); //initialize OutlookServices client +$message = $ctx->getMe()->getMessages()->createMessage(); //create a Message resource +//set Message properties +$message->Subject = "--subject--"; +$message->Body = new ItemBody(BodyType::Text,"--Content goes here--"); +$message->ToRecipients = array( + new Recipient(new EmailAddress("Jon Doe","jdoe@contoso.onmicrosoft.com")) +); +$ctx->getMe()->sendEmail($message,false); //send a Message +$ctx->executeQuery(); +```` + + +## Changelog + +1.0.0 - May 23st, 2014 +- Initial release. + +2.0.0 - February 14, 2016 +- `AuthenticationContext` and `ClientContext` classes have been introduced. diff --git a/apps/files_external/3rdparty/vgrem/php-spo/composer.json b/apps/files_external/3rdparty/vgrem/php-spo/composer.json new file mode 100644 index 0000000000000..e5cd798c77ba3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/composer.json @@ -0,0 +1,23 @@ +{ + "name": "vgrem/php-spo", + "description": "The library provides a Office 365 REST client for PHP. It allows to performs CRUD operations against Office 365 resources via an REST/OData based API", + "type": "library", + "keywords": ["sharepoint", "office365", "rest", "curl", "api"], + "authors": [ + { + "name": "Vadim Gremyachev", + "email": "vvgrem@gmail.com" + } + ], + "license": "LGPL-3.0+", + "minimum-stability": "dev", + "require": { + "php": ">=5.4", + "ext-curl": "*" + }, + "autoload": { + "psr-4": { + "Office365\\PHP\\Client\\": "src/" + } + } +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/composer.lock b/apps/files_external/3rdparty/vgrem/php-spo/composer.lock new file mode 100644 index 0000000000000..da9301c65ee02 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/composer.lock @@ -0,0 +1,21 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "ad2d01946ac5c59009ce7386f5f2d284", + "content-hash": "c008500d1e4985f2a38587abd0cad43c", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4", + "ext-curl": "*" + }, + "platform-dev": [] +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php new file mode 100644 index 0000000000000..03db06019f6f8 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php @@ -0,0 +1,39 @@ +getServiceRootUrl() . "me"); + $this->addQuery($qry,$capabilities); + $this->executeQuery(); + return $capabilities; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/ActiveDirectoryClient.php b/apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/ActiveDirectoryClient.php new file mode 100644 index 0000000000000..0d5150dea9f73 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/ActiveDirectoryClient.php @@ -0,0 +1,58 @@ +getPendingRequest()->beforeExecuteQuery(function (RequestOptions $request,ClientAction $query){ + $request->Url .= "?api-version=1.0"; + }); + parent::executeQuery(); + } + + + + public function getTenantDetails() + { + if(!isset($this->tenantDetails)){ + $this->tenantDetails = new TenantDetailCollection($this,new ResourcePathEntity($this,null,"tenantDetails")); + } + return $this->tenantDetails; + } + + + public function getDevices() + { + if(!isset($this->devices)){ + $this->devices = new DeviceCollection($this,new ResourcePathEntity($this,null,"devices")); + } + return $this->devices; + } + + + /** + * @var TenantDetailCollection $tenantDetails + */ + private $tenantDetails; + + /** + * @var DeviceCollection $devices + */ + private $devices; +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/Contact.php b/apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/Contact.php new file mode 100644 index 0000000000000..d85d0264434fe --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/GraphClient/Contact.php @@ -0,0 +1,10 @@ +isPropertyAvailable("Drive")) { + $this->setProperty("Drive", + new Drive($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Drive" + ))); + } + return $this->getProperty("Drive"); + } + + + /** + * @return FileCollection + */ + public function getFiles() + { + if (!$this->isPropertyAvailable("Files")) { + $this->setProperty("Files", + new FileCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Files" + ))); + } + return $this->getProperty("Files"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/Drive.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/Drive.php new file mode 100644 index 0000000000000..cd712f70b6065 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/Drive.php @@ -0,0 +1,55 @@ +getProperty("owner"); + } + + + /** + * Sets the user account that owns the drive. + * @param string $value + */ + public function setOwner($value){ + return $this->setProperty("owner",$value); + } + + + /** + * @return ItemCollection + */ + public function getFiles(){ + if (!$this->isPropertyAvailable("files")) { + $this->setProperty("files", + new ItemCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"files") + )); + } + return $this->getProperty("files"); + } + + + + + + + /** + * @param string $value + */ + public function setFiles($value){ + return $this->setProperty("files",$value); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/File.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/File.php new file mode 100644 index 0000000000000..a102a71a97fde --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/File.php @@ -0,0 +1,52 @@ +getProperty("contentUrl"); + } + + + /** + * + * @param string $value + */ + public function setContentUrl($value){ + return $this->setProperty("contentUrl",$value); + } + + + /** + * + * @return ImageFacet + */ + public function getImage(){ + return $this->getProperty("image"); + } + + + /** + * + * @param ImageFacet $value + */ + public function setImage($value){ + return $this->setProperty("image",$value); + } + + + + function getEntityTypeName() + { + return "#Microsoft.FileServices.File"; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FileCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FileCollection.php new file mode 100644 index 0000000000000..44a126cf5b28a --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FileCollection.php @@ -0,0 +1,10 @@ +getProperty("childCount"); + } + + + /** + * + * @param int $value + */ + public function setChildCount($value){ + return $this->setProperty("childCount",$value); + } + + + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FolderCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FolderCollection.php new file mode 100644 index 0000000000000..97c9db2f30c91 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/FolderCollection.php @@ -0,0 +1,9 @@ +getProperty("webUrl"); + } + + + /** + * + * @param string $value + */ + public function setWebUrl($value){ + return $this->setProperty("webUrl",$value); + } + + + + /** + * + * @return ItemCollection + */ + public function getChildren(){ + return $this->getProperty("children"); + } + + + /** + * + * @param ItemCollection $value + */ + public function setChildren($value){ + return $this->setProperty("children",$value); + } + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemCollection.php new file mode 100644 index 0000000000000..c586b54fac540 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemCollection.php @@ -0,0 +1,22 @@ +getContext()); + //$payload->setContent($content); + $qry = new ClientAction($this->getResourceUrl() . "/add",$payload,ClientActionType::CreateEntity); + $this->getContext()->addQuery($qry); + } + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemReference.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemReference.php new file mode 100644 index 0000000000000..d70e78ed8cab3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/ItemReference.php @@ -0,0 +1,12 @@ +getPendingRequest()->beforeExecuteQuery(function (RequestOptions $request,ClientAction $query){ + + }); + parent::executeQuery(); + } + + + + /** + * @return CurrentUserRequestContext + */ + public function getMe(){ + if(!isset($this->me)) + $this->me = new CurrentUserRequestContext($this,new ResourcePathEntity($this,null,"me")); + return $this->me; + } + + + + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php new file mode 100644 index 0000000000000..4d3dfa8457c18 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php @@ -0,0 +1,25 @@ +format(DateTime::ISO8601)) + . "&endDateTime=" . rawurlencode($endDateTime->format(DateTime::W3C)); + $events = new EventCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),$url) + ); + $qry = new ClientActionReadEntity($events->getResourceUrl()); + $this->getContext()->addQuery($qry,$events); + return $events; + } + + /** + * The calendar name. + * @var string + */ + public $Name; + + + /** + * Specifies the color theme to distinguish the calendar from other calendars in a UI. + * @var int + */ + public $Color; + + + /** + * The calendar view for the calendar. Navigation property. + * @var array + */ + public $CalendarView; + + + /** + * The events in the calendar. Navigation property. + * @var array + */ + public $Events; +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/CalendarCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/CalendarCollection.php new file mode 100644 index 0000000000000..b8fa70c9957a7 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/CalendarCollection.php @@ -0,0 +1,12 @@ +getContext()); + $qry = new ClientActionCreateEntity($this, $contact); + $this->getContext()->addQuery($qry, $contact); + $this->addChild($contact); + return $contact; + } + + + + + /** + * Get a contact by using the contact ID. + * @param string $contactId + * @return Contact + */ + function getById($contactId){ + return new Contact( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),$contactId) + ); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ContactFolder.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ContactFolder.php new file mode 100644 index 0000000000000..e901907747043 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ContactFolder.php @@ -0,0 +1,41 @@ +Name = $typeName; + $this->Address = $address; + parent::__construct(); + } + + /** + * The display name of the person or entity. + * @var string + */ + public $Name; + + + /** + * The email address of the person or entity. + * @var string + */ + public $Address; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Event.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Event.php new file mode 100644 index 0000000000000..12503c34117f6 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Event.php @@ -0,0 +1,66 @@ +getContext()); + $qry = new ClientActionCreateEntity($this, $event); + $this->getContext()->addQuery($qry, $event); + $this->addChild($event); + return $event; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/EventType.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/EventType.php new file mode 100644 index 0000000000000..eac053af10509 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/EventType.php @@ -0,0 +1,14 @@ +getContext(), $this->getResourcePath()); + $folder->setProperty('DisplayName', $displayName); + $qry = new ClientActionCreateEntity($this, $folder); + $this->getContext()->addQuery($qry, $folder); + $this->addChild($folder); + return $folder; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/FreeBusyStatus.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/FreeBusyStatus.php new file mode 100644 index 0000000000000..54acea9659a6b --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/FreeBusyStatus.php @@ -0,0 +1,17 @@ +ContentType = $contentType; + $this->Content = $content; + parent::__construct(); + } + + /** + * The content type: Text = 0, HTML = 1. + * @var string + */ + public $ContentType; + + + /** + * The text or HTML content. + * @var string + */ + public $Content; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ItemCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ItemCollection.php new file mode 100644 index 0000000000000..9104e4da206e8 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/ItemCollection.php @@ -0,0 +1,12 @@ +isPropertyAvailable("Messages")) { + $this->setProperty("Messages", + new MessageCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Messages" + ))); + } + return $this->getProperty("Messages"); + } + + /** + * @return FolderCollection + */ + public function getChildFolders() + { + if (!$this->isPropertyAvailable("ChildFolders")) { + $this->setProperty("ChildFolders", + new FolderCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "ChildFolders" + ))); + } + + return $this->getProperty("ChildFolders"); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MeetingMessageType.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MeetingMessageType.php new file mode 100644 index 0000000000000..2cb25c1ff4c96 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MeetingMessageType.php @@ -0,0 +1,15 @@ +add("Comment",$comment); + $qry = new ClientActionInvokePostMethod($this,"Reply",null,$payload); + $this->getContext()->addQuery($qry); + } + + + /** + * Reply to the sender of a message by specifying a comment and using the Reply method. + * @param string $comment + */ + public function replyAll($comment) + { + $payload = new OperationParameterCollection(); + $payload->add("Comment",$comment); + $qry = new ClientActionInvokePostMethod($this,"ReplyAll",null,$payload); + $this->getContext()->addQuery($qry); + } + + + /** + * Forward a message by using the Forward method and optionally specifying a comment. + * @param string $comment + * @param array $toRecipients + */ + public function forward($comment,$toRecipients) + { + $payload = new OperationParameterCollection(); + $payload->add("Comment",$comment); + $payload->add("ToRecipients",$toRecipients); + $qry = new ClientActionInvokePostMethod($this,"Forward",null,$payload); + $this->getContext()->addQuery($qry); + } + + + /** + * Move a message to a folder. This creates a new copy of the message in the destination folder. + * @param string $destinationId The destination folder ID, or the Inbox, Drafts, SentItems, or + * DeletedItems well-known folder name. + */ + public function move($destinationId){ + $payload = new OperationParameterCollection(); + $payload->add("DestinationId",$destinationId); + $qry = new ClientActionInvokePostMethod($this,"Move",null,$payload); + $this->getContext()->addQuery($qry); + } + + /** + * Marks a message as read/unread + * @param bool $isRead whether or not the message is read + */ + public function read($isRead) + { + $this->setProperty("IsRead", $isRead); + $qry = new ClientActionUpdateEntity($this); + $this->getContext()->addQuery($qry); + } + + /** + * Marks a message as important/unimportant + * @param int $importance importance level (1,2,3) + */ + public function important($importance) + { + $this->setProperty("Importance", $importance); + $qry = new ClientActionUpdateEntity($this); + $this->getContext()->addQuery($qry); + } + + /** + * @param $attachmentType + * @return Attachment + */ + public function addAttachment($attachmentType){ + $attachment = new $attachmentType($this->getContext()); + $this->Attachments[] = $attachment; + return $attachment; + } + + + /** + * The FileAttachment and ItemAttachment attachments for the message. + * @var array + */ + public $Attachments; + + + /** + * The Bcc recipients for the message. + * @var array + */ + public $BccRecipients; + + + + /** + * The body of the message. + * @var ItemBody + */ + public $Body; + + + /** + * The first 255 characters of the message body content. + * @var string + */ + public $BodyPreview; + + + /** + * The categories associated with the message. + * @var array + */ + public $Categories; + + /** + * The subject of the message. + * @var string + */ + public $Subject; + + + /** + * The Cc recipients for the message. + * @var array + */ + public $CcRecipients; + + /** + * The To recipients for the message. + * @var array + */ + public $ToRecipients; + + + /** + * The ID of the conversation the email belongs to. + * @var string + */ + public $ConversationId; + + + /** + * Indicates whether the message has attachments. + * @var bool + */ + public $HasAttachments; + + + /** + * The mailbox owner and sender of the message. + * @var Recipient + */ + public $From; + + + /** + * The importance of the message + * @var string + */ + public $Importance; + + + /** + * The classification of this message for the user, + * based on inferred relevance or importance, or on an explicit override. + * @var int + */ + public $InferenceClassification; + + /** + * The account that is actually used to generate the message. + * @var Recipient + */ + public $Sender; + + + /** + * Indicates whether the message is a draft. A message is a draft if it hasn't been sent yet. + * @var bool + */ + public $IsDraft; + + + /** + * Indicates whether a read receipt is requested for the message. + * @var bool + */ + public $IsReadReceiptRequested; + + + /** + * Indicates whether a read receipt is requested for the message. + * @var bool + */ + public $IsDeliveryReceiptRequested; + + + /** + * The email addresses to use when replying. + * @var array + */ + public $ReplyTo; + + + /** + * The URL to open the message in Outlook Web App. + * @var string + */ + public $WebLink; + + + /** + * The collection of open type data extensions defined for the message. Navigation property. + * @var array + */ + public $Extensions; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MessageCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MessageCollection.php new file mode 100644 index 0000000000000..0b3626deea43a --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/MessageCollection.php @@ -0,0 +1,42 @@ +getContext()); + $qry = new ClientActionCreateEntity($this, $message); + $this->getContext()->addQuery($qry, $message); + $this->addChild($message); + return $message; + } + + /** + * @param $messageId + * @return Message + */ + public function getMessage($messageId) + { + if (!$this->isPropertyAvailable("Messages")) { + $this->setProperty("Messages", + new Message($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + $messageId + ))); + } + return $this->getProperty("Messages"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OpenTypeExtension.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OpenTypeExtension.php new file mode 100644 index 0000000000000..143cb5e09bcfe --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OpenTypeExtension.php @@ -0,0 +1,12 @@ +version = $version; + $this->serviceRootUrl = $this->serviceRootUrl . $version . "/"; + parent::__construct($this->serviceRootUrl, $authContext, new JsonFormat(ODataMetadataLevel::Verbose), $version); + } + + + + /** + * Submits query to Outlook REST/OData service + */ + public function executeQuery() + { + $this->getPendingRequest()->beforeExecuteQuery(function (RequestOptions $request,ClientAction $query){ + $this->prepareOutlookServicesRequest($request,$query); + }); + parent::executeQuery(); + } + + + + + + private function prepareOutlookServicesRequest(RequestOptions $request,ClientAction $query) + { + //set data modification headers + if ($query->ActionType == ClientActionType::UpdateEntity) { + $request->Method = HttpMethod::Patch; + } else if ($query->ActionType == ClientActionType::DeleteEntity) { + $request->Method = HttpMethod::Delete; + } + } + + + + /** + * @return User + */ + public function getMe(){ + if(!isset($this->me)) + $this->me = new User($this,new ResourcePathEntity($this,null,"me")); + return $this->me; + } + + + /** + * @return UserCollection + */ + public function getUsers(){ + if(!isset($this->users)) + $this->users = new UserCollection($this,new ResourcePathEntity($this,null,"Users")); + return $this->users; + } + + + /** + * @return GroupCollection + */ + public function getGroups(){ + if(!isset($this->groups)) + $this->groups = new GroupCollection($this,new ResourcePathEntity($this,null,"Groups")); + return $this->groups; + } + + + /** + * @var string + */ + private $serviceRootUrl = "https://outlook.office365.com/api/"; + + /** + * @var string + */ + public $version; + + /** + * @var User + */ + private $me; + + + /** + * @var UserCollection + */ + private $users; + + + /** + * @var GroupCollection + */ + private $groups; + +} + diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OutlookEntity.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OutlookEntity.php new file mode 100644 index 0000000000000..8e051cb5dc309 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/OutlookEntity.php @@ -0,0 +1,91 @@ +getContext()->addQuery($qry); + } + + + /** + * Deletes a resource + */ + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + } + + + public function addAnnotation($name, $value) + { + $this->annotations["@odata.$name"] = $value; + } + + public function ensureTypeAnnotation() + { + $typeName = $this->getEntityTypeName(); + $this->addAnnotation("type","#Microsoft.OutlookServices.$typeName"); + } + + + function getChangedProperties() + { + $properties = parent::getChangedProperties(); + $reflection = new ReflectionObject($this); + foreach ($reflection->getProperties(ReflectionProperty::IS_PUBLIC) as $p) { + $val = $p->getValue($this); + if (!is_null($val)) { + $properties[$p->name] = $val; + } + } + foreach ($this->annotations as $key => $val) { + $properties[$key] = $val; + } + return $properties; + } + + + function setProperty($name, $value, $persistChanges = true) + { + if($name == "Id"){ + if(is_null($this->getResourcePath())) + $this->setResourceUrl($this->parentCollection->getResourcePath()->toUrl() . "/" . $value); + $this->{$name} = $value; + } + else + parent::setProperty($name, $value, $persistChanges); + } + + + + /** + * @var string + */ + public $Id; + + + /** + * @var array + */ + protected $annotations = array(); + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Photo.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Photo.php new file mode 100644 index 0000000000000..1641d87d65df6 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/Photo.php @@ -0,0 +1,12 @@ +EmailAddress = $emailAddress; + parent::__construct(); + } + + /** + * The recipient's email address. + * @var EmailAddress + */ + public $EmailAddress; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/RecurrencePattern.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/RecurrencePattern.php new file mode 100644 index 0000000000000..3a685a04e8858 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/RecurrencePattern.php @@ -0,0 +1,63 @@ +isPropertyAvailable("Messages")) { + $this->setProperty("Messages", + new MessageCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Messages" + ))); + } + return $this->getProperty("Messages"); + } + + /** + * @param string $folderId + * @return MailFolder + */ + public function getFolder($folderId) + { + if (!$this->isPropertyAvailable("Folders")) { + $this->setProperty("Folders", + new MailFolder($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + $this->getFolderEntityName() . "/" . $folderId + ))); + } + return $this->getProperty("Folders"); + } + + /** + * @return MailFolder + */ + public function getFolders() + { + if (!$this->isPropertyAvailable("Folders")) { + $this->setProperty("Folders", + new MailFolder($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + $this->getFolderEntityName() + ))); + } + return $this->getProperty("Folders"); + } + + + /** + * @param Message $message + * @param bool $saveToSentItems + */ + public function sendEmail(Message $message, $saveToSentItems) + { + $payload = new OperationParameterCollection(); + $payload->add("Message", $message); + $payload->add("SaveToSentItems", $saveToSentItems); + $action = new ClientActionInvokePostMethod($this, "SendMail", null, $payload); + $this->getContext()->addQuery($action); + } + + /** + * @return ContactCollection + */ + public function getContacts() + { + if (!$this->isPropertyAvailable("Contacts")) { + $this->setProperty("Contacts", + new ContactCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Contacts" + ))); + } + return $this->getProperty("Contacts"); + } + + + /** + * @return EventCollection + */ + public function getEvents() + { + if (!$this->isPropertyAvailable("Events")) { + $this->setProperty("Events", + new EventCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Events" + ))); + } + return $this->getProperty("Events"); + } + + + /** + * @return CalendarCollection + */ + public function getCalendars() + { + if (!$this->isPropertyAvailable("Calendars")) { + $this->setProperty("Calendars", + new CalendarCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Calendars" + ))); + } + return $this->getProperty("Calendars"); + } + + + /** + * @return CalendarGroupCollection + */ + public function getCalendarGroups() + { + if (!$this->isPropertyAvailable("CalendarGroups")) { + $this->setProperty("CalendarGroups", + new CalendarGroupCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "CalendarGroups" + ))); + } + return $this->getProperty("CalendarGroups"); + } + + + /** + * @return SubscriptionCollection + */ + public function getSubscriptions() + { + if (!$this->isPropertyAvailable("Subscriptions")) { + $this->setProperty("Subscriptions", + new SubscriptionCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Subscriptions" + ))); + } + return $this->getProperty("Subscriptions"); + } + + + /** + * @return Calendar + */ + public function getCalendar() + { + if (!$this->isPropertyAvailable("Calendar")) { + $this->setProperty("Calendar", + new Calendar( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Calendar") + )); + } + return $this->getProperty("Calendar"); + } + + + /** + * @return string + * @throws \Exception + */ + private function getFolderEntityName() + { + if ($this->getContext()->getApiVersion() == Office365Version::V1) + return "Folders"; + if ($this->getContext()->getApiVersion() == Office365Version::V2) + return "MailFolders"; + + throw new \Exception("Unknown API version '" . $this->getContext()->getApiVersion() . "'"); + } + + + /** + * The user's alias. Typically the SMTP address of the user. + * @var string + */ + public $Alias; + + + /** + * The user's display name. + * @var string + */ + public $DisplayName; + + + /** + * The user's primary calendar. Navigation property. + * @var Calendar + */ + public $Calendar; + + + /** + * The GUID assigned to the user's mailbox. + * @var string + */ + public $MailboxGuid; + + /** + * The root folder of the user's mailbox. + * @var MailFolder + */ + public $RootFolder; +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/UserCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/UserCollection.php new file mode 100644 index 0000000000000..277be8a2f397b --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OutlookServices/UserCollection.php @@ -0,0 +1,11 @@ +url = $url; + $this->clientId = $clientId; + $this->clientSecret = $clientSecret; + $this->redirectUrl = $redirectUrl; + } + + public function getAuthorizationHeader() + { + return 'Bearer ' . $this->accessToken->access_token; + } + + + + + /** + * Acquires the access token from a Microsoft Azure Access Control Service (ACS) + * @param array $parameters + */ + public function acquireToken($parameters) + { + $realm = $this->getRealmFromTargetUrl(); + $urlInfo = parse_url($this->url); + $this->accessToken = $this->getAppOnlyAccessToken($urlInfo["host"],$realm); + } + + + /** + * @return mixed + */ + private function getRealmFromTargetUrl() + { + $headers = array(); + $headers['Authorization'] = 'Bearer'; + $response = Requests::head($this->url, $headers); + return $this->processRealmResponse($response); + } + + + private function processRealmResponse($response){ + $headerKey = "WWW-Authenticate"; + $result = array_filter( + explode("\r\n", $response), + function ($line) use ($headerKey) { + return substr($line, 0, strlen($headerKey)) === $headerKey; + } + ); + + if(count($result) > 0){ + $authHeader = explode(",", reset($result)); + $bearerHeader = explode(':', $authHeader[0]); + $realm = explode('=', $bearerHeader[1]); + return str_replace('"', '', $realm[1]); + } + return null; + } + + private function getAppOnlyAccessToken($targetHost,$targetRealm) + { + $resource = $this->getFormattedPrincipal(self::$SharePointPrincipal,$targetHost,$targetRealm); + $clientId = $this->getFormattedPrincipal($this->clientId,null, $targetRealm); + $stsUrl = $this->getSecurityTokenServiceUrl($targetRealm); + $oauth2Request = $this->createAccessTokenRequestWithClientCredentials($clientId,$this->clientSecret,$resource); + + $headers = array(); + $headers[] = 'content-Type: application/x-www-form-urlencoded'; + $response = Requests::post($stsUrl, $headers, $oauth2Request); + return json_decode($response); + } + + + private function getFormattedPrincipal($principalName, $hostName, $realm) + { + if ($hostName) { + return "$principalName/$hostName@$realm"; + } + return "$principalName@$realm"; + } + + private function getSecurityTokenServiceUrl($realm){ + return "https://accounts.accesscontrol.windows.net/$realm/tokens/OAuth/2"; + } + + private function createAccessTokenRequestWithClientCredentials($clientId, $clientSecret, $scope) + { + $data = array( + 'grant_type' => 'client_credentials', + 'client_id' => $clientId, + 'client_secret' => $clientSecret, + 'scope' => $scope, + 'resource' => $scope + ); + return http_build_query($data); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/AuthenticationContext.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/AuthenticationContext.php new file mode 100644 index 0000000000000..fb114621cab64 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/AuthenticationContext.php @@ -0,0 +1,186 @@ +authorityUrl = $authorityUrl; + } + + /** + * Gets URL of the authorize endpoint including the query parameters. + * @param string $authorizeUrl + * @param string $clientId + * @param string $redirectUrl + * @param array $parameters + * @return string + */ + public function getAuthorizationRequestUrl($authorizeUrl, $clientId, $redirectUrl, $parameters = []) + { + $parameters = array_merge($parameters, array( + 'response_type' => 'code', + 'client_id' => $clientId, + //'nonce' => $stateGuid->toString(), + 'redirect_uri' => $redirectUrl, + //'post_logout_redirect_uri' => $redirectUrl, + //'response_mode' => 'form_post', + //'scope' => 'openid+profile' + )); + return $authorizeUrl . "?" . http_build_query($parameters); + } + + /** + * Acquire security token from STS + * @param string $username + * @param string $password + */ + public function acquireTokenForUser($username, $password) + { + $this->provider = new SamlTokenProvider($this->authorityUrl); + $parameters = array( + 'username' => $username, + 'password' => $password + ); + $this->provider->acquireToken($parameters); + } + + /** + * @param string $resource + * @param ClientCredential $clientCredentials + */ + public function acquireTokenForClientCredential($resource, $clientCredentials) + { + $this->provider = new OAuthTokenProvider($this->authorityUrl); + $parameters = array( + 'grant_type' => 'client_credentials', + 'client_id' => $clientCredentials->ClientId, + 'client_secret' => $clientCredentials->ClientSecret, + 'scope' => $resource, + 'resource' => $resource + ); + $this->provider->acquireToken($parameters); + } + + /** + * @param $resource + * @param $clientId + * @param $clientSecret + * @param $refreshToken + * @param $redirectUri + */ + public function exchangeRefreshToken($resource, $clientId, $clientSecret, $refreshToken, $redirectUri) + { + $this->provider = new OAuthTokenProvider($this->authorityUrl); + $parameters = array( + 'grant_type' => 'refresh_token', + 'client_id' => $clientId, + 'client_secret' => $clientSecret, + 'resource' => $resource, + 'redirect_uri' => $redirectUri, + 'refresh_token' => $refreshToken + ); + $this->provider->acquireToken($parameters); + } + + /** + * @param string $resource + * @param string $clientId + * @param string $clientSecret + * @param UserCredentials $credentials + */ + public function acquireTokenForUserCredential($resource, $clientId, $clientSecret, $credentials) + { + $this->provider = new OAuthTokenProvider($this->authorityUrl); + $parameters = array( + 'grant_type' => 'password', + 'client_id' => $clientId, + 'client_secret' => $clientSecret, + 'username' => $credentials->Username, + 'password' => $credentials->Password, + 'scope' => 'openid', + 'resource' => $resource + ); + $this->provider->acquireToken($parameters); + } + + /** + * @param string $uri + * @param string $resource + * @param string $clientId + * @param string $clientSecret + * @param string $code + * @param string $redirectUrl + */ + public function acquireTokenByAuthorizationCode($uri,$resource, $clientId, $clientSecret, $code, $redirectUrl) + { + $this->provider = new OAuthTokenProvider($uri); + $parameters = array( + 'grant_type' => 'authorization_code', + 'client_id' => $clientId, + 'client_secret' => $clientSecret, + 'code' => $code, + 'resource' => $resource, + "redirect_uri" => $redirectUrl + ); + $this->provider->acquireToken($parameters); + } + + /** + * @param RequestOptions $options + * @throws \Exception + */ + public function authenticateRequest(RequestOptions $options) + { + if ($this->provider instanceof SamlTokenProvider) { + $options->addCustomHeader('Cookie', $this->provider->getAuthenticationCookie()); + } elseif ($this->provider instanceof ACSTokenProvider || $this->provider instanceof OAuthTokenProvider) { + $options->addCustomHeader('Authorization', $this->provider->getAuthorizationHeader()); + } else { + throw new \Exception("Unknown authentication provider"); + } + } + + /** + * @return null|\stdClass + */ + public function getAccessToken() + { + if ($this->provider instanceof OAuthTokenProvider) { + return $this->provider->getAccessToken(); + } + return null; + } + + /** + * @param $accessToken + */ + public function setAccessToken($accessToken) + { + $this->provider = new OAuthTokenProvider($this->authorityUrl); + $this->provider->setAccessToken($accessToken); + } +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php new file mode 100644 index 0000000000000..ced74adf41d4d --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php @@ -0,0 +1,11 @@ +Expires; + } + + /** + * @var string + */ + public $Cookie; + + /** + * @var DateTime + */ + public $Expires; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php new file mode 100644 index 0000000000000..f5276ec2efd86 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php @@ -0,0 +1,10 @@ +userCredentials = new UserCredentials($username,$password); + $this->AuthType = CURLAUTH_BASIC; //default Auth schema + } + + public function authenticateRequest(RequestOptions $options) + { + $options->AuthType = $this->AuthType; + $options->UserCredentials = $this->userCredentials; + } + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php new file mode 100644 index 0000000000000..acb107fa8d0a0 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php @@ -0,0 +1,116 @@ +authorityUrl = $authorityUrl; + } + + public function getAuthorizationHeader() + { + return 'Bearer ' . $this->accessToken->access_token; + } + + public function getAccessToken() + { + return $this->accessToken; + } + + public function setAccessToken($accessToken) + { + if (!$this->accessToken instanceof \stdClass) { + $this->accessToken = new \stdClass(); + } + $this->accessToken->access_token = $accessToken; + } + + /** + * Acquires the access token + * @param array $parameters + */ + public function acquireToken($parameters) + { + $request = $this->createRequest($parameters); + $response = Requests::execute($request); + $this->parseToken($response, $parameters); + } + + /** + * @param $parameters + * @return RequestOptions + */ + private function createRequest($parameters) + { + $tokenUrl = $this->authorityUrl . self::$TokenEndpoint; + $request = new RequestOptions($tokenUrl); + $request->addCustomHeader('content-Type', 'application/x-www-form-urlencoded'); + $request->Method = HttpMethod::Post; + $request->Data = http_build_query($parameters); + return $request; + } + + /** + * Parse the id token that represents a JWT token that contains information about the user + * @param string $tokenValue + */ + private function parseToken($tokenValue, $parameters) + { + $tokenPayload = json_decode($tokenValue); + if (is_object($tokenPayload)) { + $this->accessToken = $tokenPayload; + if (isset($tokenPayload->id_token)) { + $idToken = $tokenPayload->id_token; + $idTokenPayload = base64_decode( + explode('.', $idToken)[1] + ); + $this->accessToken->id_token_info = json_decode($idTokenPayload, true); + } + } + } +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php new file mode 100644 index 0000000000000..8b6f27e1fd226 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php @@ -0,0 +1,142 @@ +authorityUrl = $authorityUrl; + } + + + public function getAuthenticationCookie() + { + return 'FedAuth=' . $this->FedAuth . '; rtFa=' . $this->rtFa; + } + + + + public function acquireToken($parameters) + { + $token = $this->acquireSecurityToken($parameters['username'], $parameters['password']); + $this->acquireAuthenticationCookies($token); + } + + + /** + * Acquire SharePoint Online authentication (FedAuth and rtFa) cookies + * @param mixed $token + * @throws Exception + */ + protected function acquireAuthenticationCookies($token) + { + $urlInfo = parse_url($this->authorityUrl); + $url = $urlInfo['scheme'] . '://' . $urlInfo['host'] . self::$SignInPageUrl; + $response = Requests::post($url,null,$token,true); + $cookies = Requests::parseCookies($response); + $this->FedAuth = $cookies['FedAuth']; + $this->rtFa = $cookies['rtFa']; + } + + + /** + * Acquire the service token from STS + * + * @param string $username + * @param string $password + * @return string + * @throws Exception + */ + protected function acquireSecurityToken($username, $password) + { + $data = $this->prepareSecurityTokenRequest($username, $password, $this->authorityUrl); + $response = Requests::post(self::$StsUrl,null,$data); + return $this->processSecurityTokenResponse($response); + } + + + /** + * Verify and extract security token from the HTTP response + * @param mixed $response + * @return mixed + * @throws Exception + */ + protected function processSecurityTokenResponse($response) + { + $xml = new \DOMDocument(); + $xml->loadXML($response); + $xpath = new \DOMXPath($xml); + if ($xpath->query("//S:Fault")->length > 0) { + $nodeErr = $xpath->query("//S:Fault/S:Detail/psf:error/psf:internalerror/psf:text")->item(0); + throw new \Exception($nodeErr->nodeValue); + } + $nodeToken = $xpath->query("//wsse:BinarySecurityToken")->item(0); + if (empty($nodeToken)) { + throw new \RuntimeException('Error trying to get a token, check your URL or credentials'); + } + + return $nodeToken->nodeValue; + } + + /** + * Construct the request body to acquire security token from STS endpoint + * + * @param string $username + * @param string $password + * @param string $address + * @return string + * @throws Exception + */ + protected function prepareSecurityTokenRequest($username, $password, $address) + { + $fileName = __DIR__ . '/xml/SAML.xml'; + if (!file_exists($fileName)) { + throw new \Exception("The file $fileName does not exist"); + } + + $template = file_get_contents($fileName); + $template = str_replace('{username}', $username, $template); + $template = str_replace('{password}', $password, $template); + $template = str_replace('{address}', $address, $template); + return $template; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/xml/SAML.xml b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/xml/SAML.xml new file mode 100644 index 0000000000000..68defbb0c7269 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/xml/SAML.xml @@ -0,0 +1,30 @@ + + + http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue + + http://www.w3.org/2005/08/addressing/anonymous + + https://login.microsoftonline.com/extSTS.srf + + + {username} + {password} + + + + + + + + {address} + + + http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey + http://schemas.xmlsoap.org/ws/2005/02/trust/Issue + urn:oasis:names:tc:SAML:1.0:assertion + + + \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientAction.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientAction.php new file mode 100644 index 0000000000000..02afdf0e28885 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientAction.php @@ -0,0 +1,56 @@ +ResourceUrl = $resourceUrl; + $this->Payload = $payload; + $this->ActionType = $actionType; + $this->PayloadFormatType = FormatType::Json; + } + + /** + * @return string + */ + public function getId(){ + return spl_object_hash($this); + } + +} + diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionCreateEntity.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionCreateEntity.php new file mode 100644 index 0000000000000..073cf2ab4573e --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionCreateEntity.php @@ -0,0 +1,19 @@ +getResourceUrl(), $payload, (int)ClientActionType::CreateEntity); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionDeleteEntity.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionDeleteEntity.php new file mode 100644 index 0000000000000..7a74c3b6b9679 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionDeleteEntity.php @@ -0,0 +1,18 @@ +getResourceUrl(), null, (int)ClientActionType::DeleteEntity); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokeGetMethod.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokeGetMethod.php new file mode 100644 index 0000000000000..3f94618480263 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokeGetMethod.php @@ -0,0 +1,23 @@ +getResourceUrl() . "/" . ODataPathParser::fromMethod($methodName,$actionParameters); + parent::__construct($url,$requestPayload,$actionType); + $this->MethodName = $methodName; + $this->MethodParameters = $actionParameters; + } + + + /** + * @var string + */ + public $MethodName; + + + /** + * @var array + */ + public $MethodParameters; +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokePostMethod.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokePostMethod.php new file mode 100644 index 0000000000000..bca8b5827ab41 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientActionInvokePostMethod.php @@ -0,0 +1,22 @@ +getResourceUrl(), $clientObject, (int)ClientActionType::UpdateEntity); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObject.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObject.php new file mode 100644 index 0000000000000..665878f4b72b3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObject.php @@ -0,0 +1,254 @@ +context = $ctx; + $this->resourcePath = $resourcePath; + } + + /** + * @return ClientRuntimeContext + */ + public function getContext() + { + return $this->context; + } + + /** + * Removes object from parent collection + */ + protected function removeFromParentCollection() + { + if ($this->parentCollection === null) { + return; + } + $this->parentCollection->removeChild($this); + } + + /** + * @return array + */ + public function getChangedProperties() + { + return $this->changedProperties; + } + + /** + * Resolve the resource path + * @return ResourcePath + */ + public function getResourcePath() + { + return $this->resourcePath; + } + + /** + * @param string $resourcePathUrl + */ + public function setResourceUrl($resourcePathUrl) + { + $this->resourcePath = ResourcePath::parse($this->getContext(), $resourcePathUrl); + } + + /** + * Resolve the resource path + * @return string + */ + public function getResourceUrl() + { + return $this->getContext()->getServiceRootUrl() . $this->getResourcePath()->toUrl(); + } + + /** + * Gets entity type name for a resource + * @return string + */ + public function getEntityTypeName() + { + if (isset($this->resourceType)) { + return $this->resourceType; + } + $classInfo = explode("\\", get_class($this)); + return end($classInfo); + } + + /** + * Converts JSON object into OData Entity + * @param mixed $json + */ + public function convertFromJson($json) + { + foreach ($json as $key => $value) { + if ($this->isMetadataProperty($key)) { + continue; + } + if (is_object($value)) { + if ($this->isDeferredProperty($value)) { //deferred property + $this->setProperty($key, null, false); + } else { + $propertyObject = $this->getProperty($key); + if ($propertyObject instanceof ClientObject || $propertyObject instanceof ClientValueObject) { + $propertyObject->convertFromJson($value); + } else { + $this->setProperty($key, $value, false); + } + } + } elseif (is_array($value)) { + $this->convertFromJson($value); + } else { + $this->setProperty($key, $value, false); + } + } + if(!is_null($this->resourcePath)) + $this->resourcePath->ServerObjectIsNull = false; + } + + /** + * Determine whether client object property has been loaded + * @param $name + * @return bool + */ + public function isPropertyAvailable($name) + { + return isset($this->properties[$name]) && !isset($this->properties[$name]->__deferred); + } + + + /** + * Determine whether client object has been retrieved from the server + * @return bool + */ + public function getServerObjectIsNull(){ + if(!is_null($this->resourcePath)) + return $this->resourcePath->ServerObjectIsNull; + return true; + } + + /** + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * A preferred way of getting the client object property + * @param string $name + * @return mixed|null + */ + public function getProperty($name) + { + return $this->{$name}; + } + + /** + * A preferred way of setting the client object property + * @param string $name + * @param mixed $value + * @param bool $persistChanges + */ + public function setProperty($name, $value, $persistChanges = true) + { + if ($persistChanges) { + $this->changedProperties[$name] = $value; + } + + //save property + $this->{$name} = $value; + + + //update resource path + if ($name === "Id") { + if (is_null($this->getResourcePath())) { + if (is_int($value)) { + $entityKey = "({$value})"; + } else { + $entityKey = "(guid'{$value}')"; + } + $this->setResourceUrl($this->parentCollection->getResourcePath()->toUrl() . $entityKey); + } + } + + } + + /** + * @param $name + * @param $value + */ + public function __set($name, $value) + { + $this->properties[$name] = $value; + } + + /** + * @param $name + * @return mixed|null + */ + public function __get($name) + { + if (array_key_exists($name, $this->properties)) { + return $this->properties[$name]; + } + return null; + } + + /** + * @param $name + * @return bool + */ + public function __isset($name) + { + return isset($this->properties[$name]); + } + + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObjectCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObjectCollection.php new file mode 100644 index 0000000000000..7010c2c421439 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientObjectCollection.php @@ -0,0 +1,275 @@ +queryOptions = $queryOptions; + if (!isset($this->queryOptions)) + $this->queryOptions = new ODataQueryOptions(); + } + + /** + * @return string + */ + public function getResourceUrl() + { + $url = parent::getResourceUrl(); + if (!$this->queryOptions->isEmpty()) + $url = $url . "?" . $this->queryOptions->toUrl(); + return $url; + } + + + /** + * Adds client object into collection + * @param ClientObject $clientObject + * @param int $index + */ + public function addChildAt(ClientObject $clientObject, $index ) + { + array_splice($this->data,$index,0,[$clientObject]); + if (is_null($clientObject->parentCollection)) + $clientObject->parentCollection = $this; + } + + /** + * Adds client object into collection + * @param ClientObject $clientObject + */ + public function addChild(ClientObject $clientObject) + { + $this->data[] = $clientObject; + if (is_null($clientObject->parentCollection)) + $clientObject->parentCollection = $this; + } + + /** + * @param ClientObject $clientObject + */ + public function removeChild(ClientObject $clientObject) + { + if (($key = array_search($clientObject, $this->data)) !== false) { + unset($this->data[$key]); + } + } + + /** + * @return array + */ + public function getData() + { + return $this->data; + } + + + /** + * Gets the item by entity identifier + * @param int $id + * @return ClientObject + */ + public function getItemById($id) + { + $result = array_filter( + $this->data, + function (ClientObject $item) use ($id) { + return $item->getProperty("Id") === $id; + } + ); + if (count($result) > 0) + return array_values($result)[0]; + return null; + } + + + /** + * Finds items by entity property + * @param callable $callback + * @return array + */ + public function findItems(callable $callback) + { + $result = array_filter( + $this->data, + function (ClientObject $item) use ($callback) { + return call_user_func($callback, $item); + } + ); + if (count($result) > 0) + return array_values($result); + return null; + } + + + /** + * Gets the item at the specified index + * @param $index + * @return ClientObject + */ + public function getItem($index) + { + return $this->data[$index]; + } + + /** + * @return int + */ + public function getCount() + { + return count($this->data); + } + + + public function clearData() + { + $this->data = array(); + } + + + public function AreItemsAvailable() + { + return ($this->getCount() > 0); + } + + /** + * @return ODataQueryOptions + */ + public function getQueryOptions() + { + return $this->queryOptions; + } + + /** + * Specifies a subset of properties to return. + * @param $value + * @return ClientObjectCollection $this + */ + public function select($value) + { + $this->queryOptions->Select = $value; + return $this; + } + + /** + * Specifies an expression or function that must evaluate to true for a record to be returned in the collection. + * @param $value + * @return ClientObjectCollection $this + */ + public function filter($value) + { + $this->queryOptions->Filter = rawurlencode($value); + return $this; + } + + /** + * Directs that related records should be retrieved in the record or collection being retrieved. + * @param $value + * @return ClientObjectCollection $this + */ + public function expand($value) + { + $this->queryOptions->Expand = $value; + return $this; + } + + /** + * Determines the maximum number of records to return. + * @param $value + * @return ClientObjectCollection $this + */ + public function orderBy($value) + { + $this->queryOptions->OrderBy = $value; + return $this; + } + + /** + * Determines the maximum number of records to return. + * @param $value + * @return ClientObjectCollection $this + */ + public function top($value) + { + $this->queryOptions->Top = $value; + return $this; + } + + /** + * Sets the number of records to skip before it retrieves records in a collection. + * @param $value + * @return ClientObjectCollection $this + */ + public function skip($value) + { + $this->queryOptions->Skip = $value; + return $this; + } + + + /** + * Creates resource for a collection + * @return ClientObject + */ + public function createTypedObject() + { + $clientObjectType = $this->getItemTypeName(); + return new $clientObjectType($this->getContext()); + } + + + /** + * @return string + */ + /** + * @return string + */ + public function getItemTypeName() + { + return str_replace("Collection", "", get_class($this)); + } + + /** + * Converts JSON into payload + * @param mixed $json + */ + public function convertFromJson($json) + { + $this->clearData(); + foreach ($json as $item) { + $clientObject = $this->createTypedObject(); + $clientObject->parentCollection = $this; + $clientObject->convertFromJson($item); + $this->addChild($clientObject); + } + if(!is_null($this->resourcePath)) + $this->resourcePath->ServerObjectIsNull = false; + } + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRequest.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRequest.php new file mode 100644 index 0000000000000..23778b68055dd --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRequest.php @@ -0,0 +1,233 @@ +context = $context; + $this->payloadFormatType = FormatType::Json; + $this->format = $format; + $this->eventsList = array( + "BeforeExecuteQuery" => null, + "AfterExecuteQuery" => null + ); + } + + /** + * Add query into request queue + * @param ClientAction $query + * @param ClientObject $resultObject + */ + public function addQuery(ClientAction $query, $resultObject = null) + { + if (isset($resultObject)) { + $queryId = $query->getId(); + $this->resultObjects[$queryId] = $resultObject; + } + $this->queries[] = $query; + } + + /** + * @param callable $event + */ + public function beforeExecuteQuery(callable $event) + { + $this->eventsList["BeforeExecuteQuery"] = $event; + } + + /** + * @param callable $event + */ + public function afterExecuteQuery(callable $event) + { + $this->eventsList["AfterExecuteQuery"] = $event; + } + + /** + * @param RequestOptions $request + * @return ODataPayload + */ + public function executeQueryDirect(RequestOptions $request) + { + //Auth mandatory headers + $this->context->authenticateRequest($request); + //set media type headers + $this->setMediaTypeHeaders($request); + return Requests::execute($request); + } + + /** + * @param RequestOptions $request + */ + private function setMediaTypeHeaders(RequestOptions $request) + { + $request->addCustomHeader("Accept", $this->format->getMediaType()); + $request->addCustomHeader("content-type", $this->format->getMediaType()); + } + + /** + * Submit client request(s) to Office 365 API OData/SOAP service + */ + public function executeQuery() + { + $serializer = new JsonPayloadSerializer($this->format); + foreach ($this->queries as $qry) { + $request = $this->buildRequest($qry); + if (is_callable($this->eventsList["BeforeExecuteQuery"])) { + call_user_func_array($this->eventsList["BeforeExecuteQuery"], array( + $request, + $qry + )); + } + $response = $this->executeQueryDirect($request); + if (empty($response)) { + continue; + } + $responseType = $this->validateResponse($response); + //if(is_callable($this->eventsList["AfterExecuteQuery"])) + // call_user_func_array($this->eventsList["AfterExecuteQuery"],array($payload)); + //populate object + if (array_key_exists($qry->getId(), $this->resultObjects)) { + $resultObject = $this->resultObjects[$qry->getId()]; + if ($resultObject instanceof ListItemCollection && $responseType == FormatType::Xml) { + $resultObject->populateFromXmlPayload($response); //custom payload process + }else { + if ($resultObject instanceof ClientResult && $qry instanceof ClientActionInvokeMethod) { + $resultObject->EntityName = $qry->MethodName; + } + $serializer->deserialize($response, $resultObject); + } + } + } + $this->queries = array(); + } + + /** + * @param $response + * @param $resultObject + */ + public function populateObject($response, $resultObject) + { + $ser = new JsonPayloadSerializer($this->format); + $ser->deserialize($response, $resultObject); + } + + /** + * @param $response + * @return int + * @throws Exception + */ + private function validateResponse($response) + { + $json = JsonConvert::deserialize($response); + if (json_last_error() != JSON_ERROR_NONE) { + return FormatType::Xml; + } + if (property_exists($json, 'error')) { + if (is_string($json->error->message)) { + $message = $json->error->message; + }elseif (is_object($json->error->message)) { + $message = $json->error->message->value; + }else{ + $message = "Unknown error"; + } + throw new Exception($message); + } + return FormatType::Json; + } + + + /** + * @param ClientAction $query + * @return RequestOptions + */ + public function buildRequest(ClientAction $query) + { + $request = new RequestOptions($query->ResourceUrl); + if ($query->ActionType === ClientActionType::PostMethod || + $query->ActionType === ClientActionType::CreateEntity || + $query->ActionType === ClientActionType::UpdateEntity || + $query->ActionType === ClientActionType::DeleteEntity + ) { + $request->Method = HttpMethod::Post; + } + //set payload + if (!is_null($query->Payload)) { + if (is_string($query->Payload)) + $request->Data = $query->Payload; + else { + $serializer = new JsonPayloadSerializer($this->format); + $request->Data = $serializer->serialize($query->Payload); + } + } + return $request; + } + + + /** + * @param ClientObject $clientObject + * @param ODataQueryOptions $queryOptions + */ + public function addQueryAndResultObject(ClientObject $clientObject, ODataQueryOptions $queryOptions = null) + { + $resourceUrl = $clientObject->getResourceUrl(); + if (!is_null($queryOptions)) { + $resourceUrl .= '?' . $queryOptions->toUrl(); + } + $qry = new ClientActionReadEntity($resourceUrl); + $this->addQuery($qry, $clientObject); + } + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientResult.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientResult.php new file mode 100644 index 0000000000000..64ab33ff2ef4e --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientResult.php @@ -0,0 +1,36 @@ +Value = $json; + } + + function getEntityTypeName() + { + return null; + } + + + /** + * @var string + */ + public $Value; + + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php new file mode 100644 index 0000000000000..820f74899425c --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php @@ -0,0 +1,166 @@ +version = $version; + $this->serviceRootUrl = $serviceUrl; + $this->authContext = $authContext; + $this->format = $format; + } + + /** + * @param RequestOptions $options + */ + public function authenticateRequest(RequestOptions $options) + { + $this->authContext->authenticateRequest($options); + } + + /** + * Gets the service root URL that identifies the root of an OData service + * @return string + */ + public function getServiceRootUrl() + { + return $this->serviceRootUrl; + } + + /** + * Gets the api version being used + * @return string + */ + public function getApiVersion() + { + return $this->version; + } + + /** + * Prepare to load resource + * @param ClientObject $clientObject + * @param array $selectProperties + * @return ClientRuntimeContext + * + */ + public function load(ClientObject $clientObject, array $selectProperties = null) + { + if(!is_null($selectProperties)) { + $queryOptions = new ODataQueryOptions(); + $queryOptions->Select = implode(",",$selectProperties); + $this->getPendingRequest()->addQueryAndResultObject($clientObject, $queryOptions); + } + else + $this->getPendingRequest()->addQueryAndResultObject($clientObject); + return $this; + } + + + /** + * @param ClientObject $clientObject + * @param ODataQueryOptions $query + */ + public function loadQuery(ClientObject $clientObject,ODataQueryOptions $query = null) + { + $this->getPendingRequest()->addQueryAndResultObject($clientObject, $query); + } + + /** + * Submit client request to SharePoint OData/SOAP service + * + * @return self + */ + public function executeQuery() + { + $this->getPendingRequest()->executeQuery(); + return $this; + } + + /** + * @param RequestOptions $options + * @return ODataPayload + */ + public function executeQueryDirect(RequestOptions $options) + { + return $this->getPendingRequest()->executeQueryDirect($options); + } + + /** + * @param $response + * @param $resultObject + * @return self + */ + public function populateObject($response, $resultObject) + { + $this->getPendingRequest()->populateObject($response, $resultObject); + return $this; + } + + /** + * @param ClientAction $query + * @param ClientObject $resultObject + * @return self + */ + public function addQuery(ClientAction $query, $resultObject = null) + { + $this->getPendingRequest()->addQuery($query, $resultObject); + return $this; + } + + /** + * @return ClientRequest + */ + public function getPendingRequest() + { + if (!isset($this->pendingRequest)) { + $this->pendingRequest = new ClientRequest($this, $this->format); + } + return $this->pendingRequest; + } + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObject.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObject.php new file mode 100644 index 0000000000000..3464125897a81 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObject.php @@ -0,0 +1,66 @@ +entityTypeName = $entityTypeName; + } + + public function getEntityTypeName() + { + if(!isset($this->entityTypeName)){ + $typeInfo = explode("\\",get_class($this)); + $this->entityTypeName = end($typeInfo); + } + return $this->entityTypeName; + } + + /** + * CConverts the JSON into a complex type + * @param mixed $json + */ + function convertFromJson($json) + { + foreach ($json as $key => $value) { + if ($this->isMetadataProperty($key)) { + continue; + } + if (is_object($value)) { + if ($this->isDeferredProperty($value)) { //deferred property + $this->{$key} = null; + } + else { + if(property_exists($value,"results")) //collection of properties? + $this->{$key} = $value->results; + } + } + else { + $this->{$key} = $value; + } + } + } + + + + /** + * @var string + */ + private $entityTypeName; + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObjectCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObjectCollection.php new file mode 100644 index 0000000000000..0257bbe593704 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientValueObjectCollection.php @@ -0,0 +1,89 @@ +data)) + $this->data = array(); + $this->data[] = $value; + } + + + /** + * @return array + */ + public function getData() + { + return $this->data; + } + + + /** + * Clear collection + */ + public function clearData() + { + $this->data = array(); + } + + /** + * @return int + */ + public function getCount() + { + return count($this->data); + } + + + /** + * Creates entity for a collection + * @return ClientValueObject + */ + public function createTypedValueObject() + { + $clientValueObjectType = $this->getItemTypeName(); + return new $clientValueObjectType(); + } + + /** + * @return string + */ + function getItemTypeName() + { + return str_replace("Collection","",get_class($this)); + } + + + function convertFromJson($json) + { + $this->clearData(); + if (in_array($this->getEntityTypeName(), ODataPrimitiveTypeKind::getPrimitiveCollectionNames())) { + $this->data = $json->results; + } else { + foreach ($json as $item) { + $clientValueObject = $this->createTypedValueObject(); + $clientValueObject->convertFromJson($item); + $this->addChild($clientValueObject); + } + } + } + + + /** + * @var array + */ + private $data = null; + + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ContextWebInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ContextWebInformation.php new file mode 100644 index 0000000000000..68a994cbccc65 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ContextWebInformation.php @@ -0,0 +1,53 @@ +Streaming = false; + $this->IEEE754Compatible = true; + } + + + public function getMediaType() + { + $streamingValue = var_export($this->Streaming,true); + $IEEE754CompatibleValue = var_export($this->IEEE754Compatible,true); + switch($this->MetadataLevel){ + case ODataMetadataLevel::Verbose: + $metadataValue = "full"; + break; + default: + $metadataValue = $this->MetadataLevel; + break; + } + return "application/json;OData.metadata={$metadataValue};OData.streaming={$streamingValue};IEEE754Compatible={$IEEE754CompatibleValue}"; + } + + /** + * @var bool + */ + public $Streaming; + + + /** + * @var bool + */ + public $IEEE754Compatible; +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonLightFormat.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonLightFormat.php new file mode 100644 index 0000000000000..9266d9c026667 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonLightFormat.php @@ -0,0 +1,21 @@ +MetadataLevel}"; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonPayloadSerializer.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonPayloadSerializer.php new file mode 100644 index 0000000000000..a2e4eaed89c5b --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/JsonPayloadSerializer.php @@ -0,0 +1,81 @@ +Format = $format; + } + + + /** + * Generates payload for serialization + * @param ODataPayload $payload + * @return string + */ + public function serialize(ODataPayload $payload) + { + $jsonValue = $payload->convertToJson(); + if($this->Format instanceof JsonLightFormat && $this->Format->MetadataLevel == ODataMetadataLevel::Verbose){ + $metadataType = $payload->getEntityTypeName(); + if(substr( $metadataType, 0, 3 ) !== "SP.") + $metadataType = "SP." . $metadataType; + $jsonValue["__metadata"] = array("type" => $metadataType); + } + if(isset($payload->EntityName)){ + $jsonValue = array( $payload->EntityName => $jsonValue); + } + return JsonConvert::serialize($jsonValue); + } + + + /** + * Deserializes JSON payload + * @param string $value + * @param ODataPayload $payload + */ + public function deserialize($value,ODataPayload $payload) + { + $jsonValue = JsonConvert::deserialize($value); + if($this->Format instanceof JsonLightFormat){ + if($this->Format->MetadataLevel == ODataMetadataLevel::Verbose){ + if(property_exists($jsonValue,"d")){ + $jsonValue = $jsonValue->d; + } + if(property_exists($jsonValue,"results")) { + $jsonValue = $jsonValue->results; + } + } + else { + if(property_exists($jsonValue,"value")) { + $jsonValue = $jsonValue->value; + } + } + } + else { + if($this->Format->MetadataLevel == ODataMetadataLevel::Verbose && property_exists($jsonValue,"value")) { + $jsonValue = $jsonValue->value; + } + } + + if(isset($payload->EntityName)) + $jsonValue = $jsonValue->{$payload->EntityName}; + $payload->convertFromJson($jsonValue); + } + + /** + * @var ODataFormat + */ + public $Format; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataException.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataException.php new file mode 100644 index 0000000000000..1e5495b7f6c6a --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataException.php @@ -0,0 +1,10 @@ +MetadataLevel = $metadataLevel; + } + + + /** + * @return string + */ + public abstract function getMediaType(); + + /** + * @return bool + */ + public function isJson() + { + if($this instanceof JsonFormat || $this instanceof JsonLightFormat) + return true; + return false; + } + + + /** + * @return bool + */ + public function isAtom() + { + if($this instanceof AtomFormat) + return true; + return false; + } + + /** + * Controls information from the payload + * @var int + */ + public $MetadataLevel; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataMetadataLevel.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataMetadataLevel.php new file mode 100644 index 0000000000000..e99b8ae860677 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataMetadataLevel.php @@ -0,0 +1,12 @@ +mapToJson($this); + } + + /** + * Converts OData entity/complex type into Json payload + * @param $value + * @return array|mixed + */ + protected function mapToJson($value) + { + if (is_object($value)) { + if ($value instanceof ClientValueObject) { + $properties = get_object_vars($value); + foreach (get_object_vars($value) as $key => $value) { + if (is_null($value) || ($key == "EntityName")) + unset($properties[$key]); + } + return array_map(function ($p) { + return $this->mapToJson($p); + }, $properties); + } elseif ($value instanceOf ClientObject) { + if ($value instanceof ClientObjectCollection) { + return array_map(function ($p) { + return $this->mapToJson($p); + }, $value->getData()); + } else + return array_map(function ($p) { + return $this->mapToJson($p); + }, $value->getChangedProperties()); + } + } elseif (is_array($value)) { + return array_map(function ($item) { + return $this->mapToJson($item); + }, $value); + } + return $value; + } + + /** + * @return ODataPayload + */ + public function toQueryPayload() + { + $this->EntityName = "query"; + return $this; + } + + + public function toParametersPayload() + { + $this->EntityName = "parameters"; + return $this; + } + + + /** + * @param string $key + * @return bool + */ + protected function isMetadataProperty($key) + { + return $key == "__metadata"; + } + + protected function isDeferredProperty($value) + { + if (isset($value->__deferred)) + return true; + return false; + } + + + /** + * Gets entity type name + * @return string + */ + abstract function getEntityTypeName(); + + + /** + * Converts JSON into payload + * @param mixed $json + */ + abstract function convertFromJson($json); + + + /** + * @var string + */ + public $EntityName; + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataPayloadKind.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataPayloadKind.php new file mode 100644 index 0000000000000..e24eba22b2183 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/OData/ODataPayloadKind.php @@ -0,0 +1,46 @@ +getProperties()) == 0); + } + + public function toUrl() + { + $url = implode('&',array_map( + function ($key,$val) { + $key = "\$" . strtolower($key); + return "$key=$val"; + },array_keys($this->getProperties()),$this->getProperties()) + ); + return $url; + } + + + private function getProperties(){ + return array_filter((array) $this); + } + + public $Select; + + public $Filter; + + public $Expand; + + public $OrderBy; + + public $Top; + + public $Skip; + + public $Search; +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Office365Version.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Office365Version.php new file mode 100644 index 0000000000000..1fd1101ad2445 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Office365Version.php @@ -0,0 +1,12 @@ +parameters = array(); + } + + function add($name, $value) + { + $this->parameters{$name} = $value; + } + + /** + * Gets entity type name + * @return string + */ + function getEntityTypeName() + { + return null; + } + + + /** + * Converts JSON into payload + * @param mixed $json + */ + function convertFromJson($json) + { + foreach ($json as $key => $value) + $this->parameters[$key] = $value; + } + + + function convertToJson() + { + return array_map(function ($p) { + return $this->mapToJson($p); + }, $this->parameters); + } + + + /** + * @var array + */ + private $parameters; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/RequestContext.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/RequestContext.php new file mode 100644 index 0000000000000..cb5b2ae10caa0 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/RequestContext.php @@ -0,0 +1,55 @@ +site)){ + $this->site = new Site($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Site")); + } + return $this->site; + } + + /** + * @return mixed|null|Site + */ + public function getWeb() + { + if(!isset($this->web)){ + $this->web = new Web($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Web")); + } + return $this->web; + } + + + public static function GetCurrent(ClientRuntimeContext $context) + { + static $current = null; + if ($current === null) { + $current = new RequestContext($context,null); + } + return $current; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePath.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePath.php new file mode 100644 index 0000000000000..ffa52de1594a3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePath.php @@ -0,0 +1,107 @@ +context = $context; + $this->parent = $parent; + $this->ServerObjectIsNull = true; + } + + + /** + * @return ClientRuntimeContext + */ + public function getContext(){ + return $this->context; + } + + /** + * @return null|ResourcePath + */ + public function getParent(){ + return $this->parent; + } + + + /** + * @param ClientRuntimeContext $context + * @param string $value + * @return null|ResourcePathEntity + */ + public static function parse(ClientRuntimeContext $context, $value){ + + $pathNames = ODataPathParser::parsePathString($value); + $path = null; + foreach ($pathNames as $pathName){ + $path = new ResourcePathEntity($context,$path,$pathName); + } + return $path; + } + + + /** + * @return bool + */ + public function isInitialized(){ + return !is_null($this->getName()); + } + + + + /** + * @return string + */ + public function toUrl() + { + $paths = array(); + $current = clone $this; + while (isset($current)) { + array_unshift($paths, $current->getName()); + $current = $current->parent; + } + return implode("/", $paths); + } + + + /** + * @param string $url + */ + public function fromUrl($url){ + + } + + + public abstract function getName(); + + + /** + * @var ResourcePath + */ + protected $parent; + + + /** + * @var ClientRuntimeContext + */ + protected $context; + + + /** + * @var bool + */ + public $ServerObjectIsNull; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathEntity.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathEntity.php new file mode 100644 index 0000000000000..03436c6403e13 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathEntity.php @@ -0,0 +1,41 @@ +entityName = $entityName; + } + + + /** + * Gets entity name + * @return string + */ + public function getName() + { + return $this->entityName; + } + + + /** + * @var string + */ + protected $entityName; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathLink.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathLink.php new file mode 100644 index 0000000000000..c815db5e99404 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ResourcePathLink.php @@ -0,0 +1,16 @@ +methodName = $methodName; + $this->methodParameters = $methodParameters; + } + + + public function getName() + { + return ODataPathParser::fromMethod($this->methodName,$this->methodParameters); + } + + /** + * @var array + */ + protected $methodParameters; + + /** + * @var string + */ + protected $methodName; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Soap/SoapClientRequest.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Soap/SoapClientRequest.php new file mode 100644 index 0000000000000..2f9606ffee781 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Soap/SoapClientRequest.php @@ -0,0 +1,43 @@ +"); + $root->addAttribute("xmlns","http://schemas.microsoft.com/sharepoint/clientquery/2009"); + $root->addAttribute("ApplicationName",""); + $actions = $root->addChild("Actions"); + foreach( $this->queries as $query ) { + $objectPath = $actions->addChild("ObjectPath"); + } + $objectPaths = $root->addChild("ObjectPaths"); + $dom = dom_import_simplexml($root); + return $dom->ownerDocument->saveXML($dom->ownerDocument->documentElement);*/ + } + + + /** + * @param ClientAction $query + * @return RequestOptions + */ + public function buildRequest(ClientAction $query) + { + // TODO: Implement buildRequest() method. + } + + /** + * @param string $response + * @param ClientAction $query + */ + public function processResponse($response, ClientAction $query) + { + // TODO: Implement processResponse() method. + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/ClientCredential.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/ClientCredential.php new file mode 100644 index 0000000000000..a36fc9eefc04f --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/ClientCredential.php @@ -0,0 +1,28 @@ +ClientId = $clientId; + $this->ClientSecret = $clientSecret; + } + + + /** + * @var string $ClientId + */ + public $ClientId; + + + /** + * @var string $ClientSecret + */ + public $ClientSecret; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/EnumType.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/EnumType.php new file mode 100644 index 0000000000000..b78a421ed2a7e --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/EnumType.php @@ -0,0 +1,29 @@ +getConstants()); + return $enums[$value]; + } + + public static function getNames(){ + $reflection = new ReflectionClass(get_called_class()); + $enums = $reflection->getConstants(); + return array_keys($enums); + } + + + public static function getValues(){ + $reflection = new ReflectionClass(get_called_class()); + $enums = $reflection->getConstants(); + return array_values($enums); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Guid.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Guid.php new file mode 100644 index 0000000000000..a018c781a7b19 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Guid.php @@ -0,0 +1,78 @@ +guidString = $this->normalizeGuidString($guidText); + } + + public function toString($format=null) + { + if($format == "N") + $value = str_replace("-","",$this->guidString); + else if($format == "B") + $value = '{' . $this->guidString . '}'; + else + $value = $this->guidString; + return $value; + } + + /** + * @return Guid + */ + public static function newGuid() + { + $result = ''; + for ($index = 0; $index < 32; $index++) { + $value = floor(rand(0,15)); + + switch ($index) { + case 8: + $result .= '-'; + break; + case 12: + $value = 4; + $result .= '-'; + break; + case 16: + $value = $value & 3 | 8; + $result .= '-'; + break; + case 20: + $result .= '-'; + break; + } + $result .= self::$Hexcode[$value]; + } + $uuidOut = new Guid($result); + return $uuidOut; + } + + private function normalizeGuidString($guidText) + { + $newUuidText = str_replace(' ', '', $guidText); + $newUuidText = str_replace('{', '', $newUuidText); + $newUuidText = str_replace('}', '', $newUuidText); + $newUuidText = strtolower($newUuidText); + return $newUuidText; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/JsonConvert.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/JsonConvert.php new file mode 100644 index 0000000000000..a0046917419aa --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/JsonConvert.php @@ -0,0 +1,54 @@ + $value) { + $target->{$key} = $value; + } + } + + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php new file mode 100644 index 0000000000000..d41d7b2388bf7 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php @@ -0,0 +1,130 @@ +Url = $url; + $this->Method = $methodType; + $this->Headers = $headers; + $this->IncludeBody = true; + $this->IncludeHeaders = false; + $this->AuthType = null; + $this->UserCredentials = null; + $this->Verbose = false; + $this->SSLVersion = null; + } + + public function toArray() + { + return [ + 'Url' => $this->Url, + 'Method' => $this->Method, + 'Headers' => $this->Headers, + 'Data' => $this->Data, + 'IncludeBody' => $this->IncludeBody, + 'IncludeHeaders' => $this->IncludeHeaders, + 'AuthType' => $this->AuthType, + 'Verbose' => $this->Verbose, + 'UserCredentials' => $this->UserCredentials, + 'SSLVersion' => $this->SSLVersion, + ]; + } + + + public function addCustomHeader($name, $value) + { + if (is_null($this->Headers)) + $this->Headers = array(); + if (!array_key_exists($name, $this->Headers)) + $this->Headers[$name] = $value; + } + + public function getRawHeaders() + { + $headers = array_map( + function ($k, $v) { + return "$k:$v"; + }, + array_keys($this->Headers), + array_values($this->Headers) + ); + return $headers; + } + + + /** + * @var string + */ + public $Url; + + + /** + * @var bool + */ + public $Method; + + /** + * Gets/sets custom HTTP headers + * @var array + */ + public $Headers; + + + /** + * @var string + */ + public $Data; + + /** + * Gets/sets whether to return response headers only + * @var bool + */ + public $IncludeHeaders; + + + /** + * Do the download request without getting the body + * @var bool + */ + public $IncludeBody; + + + /** + * @var int + */ + public $AuthType; + + + /** + * @var UserCredentials + */ + public $UserCredentials; + + + /** + * @var bool + */ + public $Verbose; + + + /** + * @var int + */ + public $SSLVersion; + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php new file mode 100644 index 0000000000000..13ed51ce02bf0 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php @@ -0,0 +1,131 @@ + false, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_RETURNTRANSFER => true, + ); + + public static function getHistory() + { + return self::$history; + } + + protected static $history = []; + + public static function execute(RequestOptions $options) + { + $call = []; + $call['request'] = $options->toArray(); + + $ch = Requests::init($options); + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + $call['response'] = $response; + + if ($response === false) { + throw new \Exception(curl_error($ch)); + } + curl_close($ch); + + self::$history[] = $call; + + return $response; + } + + + public static function get($url,$headers) + { + $options = new RequestOptions($url); + $options->Headers = $headers; + return Requests::execute($options); + } + + public static function head($url,$headers) + { + $options = new RequestOptions($url); + $options->IncludeHeaders = true; + $options->IncludeBody = false; + $options->Headers = $headers; + return Requests::execute($options); + } + + public static function post($url, $headers, $data, $includeHeaders = false) + { + $options = new RequestOptions($url); + $options->Method = HttpMethod::Post; + $options->Headers = $headers; + $options->Data = $data; + $options->IncludeHeaders = $includeHeaders; + return Requests::execute($options); + } + + + /** + * Parse cookies (http://stackoverflow.com/a/895858/1375553) + * @param $response + * @return array + */ + public static function parseCookies($response) + { + preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', $response, $matches); + $cookies = array(); + foreach($matches[1] as $item) { + list($k, $v) = explode('=', $item,2); + $cookies[$k] = $v; + } + return $cookies; + } + + + /** + * Init Curl with the default parameters + * @param RequestOptions $options + * @return resource [type] [description] + */ + private static function init(RequestOptions $options) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $options->Url); + curl_setopt_array($ch, self::$defaultOptions); //default options + //include headers in response + curl_setopt($ch, CURLOPT_HEADER, $options->IncludeHeaders); + //include body in response + curl_setopt($ch, CURLOPT_NOBODY, !$options->IncludeBody); + //Set method + if($options->Method == HttpMethod::Post) + curl_setopt($ch, CURLOPT_POST, 1); + else if($options->Method == HttpMethod::Patch) + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $options->Method); + else if($options->Method == HttpMethod::Delete) + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $options->Method); + //set Post Body + if(isset($options->Data)) + curl_setopt($ch, CURLOPT_POSTFIELDS, $options->Data); + $options->addCustomHeader("content-length",strlen($options->Data)); + //custom HTTP headers + if($options->Headers) + curl_setopt($ch, CURLOPT_HTTPHEADER, $options->getRawHeaders()); + //debugging mode + curl_setopt($ch,CURLOPT_VERBOSE, $options->Verbose); + //SSL Version + if(!is_null($options->SSLVersion)) { + curl_setopt($ch,CURLOPT_SSLVERSION, $options->SSLVersion); + } + //authentication + if(!is_null($options->AuthType)) + curl_setopt($ch,CURLOPT_HTTPAUTH, $options->AuthType); + if(!is_null($options->UserCredentials)) + curl_setopt($ch,CURLOPT_USERPWD, $options->UserCredentials->toString()); + + return $ch; + } + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/UserCredentials.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/UserCredentials.php new file mode 100644 index 0000000000000..3fec6066cf307 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/UserCredentials.php @@ -0,0 +1,31 @@ +Username = $username; + $this->Password = $password; + } + + public function toString(){ + return $this->Username . ':' . $this->Password; + } + + /** + * @var string + */ + public $Username; + + + /** + * @var string + */ + public $Password; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AddFieldOptions.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AddFieldOptions.php new file mode 100644 index 0000000000000..92a726d57c214 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AddFieldOptions.php @@ -0,0 +1,18 @@ +getContext()->addQuery($qry); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php new file mode 100644 index 0000000000000..5ab3be6e0ff47 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php @@ -0,0 +1,39 @@ +getContext()); + $qry = new ClientActionCreateEntity($this,$information); + $this->getContext()->addQuery($qry,$attachment); + $this->addChild($attachment); + return $attachment; + } + + /** + * @param string $fileName + * @return Attachment + */ + public function getByFileName($fileName) + { + return new Attachment( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"GetByFileName",array($fileName)) + ); + } + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCreationInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCreationInformation.php new file mode 100644 index 0000000000000..5bb2daa518f3e --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCreationInformation.php @@ -0,0 +1,23 @@ +High & (int)32767) == (int)32767) + return (int)$this->Low == (int)65535; + return false; + } + $high = (int)($perm - 1); + $low = 1; + if ($high >= 0 && $high < 32) + return 0 != ((int)$this->Low & (int)($low << $high)); + if ($high >= 32 && $high < 64) + return 0 != ((int)$this->High & (int)($low << $high - 32)); + return false; + } + + /** + * + */ + public function clearAll() + { + $this->Low = 0; + $this->High = 0; + } + + + /*function convertToEntity(ODataPayload $payload, ODataFormat $format) + { + if($format->MetadataLevel == ODataMetadataLevel::Verbose) + $payload = $payload->Value->GetUserEffectivePermissions; + parent::convertToEntity($payload, $format); + }*/ + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/CamlQuery.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/CamlQuery.php new file mode 100644 index 0000000000000..2378eaaa38238 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/CamlQuery.php @@ -0,0 +1,54 @@ +ViewXml = "\r\n \r\n \r\n"; + return $qry; + } + + public static function createAllFoldersQuery() + { + $qry = new CamlQuery(); + $qry->ViewXml = "\r\n \r\n \r\n \r\n \r\n 1\r\n \r\n \r\n \r\n"; + return $qry; + } + + + /** + * Gets or sets a value that indicates whether the query returns dates in Coordinated Universal Time (UTC) format. + * @var \DateTime + */ + public $DatesInUtc; + + /** + * Gets or sets a value that specifies the server relative URL of a list folder from which results will be returned. + * @var string + */ + public $FolderServerRelativeUrl; + + /** + * Gets or sets a value that specifies the information required to get the next page of data for the list view. + * @var ListItemCollectionPosition + */ + public $ListItemCollectionPosition; + + + /** + * Gets or sets value that specifies the XML schema that defines the list view. + * @var string + */ + public $ViewXml; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Change.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Change.php new file mode 100644 index 0000000000000..95f6d6e589ca1 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Change.php @@ -0,0 +1,19 @@ +ViewName = ""; + $this->Query = ""; + $this->QueryOptions = ""; + $this->Contains = ""; + parent::__construct(); + } + + + /** + * A string that contains either the title or the GUID for the list. When querying the UserInfo table, + * the string contains UserInfo. Using the GUID results in better performance. + */ + //public $ListName; + + /** + * A string that contains the GUID for the view, which determines the view to use for the default view + * attributes represented by the query, viewFields, and rowLimit parameters. If this argument is not supplied, + * the default view is assumed. If it is supplied, the value of the query, viewFields, + * or rowLimit parameter overrides the equivalent setting within the view. For example, + * if the view specified by the viewFields parameter has a row limit of 100 rows but the rowLimit parameter + * contains a value of 1000, then 1,000 rows are returned in the response. + */ + public $ViewName; + + /** + * A Query element containing the query that determines which records are returned and in what order. + */ + public $Query; + + /** + * An XML fragment in the following form that contains separate nodes for the various properties of the SPQuery object. + */ + public $QueryOptions; + + /** + * A string that contains the change token for the request. For a description of the format that is used in this string, + * see Overview of the Change Log. If null is passed, all items in the list are returned. + */ + public $ChangeToken; + + + /** + * A Contains element that defines custom filtering for the query. + */ + public $Contains; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeQuery.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeQuery.php new file mode 100644 index 0000000000000..f9f1aff3b56da --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeQuery.php @@ -0,0 +1,252 @@ +Add = false; + $this->Alert = false; + $this->ContentType = false; + $this->DeleteObject = false; + $this->Field = false; + $this->File = false; + $this->Folder = false; + $this->Group = false; + $this->Web = false; + $this->Update = false; + $this->GroupMembershipAdd = false; + $this->GroupMembershipDelete = false; + $this->Item = false; + $this->List = false; + $this->Move = false; + $this->Navigation = false; + $this->Rename = false; + $this->Restore = false; + $this->RoleAssignmentAdd = false; + $this->RoleAssignmentDelete = false; + $this->RoleDefinitionAdd = false; + $this->RoleDefinitionDelete = false; + $this->RoleDefinitionUpdate = false; + $this->SecurityPolicy = false; + $this->Site = false; + $this->SystemUpdate = false; + $this->User = false; + $this->View = false; + parent::__construct(); + } + + + /** + * Gets or sets a value that specifies whether add changes are included in the query. + * @var boolean + */ + public $Add; + + /** + * Gets or sets a value that specifies whether changes to alerts are included in the query. + * @var bool + */ + public $Alert; + + + /** + * Gets or sets a value that specifies the end date and end time for changes that are returned through the query. + * @var ChangeToken + */ + public $ChangeTokenEnd; + + + /** + * Gets or sets a value that specifies the start date and start time for changes that are returned through the query. + * @var boolean + */ + public $ChangeTokenStart; + + + /** + * Gets or sets a value that specifies whether changes to content types are included in the query. + * @var boolean + */ + public $ContentType; + + + /** + * Gets or sets a value that specifies whether changes to content types are included in the query. + * @var boolean + */ + public $DeleteObject; + + /** + * Gets or sets a value that specifies whether changes to content types are included in the query. + * @var boolean + */ + public $Field; + + + /** + * Gets or sets a value that specifies whether changes to content types are included in the query. + * @var boolean + */ + public $File; + + + /** + * Gets or sets value that specifies whether changes to folders are included in the query. + * @var boolean + */ + public $Folder; + + + /** + * Gets or sets a value that specifies whether changes to groups are included in the query. + * @var boolean + */ + public $Group; + + + /** + * Gets or sets a value that specifies whether adding users to groups is included in the query. + * @var bool + */ + public $GroupMembershipAdd; + + + /** + * Gets or sets a value that specifies whether deleting users from the groups is included in the query. + * @var bool + */ + public $GroupMembershipDelete; + + + /** + * Gets or sets a value that specifies whether general changes to list items are included in the query. + * @var bool + */ + public $Item; + + + /** + * Gets or sets a value that specifies whether changes to lists are included in the query. + * @var bool + */ + public $List; + + + /** + * Gets or sets a value that specifies whether move changes are included in the query. + * @var boolean + */ + public $Move; + + + /** + * Gets or sets a value that specifies whether changes to the navigation structure of a site collection are included in the query. + * @var boolean + */ + public $Navigation; + + + /** + * Gets or sets a value that specifies whether renaming changes are included in the query. + * @var boolean + */ + public $Rename; + + + /** + * Gets or sets a value that specifies whether restoring items from the recycle bin or from backups is included in the query. + * @var bool + */ + public $Restore; + + + /** + * Gets or sets a value that specifies whether adding role assignments is included in the query. + * @var bool + */ + public $RoleAssignmentAdd; + + + /** + * Gets or sets a value that specifies whether adding role assignments is included in the query. + * @var bool + */ + public $RoleAssignmentDelete; + + + /** + * Gets or sets a value that specifies whether adding role assignments is included in the query. + * @var bool + */ + public $RoleDefinitionAdd; + + + /** + * Gets or sets a value that specifies whether adding role assignments is included in the query. + * @var bool + */ + public $RoleDefinitionDelete; + + + /** + * Gets or sets a value that specifies whether adding role assignments is included in the query. + * @var bool + */ + public $RoleDefinitionUpdate; + + + /** + * Gets or sets a value that specifies whether modifications to security policies are included in the query. + * @var bool + */ + public $SecurityPolicy; + + + /** + * Gets or sets a value that specifies whether changes to site collections are included in the query. + * @var bool + */ + public $Site; + + + /** + * Gets or sets a value that specifies whether updates made using the item SystemUpdate method are included in the query. + * @var bool + */ + public $SystemUpdate; + + + /** + * Gets or sets a value that specifies whether update changes are included in the query. + * @var bool + */ + public $Update; + + + /** + * Gets or sets a value that specifies whether changes to users are included in the query. + * @var bool + */ + public $User; + + + /** + * Gets or sets a value that specifies whether changes to views are included in the query. + * @var bool + */ + public $View; + + + /** + * Gets or sets a value that specifies whether changes to Web sites are included in the query. + * @var boolean + */ + public $Web; +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeSite.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeSite.php new file mode 100644 index 0000000000000..98c1222d93d7f --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ChangeSite.php @@ -0,0 +1,10 @@ +contextWebInformation)) { + $this->requestFormDigest(); + } + $request->addCustomHeader("X-RequestDigest",$this->getContextWebInformation()->FormDigestValue); + } + + /** + * Request the SharePoint Context Info + */ + protected function requestFormDigest() + { + $request = new RequestOptions($this->getServiceRootUrl() . "contextinfo"); + $request->Method = HttpMethod::Post; + $response = $this->executeQueryDirect($request); + if(!isset($this->contextWebInformation)) + $this->contextWebInformation = new ContextWebInformation(); + if($this->format->MetadataLevel == ODataMetadataLevel::Verbose){ + $this->contextWebInformation->EntityName = "GetContextWebInformation"; + } + $this->populateObject($response,$this->contextWebInformation); + } + + /** + * Submits query to SharePoint REST/OData service + */ + public function executeQuery() + { + $this->getPendingRequest()->beforeExecuteQuery(function (RequestOptions $request,ClientAction $query){ + $this->buildSharePointSpecificRequest($request,$query); + }); + parent::executeQuery(); + } + + /** + * @param RequestOptions $request + * @param ClientAction $query + */ + private function buildSharePointSpecificRequest(RequestOptions $request,ClientAction $query){ + + if($request->Method === HttpMethod::Post) { + $this->ensureFormDigest($request); + } + //set data modification headers + if ($query->ActionType === ClientActionType::UpdateEntity) { + $request->addCustomHeader("IF-MATCH", "*"); + $request->addCustomHeader("X-HTTP-Method", "MERGE"); + } else if ($query->ActionType === ClientActionType::DeleteEntity) { + $request->addCustomHeader("IF-MATCH", "*"); + $request->addCustomHeader("X-HTTP-Method", "DELETE"); + } + } + + /** + * @return Web + */ + public function getWeb() + { + if(!isset($this->web)){ + $this->web = new Web($this,new ResourcePathEntity($this,null,"Web")); + } + return $this->web; + } + + /** + * @return Site + */ + public function getSite() + { + if(!isset($this->site)){ + $this->site = new Site($this, new ResourcePathEntity($this,null,"Site")); + } + return $this->site; + } + + /** + * @return ContextWebInformation + */ + public function getContextWebInformation() + { + return $this->contextWebInformation; + } +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentType.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentType.php new file mode 100644 index 0000000000000..194dc12fedfa7 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentType.php @@ -0,0 +1,37 @@ +getContext()->addQuery($qry); + } + + + + function setProperty($name, $value, $persistChanges = true) + { + if ($name == "StringId") { + $this->setResourceUrl($this->parentCollection->getResourcePath()->toUrl() . "('{$value}')"); + $this->{$name} = $value; + } + elseif ($name == "Id"){ + $this->{$name} = $value->StringValue; + } + else + parent::setProperty($name, $value, $persistChanges); + } + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCollection.php new file mode 100644 index 0000000000000..3bda64c68953b --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCollection.php @@ -0,0 +1,43 @@ +getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"GetById",array($id)) + ); + $contentType->parentCollection = $this; + return $contentType; + } + + + /** + * Creates a ContentType resource + * @param ContentTypeCreationInformation $information + * @return ContentType + */ + public function add(ContentTypeCreationInformation $information) + { + $contentType = new ContentType($this->getContext()); + $qry = new ClientActionCreateEntity($this,$information); + $this->getContext()->addQuery($qry,$contentType); + $this->addChild($contentType); + return $contentType; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCreationInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCreationInformation.php new file mode 100644 index 0000000000000..71ed020c4eec7 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeCreationInformation.php @@ -0,0 +1,71 @@ +ParentId = $parentId; + } + + + /** + * formula: Parent content type ID + "00" + hexadecimal GUID + * ref: https://msdn.microsoft.com/en-us/library/office/aa543822(v=office.14).aspx + * @return string + */ + /*function toJson() + { + if(!isset($this->Id)){ + if(isset($this->ParentId)){ + $this->Id = new ContentTypeId(); + $this->Id->StringValue = $this->ParentId . "00" . Guid::newGuid()->toString("N"); + } + } + return parent::toJson(); + }*/ + + + /** + * Gets or sets a value that specifies the description of the content type that will be constructed. + * @var string + */ + public $Description; + + + /** + * Gets or sets a value that specifies the content type group of the content type that will be constructed. + * @var string + */ + public $Group; + + + /** + * @var ContentTypeId + */ + public $Id; + + + /** + * @var string + */ + public $Name; + + + /** + * @var string + */ + private $ParentId; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeId.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeId.php new file mode 100644 index 0000000000000..b4405766b5a98 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ContentTypeId.php @@ -0,0 +1,18 @@ +getContext()->addQuery($qry,$this); + } + + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + } + + /** + * Sets the value of the ShowInDisplayForm property for this field. + * @param $value true to show the field in the form; otherwise false. + */ + public function setShowInDisplayForm($value){ + $qry = new ClientActionInvokePostMethod( + $this, + "setShowInDisplayForm", + array($value) + ); + $this->getContext()->addQuery($qry); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldCalculated.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldCalculated.php new file mode 100644 index 0000000000000..864c1e106ed7d --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldCalculated.php @@ -0,0 +1,10 @@ +getContext(),$this->getResourcePath()); + $qry = new ClientActionCreateEntity($this,$parameters); + $this->getContext()->addQuery($qry,$field); + $this->addChild($field); + return $field; + } + + + /** + * @param string $title + * @return Field + */ + public function getByTitle($title) + { + return new Field( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getByTitle",array($title)) + ); + } + + /** + * @param string $internalNameOrTitle + * @return Field + */ + public function getByInternalNameOrTitle($internalNameOrTitle) + { + return new Field( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getByInternalNameOrTitle",array($internalNameOrTitle)) + ); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldComputed.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldComputed.php new file mode 100644 index 0000000000000..d593e8adc6aa8 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FieldComputed.php @@ -0,0 +1,10 @@ +getContext()->addQuery($qry); + } + + + /** + * Reverts an existing checkout for the file. + */ + public function undoCheckout(){ + $qry = new ClientActionInvokePostMethod($this,"undocheckout"); + $this->getContext()->addQuery($qry); + } + + + /** + * Checks the file in to a document library based on the check-in type. + * @param string $comment A comment for the check-in. Its length must be <= 1023. + */ + public function checkIn($comment){ + $qry = new ClientActionInvokePostMethod($this,"checkIn",array( + "comment" =>$comment, + "checkintype" =>0 + )); + $this->getContext()->addQuery($qry); + } + + + /** + * Approves the file submitted for content approval with the specified comment. + * @param string $comment The comment for the approval. + */ + public function approve($comment){ + $qry = new ClientActionInvokePostMethod($this,"approve",array( + "comment" =>$comment + )); + $this->getContext()->addQuery($qry); + } + + /** + * Denies approval for a file that was submitted for content approval. + * @param string $comment The comment for the denial. + */ + public function deny($comment){ + $qry = new ClientActionInvokePostMethod($this, "deny",array( + "comment" =>$comment + )); + $this->getContext()->addQuery($qry); + } + + /** + * Submits the file for content approval with the specified comment. + * @param string $comment The comment for the published file. Its length must be <= 1023. + */ + public function publish($comment){ + $qry = new ClientActionInvokePostMethod($this, "publish",array( + "comment" =>$comment + )); + $this->getContext()->addQuery($qry); + } + + + /** + * Removes the file from content approval or unpublish a major version. + * @param string $comment The comment for the unpublish operation. Its length must be <= 1023. + */ + public function unpublish($comment){ + $qry = new ClientActionInvokePostMethod($this,"unpublish", array( + "comment" => $comment + )); + $this->getContext()->addQuery($qry); + } + + + /** + * Copies the file to the destination URL. + * @param string $strNewUrl The absolute URL or server relative URL of the destination file path to copy to. + * @param bool $bOverWrite true to overwrite a file with the same name in the same location; otherwise false. + */ + public function copyTo($strNewUrl,$bOverWrite){ + $qry = new ClientActionInvokePostMethod($this, "copyto", array( + "strnewurl"=>$strNewUrl, + "boverwrite"=>$bOverWrite + )); + $this->getContext()->addQuery($qry); + } + + /** + * Moves the file to the specified destination URL. + * @param string $newUrl The absolute URL or server relative URL of the destination file path to move to. + * @param int $flags The bitwise SP.MoveOperations value for how to move the file. Overwrite = 1; AllowBrokenThickets (move even if supporting files are separated from the file) = 8. + */ + public function moveTo($newUrl,$flags){ + $qry = new ClientActionInvokePostMethod($this, "moveto", array( + "newurl"=>$newUrl, + "flags"=>$flags + )); + $this->getContext()->addQuery($qry); + } + + + /** + * Moves the file to the Recycle Bin and returns the identifier of the new Recycle Bin item. + */ + public function recycle(){ + $qry = new ClientActionInvokePostMethod($this, "recycle"); + $this->getContext()->addQuery($qry); + } + + + /** + * Opens the file + * @param ClientRuntimeContext $ctx + * @param $serverRelativeUrl + * @return mixed|string + */ + public static function openBinary(ClientRuntimeContext $ctx, $serverRelativeUrl){ + $serverRelativeUrl = rawurlencode($serverRelativeUrl); + $url = $ctx->getServiceRootUrl() . "web/getfilebyserverrelativeurl('$serverRelativeUrl')/\$value"; + $options = new RequestOptions($url); + $data = $ctx->executeQueryDirect($options); + return $data; + } + + /** + * Saves the file + * Note: it is supported to update the existing file only. For adding a new file see FileCollection.add method + * @param ClientRuntimeContext $ctx + * @param string $serverRelativeUrl + * @param string $content file content + */ + public static function saveBinary(ClientRuntimeContext $ctx, $serverRelativeUrl, $content) + { + $serverRelativeUrl = rawurlencode($serverRelativeUrl); + $url = $ctx->getServiceRootUrl() . "web/getfilebyserverrelativeurl('$serverRelativeUrl')/\$value"; + $request = new RequestOptions($url); + $request->Method = HttpMethod::Post; + $request->addCustomHeader('X-HTTP-Method','PUT'); + $request->Data = $content; + $ctx->executeQueryDirect($request); + } + + + /** + * Specifies the control set used to access, modify, or add Web Parts associated with this Web Part Page and view. + * An exception is thrown if the file is not an ASPX page. + * @param int $scope + * @return LimitedWebPartManager + */ + public function getLimitedWebPartManager($scope) + { + $manager = new LimitedWebPartManager($this->getContext(), + new ResourcePathServiceOperation($this->getContext(), + $this->getResourcePath(), + "getlimitedwebpartmanager", + array($scope) + )); + return $manager; + } + + /** + * Returns IRM settings for given file. + * + * @return InformationRightsManagementSettings + */ + public function getInformationRightsManagementSettings() + { + if(!$this->isPropertyAvailable('InformationRightsManagementSettings')){ + $this->setProperty("InformationRightsManagementSettings",new InformationRightsManagementSettings($this->getContext(),$this->getResourcePath(), "InformationRightsManagementSettings")); + } + return $this->getProperty("InformationRightsManagementSettings"); + } + + + /** + * Gets a value that returns a collection of file version objects that represent the versions of the file. + * @return FileVersionCollection + */ + public function getVersions() + { + if(!$this->isPropertyAvailable('Versions')){ + $this->setProperty("Versions", new FileVersionCollection($this->getContext(),$this->getResourcePath(), "Versions")); + } + return $this->getProperty("Versions"); + } + + /** + * Gets a value that indicates how the file is checked out of a document library + * @return int|null + */ + public function getCheckOutType() + { + if($this->isPropertyAvailable('CheckOutType')){ + return $this->getProperty("CheckOutType"); + } + return null; + } + + + /** + * Specifies the list item field (2) values for the list item corresponding to the file. + * @return ListItem + */ + public function getListItemAllFields() + { + if (!$this->isPropertyAvailable("ListItemAllFields")) { + $this->setProperty("ListItemAllFields", + new ListItem( + $this->getContext(), + new ResourcePathEntity($this->getContext(), $this->getResourcePath(), "ListItemAllFields") + ) + ); + } + return $this->getProperty("ListItemAllFields"); + } + + + + function setProperty($name, $value, $persistChanges = true) + { + parent::setProperty($name, $value, $persistChanges); + if ($name == "UniqueId") { + $this->setResourceUrl("Web/GetFileById(guid'{$value}')"); + } + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCollection.php new file mode 100644 index 0000000000000..1ceb161d3ce5f --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCollection.php @@ -0,0 +1,58 @@ +getContext(),$this->getResourcePath()); + $qry = new ClientActionInvokePostMethod( + $this, + "add", + array("overwrite"=>$fileCreationInformation->Overwrite,"url"=>rawurlencode($fileCreationInformation->Url)), + $fileCreationInformation->Content + ); + $this->getContext()->addQuery($qry,$file); + //$this->addChild($file); + return $file; + } + + + /** + * Adds a ghosted file to an existing list or document library. + * @param $urlOfFile + * @param $templateFileType + * @return File + */ + public function addTemplateFile($urlOfFile,$templateFileType) + { + $file = new File($this->getContext(),$this->getResourcePath()); + $qry = new ClientActionInvokePostMethod( + $this, + "addTemplateFile", + array( + "urlOfFile" => $urlOfFile, + "templateFileType" => (int)$templateFileType + ) + ); + $this->getContext()->addQuery($qry,$file); + return $file; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCreationInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCreationInformation.php new file mode 100644 index 0000000000000..96e9fe845133a --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileCreationInformation.php @@ -0,0 +1,37 @@ +Overwrite = true; + } + + + /** + * @var string + */ + public $Url; + + /** + * @var string + */ + public $Content; + + /** + * @var bool + */ + public $Overwrite; + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileVersion.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileVersion.php new file mode 100644 index 0000000000000..8c6fdfc203b46 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FileVersion.php @@ -0,0 +1,13 @@ +getContext()->addQuery($qry); + //$this->removeFromParentCollection(); + } + + + + public function rename($name){ + $item = $this->getListItemAllFields(); + $item->setProperty('Title',$name); + $item->setProperty('FileLeafRef', $name); + $qry = new ClientActionUpdateEntity($item); + $this->getContext()->addQuery($qry,$this); + } + + /** + * Moves the list folder to the Recycle Bin and returns the identifier of the new Recycle Bin item. + */ + public function recycle(){ + $qry = new ClientActionInvokePostMethod($this,"recycle"); + $this->getContext()->addQuery($qry); + } + + /** + * Gets the collection of all files contained in the list folder. + * You can add a file to a folder by using the Add method on the folder’s FileCollection resource. + * @return FileCollection + * @throws \Exception + */ + public function getFiles() + { + if(!$this->isPropertyAvailable('Files')){ + $this->setProperty("Files", new FileCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "Files"))); + } + return $this->getProperty("Files"); + } + + + /** + * Gets the collection of list folders contained in the list folder. + * @return FolderCollection + */ + public function getFolders() + { + if(!$this->isPropertyAvailable("Folders")){ + $this->setProperty("Folders", + new FolderCollection($this->getContext(), new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "folders"))); + } + return $this->getProperty("Folders"); + } + + + /** + * Specifies the list item field (2) values for the list item corresponding to the folder. + * @return ListItem + */ + public function getListItemAllFields() + { + if (!$this->isPropertyAvailable("ListItemAllFields")) { + $this->setProperty("ListItemAllFields", + new ListItem( + $this->getContext(), + new ResourcePathEntity($this->getContext(), $this->getResourcePath(), "ListItemAllFields") + ) + ); + } + return $this->getProperty("ListItemAllFields"); + } + + + function setProperty($name, $value, $persistChanges = true) + { + parent::setProperty($name, $value, $persistChanges); + if ($name == "UniqueId") { + $this->setResourceUrl("Web/GetFolderById(guid'{$value}')"); + } + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FolderCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FolderCollection.php new file mode 100644 index 0000000000000..72e8723816d63 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/FolderCollection.php @@ -0,0 +1,22 @@ +getContext()); + $folder->setProperty("ServerRelativeUrl", rawurlencode($url)); + $qry = new ClientActionCreateEntity($this, $folder); + $this->getContext()->addQuery($qry, $folder); + return $folder; + } +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Group.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Group.php new file mode 100644 index 0000000000000..63a5aef6c1578 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Group.php @@ -0,0 +1,24 @@ +isPropertyAvailable('Users')){ + $this->setProperty("Users", new UserCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath() , "Users"))); + } + return $this->getProperty("Users"); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCollection.php new file mode 100644 index 0000000000000..28bf44a9e3caa --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCollection.php @@ -0,0 +1,84 @@ +getContext(), $this->getResourcePath()); + $qry = new ClientActionCreateEntity($this, $parameters); + $this->getContext()->addQuery($qry, $group); + $this->addChild($group); + return $group; + } + + /** + * Returns a group from the collection based on the member ID of the group. + * @param int $id The ID of the group to get. + * @return Group The specified group. + * @throws \Exception + */ + public function getById($id) + { + $group = new Group( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(), $this->getResourcePath(), "getById", array($id)) + ); + return $group; + } + + /** + * Returns a cross-site group from the collection based on the name of the group. + * @param string $name The name of the group. The group name is specified in its LoginName property. + * @return Group + * @throws \Exception + */ + public function getByName($name) + { + $group = new Group( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(), $this->getResourcePath(), "getbyname", array($name)) + ); + return $group; + } + + /** + * Removes the group with the specified member ID from the collection. + * @param int $id The ID of the group to remove. + * @throws \Exception + */ + public function removeById($id) + { + $qry = new ClientActionInvokePostMethod($this, "removebyid", array($id)); + $this->getContext()->addQuery($qry); + } + + /** + * Removes the cross-site group with the specified name from the collection. + * @param string $groupName The name of the group to remove. The group name is specified in its LoginName property. + * @throws \Exception + */ + public function removeByLoginName($groupName) + { + $qry = new ClientActionInvokePostMethod($this, "removeByLoginName", array($groupName)); + $this->getContext()->addQuery($qry); + } +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCreationInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCreationInformation.php new file mode 100644 index 0000000000000..9cd2124aeb8ec --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/GroupCreationInformation.php @@ -0,0 +1,30 @@ +Title = $title; + $this->Description = ""; + parent::__construct("Group"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/InformationRightsManagementSettings.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/InformationRightsManagementSettings.php new file mode 100644 index 0000000000000..08af4bb516ae3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/InformationRightsManagementSettings.php @@ -0,0 +1,38 @@ +getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getByTitle",array($title)) + ); + } + + /** + * Get List by id + * @param $id + * @return SPList + */ + public function getById($id) + { + return new SPList( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getById",array($id)) + ); + } + + + /** + * Creates a List resource + * @param ListCreationInformation $parameters + * @return SPList + */ + public function add(ListCreationInformation $parameters) + { + $list = new SPList($this->getContext()); + $qry = new ClientActionCreateEntity($this,$parameters); + $this->getContext()->addQuery($qry,$list); + $this->addChild($list); + return $list; + } + + /** + * @return string + */ + public function getItemTypeName() + { + return __NAMESPACE__ . "\\" . "SPList"; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListCreationInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListCreationInformation.php new file mode 100644 index 0000000000000..e6bf965b13521 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListCreationInformation.php @@ -0,0 +1,46 @@ +Title = $title; + $this->Description = $title; + $this->BaseTemplate = ListTemplateType::GenericList; + $this->AllowContentTypes = true; + $this->ContentTypesEnabled = true; + parent::__construct("List"); + } + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItem.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItem.php new file mode 100644 index 0000000000000..ef43aac607214 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItem.php @@ -0,0 +1,94 @@ +getContext()->addQuery($qry,$this); + } + + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + } + + + public function getEntityTypeName(){ + $list = $this->getParentList(); + if(!isset($this->resourceType)) { + //determine whether ListItemEntityTypeFullName property has been requested + if(!$list->isPropertyAvailable("ListItemEntityTypeFullName")){ + $request = new RequestOptions($list->getResourceUrl() . "?\$select=ListItemEntityTypeFullName"); + $response = $this->getContext()->executeQueryDirect($request); + $this->getContext()->populateObject($response,$list); + } + $this->resourceType = $list->getProperty("ListItemEntityTypeFullName"); + } + return $this->resourceType; + } + + + /** + * @return AttachmentCollection + */ + public function getAttachmentFiles(){ + if(!$this->isPropertyAvailable('AttachmentFiles')){ + $this->setProperty("AttachmentFiles", new AttachmentCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "AttachmentFiles")),false); + } + return $this->getProperty("AttachmentFiles"); + } + + + /** + * Gets the parent list that contains the list item. + * @return SPList + */ + public function getParentList(){ + if(!$this->isPropertyAvailable('ParentList')){ + $this->setProperty("ParentList", new SPList($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "parentlist")),false); + } + return $this->getProperty("ParentList"); + } + + + /** + * Gets the associated Folder resource. + * @return Folder + */ + public function getFolder(){ + if(!$this->isPropertyAvailable('Folder')){ + $this->setProperty("Folder", new Folder($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "Folder")),false); + } + return $this->getProperty("Folder"); + } + + + /** + * Gets the associated File resource. + * @return File + */ + public function getFile(){ + if(!$this->isPropertyAvailable('File')){ + $this->setProperty("File", new File($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "File")),false); + } + return $this->getProperty("File"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollection.php new file mode 100644 index 0000000000000..28900a577b882 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollection.php @@ -0,0 +1,33 @@ +registerXPathNamespace('z', '#RowsetSchema'); + $rows = $xmlPayload->xpath("//z:row"); + foreach ($rows as $row) { + $item = new ListItem($this->getContext(), $this->getResourcePath()); + foreach ($row->attributes() as $k => $v) { + $normalizedFieldName = str_replace('ows_', '', $k); + $item->setProperty($normalizedFieldName, (string)$v); + } + $this->addChild($item); + } + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollectionPosition.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollectionPosition.php new file mode 100644 index 0000000000000..cc69979c9ea27 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ListItemCollectionPosition.php @@ -0,0 +1,17 @@ +isPropertyAvailable('PrincipalType')){ + return $this->getProperty("PrincipalType"); + } + return null; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/PrincipalType.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/PrincipalType.php new file mode 100644 index 0000000000000..fd7fd34d1a0bf --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/PrincipalType.php @@ -0,0 +1,17 @@ +getContext()->addQuery($qry,$this); + } + + + /** + * Deletes Role Assignment + */ + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + } + + + + /** + * @return Principal + */ + public function getMember() + { + if(!$this->isPropertyAvailable("Member")){ + $this->setProperty("Member", new Principal($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Member"))); + } + return $this->getProperty("Member"); + } + + function getProperty($name) + { + if($name == "Member" && !$this->isPropertyAvailable("Member")) + return $this->getMember(); + return parent::getProperty($name); + } + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleAssignmentCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleAssignmentCollection.php new file mode 100644 index 0000000000000..02af9aaa306af --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleAssignmentCollection.php @@ -0,0 +1,24 @@ +isPropertyAvailable("Groups")){ + $this->setProperty("Groups", new GroupCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Groups"))); + } + return $this->getProperty("Groups"); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinition.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinition.php new file mode 100644 index 0000000000000..79c209b5a7f41 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinition.php @@ -0,0 +1,19 @@ +getContext()->addQuery($qry); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinitionCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinitionCollection.php new file mode 100644 index 0000000000000..768540d006ca1 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/RoleDefinitionCollection.php @@ -0,0 +1,12 @@ +getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"items")); + $listItem = new ListItem($this->getContext()); + $listItem->parentCollection = $items; + $listItem->setProperty('ParentList',$this,false); + foreach($listItemCreationInformation as $key => $value){ + $listItem->setProperty($key,$value); + } + $qry = new ClientActionCreateEntity($items,$listItem); + $this->getContext()->addQuery($qry,$listItem); + return $listItem; + } + + /** + * Returns the list item with the specified list item identifier. + * @param integer $id SPList Item id + * @return ListItem List Item resource + * @throws \Exception + */ + public function getItemById($id) + { + return new ListItem( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"items({$id})") + ); + } + + + /** + * Returns a collection of items from the list based on the specified query. + * @param CamlQuery $camlQuery + * @return ListItemCollection + */ + public function getItems(CamlQuery $camlQuery = null) + { + $items = new ListItemCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"items")); + if(isset($camlQuery)){ + $qry = new ClientActionInvokePostMethod( + $this, + "GetItems", + null, + $camlQuery->toQueryPayload() + ); + $this->getContext()->addQuery($qry,$items); + } + return $items; + } + + + /** + * Updates a list resource + */ + public function update() + { + $qry = new ClientActionUpdateEntity($this); + $this->getContext()->addQuery($qry); + } + + /** + * The recommended way to delete a list is to send a DELETE request to the List resource endpoint, as shown in List request examples. + */ + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + $this->removeFromParentCollection(); + } + + + /** + * Gets the set of permissions for the specified user + * @param string $loginName + * @return BasePermissions + * @throws \Exception + */ + public function getUserEffectivePermissions($loginName) + { + $permissions = new BasePermissions(); + $qry = new ClientActionInvokeGetMethod( + $this, + "GetUserEffectivePermissions", + array(rawurlencode($loginName)) + ); + $this->getContext()->addQuery($qry,$permissions); + return $permissions; + } + + + /** + * @param ChangeLogItemQuery $query The query that contains the change token. Pass this parameter in the request body, as shown in the request example. + * @return ListItemCollection + */ + public function getListItemChangesSinceToken(ChangeLogItemQuery $query) + { + $result = new ListItemCollection($this->getContext()); + $qry = new ClientActionInvokePostMethod( + $this, + "getListItemChangesSinceToken", + null, + $query->toQueryPayload() + ); + //$qry->ResponsePayloadFormatType = FormatType::Xml; + $this->getContext()->addQuery($qry, $result); + return $result; + } + + + /** + * @param ChangeQuery $query + * @return ChangeCollection + */ + public function getChanges(ChangeQuery $query) + { + $changes = new ChangeCollection($this->getContext()); + $qry = new ClientActionInvokePostMethod( + $this, + "GetChanges", + null, + $query->toQueryPayload() + ); + $this->getContext()->addQuery($qry,$changes); + return $changes; + } + + + /** + * @return ContentTypeCollection + */ + public function getContentTypes() + { + if(!$this->isPropertyAvailable('ContentTypes')){ + $this->setProperty("ContentTypes", new ContentTypeCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "ContentTypes")),false); + } + return $this->getProperty("ContentTypes"); + } + + + /** + * @return FieldCollection + */ + public function getFields() + { + if(!$this->isPropertyAvailable('Fields')){ + $this->setProperty("Fields", new FieldCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "fields"))); + } + return $this->getProperty("Fields"); + } + + /** + * @return Folder + */ + public function getRootFolder() + { + if(!$this->isPropertyAvailable('RootFolder')){ + $this->setProperty("RootFolder", new Folder($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "rootFolder"))); + } + return $this->getProperty("RootFolder"); + } + + + /** + * @return ViewCollection + */ + public function getViews() + { + if(!$this->isPropertyAvailable('Views')){ + $this->setProperty("Views",new ViewCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "views"))); + } + return $this->getProperty("Views"); + } + + public function getInformationRightsManagementSettings() + { + if(!$this->isPropertyAvailable('InformationRightsManagementSettings')){ + $this->setProperty("InformationRightsManagementSettings", new InformationRightsManagementSettings($this->getContext(),$this->getResourcePath(), "InformationRightsManagementSettings")); + } + return $this->getProperty("InformationRightsManagementSettings"); + } + + + /** + * @return Web + */ + public function getParentWeb() + { + if(!$this->isPropertyAvailable('ParentWeb')){ + $this->setProperty("ParentWeb", new Web($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "ParentWeb"))); + } + return $this->getProperty("ParentWeb"); + } + + public function getEntityTypeName(){ + return "SP.List"; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/SecurableObject.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/SecurableObject.php new file mode 100644 index 0000000000000..93701671dbeae --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/SecurableObject.php @@ -0,0 +1,49 @@ +getContext()->addQuery($qry); + } + + + /** + * @return RoleAssignmentCollection + */ + public function getRoleAssignments() + { + if(!isset($this->RoleAssignments)){ + $this->setProperty('RoleAssignments',new RoleAssignmentCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"roleassignments"))); + } + return $this->getProperty('RoleAssignments'); + } + + /** + * Gets a Boolean value indicating whether the object has unique security or + * inherits its role assignments from a parent object. + * @return bool + */ + public function hasUniqueRoleAssignments() + { + return $this->getProperty('HasUniqueRoleAssignments'); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Site.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Site.php new file mode 100644 index 0000000000000..61c02959cb3e7 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Site.php @@ -0,0 +1,50 @@ +getContext(),$this->getResourcePath()); + $qry = new ClientActionInvokePostMethod($this,"openWebById",array($webId)); + $this->getContext()->addQuery($qry,$web); + return $web; + } + + + /** + * @return Web + */ + public function getRootWeb() + { + if(!$this->isPropertyAvailable("RootWeb")){ + $this->setProperty("RootWeb", new Web($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"RootWeb"))); + } + return $this->getProperty("RootWeb"); + } + + + /** + * @return UserCustomActionCollection + */ + public function getUserCustomActions() + { + if(!$this->isPropertyAvailable("UserCustomActions")){ + $this->setProperty("UserCustomActions", new UserCustomActionCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"UserCustomActions"))); + } + return $this->getProperty("UserCustomActions"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Social/SocialActor.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Social/SocialActor.php new file mode 100644 index 0000000000000..8cc2ba74f1446 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Social/SocialActor.php @@ -0,0 +1,12 @@ +getContext()->addQuery($qry,$this); + } + + /** + * Gets the collection of groups of which the user is a member. + * @return GroupCollection + */ + public function getGroups() + { + if(!$this->isPropertyAvailable('Groups')){ + $this->setProperty("Groups", new GroupCollection($this->getContext(), new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "groups"))); + } + return $this->getProperty("Groups"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCollection.php new file mode 100644 index 0000000000000..1b4ff9850c05f --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCollection.php @@ -0,0 +1,71 @@ +getContext(),$this->getResourcePath(),"getById",array($id)); + return new User($this->getContext(),$path); + } + + /** + * Gets the user with the specified email address. + * @param string $emailAddress The email of the user to get. + * @return User + */ + public function getByEmail($emailAddress) + { + $path = new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getByEmail",array($emailAddress)); + return new User($this->getContext(),$path); + } + + /** + * @param string $loginName + * @return User + */ + public function getByLoginName($loginName) + { + $path = new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getByLoginName",array($loginName)); + return new User($this->getContext(),$path); + } + + + /** + * Removes the user with the specified ID. + * @param int $id + */ + public function removeById($id) + { + $qry = new ClientActionInvokePostMethod($this,"removebyid",array($id)); + $this->getContext()->addQuery($qry); + } + + /** + * Removes the user with the specified login name + * @param string $loginName + */ + public function removeByLoginName($loginName) + { + $qry = new ClientActionInvokePostMethod( + $this, + "removebyloginname", + array(rawurlencode($loginName))); + $this->getContext()->addQuery($qry); + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCustomAction.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCustomAction.php new file mode 100644 index 0000000000000..0e3295f443730 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserCustomAction.php @@ -0,0 +1,12 @@ +getContext()->addQuery($qry,$clientResult); + return $clientResult; + } + + /** + * Gets user properties for the current user. + * @return PersonProperties + */ + public function getMyProperties(){ + return new PersonProperties( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getmyproperties") + ); + } + + + /** + * Gets the people who are following the current user. + * @return PersonProperties + */ + public function getMyFollowers(){ + return new PersonProperties( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getmyfollowers") + ); + } + + + /** + * Adds the specified user to the current user's list of followed users. + * @param string $accountName + */ + public function follow($accountName){ + $qry = new ClientActionInvokePostMethod($this, "follow",array(rawurlencode($accountName))); + $this->getContext()->addQuery($qry); + } + + + /** + * Remove the specified user from the current user's list of followed users. + * @param string $accountName + */ + public function stopFollowing ($accountName){ + $clientResult = new ClientResult(); + $qry = new ClientActionInvokePostMethod($this, "StopFollowing",array(rawurlencode($accountName))); + $this->getContext()->addQuery($qry,$clientResult); + } + + + /** + * Checks whether the current user is following the specified user. + * @param string $accountName + * @return ClientResult + */ + public function amIFollowing ($accountName){ + $clientResult = new ClientResult(); + $qry = new ClientActionInvokeGetMethod( + $this, + "AmIFollowing", + array(rawurlencode($accountName)) + ); + $this->getContext()->addQuery($qry,$clientResult); + return $clientResult; + } + + + /** + * @param string $accountName The account name of the user, encoded and passed as an alias in the query string, + * as shown in the request example. See Implementation notes for other example formats. + * @return PersonPropertiesCollection + */ + public function getFollowersFor($accountName){ + return new PersonPropertiesCollection( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getfollowersfor",array(rawurlencode($accountName))) + ); + } + + + /** + * Gets the specified user profile property for the specified user. + * @param string $accountName The account name of the user, encoded and passed as an alias in the query string, as shown in the request example. + * @param string $propertyName The case-sensitive name of the property to get. + * @return ClientResult The specified profile property for the specified user. + */ + public function getUserProfilePropertyFor ($accountName,$propertyName) + { + $clientResult = new ClientResult("GetUserProfilePropertyFor"); + $qry = new ClientActionInvokeGetMethod( + $this, + "GetUserProfilePropertyFor", + array( + "accountname" => rawurlencode($accountName), + "propertyname" => $propertyName + ) + ); + $this->getContext()->addQuery($qry, $clientResult); + return $clientResult; + } + + + /** + * The URL of the edit profile page for the current user. + * @var string + */ + public $EditProfileLink; + + + /** + * A Boolean value that indicates whether the current user's People I'm Following list is public. + * @var bool + */ + public $IsMyPeopleListPublic; +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/PersonProperties.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/PersonProperties.php new file mode 100644 index 0000000000000..e257060b12a57 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/UserProfiles/PersonProperties.php @@ -0,0 +1,93 @@ +getContext()->addQuery($qry); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Utilities/Utility.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Utilities/Utility.php new file mode 100644 index 0000000000000..a00b396ff1fff --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Utilities/Utility.php @@ -0,0 +1,77 @@ + $title, + "FileSystemObjectType" => 1 + ); + $item = $list->addItem($discussionPayload); + $item->getContext()->executeQuery(); + //fix discussion folder name + $item->setProperty("FileLeafRef",$title); + $item->update(); + $item->getContext()->executeQuery(); + return $item; + } + + + /** + * Creates a message item (reply) in Discussion Board + * @param ListItem $discussionItem + * @param string $subject + * @return ListItem + * @throws \Exception + */ + public static function createNewDiscussionReply(ListItem $discussionItem,$subject){ + $ctx = $discussionItem->getContext(); + $list = $discussionItem->getParentList(); + + $contentTypes = $list->getContentTypes(); + $ctx->load($contentTypes); + $ctx->executeQuery(); + $result = $contentTypes->findItems( + function (ContentType $item){ + return $item->getProperty("Name") === "Message"; + }); + if(count($result) == 0){ + throw new \Exception("Message content type not found"); + } + + $messagePayload = array( + "Body" => $subject, + "FileSystemObjectType" => 0, + "ContentTypeId" => $result[0]->getProperty("Id") + ); + $messageItem = $list->addItem($messagePayload); + $ctx->executeQuery(); + //move message into discussion folder + $ctx->load($discussionItem,array("FileRef")); + $ctx->load($messageItem,array("FileRef","FileDirRef")); + $ctx->executeQuery(); + $sourceFileUrl = $messageItem->getProperty("FileRef"); + $targetFileUrl = str_replace($messageItem->getProperty("FileDirRef"),$discussionItem->getProperty("FileRef"),$sourceFileUrl); + $ctx->getWeb()->getFileByServerRelativeUrl($sourceFileUrl)->moveTo($targetFileUrl,1); + $ctx->executeQuery(); + return $messageItem; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/View.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/View.php new file mode 100644 index 0000000000000..b2a6b7b438d92 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/View.php @@ -0,0 +1,60 @@ +getContext()->addQuery($qry,$this); + } + + /** + * Gets a value that specifies the collection of fields in the list view. + * @return ViewFieldCollection + */ + public function getViewFields() + { + if(!$this->isPropertyAvailable('ViewFields')){ + $this->setProperty("ViewFields", new ViewFieldCollection($this->getContext(), new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "ViewFields"))); + } + return $this->getProperty("ViewFields"); + } + + + /** + * The recommended way to delete a view is to send a DELETE request to the View resource endpoint, + * as shown in View request examples. + */ + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + } + + + /** + * Returns the list view as HTML. + */ + public function renderAsHtml(){ + $qry = new ClientActionInvokeGetMethod( + $this, + "renderashtml" + ); + $this->getContext()->addQuery($qry); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCollection.php new file mode 100644 index 0000000000000..072688f26c341 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCollection.php @@ -0,0 +1,55 @@ +getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getByTitle",array($title)) + ); + } + + + /** + * Get View by id + * @param $id + * @return View + */ + public function getById($id) + { + return new View( + $this->getContext(), + new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getById",array($id)) + ); + } + + + + + /** + * Creates a View resource + * @param ViewCreationInformation $parameters + * @return View + */ + public function add(ViewCreationInformation $parameters) + { + $view = new View($this->getContext(),$this->getResourcePath()); + $qry = new ClientActionCreateEntity($this,$parameters); + $this->getContext()->addQuery($qry,$view); + $this->addChild($view); + return $view; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCreationInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCreationInformation.php new file mode 100644 index 0000000000000..4817587e16600 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewCreationInformation.php @@ -0,0 +1,59 @@ +RowLimit = 30; + parent::__construct("View"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewFieldCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewFieldCollection.php new file mode 100644 index 0000000000000..2f46eb995d815 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ViewFieldCollection.php @@ -0,0 +1,13 @@ +getContext()->addQuery($qry,$this); + } + + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + //$this->removeFromParentCollection(); + } + + + /** + * Returns the collection of all changes from the change log that have occurred within the scope of the site, based on the specified query. + * @param ChangeQuery $query + * @return ChangeCollection + */ + public function getChanges(ChangeQuery $query) + { + $changes = new ChangeCollection($this->getContext()); + $qry = new ClientActionInvokePostMethod( + $this, + "GetChanges", + null, + $query->toQueryPayload() + ); + $this->getContext()->addQuery($qry,$changes); + return $changes; + } + + + /** + * Gets the collection of all lists that are contained in the Web site available to the current user + * based on the permissions of the current user. + * @return ListCollection + */ + public function getLists() + { + if(!$this->isPropertyAvailable('Lists')){ + $this->setProperty("Lists", new ListCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Lists"))); + } + return $this->getProperty("Lists"); + } + + /** + * Gets a Web site collection object that represents all Web sites immediately beneath the Web site, + * excluding children of those Web sites. + * @return WebCollection + */ + public function getWebs() + { + if(!$this->isPropertyAvailable('Webs')){ + $this->setProperty("Webs", new WebCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"webs"))); + } + return $this->getProperty("Webs"); + } + + /** + * Gets the collection of field objects that represents all the fields in the Web site. + * @return FieldCollection + */ + public function getFields() + { + if(!$this->isPropertyAvailable('Fields')){ + $this->setProperty("Fields", new FieldCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"fields"))); + } + return $this->getProperty("Fields"); + } + + /** + * Gets the collection of all first-level folders in the Web site. + * @return FolderCollection + */ + public function getFolders() + { + if(!isset($this->Folders)){ + $this->Folders = new FolderCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"folders")); + } + return $this->Folders; + } + + + /** + * Gets the collection of all users that belong to the site collection. + * @return UserCollection + */ + public function getSiteUsers() + { + if(!isset($this->SiteUsers)){ + $this->SiteUsers = new UserCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"siteusers")); + } + return $this->SiteUsers; + } + + + /** + * Gets the collection of groups for the site collection. + * @return mixed|null|GroupCollection + */ + public function getSiteGroups() + { + if(!isset($this->SiteGroups)){ + $this->setProperty("SiteGroups", new GroupCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"sitegroups"))); + } + return $this->getProperty("SiteGroups"); + } + + + /** + * Gets the collection of role definitions for the Web site. + * @return RoleAssignmentCollection + */ + public function getRoleDefinitions() + { + if(!$this->isPropertyAvailable('RoleDefinitions')){ + $this->setProperty("RoleDefinitions", new RoleDefinitionCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"roledefinitions"))); + } + return $this->getProperty("RoleDefinitions"); + } + + + /** + * Gets a value that specifies the collection of user custom actions for the site. + * @return UserCustomActionCollection + */ + public function getUserCustomActions() + { + if(!$this->isPropertyAvailable('UserCustomActions')){ + $this->setProperty("UserCustomActions", new UserCustomActionCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"UserCustomActions"))); + } + return $this->getProperty("UserCustomActions"); + } + + + /** + * @return User + */ + public function getCurrentUser() + { + if(!$this->isPropertyAvailable('CurrentUser')){ + $this->setProperty("CurrentUser", new User($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"CurrentUser"))); + } + return $this->getProperty("CurrentUser"); + } + + + /** + * @return ClientValueObjectCollection + */ + public function getSupportedUILanguageIds() + { + $value = new ClientValueObjectCollection("Collection(Edm.Int32)"); + $value->EntityName = "SupportedUILanguageIds"; + $qry = new ClientActionReadEntity($this->getResourceUrl() . "/SupportedUILanguageIds"); + $this->getContext()->addQuery($qry,$value); + return $value; + } + + /** + * Returns the file object located at the specified server-relative URL. + * @param string $serverRelativeUrl The server relative URL of the file. + * @return File + */ + public function getFileByServerRelativeUrl($serverRelativeUrl){ + $path = new ResourcePathServiceOperation($this->getContext(),$this->getResourcePath(),"getfilebyserverrelativeurl",array( + rawurlencode($serverRelativeUrl) + )); + $file = new File($this->getContext(),$path); + return $file; + } + + /** + * Returns the folder object located at the specified server-relative URL. + * @param string $serverRelativeUrl The server relative URL of the folder. + * @return Folder + */ + public function getFolderByServerRelativeUrl($serverRelativeUrl){ + return new Folder( + $this->getContext(), + new ResourcePathServiceOperation( + $this->getContext(), + $this->getResourcePath(), + "getfolderbyserverrelativeurl", + array( + rawurlencode($serverRelativeUrl) + ) + ) + ); + } + + /** + * @return ContentTypeCollection + */ + public function getContentTypes() + { + if(!$this->isPropertyAvailable('ContentTypes')){ + $this->setProperty( + 'ContentTypes', + new ContentTypeCollection( + $this->getContext(), + new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + 'ContentTypes' + ) + ), + false + ); + } + return $this->getProperty('ContentTypes'); + } + + /** + * @param string $name + * @param mixed $value + * @param bool $persistChanges + */ + public function setProperty($name, $value, $persistChanges = true) + { + parent::setProperty($name, $value, $persistChanges); + if ($name === 'Id') { + $this->setResourceUrl("Site/openWebById(guid'{$value}')"); + } + } +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCollection.php new file mode 100644 index 0000000000000..bdc1488a24a63 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCollection.php @@ -0,0 +1,33 @@ +getContext(),$this->getResourcePath()); + $qry = new ClientActionInvokePostMethod( + $this, + "Add", + null, + $webCreationInformation->toParametersPayload() + ); + $this->getContext()->addQuery($qry,$web); + $this->addChild($web); + return $web; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCreationInformation.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCreationInformation.php new file mode 100644 index 0000000000000..93b81a70658fd --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebCreationInformation.php @@ -0,0 +1,64 @@ +Url = $url; + $this->Title = $title; + $this->Description = $title; + $this->Language = 1033; + $this->WebTemplate = "STS"; + $this->UseSamePermissionsAsParentSite = true; + parent::__construct(null); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/LimitedWebPartManager.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/LimitedWebPartManager.php new file mode 100644 index 0000000000000..b75f33ed9744e --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/LimitedWebPartManager.php @@ -0,0 +1,50 @@ + $webPartXml),ODataPayloadKind::Entity,$this->getEntityTypeName()); + $webPartDefinition = new WebPartDefinition($this->getContext()); + $qry = new ClientActionInvokePostMethod( + $this, + "ImportWebPart", + null, + $payload + ); + $this->getContext()->addQuery($qry,$webPartDefinition); + return $webPartDefinition; + } + + + /** + * @return WebPartDefinitionCollection + */ + public function getWebParts() + { + if(!$this->isPropertyAvailable('WebParts')){ + $this->setProperty( + "WebParts", + new WebPartDefinitionCollection($this->getContext(),new ResourcePathEntity($this->getContext(),$this->getResourcePath(), "WebParts")) + ); + } + return $this->getProperty("WebParts"); + } + +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/PersonalizationScope.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/PersonalizationScope.php new file mode 100644 index 0000000000000..3e50ef7d63162 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/PersonalizationScope.php @@ -0,0 +1,12 @@ +getContext()->addQuery($qry); + } + + public function closeWebPart() + { + $qry = new ClientActionInvokePostMethod( + $this, + "CloseWebPart" + ); + $this->getContext()->addQuery($qry); + } + + + /** + * @return WebPart + */ + public function getWebPart() + { + if (!$this->isPropertyAvailable('WebPart')) { + $this->setProperty('WebPart', new WebPart($this->getContext(), $this->getResourcePath(), "WebPart")); + } + return $this->getProperty('WebPart'); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinitionCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinitionCollection.php new file mode 100644 index 0000000000000..a9a205f00c8f3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/WebParts/WebPartDefinitionCollection.php @@ -0,0 +1,31 @@ +getContext(),$this->getResourcePath() . "/GetById('{$id}')"); + return $webPartDefinition; + } + + /** + * @param string $controlId + * @return WebPartDefinition + */ + public function getByControlId($controlId) + { + $webPartDefinition = new WebPartDefinition($this->getContext(),$this->getResourcePath() . "/GetByControlId('{$controlId}')"); + return $webPartDefinition; + } +} \ No newline at end of file From 5228c9511a4400a2402ad308ba485786730d29ab Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 24 Mar 2017 00:45:47 +0100 Subject: [PATCH 18/32] perf tuning pt 2. recognize files and folders when blindly fetching them depending on whether a . is present in the path, with fallback. Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 49 ++++++++++--------- .../tests/SharePoint/SharePointClientTest.php | 22 +++------ 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 73d306bfdc5a3..1dbf2fe81128d 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -23,7 +23,6 @@ namespace OCA\Files_External\Lib\SharePoint; - use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; use Office365\PHP\Client\Runtime\ClientObject; use Office365\PHP\Client\Runtime\ClientObjectCollection; @@ -68,38 +67,40 @@ public function __construct(ContextsFactory $contextsFactory, $sharePointUrl, ar * @throws \Exception */ public function fetchFileOrFolder($path, array $properties = null) { - $this->ensureConnection(); - - # room for optimization: if "." present in path, try file first, - # otherwise folder - - # Attempt 1: fetch a file - try { - $file = $this->context->getWeb()->getFileByServerRelativeUrl($path); - $this->loadAndExecute($file, $properties); - return $file; - } catch (\Exception $e) { - if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1) { - # Unexpected Exception, pass it on - throw $e; - } + $fetchFileFunc = function ($path, $props) { return $this->fetchFile($path, $props);}; + $fetchFolderFunc = function ($path, $props) { return $this->fetchFolder($path, $props);}; + $fetchers = [ $fetchFileFunc, $fetchFolderFunc ]; + if(strpos($path, '.') === false) { + $fetchers = array_reverse($fetchers); } - # Attempt 2: fetch a folder - try { - $this->createClientContext(); // otherwise the old query will be repeated - return $this->fetchFolder($path, $properties); - } catch (\Exception $e) { - if($e->getMessage() !== 'Unknown Error') { // yes, SP returns this - throw $e; + foreach ($fetchers as $fetchFunction) { + try { + $instance = call_user_func_array($fetchFunction, [$path, $properties]); + return $instance; + } catch (\Exception $e) { + if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1 + && $e->getMessage() !== 'Unknown Error' + ) { + $this->createClientContext(); + # Unexpected Exception, pass it on + throw $e; + } } + $this->createClientContext(); } # Nothing succeeded, quit with not found - $this->createClientContext(); // otherwise the old query will be repeated throw new NotFoundException('File or Folder not found'); } + public function fetchFile($relativeServerPath, array $properties = null) { + $this->ensureConnection(); + $file = $this->context->getWeb()->getFileByServerRelativeUrl($relativeServerPath); + $this->loadAndExecute($file, $properties); + return $file; + } + public function fetchFolder($relativeServerPath, array $properties = null) { $this->ensureConnection(); $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); diff --git a/apps/files_external/tests/SharePoint/SharePointClientTest.php b/apps/files_external/tests/SharePoint/SharePointClientTest.php index e2ced5e9918a8..ec0b956e4feee 100644 --- a/apps/files_external/tests/SharePoint/SharePointClientTest.php +++ b/apps/files_external/tests/SharePoint/SharePointClientTest.php @@ -23,9 +23,7 @@ namespace OCA\Files_External\Tests\SharePoint; - use OCA\Files_External\Lib\SharePoint\ContextsFactory; -use OCA\Files_External\Lib\SharePoint\NotFoundException; use OCA\Files_External\Lib\SharePoint\SharePointClient; use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; use Office365\PHP\Client\SharePoint\ClientContext; @@ -103,7 +101,6 @@ public function testFetchFolderByFileOrFolder() { ->method('getAuthContext') ->willReturn($this->createMock(AuthenticationContext::class)); - $fileMock = $this->createMock(File::class); $folderCollectionMock = $this->createMock(FolderCollection::class); $fileCollectionMock = $this->createMock(FileCollection::class); @@ -116,29 +113,24 @@ public function testFetchFolderByFileOrFolder() { ->willReturn($fileCollectionMock); $webMock = $this->createMock(Web::class); - $webMock->expects($this->once()) - ->method('getFileByServerRelativeUrl') - ->with($path) - ->willReturn($fileMock); + $webMock->expects($this->never()) + ->method('getFileByServerRelativeUrl'); $webMock->expects($this->once()) ->method('getFolderByServerRelativeUrl') ->with($path) ->willReturn($folderMock); $clientContextMock = $this->createMock(ClientContext::class); - $clientContextMock->expects($this->exactly(2)) + $clientContextMock->expects($this->once()) ->method('getWeb') ->willReturn($webMock); - $clientContextMock->expects($this->exactly(4)) + $clientContextMock->expects($this->exactly(3)) ->method('load') - ->withConsecutive([$fileMock, $properties], [$folderMock, $properties]); - $clientContextMock->expects($this->at(2)) - ->method('executeQuery') - ->willThrowException(new \Exception('The file /whatwasitsname does not exist.')); - $clientContextMock->expects($this->at(7)) + ->withConsecutive([$folderMock, $properties]); + $clientContextMock->expects($this->at(4)) ->method('executeQuery'); - $this->contextsFactory->expects($this->exactly(2)) + $this->contextsFactory->expects($this->once()) ->method('getClientContext') ->willReturn($clientContextMock); From 2d5009758ea016675d9f833e7c69500dbd93b120 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Sat, 25 Mar 2017 00:52:32 +0100 Subject: [PATCH 19/32] Perf optimization part 3: further lookup reduction * look for hidden info only when really necessary * also on for folders * don't retrieve folder contents not with fetchFolder, fetchFolderContents only Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 57 +++++++++++-------- .../lib/Lib/Storage/SharePoint.php | 16 +++--- .../tests/SharePoint/SharePointClientTest.php | 28 ++------- 3 files changed, 47 insertions(+), 54 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 1dbf2fe81128d..b60ccd0640f48 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -104,48 +104,59 @@ public function fetchFile($relativeServerPath, array $properties = null) { public function fetchFolder($relativeServerPath, array $properties = null) { $this->ensureConnection(); $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); - $folderCollection = $folder->getFolders(); - $fileCollection = $folder->getFiles(); - $this->context->load($folder, $properties); - $this->context->load($folderCollection, null); - $this->context->load($fileCollection, null); - $this->context->executeQuery(); + $this->loadAndExecute($folder, $properties); return $folder; } /** * @param $relativeServerPath * @param null $properties + * @param Folder $folder * @return ClientObjectCollection[] */ public function fetchFolderContents($relativeServerPath, $properties = null, Folder $folder = null) { $this->ensureConnection(); if($folder === null) { $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); - $folderCollection = $folder->getFolders(); - $fileCollection = $folder->getFiles(); - $this->context->load($folderCollection, $properties); - $this->context->load($fileCollection, $properties); - $this->context->executeQuery(); - } else { - $folderCollection = $folder->getFolders(); - $fileCollection = $folder->getFiles(); } - $collections = ['folders' => $folderCollection, 'files' => $fileCollection]; - - foreach ($collections as $collection) { - foreach ($collection->getData() as $item) { - /** @var File|Folder $item */ - $fields = $item->getListItemAllFields(); - $this->context->load($fields, ['Id', 'Hidden']); - } - } + $folderCollection = $folder->getFolders(); + $fileCollection = $folder->getFiles(); + $this->context->load($folderCollection, $properties); + $this->context->load($fileCollection, $properties); $this->context->executeQuery(); + $collections = ['folders' => $folderCollection, 'files' => $fileCollection]; + return $collections; } + public function isHidden(ClientObject $file) { + // ClientObject itself does not have getListItemAllFields but is + // the common denominator of File and Folder + if(!$file instanceof File && !$file instanceof Folder) { + throw new \InvalidArgumentException('File or Folder expected'); + } + if($file instanceof File) { + // it's expensive, we only check folders + return false; + } + $fields = $file->getListItemAllFields(); + if($fields->getProperties() === []) { + $this->loadAndExecute($fields, ['Id', 'Hidden']); + } + $id = $fields->getProperty('Id'); + $hidden = $fields->getProperty('Hidden'); // TODO: get someone to test this in SP 2013 + if($hidden === false || $id !== null) { + // avoids listing hidden "Forms" folder (and its contents). + // Have not found a different mechanism to detect whether + // a file or folder is hidden. There used to be a Hidden + // field, but seems to have gone (since SP 2016?). + return false; + } + return true; + } + public function loadAndExecute(ClientObject $object, array $properties = null) { $this->context->load($object, $properties); $this->context->executeQuery(); diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index b9a4062ab0824..93ddf4b788ffa 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -137,13 +137,7 @@ public function opendir($path) { $items = $collection->getData(); foreach ($items as $item) { /** @var ListItem $fields */ - $id = $item->getListItemAllFields()->getProperty('Id'); - $hidden = $item->getListItemAllFields()->getProperty('Hidden'); // TODO: get someone to test this in SP 2013 - if($hidden === false || $id !== null) { - // avoids listing hidden "Forms" folder (and its contents). - // Have not found a different mechanism to detect whether - // a file or folder is hidden. There used to be a Hidden - // field, but seems to have gone (since SP 2016?). + if(!$this->spClient->isHidden($item)) { $files[] = $item->getProperty('Name'); } } @@ -372,6 +366,14 @@ private function formatPath($path) { if($path !== '') { $serverUrl .= '/' . $path; } + + $pathParts = explode('/', $serverUrl); + $filename = array_pop($pathParts); + if($filename === '.') { + // remove /. from the end of the path + $serverUrl = mb_substr($serverUrl, 0, mb_strlen($serverUrl) - 2); + } + return $serverUrl; } diff --git a/apps/files_external/tests/SharePoint/SharePointClientTest.php b/apps/files_external/tests/SharePoint/SharePointClientTest.php index ec0b956e4feee..d993880e47b3b 100644 --- a/apps/files_external/tests/SharePoint/SharePointClientTest.php +++ b/apps/files_external/tests/SharePoint/SharePointClientTest.php @@ -28,9 +28,7 @@ use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; -use Office365\PHP\Client\SharePoint\FileCollection; use Office365\PHP\Client\SharePoint\Folder; -use Office365\PHP\Client\SharePoint\FolderCollection; use Office365\PHP\Client\SharePoint\Web; use Test\TestCase; @@ -101,16 +99,7 @@ public function testFetchFolderByFileOrFolder() { ->method('getAuthContext') ->willReturn($this->createMock(AuthenticationContext::class)); - $folderCollectionMock = $this->createMock(FolderCollection::class); - $fileCollectionMock = $this->createMock(FileCollection::class); - $folderMock = $this->createMock(Folder::class); - $folderMock->expects($this->once()) - ->method('getFolders') - ->willReturn($folderCollectionMock); - $folderMock->expects($this->once()) - ->method('getFiles') - ->willReturn($fileCollectionMock); $webMock = $this->createMock(Web::class); $webMock->expects($this->never()) @@ -124,10 +113,10 @@ public function testFetchFolderByFileOrFolder() { $clientContextMock->expects($this->once()) ->method('getWeb') ->willReturn($webMock); - $clientContextMock->expects($this->exactly(3)) + $clientContextMock->expects($this->once()) ->method('load') ->withConsecutive([$folderMock, $properties]); - $clientContextMock->expects($this->at(4)) + $clientContextMock->expects($this->once()) ->method('executeQuery'); $this->contextsFactory->expects($this->once()) @@ -152,16 +141,7 @@ public function testFetchNotExistingByFileOrFolder() { ->willReturn($this->createMock(AuthenticationContext::class)); $fileMock = $this->createMock(File::class); - $folderCollectionMock = $this->createMock(FolderCollection::class); - $fileCollectionMock = $this->createMock(FileCollection::class); - $folderMock = $this->createMock(Folder::class); - $folderMock->expects($this->once()) - ->method('getFolders') - ->willReturn($folderCollectionMock); - $folderMock->expects($this->once()) - ->method('getFiles') - ->willReturn($fileCollectionMock); $webMock = $this->createMock(Web::class); $webMock->expects($this->once()) @@ -177,13 +157,13 @@ public function testFetchNotExistingByFileOrFolder() { $clientContextMock->expects($this->exactly(2)) ->method('getWeb') ->willReturn($webMock); - $clientContextMock->expects($this->exactly(4)) + $clientContextMock->expects($this->exactly(2)) ->method('load') ->withConsecutive([$fileMock, $properties], [$folderMock, $properties]); $clientContextMock->expects($this->at(2)) ->method('executeQuery') ->willThrowException(new \Exception('The file /whatwasitsname does not exist.')); - $clientContextMock->expects($this->at(7)) + $clientContextMock->expects($this->at(5)) ->method('executeQuery') ->willThrowException(new \Exception('Unknown Error')); From 0e9681aca15b530547092ff1b1fbca4474f4be22 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Sat, 25 Mar 2017 02:01:19 +0100 Subject: [PATCH 20/32] implement mkdir Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 25 ++++++ .../lib/Lib/Storage/SharePoint.php | 10 ++- .../tests/SharePoint/SharePointClientTest.php | 84 ++++++++++++++++++- .../tests/Storage/SharePointTest.php | 29 +++++++ 4 files changed, 145 insertions(+), 3 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index b60ccd0640f48..c04ebc8076832 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -81,6 +81,7 @@ public function fetchFileOrFolder($path, array $properties = null) { } catch (\Exception $e) { if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1 && $e->getMessage() !== 'Unknown Error' + && $e->getMessage() !== 'File Not Found.' ) { $this->createClientContext(); # Unexpected Exception, pass it on @@ -108,6 +109,30 @@ public function fetchFolder($relativeServerPath, array $properties = null) { return $folder; } + /** + * adds a folder on the given server path + * + * @param string $relativeServerPath + * @throws \Exception + */ + public function createFolder($relativeServerPath) { + $this->ensureConnection(); + + $serverUrlParts = explode('/', $relativeServerPath); + $newFolderName = array_pop($serverUrlParts); + $parentUrl = implode('/', $serverUrlParts); + + $parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl($parentUrl); + $parentFolder->getFolders()->add($newFolderName); + + try { + $this->context->executeQuery(); + } catch (\Exception $e) { + $this->createClientContext(); + throw $e; + } + } + /** * @param $relativeServerPath * @param null $properties diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 93ddf4b788ffa..8a0849a9442b5 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -102,8 +102,14 @@ public function getId() { * @since 6.0.0 */ public function mkdir($path) { - // TODO: Implement mkdir() method. - return true; + try { + $serverUrl = $this->formatPath($path); + $this->spClient->createFolder($serverUrl); + $this->fileCache->remove($serverUrl); + return true; + } catch (\Exception $e) { + return false; + } } /** diff --git a/apps/files_external/tests/SharePoint/SharePointClientTest.php b/apps/files_external/tests/SharePoint/SharePointClientTest.php index d993880e47b3b..bbed519c99e82 100644 --- a/apps/files_external/tests/SharePoint/SharePointClientTest.php +++ b/apps/files_external/tests/SharePoint/SharePointClientTest.php @@ -29,6 +29,7 @@ use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; +use Office365\PHP\Client\SharePoint\FolderCollection; use Office365\PHP\Client\SharePoint\Web; use Test\TestCase; @@ -167,11 +168,92 @@ public function testFetchNotExistingByFileOrFolder() { ->method('executeQuery') ->willThrowException(new \Exception('Unknown Error')); - $this->contextsFactory->expects($this->exactly(3)) ->method('getClientContext') ->willReturn($clientContextMock); $this->client->fetchFileOrFolder($path, $properties); } + + public function testCreateFolderSuccess() { + $dirName = 'New Project Dir'; + $parentPath = '/' . $this->documentLibraryTitle . '/Our Directory'; + $path = $parentPath . '/'. $dirName; + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); + + $folderCollectionMock = $this->createMock(FolderCollection::class); + $folderCollectionMock->expects($this->once()) + ->method('add') + ->with($dirName); + + $folderMock = $this->createMock(Folder::class); + $folderMock->expects($this->once()) + ->method('getFolders') + ->willReturn($folderCollectionMock); + + $webMock = $this->createMock(Web::class); + $webMock->expects($this->once()) + ->method('getFolderByServerRelativeUrl') + ->with($parentPath) + ->willReturn($folderMock); + + $clientContextMock = $this->createMock(ClientContext::class); + $clientContextMock->expects($this->once()) + ->method('getWeb') + ->willReturn($webMock); + $clientContextMock->expects($this->once()) + ->method('executeQuery'); + + $this->contextsFactory->expects($this->once()) + ->method('getClientContext') + ->willReturn($clientContextMock); + + $this->client->createFolder($path); + } + + /** + * @expectedException \Exception + */ + public function testCreateFolderError() { + $dirName = 'New Project Dir'; + $parentPath = '/' . $this->documentLibraryTitle . '/Our Directory'; + $path = $parentPath . '/'. $dirName; + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); + + $folderCollectionMock = $this->createMock(FolderCollection::class); + $folderCollectionMock->expects($this->once()) + ->method('add') + ->with($dirName); + + $folderMock = $this->createMock(Folder::class); + $folderMock->expects($this->once()) + ->method('getFolders') + ->willReturn($folderCollectionMock); + + $webMock = $this->createMock(Web::class); + $webMock->expects($this->once()) + ->method('getFolderByServerRelativeUrl') + ->with($parentPath) + ->willReturn($folderMock); + + $clientContextMock = $this->createMock(ClientContext::class); + $clientContextMock->expects($this->once()) + ->method('getWeb') + ->willReturn($webMock); + $clientContextMock->expects($this->once()) + ->method('executeQuery') + ->willThrowException(new \Exception('Whatever')); + + $this->contextsFactory->expects($this->exactly(2)) + ->method('getClientContext') + ->willReturn($clientContextMock); + + $this->client->createFolder($path); + } } diff --git a/apps/files_external/tests/Storage/SharePointTest.php b/apps/files_external/tests/Storage/SharePointTest.php index b4781e059af7d..e195b9a4455d6 100644 --- a/apps/files_external/tests/Storage/SharePointTest.php +++ b/apps/files_external/tests/Storage/SharePointTest.php @@ -23,6 +23,7 @@ namespace OCA\Files_External\Tests\Storage; +use OC\Cache\CappedMemoryCache; use OCA\Files_External\Lib\SharePoint\NotFoundException; use OCP\Files\FileInfo; use OCA\Files_External\Lib\SharePoint\ContextsFactory; @@ -68,6 +69,9 @@ class SharePointTest extends TestCase { /** @var SharePointClient|\PHPUnit_Framework_MockObject_MockObject */ protected $client; + /** @var CappedMemoryCache|\PHPUnit_Framework_MockObject_MockObject */ + protected $fileCache; + public function setUp() { parent::setUp(); @@ -79,6 +83,8 @@ public function setUp() { ->method('getClient') ->willReturn($this->client); + $this->fileCache = $this->createMock(CappedMemoryCache::class); + $parameters = [ 'host' => $this->exampleHost, 'documentLibrary' => $this->documentLibraryTitle, @@ -86,6 +92,7 @@ public function setUp() { 'password' => $this->examplePwd, 'contextFactory' => $this->factory, 'sharePointClientFactory' => $this->clientFactory, + 'cappedMemoryCache' => $this->fileCache, ]; $this->storage = new SharePoint($parameters); @@ -251,4 +258,26 @@ public function testFileExists($exists) { $this->assertSame($exists, $this->storage->file_exists($path)); } + /** + * @dataProvider boolProvider + */ + public function testMkDir($successful) { + $dirName = '/Parentfolder/NewDirectory'; + $serverPath = '/' . $this->documentLibraryTitle . $dirName; + + $invocationMocker = $this->client->expects($this->once()) + ->method('createFolder') + ->with($serverPath); + + if(!$successful) { + $invocationMocker->willThrowException(new \Exception('Whatever')); + } else { + $this->fileCache->expects($this->once()) + ->method('remove') + ->with($serverPath); + } + + $this->assertSame($successful, $this->storage->mkdir($dirName)); + } + } From aeffd16b04ec8151b78099394dd601cee4222aa6 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 27 Mar 2017 12:08:38 +0200 Subject: [PATCH 21/32] cache file and folder instances fetched by fetchFolderContents saves re-requesting any of its childeren from SP Signed-off-by: Arthur Schiwon --- .../files_external/lib/Lib/Storage/SharePoint.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 8a0849a9442b5..3f86edb9af222 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -39,6 +39,7 @@ class SharePoint extends Common { const SP_PROPERTY_SIZE = 'Length'; const SP_PROPERTY_MTIME = 'TimeLastModified'; + const SP_PROPERTY_URL = 'ServerRelativeUrl'; /** @var string */ protected $server; @@ -337,6 +338,20 @@ private function getFolderContents($serverUrl) { $cacheItem = $entry ?: []; $cacheItem['children'] = $contents; $this->fileCache->set($serverUrl, $cacheItem); + + // cache children instances + foreach ($contents as $collection) { + foreach ($collection->getData() as $item) { + /** @var File|Folder $item */ + $url = $item->getProperty(self::SP_PROPERTY_URL); + $itemEntry = $this->fileCache->get($url); + $itemEntry = $itemEntry ?: []; + if(!isset($itemEntry['instance'])) { + $itemEntry['instance'] = $item; + $this->fileCache->set($url, $itemEntry); + } + } + } } else { $contents = $entry['children']; } From 620b459e19dbde6d523b240c31a04cf69268002e Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 28 Mar 2017 13:57:35 +0200 Subject: [PATCH 22/32] implement rmdir() includes performance optimization for this and mkdir Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 18 +++++- .../lib/Lib/Storage/SharePoint.php | 41 ++++++++++--- .../tests/SharePoint/SharePointClientTest.php | 61 +++++++++++++++++++ .../tests/Storage/SharePointTest.php | 61 ++++++++++++++++++- 4 files changed, 171 insertions(+), 10 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index c04ebc8076832..6ead88fd37f3e 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -123,10 +123,26 @@ public function createFolder($relativeServerPath) { $parentUrl = implode('/', $serverUrlParts); $parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl($parentUrl); - $parentFolder->getFolders()->add($newFolderName); + $folder = $parentFolder->getFolders()->add($newFolderName); try { $this->context->executeQuery(); + return $folder; + } catch (\Exception $e) { + $this->createClientContext(); + throw $e; + } + } + + public function deleteFolder($relativeServerPath, Folder $folder = null) { + $this->ensureConnection(); + + try { + if($folder === null) { + $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); + } + $folder->deleteObject(); + $this->context->executeQuery(); } catch (\Exception $e) { $this->createClientContext(); throw $e; diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 3f86edb9af222..20721adb30e49 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -103,12 +103,19 @@ public function getId() { * @since 6.0.0 */ public function mkdir($path) { + $serverUrl = $this->formatPath($path); try { - $serverUrl = $this->formatPath($path); - $this->spClient->createFolder($serverUrl); - $this->fileCache->remove($serverUrl); + $folder = $this->spClient->createFolder($serverUrl); + $this->fileCache->set($serverUrl, [ + 'instance' => $folder, + 'children' => [ + 'folders' => $folder->getFolders(), + 'files' => $folder->getFiles() + ] + ]); return true; } catch (\Exception $e) { + $this->fileCache->remove($serverUrl); return false; } } @@ -121,8 +128,20 @@ public function mkdir($path) { * @since 6.0.0 */ public function rmdir($path) { - // TODO: Implement rmdir() method. - return true; + $serverUrl = $this->formatPath($path); + try { + $cacheEntry = $this->fileCache->get($serverUrl); + $folder = null; + if(is_array($cacheEntry) && isset($cacheEntry['instance'])) { + $folder = $cacheEntry['instance']; + } + $this->spClient->deleteFolder($serverUrl, $folder); + $this->fileCache->set($serverUrl, false); + return true; + } catch (\Exception $e) { + $this->fileCache->remove($serverUrl); + return false; + } } /** @@ -361,11 +380,19 @@ private function getFolderContents($serverUrl) { /** * @param $serverUrl * @return File|Folder + * @throws NotFoundException */ private function getFileOrFolder($serverUrl) { $entry = $this->fileCache->get($serverUrl); - if($entry === null || !isset($entry['instance'])) { - $file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); + if($entry === false) { + throw new NotFoundException('File or Folder not found'); + } else if($entry === null || !isset($entry['instance'])) { + try { + $file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]); + } catch (NotFoundException $e) { + $this->fileCache->set($serverUrl, false); + throw $e; + } $cacheItem = $entry ?: []; $cacheItem['instance'] = $file; $this->fileCache->set($serverUrl, $cacheItem); diff --git a/apps/files_external/tests/SharePoint/SharePointClientTest.php b/apps/files_external/tests/SharePoint/SharePointClientTest.php index bbed519c99e82..9e3832ec7358f 100644 --- a/apps/files_external/tests/SharePoint/SharePointClientTest.php +++ b/apps/files_external/tests/SharePoint/SharePointClientTest.php @@ -256,4 +256,65 @@ public function testCreateFolderError() { $this->client->createFolder($path); } + + public function boolXBoolProvider() { + return [ + [ true, true ], + [ true, false ], + [ false, false ], + [ false, true ], + ]; + } + + /** + * @dataProvider boolXBoolProvider + */ + public function testDeleteFolder($successfull, $folderProvided) { + $dirName = 'Target Project Dir'; + $path = '/' . $this->documentLibraryTitle . '/Our Directory/' . $dirName; + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); + + $folderMock = $this->createMock(Folder::class); + $folderMock->expects($this->once()) + ->method('deleteObject'); + + $webMock = $this->createMock(Web::class); + $clientContextMock = $this->createMock(ClientContext::class); + + $folderParameter = $folderMock; + if($folderProvided === false) { + $folderParameter = null; + + $webMock->expects($this->once()) + ->method('getFolderByServerRelativeUrl') + ->with($path) + ->willReturn($folderMock); + + $clientContextMock->expects($this->once()) + ->method('getWeb') + ->willReturn($webMock); + } + + if($successfull) { + $getClientContextCalls = 1; + $clientContextMock->expects($this->once()) + ->method('executeQuery'); + } else { + $getClientContextCalls = 2; + $this->setExpectedException(\Exception::class); + $exceptionAt = $folderProvided ? 0 : 1; + $clientContextMock->expects($this->at($exceptionAt)) + ->method('executeQuery') + ->willThrowException(new \Exception('Whatever')); + } + + $this->contextsFactory->expects($this->exactly($getClientContextCalls)) + ->method('getClientContext') + ->willReturn($clientContextMock); + + $this->client->deleteFolder($path, $folderParameter); + } } diff --git a/apps/files_external/tests/Storage/SharePointTest.php b/apps/files_external/tests/Storage/SharePointTest.php index e195b9a4455d6..4571d5fa718d8 100644 --- a/apps/files_external/tests/Storage/SharePointTest.php +++ b/apps/files_external/tests/Storage/SharePointTest.php @@ -265,19 +265,76 @@ public function testMkDir($successful) { $dirName = '/Parentfolder/NewDirectory'; $serverPath = '/' . $this->documentLibraryTitle . $dirName; + $folderMock = $this->createMock(Folder::class); + $invocationMocker = $this->client->expects($this->once()) ->method('createFolder') - ->with($serverPath); + ->with($serverPath) + ->willReturn($folderMock); if(!$successful) { + $this->fileCache->expects($this->once()) + ->method('remove') + ->with($serverPath); + $invocationMocker->willThrowException(new \Exception('Whatever')); } else { $this->fileCache->expects($this->once()) - ->method('remove') + ->method('set') ->with($serverPath); + + $folderMock->expects($this->once()) + ->method('getFolders'); + $folderMock->expects($this->once()) + ->method('getFiles'); } $this->assertSame($successful, $this->storage->mkdir($dirName)); } + public function boolXBoolProvider() { + return [ + [ true, true ], + [ true, false ], + [ false, false ], + [ false, true ], + ]; + } + + /** + * @dataProvider boolXBoolProvider + */ + public function testRmDir($successful, $useCache) { + $dirName = '/Parentfolder/TargetDirectory'; + $serverPath = '/' . $this->documentLibraryTitle . $dirName; + + $folderMock = null; + if($useCache) { + $folderMock = $this->createMock(Folder::class); + + $this->fileCache->expects($this->once()) + ->method('get') + ->with($serverPath) + ->willReturn(['instance' => $folderMock]); + } + + $invocationMocker = $this->client->expects($this->once()) + ->method('deleteFolder') + ->with($serverPath, $folderMock); + + if(!$successful) { + $this->fileCache->expects($this->once()) + ->method('remove') + ->with($serverPath); + + $invocationMocker->willThrowException(new \Exception('Whatever')); + } else { + $this->fileCache->expects($this->once()) + ->method('set') + ->with($serverPath, null); + } + + $this->assertSame($successful, $this->storage->rmdir($dirName)); + } + } From e2c03bbf389f7f14629ec152ecb21ba2b2922339 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 31 Mar 2017 11:41:48 +0200 Subject: [PATCH 23/32] implement read part of fopen Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 39 +++++++++++++++++++ .../lib/Lib/Storage/SharePoint.php | 39 +++++++++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 6ead88fd37f3e..1c0b5690dcf8e 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -26,6 +26,7 @@ use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; use Office365\PHP\Client\Runtime\ClientObject; use Office365\PHP\Client\Runtime\ClientObjectCollection; +use Office365\PHP\Client\Runtime\Utilities\RequestOptions; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; @@ -113,6 +114,7 @@ public function fetchFolder($relativeServerPath, array $properties = null) { * adds a folder on the given server path * * @param string $relativeServerPath + * @return Folder * @throws \Exception */ public function createFolder($relativeServerPath) { @@ -134,6 +136,43 @@ public function createFolder($relativeServerPath) { } } + /** + * downloads a file by passing it directly into a file resource + * + * @param $relativeServerPath + * @param resource $fp a file resource open for writing + * @return \Office365\PHP\Client\Runtime\OData\ODataPayload + * @throws \Exception + */ + public function getFileViaStream($relativeServerPath, $fp) { + if(!is_resource($fp)) { + throw new \InvalidArgumentException('file resource expected'); + } + $relativeServerPath = rawurlencode($relativeServerPath); + $url = $this->context->getServiceRootUrl() . + "web/getfilebyserverrelativeurl('$relativeServerPath')/\$value"; + $options = new RequestOptions($url); + $options->addCurlOption(CURLOPT_FILE, $fp); + + try { + $ok = $this->context->executeQueryDirect($options); + } catch(\Exception $e) { + $this->createClientContext(); + throw $e; + } + return $ok; + } + + /** + * fetches the file content (aka download) + * + * @param $relativeServerPath + * @return string the file content + */ + public function getFile($relativeServerPath) { + return File::openBinary($this->context, $relativeServerPath); + } + public function deleteFolder($relativeServerPath, Folder $folder = null) { $this->ensureConnection(); diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 20721adb30e49..683a16617823e 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -31,6 +31,7 @@ use OCA\Files_External\Lib\SharePoint\SharePointClient; use OCA\Files_External\Lib\SharePoint\SharePointClientFactory; use OCP\Files\FileInfo; +use OCP\ITempManager; use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; @@ -62,6 +63,9 @@ class SharePoint extends Common { /** @var ContextsFactory */ private $contextsFactory; + /** @var ITempManager */ + private $tempManager; + public function __construct($parameters) { $this->server = $parameters['host']; $this->documentLibrary = $parameters['documentLibrary']; @@ -266,7 +270,7 @@ public function file_exists($path) { */ public function unlink($path) { // FIXME:: all is totally wrong - $path = trim($path); + /*$path = trim($path); if($path === '/' || $path === '') { return false; } @@ -278,7 +282,7 @@ public function unlink($path) { } catch(\Exception $e) { // NOOP } - } + }*/ return false; } @@ -291,7 +295,27 @@ public function unlink($path) { * @since 6.0.0 */ public function fopen($path, $mode) { - // TODO: Implement fopen() method. + $serverUrl = $this->formatPath($path); + + switch ($mode) { + case 'r': + case 'rb': + $tmpFile = $this->tempManager->getTemporaryFile(); + + // TODO: when https://github.com/vgrem/phpSPO/pull/59 is merged, + // use getFileViaStream approach and remove the other code + /*$fp = fopen($tmpFile, 'w+'); + if(!$this->spClient->getFileViaStream($serverUrl, $fp)) { + fclose($fp); + return false; + } + fseek($fp, 0); + return $fp;*/ + + $content = $this->spClient->getFile($serverUrl); + file_put_contents($tmpFile, $content); + return fopen($tmpFile, 'r'); + } return false; } @@ -341,7 +365,14 @@ private function fixDI(array $parameters) { if(isset($parameters['cappedMemoryCache'])) { $this->fileCache = $parameters['cappedMemoryCache']; } else { - $this->fileCache = new CappedMemoryCache('256'); + // there's no API to get such + $this->fileCache = new CappedMemoryCache(); + } + + if(isset($parameters['tempManager'])) { + $this->tempManager = $parameters['tempManager']; + } else { + $this->tempManager = \OC::$server->getTempManager(); } } From 56a2d83bbc575ba23e1735bc3b2686a7c9827f62 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 5 Apr 2017 10:59:46 +0200 Subject: [PATCH 24/32] implemented fopen Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 115 ++++++++++++++++-- .../lib/Lib/Storage/SharePoint.php | 94 ++++++++++++-- 2 files changed, 193 insertions(+), 16 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 1c0b5690dcf8e..3e1777ce6434c 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -29,6 +29,7 @@ use Office365\PHP\Client\Runtime\Utilities\RequestOptions; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; +use Office365\PHP\Client\SharePoint\FileCreationInformation; use Office365\PHP\Client\SharePoint\Folder; use Office365\PHP\Client\SharePoint\SPList; @@ -120,12 +121,8 @@ public function fetchFolder($relativeServerPath, array $properties = null) { public function createFolder($relativeServerPath) { $this->ensureConnection(); - $serverUrlParts = explode('/', $relativeServerPath); - $newFolderName = array_pop($serverUrlParts); - $parentUrl = implode('/', $serverUrlParts); - - $parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl($parentUrl); - $folder = $parentFolder->getFolders()->add($newFolderName); + $parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl(dirname($relativeServerPath)); + $folder = $parentFolder->getFolders()->add(basename($relativeServerPath)); try { $this->context->executeQuery(); @@ -152,7 +149,7 @@ public function getFileViaStream($relativeServerPath, $fp) { $url = $this->context->getServiceRootUrl() . "web/getfilebyserverrelativeurl('$relativeServerPath')/\$value"; $options = new RequestOptions($url); - $options->addCurlOption(CURLOPT_FILE, $fp); + $options->StreamHandle = $fp; try { $ok = $this->context->executeQueryDirect($options); @@ -173,6 +170,110 @@ public function getFile($relativeServerPath) { return File::openBinary($this->context, $relativeServerPath); } + /** + * @param string $relativeServerPath + * @param resource $fp + * @param string $localPath - we need to pass the file size for the content length header + * @return bool + * @throws \Exception + */ + public function overwriteFileViaStream($relativeServerPath, $fp, $localPath) { + $serverRelativeUrl = rawurlencode($relativeServerPath); + $url = $this->context->getServiceRootUrl() . "web/getfilebyserverrelativeurl('$serverRelativeUrl')/\$value"; + $request = new RequestOptions($url); + $request->Method = 'POST'; // yes, POST + $request->addCustomHeader('X-HTTP-Method','PUT'); // yes, PUT + $this->context->ensureFormDigest($request); + //FIXME: Proper StreamHandle handling is not upstream, yet + $request->StreamHandle = $fp; + $request->addCustomHeader("content-length", filesize($localPath)); + + try { + $ok = $this->context->executeQueryDirect($request); + } catch(\Exception $e) { + $this->resetClientContext(); + throw $e; + } + return $ok !== false; + } + + /** + * FIXME: use StreamHandle as in overwriteFileViaStream for uploading a file + * needs to reimplement adding-file-tp-sp-logic quite some… perhaps upload an + * empty file and continue with overwriteFileViaStream? + * + * @param $relativeServerPath + * @param $content + * @return File + * @throws \Exception + */ + public function uploadNewFile($relativeServerPath, $content) { + $parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl(dirname($relativeServerPath)); + $fileCollection = $parentFolder->getFiles(); + + $info = new FileCreationInformation(); + $info->Content = $content; + $info->Url = basename($relativeServerPath); + $file = $fileCollection->add($info); + try { + $this->context->executeQuery(); + return $file; + } catch(\Exception $e) { + $this->createClientContext(); + throw $e; + } + } + + /** + * moves a file or a folder to the given destination + * + * @param string $oldPath + * @param string $newPath + * @return bool + * @throws \Exception + */ + public function rename($oldPath, $newPath) { + $this->ensureConnection(); + + try { + $item = $this->fetchFileOrFolder($oldPath); + if($item instanceof File) { + $this->renameFile($item, $newPath); + } else if($item instanceof Folder) { + $this->renameFolder($item, $newPath); + } else { + return false; + } + return true; + } catch (\Exception $e) { + $this->createClientContext(); + throw $e; + } + } + + /** + * renames a folder + * + * @param Folder $folder + * @param string $newPath + */ + private function renameFolder(Folder $folder, $newPath) { + $folder->rename(basename($newPath)); + $this->context->executeQuery(); + } + + /** + * moves a file + * + * @param File $file + * @param string $newPath + */ + private function renameFile(File $file, $newPath) { + $newPath = rawurlencode($newPath); + $file->moveTo($newPath, 0); + $this->context->executeQuery(); + #$req = $this->debugGetLastRequest(); + } public function deleteFolder($relativeServerPath, Folder $folder = null) { $this->ensureConnection(); diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 683a16617823e..d062fe231bf35 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -23,6 +23,7 @@ namespace OCA\Files_External\Lib\Storage; +use Icewind\Streams\CallbackWrapper; use Icewind\Streams\IteratorDirectory; use OC\Cache\CappedMemoryCache; use OC\Files\Storage\Common; @@ -281,9 +282,25 @@ public function unlink($path) { return true; } catch(\Exception $e) { // NOOP + } + + public function rename($path1, $path2) { + $oldPath = $this->formatPath($path1); + $newPath = $this->formatPath($path2); + try { + $isRenamed = $this->spClient->rename($oldPath, $newPath); + if($isRenamed) { + $entry = $this->fileCache->get($oldPath); + $this->fileCache->remove($newPath); + if($entry !== false) { + $this->fileCache->set($newPath, $entry); + } + $this->fileCache->remove($oldPath); } - }*/ - return false; + return $isRenamed; + } catch (\Exception $e) { + return false; + } } /** @@ -298,27 +315,86 @@ public function fopen($path, $mode) { $serverUrl = $this->formatPath($path); switch ($mode) { + case 'a': + case 'ab': + case 'a+': + // no native support + return false; case 'r': case 'rb': $tmpFile = $this->tempManager->getTemporaryFile(); - // TODO: when https://github.com/vgrem/phpSPO/pull/59 is merged, - // use getFileViaStream approach and remove the other code - /*$fp = fopen($tmpFile, 'w+'); + $fp = fopen($tmpFile, 'w+'); if(!$this->spClient->getFileViaStream($serverUrl, $fp)) { fclose($fp); return false; } fseek($fp, 0); - return $fp;*/ + return $fp; + break; + case 'r+': + case 'rb+': + case 'r+b': + // fseek 0 + case 'w': + case 'w+': + case 'wb': + case 'wb+': + case 'w+b': + // truncate + // fseek 0 + case 'x': + case 'x+': + case 'xb': + case 'xb+': + case 'x+b': + // fseek 0 + case 'c': + case 'cb': + case 'c+': + case 'cb+': + case 'c+b': + //fseek 0 + if($mode[0] === 'x' && $this->file_exists($path)) { + return false; + } + $tmpFile = $this->tempManager->getTemporaryFile(); + if($mode[0] !== 'w' && $this->file_exists($path)) { + $content = $this->fopen($path, 'r'); + if($content === false) { + // should not happen, but let's be safe + return false; + } + $this->file_put_contents($tmpFile, $content); + } + $fp = fopen($tmpFile, $mode); + return CallbackWrapper::wrap($fp, null, null, function () use ($path, $tmpFile) { + $this->writeBack($tmpFile, $path); + }); - $content = $this->spClient->getFile($serverUrl); - file_put_contents($tmpFile, $content); - return fopen($tmpFile, 'r'); } return false; } + public function writeBack($tmpFile, $path) { + $serverUrl = $this->formatPath($path); + $content = file_get_contents($tmpFile); + $fp = fopen($tmpFile, 'r'); + + try { + if ($this->file_exists($path)) { + $this->spClient->overwriteFileViaStream($serverUrl, $fp, $tmpFile); + fclose($fp); + $this->fileCache->remove($serverUrl); + } else { + $file = $this->spClient->uploadNewFile($serverUrl, $content); + $this->fileCache->set($serverUrl, ['instance' => $file]); + } + } catch (\Exception $e) { + return false; + } + } + /** * see http://php.net/manual/en/function.touch.php * If the backend does not support the operation, false should be returned From 9b79ddb4229997ae5f9b6a85bb131325a1a9edf9 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 19 Apr 2017 23:55:17 +0200 Subject: [PATCH 25/32] fixed and improved delete and rename methods Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 64 +++++++++++++------ .../lib/Lib/Storage/SharePoint.php | 37 ++++++----- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 3e1777ce6434c..ca222baf97ac2 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -27,6 +27,7 @@ use Office365\PHP\Client\Runtime\ClientObject; use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\Runtime\Utilities\RequestOptions; +use Office365\PHP\Client\Runtime\Utilities\Requests; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\FileCreationInformation; @@ -85,12 +86,12 @@ public function fetchFileOrFolder($path, array $properties = null) { && $e->getMessage() !== 'Unknown Error' && $e->getMessage() !== 'File Not Found.' ) { - $this->createClientContext(); + $this->resetClientContext(); # Unexpected Exception, pass it on throw $e; } } - $this->createClientContext(); + $this->resetClientContext(); } # Nothing succeeded, quit with not found @@ -128,7 +129,7 @@ public function createFolder($relativeServerPath) { $this->context->executeQuery(); return $folder; } catch (\Exception $e) { - $this->createClientContext(); + $this->resetClientContext(); throw $e; } } @@ -154,7 +155,7 @@ public function getFileViaStream($relativeServerPath, $fp) { try { $ok = $this->context->executeQueryDirect($options); } catch(\Exception $e) { - $this->createClientContext(); + $this->resetClientContext(); throw $e; } return $ok; @@ -219,7 +220,7 @@ public function uploadNewFile($relativeServerPath, $content) { $this->context->executeQuery(); return $file; } catch(\Exception $e) { - $this->createClientContext(); + $this->resetClientContext(); throw $e; } } @@ -246,7 +247,7 @@ public function rename($oldPath, $newPath) { } return true; } catch (\Exception $e) { - $this->createClientContext(); + $this->resetClientContext(); throw $e; } } @@ -274,21 +275,43 @@ private function renameFile(File $file, $newPath) { $this->context->executeQuery(); #$req = $this->debugGetLastRequest(); } - public function deleteFolder($relativeServerPath, Folder $folder = null) { - $this->ensureConnection(); + private function debugGetLastRequest() { + $requestHistory = Requests::getHistory(); + $request = array_pop($requestHistory); + return $request; + } + + public function delete(ClientObject $item) { + $this->ensureConnection(); try { - if($folder === null) { - $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); + if ($item instanceof File) { + $this->deleteFile($item); + } else if ($item instanceof Folder) { + $this->deleteFolder($item); } - $folder->deleteObject(); - $this->context->executeQuery(); - } catch (\Exception $e) { - $this->createClientContext(); + } catch(\Exception $e) { + $this->resetClientContext(); throw $e; } } + /** + * deletes the given file on SP + * + * @param File $file + * @throws \Exception + */ + public function deleteFile(File $file) { + $file->recycle(); + $this->context->executeQuery(); + } + + public function deleteFolder(Folder $folder) { + $folder->deleteObject(); + $this->context->executeQuery(); + } + /** * @param $relativeServerPath * @param null $properties @@ -380,15 +403,18 @@ private function ensureConnection() { } $this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']); $this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow… - $this->createClientContext(); + $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext); # Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand), e.g.: } /** - * (re)creates the sharepoint client context + * resets the sharepoint client context + * + * Usually executed, when a query resulted into an exception. The faulty + * query is not removed by default. */ - private function createClientContext() { - $this->context = null; - $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext); + private function resetClientContext() { + //FIXME: resetQueries method did not go upstream yet + $this->context->getPendingRequest()->resetQueries(); } } diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index d062fe231bf35..6c91c1dd2406b 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -135,12 +135,8 @@ public function mkdir($path) { public function rmdir($path) { $serverUrl = $this->formatPath($path); try { - $cacheEntry = $this->fileCache->get($serverUrl); - $folder = null; - if(is_array($cacheEntry) && isset($cacheEntry['instance'])) { - $folder = $cacheEntry['instance']; - } - $this->spClient->deleteFolder($serverUrl, $folder); + $folder = $this->getFileOrFolder($serverUrl); + $this->spClient->delete($folder); $this->fileCache->set($serverUrl, false); return true; } catch (\Exception $e) { @@ -270,23 +266,32 @@ public function file_exists($path) { * @since 6.0.0 */ public function unlink($path) { - // FIXME:: all is totally wrong - /*$path = trim($path); - if($path === '/' || $path === '') { + // file methods get called twice at least, returning true + if(!$this->file_exists($path)) { + return true; + } + try { + $serverUrl = $this->formatPath($path); + $this->spClient->delete($this->getFileOrFolder($serverUrl)); + $this->fileCache->set($serverUrl, false); + return true; + } catch (\Exception $e) { return false; } - foreach([true, false] as $asFile) { - try { - $fsObject = $this->spClient->fetchFileOrFolder($path, $asFile); - $fsObject->deleteObject(); - return true; - } catch(\Exception $e) { - // NOOP } public function rename($path1, $path2) { $oldPath = $this->formatPath($path1); $newPath = $this->formatPath($path2); + + try { + $item = $this->getFileOrFolder($newPath); + $this->spClient->delete($item); + $this->fileCache->remove($newPath); + } catch(NotFoundException $e) { + // noop + } + try { $isRenamed = $this->spClient->rename($oldPath, $newPath); if($isRenamed) { From 1ac9a49c0b3963163f6268c96a6cc3db9ce77c33 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Thu, 20 Apr 2017 13:16:20 +0200 Subject: [PATCH 26/32] remove resetClientContext() the troublemaker will be fixed in the lib --- .../lib/Lib/SharePoint/SharePointClient.php | 82 +++++-------------- 1 file changed, 19 insertions(+), 63 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index ca222baf97ac2..48112a0240e58 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -86,12 +86,10 @@ public function fetchFileOrFolder($path, array $properties = null) { && $e->getMessage() !== 'Unknown Error' && $e->getMessage() !== 'File Not Found.' ) { - $this->resetClientContext(); # Unexpected Exception, pass it on throw $e; } } - $this->resetClientContext(); } # Nothing succeeded, quit with not found @@ -125,13 +123,8 @@ public function createFolder($relativeServerPath) { $parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl(dirname($relativeServerPath)); $folder = $parentFolder->getFolders()->add(basename($relativeServerPath)); - try { - $this->context->executeQuery(); - return $folder; - } catch (\Exception $e) { - $this->resetClientContext(); - throw $e; - } + $this->context->executeQuery(); + return $folder; } /** @@ -152,13 +145,7 @@ public function getFileViaStream($relativeServerPath, $fp) { $options = new RequestOptions($url); $options->StreamHandle = $fp; - try { - $ok = $this->context->executeQueryDirect($options); - } catch(\Exception $e) { - $this->resetClientContext(); - throw $e; - } - return $ok; + return $this->context->executeQueryDirect($options); } /** @@ -189,13 +176,7 @@ public function overwriteFileViaStream($relativeServerPath, $fp, $localPath) { $request->StreamHandle = $fp; $request->addCustomHeader("content-length", filesize($localPath)); - try { - $ok = $this->context->executeQueryDirect($request); - } catch(\Exception $e) { - $this->resetClientContext(); - throw $e; - } - return $ok !== false; + return false !== $this->context->executeQueryDirect($request); } /** @@ -216,13 +197,8 @@ public function uploadNewFile($relativeServerPath, $content) { $info->Content = $content; $info->Url = basename($relativeServerPath); $file = $fileCollection->add($info); - try { - $this->context->executeQuery(); - return $file; - } catch(\Exception $e) { - $this->resetClientContext(); - throw $e; - } + $this->context->executeQuery(); + return $file; } /** @@ -236,20 +212,15 @@ public function uploadNewFile($relativeServerPath, $content) { public function rename($oldPath, $newPath) { $this->ensureConnection(); - try { - $item = $this->fetchFileOrFolder($oldPath); - if($item instanceof File) { - $this->renameFile($item, $newPath); - } else if($item instanceof Folder) { - $this->renameFolder($item, $newPath); - } else { - return false; - } - return true; - } catch (\Exception $e) { - $this->resetClientContext(); - throw $e; + $item = $this->fetchFileOrFolder($oldPath); + if($item instanceof File) { + $this->renameFile($item, $newPath); + } else if($item instanceof Folder) { + $this->renameFolder($item, $newPath); + } else { + return false; } + return true; } /** @@ -284,15 +255,10 @@ private function debugGetLastRequest() { public function delete(ClientObject $item) { $this->ensureConnection(); - try { - if ($item instanceof File) { - $this->deleteFile($item); - } else if ($item instanceof Folder) { - $this->deleteFolder($item); - } - } catch(\Exception $e) { - $this->resetClientContext(); - throw $e; + if ($item instanceof File) { + $this->deleteFile($item); + } else if ($item instanceof Folder) { + $this->deleteFolder($item); } } @@ -406,15 +372,5 @@ private function ensureConnection() { $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext); # Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand), e.g.: } - - /** - * resets the sharepoint client context - * - * Usually executed, when a query resulted into an exception. The faulty - * query is not removed by default. - */ - private function resetClientContext() { - //FIXME: resetQueries method did not go upstream yet - $this->context->getPendingRequest()->resetQueries(); - } + } From 72225ab1e7502260ec41e8bfb30435e506a72cd0 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Fri, 21 Apr 2017 11:25:58 +0200 Subject: [PATCH 27/32] some cleanup Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 2 +- apps/files_external/lib/Lib/Storage/SharePoint.php | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 48112a0240e58..27820cdc537de 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -370,7 +370,7 @@ private function ensureConnection() { $this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']); $this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow… $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext); - # Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand), e.g.: + # Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand) } } diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 6c91c1dd2406b..d9acb959618e1 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -36,7 +36,6 @@ use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\Folder; -use Office365\PHP\Client\SharePoint\ListItem; class SharePoint extends Common { const SP_PROPERTY_SIZE = 'Length'; @@ -163,7 +162,6 @@ public function opendir($path) { /** @var File[]|Folder[] $items */ $items = $collection->getData(); foreach ($items as $item) { - /** @var ListItem $fields */ if(!$this->spClient->isHidden($item)) { $files[] = $item->getProperty('Name'); } @@ -396,7 +394,7 @@ public function writeBack($tmpFile, $path) { $this->fileCache->set($serverUrl, ['instance' => $file]); } } catch (\Exception $e) { - return false; + // noop } } @@ -410,11 +408,9 @@ public function writeBack($tmpFile, $path) { * @since 6.0.0 */ public function touch($path, $mtime = null) { - // TODO: Implement touch() method. - return true; + return false; } - /** * work around dependency injection issues so we can test this class properly * From 007ca1487bc2b8529e0e89a9a72778c41910925b Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Sat, 22 Apr 2017 00:03:59 +0200 Subject: [PATCH 28/32] get CRUD permissions Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 40 +++++++----- .../lib/Lib/Storage/SharePoint.php | 65 ++++++++++++++++++- 2 files changed, 87 insertions(+), 18 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 27820cdc537de..9fe5b31202c13 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -28,6 +28,7 @@ use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\Runtime\Utilities\RequestOptions; use Office365\PHP\Client\Runtime\Utilities\Requests; +use Office365\PHP\Client\SharePoint\BasePermissions; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; use Office365\PHP\Client\SharePoint\FileCreationInformation; @@ -327,28 +328,33 @@ public function isHidden(ClientObject $file) { return true; } - public function loadAndExecute(ClientObject $object, array $properties = null) { - $this->context->load($object, $properties); - $this->context->executeQuery(); - } - /** - * @return SPList - * @throws NotFoundException + * requests the permission for the provided file or folder + * + * @param ClientObject $item + * @return BasePermissions */ - private function getDocumentLibrary() { - if(!is_null($this->documentLibrary)) { - return $this->documentLibrary; + public function getPermissions(ClientObject $item) { + if(!$item instanceof File && !$item instanceof Folder) { + throw new \InvalidArgumentException('File or Folder expected'); } - $lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibraryTitle . '\'')->top(1); - $this->context->load($lists)->executeQuery(); - if ($lists->getCount() === 1 && $lists->getData()[0] instanceof SPList) { - $this->documentLibrary = $lists->getData()[0]; - return $this->documentLibrary; + $listItem = $item->getListItemAllFields(); + $this->loadAndExecute($listItem, ['EffectiveBasePermissions']); + $data = $listItem->getProperty('EffectiveBasePermissions'); + if(!is_object($data) || !property_exists($data, 'High') || !property_exists($data, 'Low')) { + throw new \RuntimeException('Unexpected value from SP Server'); } + $permissions = new BasePermissions(); + $permissions->High = $data->High; + $permissions->Low = $data->Low; - throw new NotFoundException('List not found'); + return $permissions; + } + + public function loadAndExecute(ClientObject $object, array $properties = null) { + $this->context->load($object, $properties); + $this->context->executeQuery(); } /** @@ -372,5 +378,5 @@ private function ensureConnection() { $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext); # Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand) } - + } diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index d9acb959618e1..31ae855361037 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -42,6 +42,11 @@ class SharePoint extends Common { const SP_PROPERTY_MTIME = 'TimeLastModified'; const SP_PROPERTY_URL = 'ServerRelativeUrl'; + const SP_PERMISSION_READ = 1; + const SP_PERMISSION_CREATE = 2; + const SP_PERMISSION_UPDATE = 3; + const SP_PERMISSION_DELETE = 4; + /** @var string */ protected $server; @@ -154,7 +159,6 @@ public function rmdir($path) { public function opendir($path) { try { $serverUrl = $this->formatPath($path); - //$collections = $this->spClient->fetchFolderContents($serverUrl, ['Name', 'ListItemAllFields']); // does not work for some reason :( $collections = $this->getFolderContents($serverUrl); $files = []; @@ -398,6 +402,43 @@ public function writeBack($tmpFile, $path) { } } + public function isCreatable($path) { + try { + return $this->hasPermission($path, self::SP_PERMISSION_CREATE); + } catch (\Exception $e) { + return parent::isCreatable($path); + } + } + + public function isUpdatable($path) { + try { + return $this->hasPermission($path, self::SP_PERMISSION_UPDATE); + } catch (\Exception $e) { + return parent::isUpdatable($path); + } + } + + public function isReadable($path) { + try { + return $this->hasPermission($path, self::SP_PERMISSION_READ); + } catch (\Exception $e) { + return parent::isReadable($path); + } + } + + public function isDeletable($path) { + try { + return $this->hasPermission($path, self::SP_PERMISSION_DELETE); + } catch (\Exception $e) { + return parent::isDeletable($path); + } + } + + private function hasPermission($path, $permissionType) { + $serverUrl = $this->formatPath($path); + return $this->getUserPermissions($serverUrl)->has($permissionType); + } + /** * see http://php.net/manual/en/function.touch.php * If the backend does not support the operation, false should be returned @@ -485,6 +526,28 @@ private function getFolderContents($serverUrl) { return $contents; } + private function getUserPermissions($serverUrl) { + $item = $this->getFileOrFolder($serverUrl); + $entry = $this->fileCache->get($serverUrl); + if(isset($entry['permissions'])) { + if($entry['permissions'] === false) { + throw new NotFoundException('Could not retrieve permissions'); + } + return $entry['permissions']; + } + try { + $permissions = $this->spClient->getPermissions($item); + } catch (\Exception $e) { + $permissions = false; + } + $entry['permissions'] = $permissions; + $this->fileCache->set($serverUrl, $entry); + if($entry['permissions'] === false) { + throw new NotFoundException('Could not retrieve permissions'); + } + return $entry['permissions']; + } + /** * @param $serverUrl * @return File|Folder From ab29f8710fdbb102f659ac0a63b40c2dae224cae Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Mon, 24 Apr 2017 23:34:29 +0200 Subject: [PATCH 29/32] add missing PHP Doc Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/ContextsFactory.php | 10 +++ .../lib/Lib/SharePoint/SharePointClient.php | 75 +++++++++++++++---- .../lib/Lib/Storage/SharePoint.php | 35 +++++++++ 3 files changed, 106 insertions(+), 14 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/ContextsFactory.php b/apps/files_external/lib/Lib/SharePoint/ContextsFactory.php index a679da7ce442f..dadee90711036 100644 --- a/apps/files_external/lib/Lib/SharePoint/ContextsFactory.php +++ b/apps/files_external/lib/Lib/SharePoint/ContextsFactory.php @@ -30,10 +30,20 @@ class ContextsFactory { + /** + * @param string $user + * @param string $password + * @return NetworkCredentialContext + */ public function getAuthContext($user, $password) { return new NetworkCredentialContext($user, $password); } + /** + * @param string $server + * @param IAuthenticationContext $authContext + * @return ClientContext + */ public function getClientContext($server, IAuthenticationContext $authContext) { return new ClientContext($server, $authContext); } diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 9fe5b31202c13..8d87541946c09 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -57,7 +57,20 @@ class SharePointClient { /** @var string */ private $documentLibraryTitle; - public function __construct(ContextsFactory $contextsFactory, $sharePointUrl, array $credentials, $documentLibraryTitle) { + /** + * SharePointClient constructor. + * + * @param ContextsFactory $contextsFactory + * @param string $sharePointUrl + * @param array $credentials + * @param string $documentLibraryTitle + */ + public function __construct( + ContextsFactory $contextsFactory, + $sharePointUrl, + array $credentials, + $documentLibraryTitle + ) { $this->contextsFactory = $contextsFactory; $this->sharePointUrl = $sharePointUrl; $this->credentials = $credentials; @@ -65,6 +78,9 @@ public function __construct(ContextsFactory $contextsFactory, $sharePointUrl, ar } /** + * Returns the corresponding File or Folder object for the provided path. + * If none can be retrieved, an exception is thrown. + * * @param string $path * @param array $properties * @return File|Folder @@ -97,6 +113,13 @@ public function fetchFileOrFolder($path, array $properties = null) { throw new NotFoundException('File or Folder not found'); } + /** + * returns a File instance for the provided path + * + * @param string $relativeServerPath + * @param array|null $properties + * @return File + */ public function fetchFile($relativeServerPath, array $properties = null) { $this->ensureConnection(); $file = $this->context->getWeb()->getFileByServerRelativeUrl($relativeServerPath); @@ -104,6 +127,13 @@ public function fetchFile($relativeServerPath, array $properties = null) { return $file; } + /** + * returns a Folder instance for the provided path + * + * @param string $relativeServerPath + * @param array|null $properties + * @return Folder + */ public function fetchFolder($relativeServerPath, array $properties = null) { $this->ensureConnection(); $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); @@ -149,16 +179,6 @@ public function getFileViaStream($relativeServerPath, $fp) { return $this->context->executeQueryDirect($options); } - /** - * fetches the file content (aka download) - * - * @param $relativeServerPath - * @return string the file content - */ - public function getFile($relativeServerPath) { - return File::openBinary($this->context, $relativeServerPath); - } - /** * @param string $relativeServerPath * @param resource $fp @@ -248,12 +268,20 @@ private function renameFile(File $file, $newPath) { #$req = $this->debugGetLastRequest(); } - private function debugGetLastRequest() { + /** + * @return array + */ + private function _debugGetLastRequest() { $requestHistory = Requests::getHistory(); $request = array_pop($requestHistory); return $request; } + /** + * deletes a provided File or Folder + * + * @param ClientObject $item + */ public function delete(ClientObject $item) { $this->ensureConnection(); if ($item instanceof File) { @@ -264,7 +292,7 @@ public function delete(ClientObject $item) { } /** - * deletes the given file on SP + * deletes (in fact recycles) the given file on SP * * @param File $file * @throws \Exception @@ -274,12 +302,19 @@ public function deleteFile(File $file) { $this->context->executeQuery(); } + /** + * deletes (in fact recycles) the given Folder on SP. + * + * @param Folder $folder + */ public function deleteFolder(Folder $folder) { - $folder->deleteObject(); + $folder->recycle(); $this->context->executeQuery(); } /** + * returns a Folder- and a FileCollection of the children of the given directory + * * @param $relativeServerPath * @param null $properties * @param Folder $folder @@ -302,6 +337,12 @@ public function fetchFolderContents($relativeServerPath, $properties = null, Fol return $collections; } + /** + * tests whether the provided instance is hidden + * + * @param ClientObject $file + * @return bool + */ public function isHidden(ClientObject $file) { // ClientObject itself does not have getListItemAllFields but is // the common denominator of File and Folder @@ -352,6 +393,12 @@ public function getPermissions(ClientObject $item) { return $permissions; } + /** + * shortcut for querying a provided object from SP + * + * @param ClientObject $object + * @param array|null $properties + */ public function loadAndExecute(ClientObject $object, array $properties = null) { $this->context->load($object, $properties); $this->context->executeQuery(); diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 31ae855361037..593e26cd86b67 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -282,6 +282,11 @@ public function unlink($path) { } } + /** + * @param string $path1 + * @param string $path2 + * @return bool + */ public function rename($path1, $path2) { $oldPath = $this->formatPath($path1); $newPath = $this->formatPath($path2); @@ -383,6 +388,10 @@ public function fopen($path, $mode) { return false; } + /** + * @param string $tmpFile + * @param string $path + */ public function writeBack($tmpFile, $path) { $serverUrl = $this->formatPath($path); $content = file_get_contents($tmpFile); @@ -402,6 +411,10 @@ public function writeBack($tmpFile, $path) { } } + /** + * @param string $path + * @return bool + */ public function isCreatable($path) { try { return $this->hasPermission($path, self::SP_PERMISSION_CREATE); @@ -410,6 +423,10 @@ public function isCreatable($path) { } } + /** + * @param string $path + * @return bool + */ public function isUpdatable($path) { try { return $this->hasPermission($path, self::SP_PERMISSION_UPDATE); @@ -418,6 +435,10 @@ public function isUpdatable($path) { } } + /** + * @param string $path + * @return bool + */ public function isReadable($path) { try { return $this->hasPermission($path, self::SP_PERMISSION_READ); @@ -426,6 +447,10 @@ public function isReadable($path) { } } + /** + * @param string $path + * @return bool + */ public function isDeletable($path) { try { return $this->hasPermission($path, self::SP_PERMISSION_DELETE); @@ -434,6 +459,11 @@ public function isDeletable($path) { } } + /** + * @param string $path + * @param int $permissionType + * @return bool + */ private function hasPermission($path, $permissionType) { $serverUrl = $this->formatPath($path); return $this->getUserPermissions($serverUrl)->has($permissionType); @@ -526,6 +556,11 @@ private function getFolderContents($serverUrl) { return $contents; } + /** + * @param string $serverUrl + * @return \Office365\PHP\Client\SharePoint\BasePermissions + * @throws NotFoundException + */ private function getUserPermissions($serverUrl) { $item = $this->getFileOrFolder($serverUrl); $entry = $this->fileCache->get($serverUrl); From b2174888cbd831f6676160fe6833814f51b1fcfc Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 25 Apr 2017 00:51:49 +0200 Subject: [PATCH 30/32] adjust and extend unit tests Signed-off-by: Arthur Schiwon --- .../lib/Lib/SharePoint/SharePointClient.php | 15 +- .../lib/Lib/Storage/SharePoint.php | 4 +- .../tests/SharePoint/SharePointClientTest.php | 138 +++++++++++++----- .../tests/Storage/SharePointTest.php | 80 +++++----- 4 files changed, 140 insertions(+), 97 deletions(-) diff --git a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php index 8d87541946c09..48edaf4179883 100644 --- a/apps/files_external/lib/Lib/SharePoint/SharePointClient.php +++ b/apps/files_external/lib/Lib/SharePoint/SharePointClient.php @@ -170,6 +170,7 @@ public function getFileViaStream($relativeServerPath, $fp) { if(!is_resource($fp)) { throw new \InvalidArgumentException('file resource expected'); } + $this->ensureConnection(); $relativeServerPath = rawurlencode($relativeServerPath); $url = $this->context->getServiceRootUrl() . "web/getfilebyserverrelativeurl('$relativeServerPath')/\$value"; @@ -193,7 +194,6 @@ public function overwriteFileViaStream($relativeServerPath, $fp, $localPath) { $request->Method = 'POST'; // yes, POST $request->addCustomHeader('X-HTTP-Method','PUT'); // yes, PUT $this->context->ensureFormDigest($request); - //FIXME: Proper StreamHandle handling is not upstream, yet $request->StreamHandle = $fp; $request->addCustomHeader("content-length", filesize($localPath)); @@ -265,7 +265,6 @@ private function renameFile(File $file, $newPath) { $newPath = rawurlencode($newPath); $file->moveTo($newPath, 0); $this->context->executeQuery(); - #$req = $this->debugGetLastRequest(); } /** @@ -315,21 +314,16 @@ public function deleteFolder(Folder $folder) { /** * returns a Folder- and a FileCollection of the children of the given directory * - * @param $relativeServerPath - * @param null $properties * @param Folder $folder * @return ClientObjectCollection[] */ - public function fetchFolderContents($relativeServerPath, $properties = null, Folder $folder = null) { + public function fetchFolderContents(Folder $folder) { $this->ensureConnection(); - if($folder === null) { - $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath); - } $folderCollection = $folder->getFolders(); $fileCollection = $folder->getFiles(); - $this->context->load($folderCollection, $properties); - $this->context->load($fileCollection, $properties); + $this->context->load($folderCollection); + $this->context->load($fileCollection); $this->context->executeQuery(); $collections = ['folders' => $folderCollection, 'files' => $fileCollection]; @@ -379,6 +373,7 @@ public function getPermissions(ClientObject $item) { if(!$item instanceof File && !$item instanceof Folder) { throw new \InvalidArgumentException('File or Folder expected'); } + $this->ensureConnection(); $listItem = $item->getListItemAllFields(); $this->loadAndExecute($listItem, ['EffectiveBasePermissions']); diff --git a/apps/files_external/lib/Lib/Storage/SharePoint.php b/apps/files_external/lib/Lib/Storage/SharePoint.php index 593e26cd86b67..267ff5af5044e 100644 --- a/apps/files_external/lib/Lib/Storage/SharePoint.php +++ b/apps/files_external/lib/Lib/Storage/SharePoint.php @@ -529,10 +529,10 @@ private function fixDI(array $parameters) { * @return ClientObjectCollection[] */ private function getFolderContents($serverUrl) { + $folder = $this->getFileOrFolder($serverUrl); $entry = $this->fileCache->get($serverUrl); if($entry === null || !isset($entry['children'])) { - $folder = isset($entry['instance']) ? $entry['instance'] : null; - $contents = $this->spClient->fetchFolderContents($serverUrl, null, $folder); + $contents = $this->spClient->fetchFolderContents($folder); $cacheItem = $entry ?: []; $cacheItem['children'] = $contents; $this->fileCache->set($serverUrl, $cacheItem); diff --git a/apps/files_external/tests/SharePoint/SharePointClientTest.php b/apps/files_external/tests/SharePoint/SharePointClientTest.php index 9e3832ec7358f..dce9152ea4234 100644 --- a/apps/files_external/tests/SharePoint/SharePointClientTest.php +++ b/apps/files_external/tests/SharePoint/SharePointClientTest.php @@ -26,8 +26,10 @@ use OCA\Files_External\Lib\SharePoint\ContextsFactory; use OCA\Files_External\Lib\SharePoint\SharePointClient; use Office365\PHP\Client\Runtime\Auth\AuthenticationContext; +use Office365\PHP\Client\Runtime\ClientObject; use Office365\PHP\Client\SharePoint\ClientContext; use Office365\PHP\Client\SharePoint\File; +use Office365\PHP\Client\SharePoint\FileCollection; use Office365\PHP\Client\SharePoint\Folder; use Office365\PHP\Client\SharePoint\FolderCollection; use Office365\PHP\Client\SharePoint\Web; @@ -168,7 +170,7 @@ public function testFetchNotExistingByFileOrFolder() { ->method('executeQuery') ->willThrowException(new \Exception('Unknown Error')); - $this->contextsFactory->expects($this->exactly(3)) + $this->contextsFactory->expects($this->exactly(1)) ->method('getClientContext') ->willReturn($clientContextMock); @@ -250,71 +252,129 @@ public function testCreateFolderError() { ->method('executeQuery') ->willThrowException(new \Exception('Whatever')); - $this->contextsFactory->expects($this->exactly(2)) + $this->contextsFactory->expects($this->exactly(1)) ->method('getClientContext') ->willReturn($clientContextMock); $this->client->createFolder($path); } - public function boolXBoolProvider() { + public function fileTypeProvider() { return [ - [ true, true ], - [ true, false ], - [ false, false ], - [ false, true ], + [ 'file' ], + [ 'dir' ], ]; } /** - * @dataProvider boolXBoolProvider + * @dataProvider fileTypeProvider */ - public function testDeleteFolder($successfull, $folderProvided) { - $dirName = 'Target Project Dir'; - $path = '/' . $this->documentLibraryTitle . '/Our Directory/' . $dirName; + public function testDelete($fileType) { + $itemClass = $fileType === 'dir' ? Folder::class : File::class; + /** @var ClientObject|\PHPUnit_Framework_MockObject_MockObject $itemMock */ + $itemMock = $this->createMock($itemClass); + $itemMock->expects($this->once()) + ->method('recycle'); $this->contextsFactory->expects($this->once()) ->method('getAuthContext') ->willReturn($this->createMock(AuthenticationContext::class)); - $folderMock = $this->createMock(Folder::class); - $folderMock->expects($this->once()) - ->method('deleteObject'); + $clientContextMock = $this->createMock(ClientContext::class); + $this->contextsFactory->expects($this->once()) + ->method('getClientContext') + ->willReturn($clientContextMock); + + $clientContextMock->expects($this->once()) + ->method('executeQuery'); + + $this->client->delete($itemMock); + } + + /** + * @dataProvider fileTypeProvider + */ + public function testRename($fileType) { + if($fileType === 'dir') { + $fileName = 'Goodies'; + $path = '/' . $this->documentLibraryTitle . '/' . $fileName; + $newPath = $path . '1337'; + $spFetchMethod = 'getFolderByServerRelativeUrl'; + $spRenameMethod = 'rename'; + $spRenameParameter = $fileName . '1337'; + $itemClass = Folder::class; + } else { + $fileName = 'Goodies.asc'; + $path = '/' . $this->documentLibraryTitle . '/' . $fileName; + $newPath = '/' . $this->documentLibraryTitle . '/Goodies w00t.asc'; + $spFetchMethod = 'getFileByServerRelativeUrl'; + $spRenameMethod = 'moveTo'; + $spRenameParameter = rawurlencode($newPath); + $itemClass = File::class; + } + + $itemMock = $this->createMock($itemClass); + $itemMock->expects($this->once()) + ->method($spRenameMethod) + ->with($spRenameParameter); + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); $webMock = $this->createMock(Web::class); + $webMock->expects($this->once()) + ->method($spFetchMethod) + ->with($path) + ->willReturn($itemMock); + $clientContextMock = $this->createMock(ClientContext::class); + $clientContextMock->expects($this->once()) + ->method('getWeb') + ->willReturn($webMock); + + $this->contextsFactory->expects($this->once()) + ->method('getClientContext') + ->willReturn($clientContextMock); - $folderParameter = $folderMock; - if($folderProvided === false) { - $folderParameter = null; + $clientContextMock->expects($this->exactly(2)) + ->method('executeQuery'); - $webMock->expects($this->once()) - ->method('getFolderByServerRelativeUrl') - ->with($path) - ->willReturn($folderMock); + $this->client->rename($path, $newPath); + } - $clientContextMock->expects($this->once()) - ->method('getWeb') - ->willReturn($webMock); - } + public function testFetchFolderContents() { + $folderCollectionMock = $this->createMock(FolderCollection::class); + $fileCollectionMock = $this->createMock(FileCollection::class); - if($successfull) { - $getClientContextCalls = 1; - $clientContextMock->expects($this->once()) - ->method('executeQuery'); - } else { - $getClientContextCalls = 2; - $this->setExpectedException(\Exception::class); - $exceptionAt = $folderProvided ? 0 : 1; - $clientContextMock->expects($this->at($exceptionAt)) - ->method('executeQuery') - ->willThrowException(new \Exception('Whatever')); - } + /** @var Folder|\PHPUnit_Framework_MockObject_MockObject $folderMock */ + $folderMock = $this->createMock(Folder::class); + $folderMock->expects($this->once()) + ->method('getFolders') + ->willReturn($folderCollectionMock); + $folderMock->expects($this->once()) + ->method('getFiles') + ->willReturn($fileCollectionMock); + + $this->contextsFactory->expects($this->once()) + ->method('getAuthContext') + ->willReturn($this->createMock(AuthenticationContext::class)); + + $clientContextMock = $this->createMock(ClientContext::class); + $clientContextMock->expects($this->exactly(2)) + ->method('load') + ->withConsecutive([$folderCollectionMock], [$fileCollectionMock]); + $clientContextMock->expects($this->once()) + ->method('executeQuery'); - $this->contextsFactory->expects($this->exactly($getClientContextCalls)) + $this->contextsFactory->expects($this->once()) ->method('getClientContext') ->willReturn($clientContextMock); - $this->client->deleteFolder($path, $folderParameter); + $result = $this->client->fetchFolderContents($folderMock); + $this->assertSame($result['folders'], $folderCollectionMock); + $this->assertSame($result['files'], $fileCollectionMock); } + + } diff --git a/apps/files_external/tests/Storage/SharePointTest.php b/apps/files_external/tests/Storage/SharePointTest.php index 4571d5fa718d8..58bba749889e7 100644 --- a/apps/files_external/tests/Storage/SharePointTest.php +++ b/apps/files_external/tests/Storage/SharePointTest.php @@ -98,21 +98,6 @@ public function setUp() { $this->storage = new SharePoint($parameters); } - private function prepareFactoryMocks() { - $authContextMock = $this->createMock(IAuthenticationContext::class); - $this->clientContextMock = $this->createMock(ClientContext::class); - - $this->factory->expects($this->once()) - ->method('getAuthContext') - ->with($this->exampleUser, $this->examplePwd) - ->willReturn($authContextMock); - $this->factory->expects($this->once()) - ->method('getClientContext') - ->with($this->exampleHost, $authContextMock) - ->willReturn($this->clientContextMock); - - } - /** * @expectedException \InvalidArgumentException */ @@ -292,49 +277,52 @@ public function testMkDir($successful) { $this->assertSame($successful, $this->storage->mkdir($dirName)); } - public function boolXBoolProvider() { - return [ - [ true, true ], - [ true, false ], - [ false, false ], - [ false, true ], - ]; - } - /** - * @dataProvider boolXBoolProvider + * @dataProvider boolProvider */ - public function testRmDir($successful, $useCache) { + public function testRmDir($successful) { $dirName = '/Parentfolder/TargetDirectory'; $serverPath = '/' . $this->documentLibraryTitle . $dirName; - $folderMock = null; - if($useCache) { - $folderMock = $this->createMock(Folder::class); - - $this->fileCache->expects($this->once()) - ->method('get') - ->with($serverPath) - ->willReturn(['instance' => $folderMock]); - } + $folderMock = $this->createMock(Folder::class); + $this->client->expects($this->once()) + ->method('fetchFileOrFolder') + ->with($serverPath) + ->willReturn($folderMock); $invocationMocker = $this->client->expects($this->once()) - ->method('deleteFolder') - ->with($serverPath, $folderMock); + ->method('delete') + ->with($folderMock); if(!$successful) { - $this->fileCache->expects($this->once()) - ->method('remove') - ->with($serverPath); - - $invocationMocker->willThrowException(new \Exception('Whatever')); - } else { - $this->fileCache->expects($this->once()) - ->method('set') - ->with($serverPath, null); + $invocationMocker->willThrowException(new \Exception('nope')); } $this->assertSame($successful, $this->storage->rmdir($dirName)); } + public function testUnlink() { + $path = '/dingdong/nothing.sh'; + + $serverPath = '/' . $this->documentLibraryTitle; + if(trim($path, '/') !== '') { + $serverPath .= '/' . trim($path, '/'); + } + + $fileMock = $this->createMock(File::class); + + $this->client->expects($this->exactly(2)) + ->method('fetchFileOrFolder') + ->with($serverPath) + ->willReturn($fileMock); + + $this->client->expects($this->once()) + ->method('delete') + ->with($fileMock); + + $this->storage->unlink($path); + } + + + } From f022d44309027221cc711fd73bb4600d53c5f10b Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 25 Apr 2017 01:07:18 +0200 Subject: [PATCH 31/32] Update phpSPO and apply https://github.com/vgrem/phpSPO/pull/63 Signed-off-by: Arthur Schiwon --- apps/files_external/3rdparty/composer.lock | 8 +- .../3rdparty/composer/ClassLoader.php | 10 +- apps/files_external/3rdparty/composer/LICENSE | 2 +- .../3rdparty/composer/autoload_classmap.php | 41 +++++++- .../3rdparty/composer/autoload_static.php | 41 +++++++- .../3rdparty/composer/installed.json | 8 +- .../3rdparty/vgrem/php-spo/.gitignore | 2 - .../3rdparty/vgrem/php-spo/README.md | 1 + .../Discovery/CapabilityDiscoveryResult.php | 39 -------- .../php-spo/src/Discovery/DiscoveryClient.php | 15 ++- .../php-spo/src/Discovery/ServiceInfo.php | 14 +++ .../src/Discovery/ServiceInfoCollection.php | 13 +++ .../3rdparty/vgrem/php-spo/src/OneNote/Me.php | 30 ++++++ .../php-spo/src/OneNote/MyOrganization.php | 13 +++ .../vgrem/php-spo/src/OneNote/Notebook.php | 47 +++++++++ .../php-spo/src/OneNote/NotebookLinks.php | 12 +++ .../vgrem/php-spo/src/OneNote/Notes.php | 31 ++++++ .../php-spo/src/OneNote/OneNoteClient.php | 97 +++++++++++++++++++ .../vgrem/php-spo/src/OneNote/Page.php | 12 +++ .../php-spo/src/OneNote/PageCollection.php | 12 +++ .../vgrem/php-spo/src/OneNote/PageLinks.php | 11 +++ .../php-spo/src/OneNote/PatchActionType.php | 14 +++ .../vgrem/php-spo/src/OneNote/Resource.php | 12 +++ .../vgrem/php-spo/src/OneNote/Section.php | 12 +++ .../php-spo/src/OneNote/SectionGroup.php | 12 +++ .../vgrem/php-spo/src/OneNote/Site.php | 11 +++ .../php-spo/src/OneNote/SiteCollection.php | 12 +++ .../php-spo/src/OneNote/SiteMetadata.php | 12 +++ .../vgrem/php-spo/src/OneNote/UserRole.php | 13 +++ .../Runtime/Auth/AuthenticationContext.php | 1 + .../src/Runtime/Auth/LiveConnectProvider.php | 19 ++++ .../php-spo/src/Runtime/ClientRequest.php | 3 +- .../src/Runtime/ClientRuntimeContext.php | 16 ++- .../src/Runtime/Utilities/RequestOptions.php | 9 +- .../src/Runtime/Utilities/Requests.php | 2 + .../php-spo/src/SharePoint/Attachment.php | 16 +++ .../src/SharePoint/AttachmentCollection.php | 9 +- .../php-spo/src/SharePoint/ClientContext.php | 2 +- .../vgrem/php-spo/src/SharePoint/File.php | 5 +- .../src/SharePoint/Portal/GroupSiteInfo.php | 41 ++++++++ .../SharePoint/Portal/GroupSiteManager.php | 49 ++++++++++ .../src/SharePoint/Publishing/Search.php | 12 +++ .../Publishing/SpotlightChannel.php | 12 +++ .../Publishing/SpotlightChannelCollection.php | 11 +++ .../SharePoint/Publishing/SpotlightVideo.php | 12 +++ .../Publishing/SpotlightVideoCollection.php | 12 +++ .../SharePoint/Publishing/VideoChannel.php | 72 ++++++++++++++ .../Publishing/VideoChannelCollection.php | 28 ++++++ .../SharePoint/Publishing/VideoCollection.php | 35 +++++++ .../src/SharePoint/Publishing/VideoItem.php | 63 ++++++++++++ .../Publishing/VideoPermissionGroup.php | 12 +++ .../Publishing/VideoPlaybackMetadata.php | 12 +++ .../Publishing/VideoPlaybackOrigin.php | 11 +++ .../Publishing/VideoProcessingStatus.php | 12 +++ .../Publishing/VideoServiceDiscoverer.php | 42 ++++++++ .../Publishing/VideoServiceManager.php | 64 ++++++++++++ .../SharePoint/Publishing/VideoThumbnail.php | 12 +++ .../Publishing/VideoThumbnailChoices.php | 20 ++++ .../Publishing/ViewControlState.php | 18 ++++ .../WebParts/LimitedWebPartManager.php | 6 +- 60 files changed, 1119 insertions(+), 76 deletions(-) delete mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/ServiceInfo.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/ServiceInfoCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Me.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/MyOrganization.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Notebook.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/NotebookLinks.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Notes.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/OneNoteClient.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Page.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/PageCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/PageLinks.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/PatchActionType.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Resource.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Section.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/SectionGroup.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Site.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/SiteCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/SiteMetadata.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/UserRole.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Auth/LiveConnectProvider.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Portal/GroupSiteInfo.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Portal/GroupSiteManager.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/Search.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/SpotlightChannel.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/SpotlightChannelCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/SpotlightVideo.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/SpotlightVideoCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoChannel.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoChannelCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoCollection.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoItem.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoPermissionGroup.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoPlaybackMetadata.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoPlaybackOrigin.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoProcessingStatus.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceDiscoverer.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceManager.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnail.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnailChoices.php create mode 100644 apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/ViewControlState.php diff --git a/apps/files_external/3rdparty/composer.lock b/apps/files_external/3rdparty/composer.lock index 6d08a1c168934..5857e3383ec57 100644 --- a/apps/files_external/3rdparty/composer.lock +++ b/apps/files_external/3rdparty/composer.lock @@ -94,12 +94,12 @@ "source": { "type": "git", "url": "https://github.com/vgrem/phpSPO.git", - "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686" + "reference": "9a866bae3552d01b8a8e33ddd8faf8adc66e2423" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/59a2956f94f694592e3d3c6252f0e753f73a1686", - "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686", + "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/9a866bae3552d01b8a8e33ddd8faf8adc66e2423", + "reference": "9a866bae3552d01b8a8e33ddd8faf8adc66e2423", "shasum": "" }, "require": { @@ -130,7 +130,7 @@ "rest", "sharepoint" ], - "time": "2017-02-22 10:52:00" + "time": "2017-04-19 08:17:21" } ], "packages-dev": [], diff --git a/apps/files_external/3rdparty/composer/ClassLoader.php b/apps/files_external/3rdparty/composer/ClassLoader.php index 4626994fd4d8a..2c72175e7723a 100644 --- a/apps/files_external/3rdparty/composer/ClassLoader.php +++ b/apps/files_external/3rdparty/composer/ClassLoader.php @@ -374,9 +374,13 @@ private function findFileWithExtension($class, $ext) $first = $class[0]; if (isset($this->prefixLengthsPsr4[$first])) { - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { - if (0 === strpos($class, $prefix)) { - foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath.'\\'; + if (isset($this->prefixDirsPsr4[$search])) { + foreach ($this->prefixDirsPsr4[$search] as $dir) { + $length = $this->prefixLengthsPsr4[$first][$search]; if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { return $file; } diff --git a/apps/files_external/3rdparty/composer/LICENSE b/apps/files_external/3rdparty/composer/LICENSE index 1a28124886db8..f27399a042d95 100644 --- a/apps/files_external/3rdparty/composer/LICENSE +++ b/apps/files_external/3rdparty/composer/LICENSE @@ -1,5 +1,5 @@ -Copyright (c) 2016 Nils Adermann, Jordi Boggiano +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 diff --git a/apps/files_external/3rdparty/composer/autoload_classmap.php b/apps/files_external/3rdparty/composer/autoload_classmap.php index 5bdff2e38bdfd..214970f536539 100644 --- a/apps/files_external/3rdparty/composer/autoload_classmap.php +++ b/apps/files_external/3rdparty/composer/autoload_classmap.php @@ -61,8 +61,9 @@ 'Icewind\\Streams\\Url' => $vendorDir . '/icewind/streams/src/Url.php', 'Icewind\\Streams\\UrlCallback' => $vendorDir . '/icewind/streams/src/UrlCallBack.php', 'Icewind\\Streams\\Wrapper' => $vendorDir . '/icewind/streams/src/Wrapper.php', - 'Office365\\PHP\\Client\\Discovery\\CapabilityDiscoveryResult' => $vendorDir . '/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php', 'Office365\\PHP\\Client\\Discovery\\DiscoveryClient' => $vendorDir . '/vgrem/php-spo/src/Discovery/DiscoveryClient.php', + 'Office365\\PHP\\Client\\Discovery\\ServiceInfo' => $vendorDir . '/vgrem/php-spo/src/Discovery/ServiceInfo.php', + 'Office365\\PHP\\Client\\Discovery\\ServiceInfoCollection' => $vendorDir . '/vgrem/php-spo/src/Discovery/ServiceInfoCollection.php', 'Office365\\PHP\\Client\\FileServices\\IdentitySet' => $vendorDir . '/vgrem/php-spo/src/OneDrive/IdentitySet.php', 'Office365\\PHP\\Client\\FileServices\\ImageFacet' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ImageFacet.php', 'Office365\\PHP\\Client\\FileServices\\ItemReference' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ItemReference.php', @@ -87,6 +88,23 @@ 'Office365\\PHP\\Client\\OneDrive\\ItemCollection' => $vendorDir . '/vgrem/php-spo/src/OneDrive/ItemCollection.php', 'Office365\\PHP\\Client\\OneDrive\\OneDriveClient' => $vendorDir . '/vgrem/php-spo/src/OneDrive/OneDriveClient.php', 'Office365\\PHP\\Client\\OneDrive\\OneDriveErrorCode' => $vendorDir . '/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php', + 'Office365\\PHP\\Client\\OneNote\\Me' => $vendorDir . '/vgrem/php-spo/src/OneNote/Me.php', + 'Office365\\PHP\\Client\\OneNote\\MyOrganization' => $vendorDir . '/vgrem/php-spo/src/OneNote/MyOrganization.php', + 'Office365\\PHP\\Client\\OneNote\\Notebook' => $vendorDir . '/vgrem/php-spo/src/OneNote/Notebook.php', + 'Office365\\PHP\\Client\\OneNote\\NotebookLinks' => $vendorDir . '/vgrem/php-spo/src/OneNote/NotebookLinks.php', + 'Office365\\PHP\\Client\\OneNote\\Notes' => $vendorDir . '/vgrem/php-spo/src/OneNote/Notes.php', + 'Office365\\PHP\\Client\\OneNote\\OneNoteClient' => $vendorDir . '/vgrem/php-spo/src/OneNote/OneNoteClient.php', + 'Office365\\PHP\\Client\\OneNote\\Page' => $vendorDir . '/vgrem/php-spo/src/OneNote/Page.php', + 'Office365\\PHP\\Client\\OneNote\\PageCollection' => $vendorDir . '/vgrem/php-spo/src/OneNote/PageCollection.php', + 'Office365\\PHP\\Client\\OneNote\\PageLinks' => $vendorDir . '/vgrem/php-spo/src/OneNote/PageLinks.php', + 'Office365\\PHP\\Client\\OneNote\\PatchActionType' => $vendorDir . '/vgrem/php-spo/src/OneNote/PatchActionType.php', + 'Office365\\PHP\\Client\\OneNote\\Resource' => $vendorDir . '/vgrem/php-spo/src/OneNote/Resource.php', + 'Office365\\PHP\\Client\\OneNote\\Section' => $vendorDir . '/vgrem/php-spo/src/OneNote/Section.php', + 'Office365\\PHP\\Client\\OneNote\\SectionGroup' => $vendorDir . '/vgrem/php-spo/src/OneNote/SectionGroup.php', + 'Office365\\PHP\\Client\\OneNote\\Site' => $vendorDir . '/vgrem/php-spo/src/OneNote/Site.php', + 'Office365\\PHP\\Client\\OneNote\\SiteCollection' => $vendorDir . '/vgrem/php-spo/src/OneNote/SiteCollection.php', + 'Office365\\PHP\\Client\\OneNote\\SiteMetadata' => $vendorDir . '/vgrem/php-spo/src/OneNote/SiteMetadata.php', + 'Office365\\PHP\\Client\\OneNote\\UserRole' => $vendorDir . '/vgrem/php-spo/src/OneNote/UserRole.php', 'Office365\\PHP\\Client\\OutlookServices\\Attachment' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Attachment.php', 'Office365\\PHP\\Client\\OutlookServices\\AttachmentCollection' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/AttachmentCollection.php', 'Office365\\PHP\\Client\\OutlookServices\\Attendee' => $vendorDir . '/vgrem/php-spo/src/OutlookServices/Attendee.php', @@ -153,6 +171,7 @@ 'Office365\\PHP\\Client\\Runtime\\Auth\\BaseTokenProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\CookieCacheEntry' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/CookieCacheEntry.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\IAuthenticationContext' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\LiveConnectProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/LiveConnectProvider.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\NetworkCredentialContext' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/NetworkCredentialContext.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\OAuthTokenProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\SamlTokenProvider' => $vendorDir . '/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php', @@ -275,8 +294,28 @@ 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingInformation' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ObjectSharingInformation.php', 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingSettings' => $vendorDir . '/vgrem/php-spo/src/SharePoint/ObjectSharingSettings.php', 'Office365\\PHP\\Client\\SharePoint\\PermissionKind' => $vendorDir . '/vgrem/php-spo/src/SharePoint/PermissionKind.php', + 'Office365\\PHP\\Client\\SharePoint\\Portal\\GroupSiteInfo' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Portal/GroupSiteInfo.php', + 'Office365\\PHP\\Client\\SharePoint\\Portal\\GroupSiteManager' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Portal/GroupSiteManager.php', 'Office365\\PHP\\Client\\SharePoint\\Principal' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Principal.php', 'Office365\\PHP\\Client\\SharePoint\\PrincipalType' => $vendorDir . '/vgrem/php-spo/src/SharePoint/PrincipalType.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\Search' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/Search.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightChannel' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightChannel.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightChannelCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightChannelCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightVideo' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightVideo.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightVideoCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightVideoCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoChannel' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoChannel.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoChannelCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoChannelCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoItem' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoItem.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoPermissionGroup' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoPermissionGroup.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoPlaybackMetadata' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoPlaybackMetadata.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoPlaybackOrigin' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoPlaybackOrigin.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoProcessingStatus' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoProcessingStatus.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoServiceDiscoverer' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceDiscoverer.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoServiceManager' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceManager.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoThumbnail' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnail.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoThumbnailChoices' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnailChoices.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\ViewControlState' => $vendorDir . '/vgrem/php-spo/src/SharePoint/Publishing/ViewControlState.php', 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItem' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RecycleBinItem.php', 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItemCollection' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RecycleBinItemCollection.php', 'Office365\\PHP\\Client\\SharePoint\\RoleAssignment' => $vendorDir . '/vgrem/php-spo/src/SharePoint/RoleAssignment.php', diff --git a/apps/files_external/3rdparty/composer/autoload_static.php b/apps/files_external/3rdparty/composer/autoload_static.php index eb1f56aa483d0..476fbdad027a6 100644 --- a/apps/files_external/3rdparty/composer/autoload_static.php +++ b/apps/files_external/3rdparty/composer/autoload_static.php @@ -99,8 +99,9 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Icewind\\Streams\\Url' => __DIR__ . '/..' . '/icewind/streams/src/Url.php', 'Icewind\\Streams\\UrlCallback' => __DIR__ . '/..' . '/icewind/streams/src/UrlCallBack.php', 'Icewind\\Streams\\Wrapper' => __DIR__ . '/..' . '/icewind/streams/src/Wrapper.php', - 'Office365\\PHP\\Client\\Discovery\\CapabilityDiscoveryResult' => __DIR__ . '/..' . '/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php', 'Office365\\PHP\\Client\\Discovery\\DiscoveryClient' => __DIR__ . '/..' . '/vgrem/php-spo/src/Discovery/DiscoveryClient.php', + 'Office365\\PHP\\Client\\Discovery\\ServiceInfo' => __DIR__ . '/..' . '/vgrem/php-spo/src/Discovery/ServiceInfo.php', + 'Office365\\PHP\\Client\\Discovery\\ServiceInfoCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/Discovery/ServiceInfoCollection.php', 'Office365\\PHP\\Client\\FileServices\\IdentitySet' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/IdentitySet.php', 'Office365\\PHP\\Client\\FileServices\\ImageFacet' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/ImageFacet.php', 'Office365\\PHP\\Client\\FileServices\\ItemReference' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/ItemReference.php', @@ -125,6 +126,23 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Office365\\PHP\\Client\\OneDrive\\ItemCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/ItemCollection.php', 'Office365\\PHP\\Client\\OneDrive\\OneDriveClient' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/OneDriveClient.php', 'Office365\\PHP\\Client\\OneDrive\\OneDriveErrorCode' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneDrive/OneDriveErrorCode.php', + 'Office365\\PHP\\Client\\OneNote\\Me' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/Me.php', + 'Office365\\PHP\\Client\\OneNote\\MyOrganization' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/MyOrganization.php', + 'Office365\\PHP\\Client\\OneNote\\Notebook' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/Notebook.php', + 'Office365\\PHP\\Client\\OneNote\\NotebookLinks' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/NotebookLinks.php', + 'Office365\\PHP\\Client\\OneNote\\Notes' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/Notes.php', + 'Office365\\PHP\\Client\\OneNote\\OneNoteClient' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/OneNoteClient.php', + 'Office365\\PHP\\Client\\OneNote\\Page' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/Page.php', + 'Office365\\PHP\\Client\\OneNote\\PageCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/PageCollection.php', + 'Office365\\PHP\\Client\\OneNote\\PageLinks' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/PageLinks.php', + 'Office365\\PHP\\Client\\OneNote\\PatchActionType' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/PatchActionType.php', + 'Office365\\PHP\\Client\\OneNote\\Resource' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/Resource.php', + 'Office365\\PHP\\Client\\OneNote\\Section' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/Section.php', + 'Office365\\PHP\\Client\\OneNote\\SectionGroup' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/SectionGroup.php', + 'Office365\\PHP\\Client\\OneNote\\Site' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/Site.php', + 'Office365\\PHP\\Client\\OneNote\\SiteCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/SiteCollection.php', + 'Office365\\PHP\\Client\\OneNote\\SiteMetadata' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/SiteMetadata.php', + 'Office365\\PHP\\Client\\OneNote\\UserRole' => __DIR__ . '/..' . '/vgrem/php-spo/src/OneNote/UserRole.php', 'Office365\\PHP\\Client\\OutlookServices\\Attachment' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Attachment.php', 'Office365\\PHP\\Client\\OutlookServices\\AttachmentCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/AttachmentCollection.php', 'Office365\\PHP\\Client\\OutlookServices\\Attendee' => __DIR__ . '/..' . '/vgrem/php-spo/src/OutlookServices/Attendee.php', @@ -191,6 +209,7 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Office365\\PHP\\Client\\Runtime\\Auth\\BaseTokenProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/BaseTokenProvider.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\CookieCacheEntry' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/CookieCacheEntry.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\IAuthenticationContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/IAuthenticationContext.php', + 'Office365\\PHP\\Client\\Runtime\\Auth\\LiveConnectProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/LiveConnectProvider.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\NetworkCredentialContext' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/NetworkCredentialContext.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\OAuthTokenProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/OAuthTokenProvider.php', 'Office365\\PHP\\Client\\Runtime\\Auth\\SamlTokenProvider' => __DIR__ . '/..' . '/vgrem/php-spo/src/Runtime/Auth/SamlTokenProvider.php', @@ -313,8 +332,28 @@ class ComposerStaticInit98fe9b281934250b3a93f69a5ce843b3 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingInformation' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ObjectSharingInformation.php', 'Office365\\PHP\\Client\\SharePoint\\ObjectSharingSettings' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/ObjectSharingSettings.php', 'Office365\\PHP\\Client\\SharePoint\\PermissionKind' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/PermissionKind.php', + 'Office365\\PHP\\Client\\SharePoint\\Portal\\GroupSiteInfo' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Portal/GroupSiteInfo.php', + 'Office365\\PHP\\Client\\SharePoint\\Portal\\GroupSiteManager' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Portal/GroupSiteManager.php', 'Office365\\PHP\\Client\\SharePoint\\Principal' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Principal.php', 'Office365\\PHP\\Client\\SharePoint\\PrincipalType' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/PrincipalType.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\Search' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/Search.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightChannel' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightChannel.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightChannelCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightChannelCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightVideo' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightVideo.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\SpotlightVideoCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/SpotlightVideoCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoChannel' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoChannel.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoChannelCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoChannelCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoCollection.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoItem' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoItem.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoPermissionGroup' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoPermissionGroup.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoPlaybackMetadata' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoPlaybackMetadata.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoPlaybackOrigin' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoPlaybackOrigin.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoProcessingStatus' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoProcessingStatus.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoServiceDiscoverer' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceDiscoverer.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoServiceManager' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceManager.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoThumbnail' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnail.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\VideoThumbnailChoices' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnailChoices.php', + 'Office365\\PHP\\Client\\SharePoint\\Publishing\\ViewControlState' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/Publishing/ViewControlState.php', 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItem' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RecycleBinItem.php', 'Office365\\PHP\\Client\\SharePoint\\RecycleBinItemCollection' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RecycleBinItemCollection.php', 'Office365\\PHP\\Client\\SharePoint\\RoleAssignment' => __DIR__ . '/..' . '/vgrem/php-spo/src/SharePoint/RoleAssignment.php', diff --git a/apps/files_external/3rdparty/composer/installed.json b/apps/files_external/3rdparty/composer/installed.json index 0f2475d0fe83a..42e2e30781ff9 100644 --- a/apps/files_external/3rdparty/composer/installed.json +++ b/apps/files_external/3rdparty/composer/installed.json @@ -92,19 +92,19 @@ "source": { "type": "git", "url": "https://github.com/vgrem/phpSPO.git", - "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686" + "reference": "9a866bae3552d01b8a8e33ddd8faf8adc66e2423" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/59a2956f94f694592e3d3c6252f0e753f73a1686", - "reference": "59a2956f94f694592e3d3c6252f0e753f73a1686", + "url": "https://api.github.com/repos/vgrem/phpSPO/zipball/9a866bae3552d01b8a8e33ddd8faf8adc66e2423", + "reference": "9a866bae3552d01b8a8e33ddd8faf8adc66e2423", "shasum": "" }, "require": { "ext-curl": "*", "php": ">=5.4" }, - "time": "2017-02-22T10:52:00+00:00", + "time": "2017-04-19T08:17:21+00:00", "type": "library", "installation-source": "source", "autoload": { diff --git a/apps/files_external/3rdparty/vgrem/php-spo/.gitignore b/apps/files_external/3rdparty/vgrem/php-spo/.gitignore index 821719b92568b..1bf3fee59608b 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/.gitignore +++ b/apps/files_external/3rdparty/vgrem/php-spo/.gitignore @@ -159,7 +159,5 @@ $RECYCLE.BIN/ examples/SharePoint/todoapp/ src/ExcelServices/ src/SharePoint/DocumentManagement/Video/ -src/SharePoint/Publishing/ -src/VideoService/ examples/GraphExplorer/bower_components vendor \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/README.md b/apps/files_external/3rdparty/vgrem/php-spo/README.md index 76e41b05e7317..6f45dbf5fd603 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/README.md +++ b/apps/files_external/3rdparty/vgrem/php-spo/README.md @@ -8,6 +8,7 @@ The library provides a Office 365 REST client for PHP applications. It allows to - [Outlook Contacts REST API](https://msdn.microsoft.com/en-us/office/office365/api/contacts-rest-operations) - [Outlook Calendar REST API](https://msdn.microsoft.com/en-us/office/office365/api/calendar-rest-operations) - [Outlook Mail REST API](https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations) + - OneNote REST API ### Status diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php deleted file mode 100644 index 03db06019f6f8..0000000000000 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/CapabilityDiscoveryResult.php +++ /dev/null @@ -1,39 +0,0 @@ -getServiceRootUrl() . "me"); - $this->addQuery($qry,$capabilities); - $this->executeQuery(); - return $capabilities; + $allServices = new ServiceInfoCollection(); + $qry = new ClientActionReadEntity($this->getServiceRootUrl() . "me/allServices"); + $this->addQuery($qry,$allServices); + return $allServices; } - } \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/ServiceInfo.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/ServiceInfo.php new file mode 100644 index 0000000000000..44dc55e580403 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Discovery/ServiceInfo.php @@ -0,0 +1,14 @@ +isPropertyAvailable("Notes")) { + $this->setProperty("Notes", + new Notes($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Notes" + ))); + } + return $this->getProperty("Notes"); + } + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/MyOrganization.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/MyOrganization.php new file mode 100644 index 0000000000000..fe974c33372d0 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/MyOrganization.php @@ -0,0 +1,13 @@ +isPropertyAvailable("UserRole")) { + $this->setProperty("UserRole", + new UserRole($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "UserRole" + ))); + } + return $this->getProperty("UserRole"); + } + + + + /** + * @return NotebookLinks + */ + public function getNotebookLinks() + { + if (!$this->isPropertyAvailable("NotebookLinks")) { + $this->setProperty("NotebookLinks", + new NotebookLinks($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "NotebookLinks" + ))); + } + return $this->getProperty("NotebookLinks"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/NotebookLinks.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/NotebookLinks.php new file mode 100644 index 0000000000000..9684fb6f83f83 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/NotebookLinks.php @@ -0,0 +1,12 @@ +isPropertyAvailable("Pages")) { + $this->setProperty("Pages", + new PageCollection($this->getContext(), new ResourcePathEntity( + $this->getContext(), + $this->getResourcePath(), + "Pages" + ))); + } + return $this->getProperty("Pages"); + } + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/OneNoteClient.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/OneNoteClient.php new file mode 100644 index 0000000000000..3e32700f067e7 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/OneNoteClient.php @@ -0,0 +1,97 @@ +version = $version; + $this->serviceRootUrl = $this->serviceRootUrl . $version . "/"; + parent::__construct($this->serviceRootUrl, $authContext, new JsonFormat(ODataMetadataLevel::NoMetadata), $version); + } + + + + /** + * Submits query to OneNote REST/OData service + */ + public function executeQuery() + { + $this->getPendingRequest()->beforeExecuteQuery(function (RequestOptions $request,ClientAction $query){ + $this->prepareOutlookServicesRequest($request,$query); + }); + parent::executeQuery(); + } + + + + + + private function prepareOutlookServicesRequest(RequestOptions $request,ClientAction $query) + { + //set data modification headers + if ($query->ActionType == ClientActionType::UpdateEntity) { + $request->Method = HttpMethod::Patch; + } else if ($query->ActionType == ClientActionType::DeleteEntity) { + $request->Method = HttpMethod::Delete; + } + } + + + /** + * @return Me + */ + public function getMe(){ + if(!isset($this->me)) + $this->me = new Me($this,new ResourcePathEntity($this,null,"Me")); + return $this->me; + } + + + /** + * @return MyOrganization + */ + public function getMyOrganization(){ + if(!isset($this->myOrg)) + $this->myOrg = new MyOrganization($this,new ResourcePathEntity($this,null,"MyOrganization")); + return $this->myOrg; + } + + + /** + * @var Me + */ + private $me; + + + /** + * @var MyOrganization + */ + private $myOrg; + + + /** + * @var string + */ + private $serviceRootUrl = "https://www.onenote.com/api/"; + + /** + * @var string + */ + public $version; + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Page.php b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Page.php new file mode 100644 index 0000000000000..cbd8ea52c23d3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/OneNote/Page.php @@ -0,0 +1,12 @@ +format); - foreach ($this->queries as $qry) { + while(($qry = array_shift($this->queries)) !== null) { $request = $this->buildRequest($qry); if (is_callable($this->eventsList["BeforeExecuteQuery"])) { call_user_func_array($this->eventsList["BeforeExecuteQuery"], array( @@ -151,7 +151,6 @@ public function executeQuery() } } } - $this->queries = array(); } /** diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php index 820f74899425c..0cf71b02b9cb8 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/ClientRuntimeContext.php @@ -38,7 +38,7 @@ class ClientRuntimeContext /** * @var ODataFormat */ - protected $format; + public $Format; /** * REST client context ctor @@ -52,7 +52,7 @@ public function __construct($serviceUrl, IAuthenticationContext $authContext, OD $this->version = $version; $this->serviceRootUrl = $serviceUrl; $this->authContext = $authContext; - $this->format = $format; + $this->Format = $format; } /** @@ -72,6 +72,15 @@ public function getServiceRootUrl() return $this->serviceRootUrl; } + + /** + * @param $url string + */ + public function setServiceRootUrl($url) + { + $this->serviceRootUrl = $url; + } + /** * Gets the api version being used * @return string @@ -158,9 +167,10 @@ public function addQuery(ClientAction $query, $resultObject = null) public function getPendingRequest() { if (!isset($this->pendingRequest)) { - $this->pendingRequest = new ClientRequest($this, $this->format); + $this->pendingRequest = new ClientRequest($this, $this->Format); } return $this->pendingRequest; } + } diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php index d41d7b2388bf7..26fbe63e4ce70 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/RequestOptions.php @@ -27,6 +27,7 @@ public function __construct($url, $headers = array(), $data = null, $methodType $this->UserCredentials = null; $this->Verbose = false; $this->SSLVersion = null; + $this->StreamHandle = null; } public function toArray() @@ -42,10 +43,10 @@ public function toArray() 'Verbose' => $this->Verbose, 'UserCredentials' => $this->UserCredentials, 'SSLVersion' => $this->SSLVersion, + 'StreamHandle' => $this->StreamHandle, ]; } - public function addCustomHeader($name, $value) { if (is_null($this->Headers)) @@ -127,4 +128,10 @@ function ($k, $v) { */ public $SSLVersion; + + /** + * @var resource + */ + public $StreamHandle; + } diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php index 13ed51ce02bf0..2793e0edf83b6 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/Runtime/Utilities/Requests.php @@ -109,6 +109,8 @@ private static function init(RequestOptions $options) //set Post Body if(isset($options->Data)) curl_setopt($ch, CURLOPT_POSTFIELDS, $options->Data); + if(is_resource($options->StreamHandle)) + curl_setopt($ch, CURLOPT_FILE, $options->StreamHandle); $options->addCustomHeader("content-length",strlen($options->Data)); //custom HTTP headers if($options->Headers) diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Attachment.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Attachment.php index c613254e74f59..01989a918a981 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Attachment.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Attachment.php @@ -16,4 +16,20 @@ public function deleteObject() $this->getContext()->addQuery($qry); } + + /** + * @return string + */ + public function getFileName(){ + return $this->getProperty("FileName"); + } + + + /** + * @return string + */ + public function getServerRelativeUrl(){ + return $this->getProperty("ServerRelativeUrl"); + } + } \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php index 5ab3be6e0ff47..ceacdd9fcb209 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/AttachmentCollection.php @@ -3,6 +3,7 @@ namespace Office365\PHP\Client\SharePoint; use Office365\PHP\Client\Runtime\ClientActionCreateEntity; +use Office365\PHP\Client\Runtime\ClientActionInvokePostMethod; use Office365\PHP\Client\Runtime\ClientObjectCollection; use Office365\PHP\Client\Runtime\ResourcePathServiceOperation; @@ -16,8 +17,12 @@ class AttachmentCollection extends ClientObjectCollection */ public function add(AttachmentCreationInformation $information) { - $attachment = new Attachment($this->getContext()); - $qry = new ClientActionCreateEntity($this,$information); + $attachment = new Attachment($this->getContext(),$this->getResourcePath()); + $qry = new ClientActionInvokePostMethod( + $this, + "add", + array("FileName" =>rawurlencode($information->FileName)), + $information->ContentStream); $this->getContext()->addQuery($qry,$attachment); $this->addChild($attachment); return $attachment; diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ClientContext.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ClientContext.php index d42a34c43a3f2..f441e94612e1c 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ClientContext.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/ClientContext.php @@ -66,7 +66,7 @@ protected function requestFormDigest() $response = $this->executeQueryDirect($request); if(!isset($this->contextWebInformation)) $this->contextWebInformation = new ContextWebInformation(); - if($this->format->MetadataLevel == ODataMetadataLevel::Verbose){ + if($this->Format->MetadataLevel == ODataMetadataLevel::Verbose){ $this->contextWebInformation->EntityName = "GetContextWebInformation"; } $this->populateObject($response,$this->contextWebInformation); diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/File.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/File.php index 360feb823447a..b2e1f4147f354 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/File.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/File.php @@ -159,6 +159,9 @@ public static function saveBinary(ClientRuntimeContext $ctx, $serverRelativeUrl, $request->Method = HttpMethod::Post; $request->addCustomHeader('X-HTTP-Method','PUT'); $request->Data = $content; + if($ctx instanceof ClientContext) { + $ctx->ensureFormDigest($request); + } $ctx->executeQueryDirect($request); } @@ -245,4 +248,4 @@ function setProperty($name, $value, $persistChanges = true) $this->setResourceUrl("Web/GetFileById(guid'{$value}')"); } } -} \ No newline at end of file +} diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Portal/GroupSiteInfo.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Portal/GroupSiteInfo.php new file mode 100644 index 0000000000000..33d4933e69e1a --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Portal/GroupSiteInfo.php @@ -0,0 +1,41 @@ +Format->MetadataLevel = ODataMetadataLevel::NoMetadata; + parent::__construct($ctx,new ResourcePathEntity($ctx,null,"GroupSiteManager")); + + } + + /** + * @param string $displayName + * @param string $alias + * @param boolean $isPublic + * @param string $description + * @param null $additionalOwners + * @return GroupSiteInfo + */ + public function createGroupEx($displayName,$alias,$isPublic,$description="",$additionalOwners=null) { + $payload = new OperationParameterCollection(); + $payload->add("displayName",$displayName); + $payload->add("alias",$alias); + $payload->add("isPublic",$isPublic); + + + $info = new GroupSiteInfo(); + $qry = new ClientAction($this->getResourceUrl() . "/CreateGroupEx", $payload,ClientActionType::CreateEntity); + $this->getContext()->addQuery($qry,$info); + return $info; + } + + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/Search.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/Search.php new file mode 100644 index 0000000000000..d09dbbe0e3302 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/Search.php @@ -0,0 +1,12 @@ +getProperty("Id"); + } + + public function getTitle(){ + return $this->getProperty("Title"); + } + + public function getDescription(){ + return $this->getProperty("Description"); + } + + public function getServerRelativeUrl(){ + return $this->getProperty("ServerRelativeUrl"); + } + + + public function getTileHtmlColor(){ + return $this->getProperty("TileHtmlColor"); + } + + + /** + * @return VideoCollection + */ + public function GetAllVideos(){ + return new VideoCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"GetAllVideos") + ); + } + + /** + * @return SpotlightVideoCollection + */ + public function getSpotlightVideos(){ + return new SpotlightVideoCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"SpotlightVideos") + ); + } + + + /** + * @return VideoCollection + */ + public function getVideos(){ + return new VideoCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Videos") + ); + } + + + public function getEntityTypeName() + { + return implode(".",array("SP","Publishing",parent::getEntityTypeName())); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoChannelCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoChannelCollection.php new file mode 100644 index 0000000000000..6f60eb23e2980 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoChannelCollection.php @@ -0,0 +1,28 @@ +getContext()); + $channel->setProperty("Title",$title); + $channel->setProperty("TileHtmlColor","#0072c6"); + $qry = new ClientActionCreateEntity($this, $channel); + $this->getContext()->addQuery($qry, $channel); + $this->addChild($channel); + return $channel; + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoCollection.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoCollection.php new file mode 100644 index 0000000000000..3157dd16ef2c0 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoCollection.php @@ -0,0 +1,35 @@ +getContext()); + $videoItem->setProperty("Title",$title); + if(isset($description)) + $videoItem->setProperty("Description",$description); + if(isset($fileName)) + $videoItem->setProperty("FileName",$fileName); + $qry = new ClientActionCreateEntity($this, $videoItem); + $this->getContext()->addQuery($qry, $videoItem); + $this->addChild($videoItem); + return $videoItem; + } + + + /** + * @return string + */ + public function getItemTypeName() + { + return __NAMESPACE__ . "\\" . "VideoItem"; + } +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoItem.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoItem.php new file mode 100644 index 0000000000000..4fe579e9065d4 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoItem.php @@ -0,0 +1,63 @@ +getContext()->addQuery($qry); + } + + public function deleteObject() + { + $qry = new ClientActionDeleteEntity($this); + $this->getContext()->addQuery($qry); + } + + public function saveBinaryStream($content){ + $ctx = $this->getContext(); + $methodName = "GetFile()/SaveBinaryStream"; + $requestUrl = $this->getResourceUrl() . "/" . $methodName; + $request = new RequestOptions($requestUrl); + $request->Method = HttpMethod::Post; + $request->Data = $content; + if($ctx instanceof ClientContext) + $ctx->ensureFormDigest($request); + $response = $ctx->executeQueryDirect($request); + } + + + function setProperty($name, $value, $persistChanges = true) + { + if($name == "ID"){ + if(is_null($this->getResourcePath())) + $this->setResourceUrl($this->parentCollection->getResourcePath()->toUrl() . "(guid'{$value}')"); + $this->{$name} = $value; + } + else + parent::setProperty($name, $value, $persistChanges); + } + + + public function getEntityTypeName() + { + return implode(".",array("SP","Publishing",parent::getEntityTypeName())); + } + + + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoPermissionGroup.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoPermissionGroup.php new file mode 100644 index 0000000000000..fd125dbd10270 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoPermissionGroup.php @@ -0,0 +1,12 @@ +getProperty("VideoPortalUrl"); + } + + + + public function getVideoPortalLayoutsUrl(){ + return $this->getProperty("VideoPortalLayoutsUrl"); + } + + + public function getPlayerUrlTemplate(){ + return $this->getProperty("PlayerUrlTemplate"); + } + + /** + * @return boolean + */ + public function getIsVideoPortalEnabled(){ + return $this->getProperty("IsVideoPortalEnabled"); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceManager.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceManager.php new file mode 100644 index 0000000000000..e4bceda1158c3 --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoServiceManager.php @@ -0,0 +1,64 @@ +setServiceRootUrl($videoPortalUrl . "/_api/"); + parent::__construct($ctx,new ResourcePathEntity($ctx,null,"VideoService")); + } + + + /** + * @return VideoChannelCollection + */ + public function getChannels(){ + return new VideoChannelCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"Channels") + ); + } + + + /** + * @return VideoChannelCollection + */ + public function getCanEditChannels(){ + return new VideoChannelCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"CanEditChannels") + ); + } + + + + /** + * @return SpotlightChannelCollection + */ + public function getSpotlightChannels(){ + return new SpotlightChannelCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"SpotlightChannels") + ); + } + + /** + * @return SpotlightVideoCollection + */ + public function getSpotlightVideos(){ + return new SpotlightVideoCollection( + $this->getContext(), + new ResourcePathEntity($this->getContext(),$this->getResourcePath(),"SpotlightVideos") + ); + } + +} \ No newline at end of file diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnail.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnail.php new file mode 100644 index 0000000000000..1c712aac635fe --- /dev/null +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoThumbnail.php @@ -0,0 +1,12 @@ + $webPartXml),ODataPayloadKind::Entity,$this->getEntityTypeName()); + $payload = new OperationParameterCollection(); + $payload->add("webPartXml",$webPartXml); $webPartDefinition = new WebPartDefinition($this->getContext()); $qry = new ClientActionInvokePostMethod( $this, From 90d36566a168c955a46b47e89bba0249e982f7c9 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Wed, 26 Apr 2017 11:37:54 +0200 Subject: [PATCH 32/32] syntax fixes in upstream lib for php < 7.1 Signed-off-by: Arthur Schiwon --- .../src/SharePoint/Publishing/VideoProcessingStatus.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoProcessingStatus.php b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoProcessingStatus.php index 6cc9dcf3f65b4..7610f5be41e8c 100644 --- a/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoProcessingStatus.php +++ b/apps/files_external/3rdparty/vgrem/php-spo/src/SharePoint/Publishing/VideoProcessingStatus.php @@ -7,6 +7,6 @@ class VideoProcessingStatus { - public const PendingProcessing = 0; - public const Processing = 1; -} \ No newline at end of file + const PendingProcessing = 0; + const Processing = 1; +}