Completed
Pull Request — master (#4106)
by Blizzz
15:12 queued 15s
created
apps/files_external/lib/AppInfo/Application.php 1 patch
Indentation   +103 added lines, -103 removed lines patch added patch discarded remove patch
@@ -52,108 +52,108 @@
 block discarded – undo
52 52
  */
53 53
 class Application extends App implements IBackendProvider, IAuthMechanismProvider {
54 54
 
55
-	public function __construct(array $urlParams = array()) {
56
-		parent::__construct('files_external', $urlParams);
57
-
58
-		$container = $this->getContainer();
59
-
60
-		$container->registerService('OCP\Files\Config\IUserMountCache', function (IAppContainer $c) {
61
-			return $c->getServer()->query('UserMountCache');
62
-		});
63
-
64
-		$backendService = $container->query('OCA\\Files_External\\Service\\BackendService');
65
-		$backendService->registerBackendProvider($this);
66
-		$backendService->registerAuthMechanismProvider($this);
67
-
68
-		// force-load auth mechanisms since some will register hooks
69
-		// TODO: obsolete these and use the TokenProvider to get the user's password from the session
70
-		$this->getAuthMechanisms();
71
-
72
-		// app developers: do NOT depend on this! it will disappear with oC 9.0!
73
-		\OC::$server->getEventDispatcher()->dispatch(
74
-			'OCA\\Files_External::loadAdditionalBackends'
75
-		);
76
-	}
77
-
78
-	/**
79
-	 * Register settings templates
80
-	 */
81
-	public function registerSettings() {
82
-		$container = $this->getContainer();
83
-		$userSession = $container->getServer()->getUserSession();
84
-		if (!$userSession->isLoggedIn()) {
85
-			return;
86
-		}
87
-		$backendService = $container->query('OCA\\Files_External\\Service\\BackendService');
88
-
89
-		/** @var \OCA\Files_External\Service\UserGlobalStoragesService $userGlobalStoragesService */
90
-		$userGlobalStoragesService = $container->query('OCA\Files_External\Service\UserGlobalStoragesService');
91
-		if (count($userGlobalStoragesService->getStorages()) > 0 || $backendService->isUserMountingAllowed()) {
92
-			\OCP\App::registerPersonal('files_external', 'personal');
93
-		}
94
-	}
95
-
96
-	/**
97
-	 * @{inheritdoc}
98
-	 */
99
-	public function getBackends() {
100
-		$container = $this->getContainer();
101
-
102
-		$backends = [
103
-			$container->query(Local::class),
104
-			$container->query(FTP::class),
105
-			$container->query(DAV::class),
106
-			$container->query(OwnCloud::class),
107
-			$container->query(SFTP::class),
108
-			$container->query(AmazonS3::class),
109
-			$container->query(Dropbox::class),
110
-			$container->query(Google::class),
111
-			$container->query(Swift::class),
112
-			$container->query(SFTP_Key::class),
113
-			$container->query(SMB::class),
114
-			$container->query(SMB_OC::class),
115
-			$container->query(SharePoint::class),
116
-		];
117
-
118
-		return $backends;
119
-	}
120
-
121
-	/**
122
-	 * @{inheritdoc}
123
-	 */
124
-	public function getAuthMechanisms() {
125
-		$container = $this->getContainer();
126
-
127
-		return [
128
-			// AuthMechanism::SCHEME_NULL mechanism
129
-			$container->query('OCA\Files_External\Lib\Auth\NullMechanism'),
130
-
131
-			// AuthMechanism::SCHEME_BUILTIN mechanism
132
-			$container->query('OCA\Files_External\Lib\Auth\Builtin'),
133
-
134
-			// AuthMechanism::SCHEME_PASSWORD mechanisms
135
-			$container->query('OCA\Files_External\Lib\Auth\Password\Password'),
136
-			$container->query('OCA\Files_External\Lib\Auth\Password\SessionCredentials'),
137
-			$container->query('OCA\Files_External\Lib\Auth\Password\LoginCredentials'),
138
-			$container->query('OCA\Files_External\Lib\Auth\Password\UserProvided'),
139
-			$container->query('OCA\Files_External\Lib\Auth\Password\GlobalAuth'),
140
-
141
-			// AuthMechanism::SCHEME_OAUTH1 mechanisms
142
-			$container->query('OCA\Files_External\Lib\Auth\OAuth1\OAuth1'),
143
-
144
-			// AuthMechanism::SCHEME_OAUTH2 mechanisms
145
-			$container->query('OCA\Files_External\Lib\Auth\OAuth2\OAuth2'),
146
-
147
-			// AuthMechanism::SCHEME_PUBLICKEY mechanisms
148
-			$container->query('OCA\Files_External\Lib\Auth\PublicKey\RSA'),
149
-
150
-			// AuthMechanism::SCHEME_OPENSTACK mechanisms
151
-			$container->query('OCA\Files_External\Lib\Auth\OpenStack\OpenStack'),
152
-			$container->query('OCA\Files_External\Lib\Auth\OpenStack\Rackspace'),
153
-
154
-			// Specialized mechanisms
155
-			$container->query('OCA\Files_External\Lib\Auth\AmazonS3\AccessKey'),
156
-		];
157
-	}
55
+    public function __construct(array $urlParams = array()) {
56
+        parent::__construct('files_external', $urlParams);
57
+
58
+        $container = $this->getContainer();
59
+
60
+        $container->registerService('OCP\Files\Config\IUserMountCache', function (IAppContainer $c) {
61
+            return $c->getServer()->query('UserMountCache');
62
+        });
63
+
64
+        $backendService = $container->query('OCA\\Files_External\\Service\\BackendService');
65
+        $backendService->registerBackendProvider($this);
66
+        $backendService->registerAuthMechanismProvider($this);
67
+
68
+        // force-load auth mechanisms since some will register hooks
69
+        // TODO: obsolete these and use the TokenProvider to get the user's password from the session
70
+        $this->getAuthMechanisms();
71
+
72
+        // app developers: do NOT depend on this! it will disappear with oC 9.0!
73
+        \OC::$server->getEventDispatcher()->dispatch(
74
+            'OCA\\Files_External::loadAdditionalBackends'
75
+        );
76
+    }
77
+
78
+    /**
79
+     * Register settings templates
80
+     */
81
+    public function registerSettings() {
82
+        $container = $this->getContainer();
83
+        $userSession = $container->getServer()->getUserSession();
84
+        if (!$userSession->isLoggedIn()) {
85
+            return;
86
+        }
87
+        $backendService = $container->query('OCA\\Files_External\\Service\\BackendService');
88
+
89
+        /** @var \OCA\Files_External\Service\UserGlobalStoragesService $userGlobalStoragesService */
90
+        $userGlobalStoragesService = $container->query('OCA\Files_External\Service\UserGlobalStoragesService');
91
+        if (count($userGlobalStoragesService->getStorages()) > 0 || $backendService->isUserMountingAllowed()) {
92
+            \OCP\App::registerPersonal('files_external', 'personal');
93
+        }
94
+    }
95
+
96
+    /**
97
+     * @{inheritdoc}
98
+     */
99
+    public function getBackends() {
100
+        $container = $this->getContainer();
101
+
102
+        $backends = [
103
+            $container->query(Local::class),
104
+            $container->query(FTP::class),
105
+            $container->query(DAV::class),
106
+            $container->query(OwnCloud::class),
107
+            $container->query(SFTP::class),
108
+            $container->query(AmazonS3::class),
109
+            $container->query(Dropbox::class),
110
+            $container->query(Google::class),
111
+            $container->query(Swift::class),
112
+            $container->query(SFTP_Key::class),
113
+            $container->query(SMB::class),
114
+            $container->query(SMB_OC::class),
115
+            $container->query(SharePoint::class),
116
+        ];
117
+
118
+        return $backends;
119
+    }
120
+
121
+    /**
122
+     * @{inheritdoc}
123
+     */
124
+    public function getAuthMechanisms() {
125
+        $container = $this->getContainer();
126
+
127
+        return [
128
+            // AuthMechanism::SCHEME_NULL mechanism
129
+            $container->query('OCA\Files_External\Lib\Auth\NullMechanism'),
130
+
131
+            // AuthMechanism::SCHEME_BUILTIN mechanism
132
+            $container->query('OCA\Files_External\Lib\Auth\Builtin'),
133
+
134
+            // AuthMechanism::SCHEME_PASSWORD mechanisms
135
+            $container->query('OCA\Files_External\Lib\Auth\Password\Password'),
136
+            $container->query('OCA\Files_External\Lib\Auth\Password\SessionCredentials'),
137
+            $container->query('OCA\Files_External\Lib\Auth\Password\LoginCredentials'),
138
+            $container->query('OCA\Files_External\Lib\Auth\Password\UserProvided'),
139
+            $container->query('OCA\Files_External\Lib\Auth\Password\GlobalAuth'),
140
+
141
+            // AuthMechanism::SCHEME_OAUTH1 mechanisms
142
+            $container->query('OCA\Files_External\Lib\Auth\OAuth1\OAuth1'),
143
+
144
+            // AuthMechanism::SCHEME_OAUTH2 mechanisms
145
+            $container->query('OCA\Files_External\Lib\Auth\OAuth2\OAuth2'),
146
+
147
+            // AuthMechanism::SCHEME_PUBLICKEY mechanisms
148
+            $container->query('OCA\Files_External\Lib\Auth\PublicKey\RSA'),
149
+
150
+            // AuthMechanism::SCHEME_OPENSTACK mechanisms
151
+            $container->query('OCA\Files_External\Lib\Auth\OpenStack\OpenStack'),
152
+            $container->query('OCA\Files_External\Lib\Auth\OpenStack\Rackspace'),
153
+
154
+            // Specialized mechanisms
155
+            $container->query('OCA\Files_External\Lib\Auth\AmazonS3\AccessKey'),
156
+        ];
157
+    }
158 158
 
159 159
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/Backend/SharePoint.php 1 patch
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -32,18 +32,18 @@
 block discarded – undo
32 32
 
33 33
 class SharePoint extends Backend {
34 34
 
35
-	public function __construct(IL10N $l, Password $legacyAuth) {
36
-		$this
37
-			->setIdentifier('sharepoint')
38
-			->setStorageClass(SharePointStorage::class)
39
-			->setText($l->t('SharePoint'))
40
-			->addParameters([
41
-				(new DefinitionParameter('host', $l->t('Host'))),
42
-				(new DefinitionParameter('documentLibrary', $l->t('Document Library'))),
43
-			])
44
-			->addAuthScheme(AuthMechanism::SCHEME_PASSWORD)
45
-			->setLegacyAuthMechanism($legacyAuth)
46
-		;
47
-	}
35
+    public function __construct(IL10N $l, Password $legacyAuth) {
36
+        $this
37
+            ->setIdentifier('sharepoint')
38
+            ->setStorageClass(SharePointStorage::class)
39
+            ->setText($l->t('SharePoint'))
40
+            ->addParameters([
41
+                (new DefinitionParameter('host', $l->t('Host'))),
42
+                (new DefinitionParameter('documentLibrary', $l->t('Document Library'))),
43
+            ])
44
+            ->addAuthScheme(AuthMechanism::SCHEME_PASSWORD)
45
+            ->setLegacyAuthMechanism($legacyAuth)
46
+        ;
47
+    }
48 48
 
49 49
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/SharePoint/ContextsFactory.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -30,12 +30,12 @@
 block discarded – undo
30 30
 
31 31
 class ContextsFactory {
32 32
 
33
-	public function getAuthContext($user, $password) {
34
-		return new NetworkCredentialContext($user, $password);
35
-	}
33
+    public function getAuthContext($user, $password) {
34
+        return new NetworkCredentialContext($user, $password);
35
+    }
36 36
 
37
-	public function getClientContext($server, IAuthenticationContext $authContext) {
38
-		return new ClientContext($server, $authContext);
39
-	}
37
+    public function getClientContext($server, IAuthenticationContext $authContext) {
38
+        return new ClientContext($server, $authContext);
39
+    }
40 40
 
41 41
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/SharePoint/SharePointClientFactory.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -24,19 +24,19 @@
 block discarded – undo
24 24
 namespace OCA\Files_External\Lib\SharePoint;
25 25
 
26 26
 class SharePointClientFactory {
27
-	/**
28
-	 * @param ContextsFactory $contextsFactory
29
-	 * @param string $sharePointUrl
30
-	 * @param array $credentials
31
-	 * @param string $documentLibraryTitle
32
-	 * @return SharePointClient
33
-	 */
34
-	public function getClient(
35
-		ContextsFactory $contextsFactory,
36
-		$sharePointUrl,
37
-		array $credentials,
38
-		$documentLibraryTitle)
39
-	{
40
-		return new SharePointClient($contextsFactory, $sharePointUrl, $credentials, $documentLibraryTitle);
41
-	}
27
+    /**
28
+     * @param ContextsFactory $contextsFactory
29
+     * @param string $sharePointUrl
30
+     * @param array $credentials
31
+     * @param string $documentLibraryTitle
32
+     * @return SharePointClient
33
+     */
34
+    public function getClient(
35
+        ContextsFactory $contextsFactory,
36
+        $sharePointUrl,
37
+        array $credentials,
38
+        $documentLibraryTitle)
39
+    {
40
+        return new SharePointClient($contextsFactory, $sharePointUrl, $credentials, $documentLibraryTitle);
41
+    }
42 42
 }
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/Storage/SharePoint.php 3 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -346,7 +346,7 @@  discard block
 block discarded – undo
346 346
 	}
347 347
 
348 348
 	/**
349
-	 * @param $serverUrl
349
+	 * @param string $serverUrl
350 350
 	 * @return ClientObjectCollection[]
351 351
 	 */
352 352
 	private function getFolderContents($serverUrl) {
@@ -378,7 +378,7 @@  discard block
 block discarded – undo
378 378
 	}
379 379
 
380 380
 	/**
381
-	 * @param $serverUrl
381
+	 * @param string $serverUrl
382 382
 	 * @return File|Folder
383 383
 	 * @throws NotFoundException
384 384
 	 */
@@ -405,7 +405,7 @@  discard block
 block discarded – undo
405 405
 	/**
406 406
 	 * creates the relative server "url" out of the provided path
407 407
 	 *
408
-	 * @param $path
408
+	 * @param string $path
409 409
 	 * @return string
410 410
 	 */
411 411
 	private function formatPath($path) {
Please login to merge, or discard this patch.
Indentation   +398 added lines, -398 removed lines patch added patch discarded remove patch
@@ -38,239 +38,239 @@  discard block
 block discarded – undo
38 38
 use Office365\PHP\Client\SharePoint\ListItem;
39 39
 
40 40
 class SharePoint extends Common {
41
-	const SP_PROPERTY_SIZE = 'Length';
42
-	const SP_PROPERTY_MTIME = 'TimeLastModified';
43
-	const SP_PROPERTY_URL = 'ServerRelativeUrl';
44
-
45
-	/** @var  string */
46
-	protected $server;
47
-
48
-	/** @var  string */
49
-	protected $documentLibrary;
50
-
51
-	/** @var  string */
52
-	protected $authUser;
53
-
54
-	/** @var  string */
55
-	protected $authPwd;
56
-
57
-	/** @var  SharePointClient */
58
-	protected $spClient;
59
-
60
-	/** @var  CappedMemoryCache */
61
-	protected $fileCache;
62
-
63
-	/** @var ContextsFactory */
64
-	private $contextsFactory;
65
-
66
-	/** @var ITempManager */
67
-	private $tempManager;
68
-
69
-	public function __construct($parameters) {
70
-		$this->server = $parameters['host'];
71
-		$this->documentLibrary = $parameters['documentLibrary'];
72
-
73
-		if(strpos($this->documentLibrary, '"') !== false) {
74
-			// they are, amongst others, not allowed and we use it in the filter
75
-			// cf. https://support.microsoft.com/en-us/kb/2933738
76
-			// TODO: verify, it talks about files and folders mostly
77
-			throw new \InvalidArgumentException('Illegal character in Document Library Name');
78
-		}
79
-
80
-		if(!isset($parameters['user']) || !isset($parameters['password'])) {
81
-			throw new \UnexpectedValueException('No user or password given');
82
-		}
83
-		$this->authUser = $parameters['user'];
84
-		$this->authPwd  = $parameters['password'];
85
-
86
-		$this->fixDI($parameters);
87
-	}
88
-
89
-	/**
90
-	 * Get the identifier for the storage,
91
-	 * the returned id should be the same for every storage object that is created with the same parameters
92
-	 * and two storage objects with the same id should refer to two storages that display the same files.
93
-	 *
94
-	 * @return string
95
-	 * @since 6.0.0
96
-	 */
97
-	public function getId() {
98
-		return 'SharePoint::' . $this->server . '::' . $this->documentLibrary . '::' . $this->authUser;
99
-	}
100
-
101
-	/**
102
-	 * see http://php.net/manual/en/function.mkdir.php
103
-	 * implementations need to implement a recursive mkdir
104
-	 *
105
-	 * @param string $path
106
-	 * @return bool
107
-	 * @since 6.0.0
108
-	 */
109
-	public function mkdir($path) {
110
-		$serverUrl = $this->formatPath($path);
111
-		try {
112
-			$folder = $this->spClient->createFolder($serverUrl);
113
-			$this->fileCache->set($serverUrl, [
114
-				'instance' => $folder,
115
-				'children' => [
116
-					'folders' => $folder->getFolders(),
117
-					'files' => $folder->getFiles()
118
-				]
119
-			]);
120
-			return true;
121
-		} catch (\Exception $e) {
122
-			$this->fileCache->remove($serverUrl);
123
-			return false;
124
-		}
125
-	}
126
-
127
-	/**
128
-	 * see http://php.net/manual/en/function.rmdir.php
129
-	 *
130
-	 * @param string $path
131
-	 * @return bool
132
-	 * @since 6.0.0
133
-	 */
134
-	public function rmdir($path) {
135
-		$serverUrl = $this->formatPath($path);
136
-		try {
137
-			$cacheEntry = $this->fileCache->get($serverUrl);
138
-			$folder = null;
139
-			if(is_array($cacheEntry) && isset($cacheEntry['instance'])) {
140
-				$folder = $cacheEntry['instance'];
141
-			}
142
-			$this->spClient->deleteFolder($serverUrl, $folder);
143
-			$this->fileCache->set($serverUrl, false);
144
-			return true;
145
-		} catch (\Exception $e) {
146
-			$this->fileCache->remove($serverUrl);
147
-			return false;
148
-		}
149
-	}
150
-
151
-	/**
152
-	 * see http://php.net/manual/en/function.opendir.php
153
-	 *
154
-	 * @param string $path
155
-	 * @return resource|false
156
-	 * @since 6.0.0
157
-	 */
158
-	public function opendir($path) {
159
-		try {
160
-			$serverUrl = $this->formatPath($path);
161
-			//$collections = $this->spClient->fetchFolderContents($serverUrl, ['Name', 'ListItemAllFields']);	// does not work for some reason :(
162
-			$collections = $this->getFolderContents($serverUrl);
163
-			$files = [];
164
-
165
-			foreach ($collections as $collection) {
166
-				/** @var File[]|Folder[] $items */
167
-				$items = $collection->getData();
168
-				foreach ($items as $item) {
169
-					/** @var ListItem $fields */
170
-					if(!$this->spClient->isHidden($item)) {
171
-						$files[] = $item->getProperty('Name');
172
-					}
173
-				}
174
-			}
175
-
176
-			return IteratorDirectory::wrap($files);
177
-		} catch (NotFoundException $e) {
178
-			return false;
179
-		}
180
-	}
181
-
182
-	/**
183
-	 * see http://php.net/manual/en/function.stat.php
184
-	 * only the following keys are required in the result: size and mtime
185
-	 *
186
-	 * @param string $path
187
-	 * @return array|false
188
-	 * @since 6.0.0
189
-	 */
190
-	public function stat($path) {
191
-		$serverUrl = $this->formatPath($path);
192
-		try {
193
-			$file = $this->getFileOrFolder($serverUrl);
194
-		} catch (\Exception $e) {
195
-			return false;
196
-		}
197
-
198
-		$size = $file->getProperty(self::SP_PROPERTY_SIZE) ?: FileInfo::SPACE_UNKNOWN;
199
-		$mtimeValue = $file->getProperty(self::SP_PROPERTY_MTIME);
200
-		$mtime = $mtimeValue ? new \DateTime($mtimeValue) : null;
201
-
202
-		$stat = [
203
-			// int64, size in bytes, excluding the size of any Web Parts that are used in the file.
204
-			'size'  => $size,
205
-			'mtime' => $mtime->getTimestamp(),
206
-			// no property in SP 2013 & 2016, other storages do the same  :speak_no_evil:
207
-			'atime' => time(),
208
-		];
209
-
210
-		if(!is_null($stat['mtime'])) {
211
-			return $stat;
212
-		}
213
-
214
-		// If we do not get a mtime from SP, we treat it as an error
215
-		// thus returning false, according to PHP documentation on stat()
216
-		return false;
217
-	}
218
-
219
-	/**
220
-	 * see http://php.net/manual/en/function.filetype.php
221
-	 *
222
-	 * @param string $path
223
-	 * @return false|string
224
-	 * @throws \Exception
225
-	 * @since 6.0.0
226
-	 */
227
-	public function filetype($path) {
228
-		try {
229
-			$serverUrl = $this->formatPath($path);
230
-			$object = $this->getFileOrFolder($serverUrl);
231
-		} catch (NotFoundException $e) {
232
-			return false;
233
-		}
234
-		if($object instanceof File) {
235
-			return 'file';
236
-		} else if($object instanceof Folder) {
237
-			return 'dir';
238
-		} else {
239
-			return false;
240
-		}
241
-	}
242
-
243
-	/**
244
-	 * see http://php.net/manual/en/function.file_exists.php
245
-	 *
246
-	 * @param string $path
247
-	 * @return bool
248
-	 * @since 6.0.0
249
-	 */
250
-	public function file_exists($path) {
251
-		try {
252
-			$serverUrl = $this->formatPath($path);
253
-			// alternative approach is to use a CAML query instead of querying
254
-			// for file and folder. It is not necessarily faster, though.
255
-			// Would need evaluation of typical use cases (I assume most often
256
-			// existing files are checked) and measurements.
257
-			$this->getFileOrFolder($serverUrl);
258
-			return true;
259
-		} catch (NotFoundException $e) {
260
-			return false;
261
-		}
262
-	}
263
-
264
-	/**
265
-	 * see http://php.net/manual/en/function.unlink.php
266
-	 *
267
-	 * @param string $path
268
-	 * @return bool
269
-	 * @since 6.0.0
270
-	 */
271
-	public function unlink($path) {
272
-		//  FIXME:: all is totally wrong
273
-		/*$path = trim($path);
41
+    const SP_PROPERTY_SIZE = 'Length';
42
+    const SP_PROPERTY_MTIME = 'TimeLastModified';
43
+    const SP_PROPERTY_URL = 'ServerRelativeUrl';
44
+
45
+    /** @var  string */
46
+    protected $server;
47
+
48
+    /** @var  string */
49
+    protected $documentLibrary;
50
+
51
+    /** @var  string */
52
+    protected $authUser;
53
+
54
+    /** @var  string */
55
+    protected $authPwd;
56
+
57
+    /** @var  SharePointClient */
58
+    protected $spClient;
59
+
60
+    /** @var  CappedMemoryCache */
61
+    protected $fileCache;
62
+
63
+    /** @var ContextsFactory */
64
+    private $contextsFactory;
65
+
66
+    /** @var ITempManager */
67
+    private $tempManager;
68
+
69
+    public function __construct($parameters) {
70
+        $this->server = $parameters['host'];
71
+        $this->documentLibrary = $parameters['documentLibrary'];
72
+
73
+        if(strpos($this->documentLibrary, '"') !== false) {
74
+            // they are, amongst others, not allowed and we use it in the filter
75
+            // cf. https://support.microsoft.com/en-us/kb/2933738
76
+            // TODO: verify, it talks about files and folders mostly
77
+            throw new \InvalidArgumentException('Illegal character in Document Library Name');
78
+        }
79
+
80
+        if(!isset($parameters['user']) || !isset($parameters['password'])) {
81
+            throw new \UnexpectedValueException('No user or password given');
82
+        }
83
+        $this->authUser = $parameters['user'];
84
+        $this->authPwd  = $parameters['password'];
85
+
86
+        $this->fixDI($parameters);
87
+    }
88
+
89
+    /**
90
+     * Get the identifier for the storage,
91
+     * the returned id should be the same for every storage object that is created with the same parameters
92
+     * and two storage objects with the same id should refer to two storages that display the same files.
93
+     *
94
+     * @return string
95
+     * @since 6.0.0
96
+     */
97
+    public function getId() {
98
+        return 'SharePoint::' . $this->server . '::' . $this->documentLibrary . '::' . $this->authUser;
99
+    }
100
+
101
+    /**
102
+     * see http://php.net/manual/en/function.mkdir.php
103
+     * implementations need to implement a recursive mkdir
104
+     *
105
+     * @param string $path
106
+     * @return bool
107
+     * @since 6.0.0
108
+     */
109
+    public function mkdir($path) {
110
+        $serverUrl = $this->formatPath($path);
111
+        try {
112
+            $folder = $this->spClient->createFolder($serverUrl);
113
+            $this->fileCache->set($serverUrl, [
114
+                'instance' => $folder,
115
+                'children' => [
116
+                    'folders' => $folder->getFolders(),
117
+                    'files' => $folder->getFiles()
118
+                ]
119
+            ]);
120
+            return true;
121
+        } catch (\Exception $e) {
122
+            $this->fileCache->remove($serverUrl);
123
+            return false;
124
+        }
125
+    }
126
+
127
+    /**
128
+     * see http://php.net/manual/en/function.rmdir.php
129
+     *
130
+     * @param string $path
131
+     * @return bool
132
+     * @since 6.0.0
133
+     */
134
+    public function rmdir($path) {
135
+        $serverUrl = $this->formatPath($path);
136
+        try {
137
+            $cacheEntry = $this->fileCache->get($serverUrl);
138
+            $folder = null;
139
+            if(is_array($cacheEntry) && isset($cacheEntry['instance'])) {
140
+                $folder = $cacheEntry['instance'];
141
+            }
142
+            $this->spClient->deleteFolder($serverUrl, $folder);
143
+            $this->fileCache->set($serverUrl, false);
144
+            return true;
145
+        } catch (\Exception $e) {
146
+            $this->fileCache->remove($serverUrl);
147
+            return false;
148
+        }
149
+    }
150
+
151
+    /**
152
+     * see http://php.net/manual/en/function.opendir.php
153
+     *
154
+     * @param string $path
155
+     * @return resource|false
156
+     * @since 6.0.0
157
+     */
158
+    public function opendir($path) {
159
+        try {
160
+            $serverUrl = $this->formatPath($path);
161
+            //$collections = $this->spClient->fetchFolderContents($serverUrl, ['Name', 'ListItemAllFields']);	// does not work for some reason :(
162
+            $collections = $this->getFolderContents($serverUrl);
163
+            $files = [];
164
+
165
+            foreach ($collections as $collection) {
166
+                /** @var File[]|Folder[] $items */
167
+                $items = $collection->getData();
168
+                foreach ($items as $item) {
169
+                    /** @var ListItem $fields */
170
+                    if(!$this->spClient->isHidden($item)) {
171
+                        $files[] = $item->getProperty('Name');
172
+                    }
173
+                }
174
+            }
175
+
176
+            return IteratorDirectory::wrap($files);
177
+        } catch (NotFoundException $e) {
178
+            return false;
179
+        }
180
+    }
181
+
182
+    /**
183
+     * see http://php.net/manual/en/function.stat.php
184
+     * only the following keys are required in the result: size and mtime
185
+     *
186
+     * @param string $path
187
+     * @return array|false
188
+     * @since 6.0.0
189
+     */
190
+    public function stat($path) {
191
+        $serverUrl = $this->formatPath($path);
192
+        try {
193
+            $file = $this->getFileOrFolder($serverUrl);
194
+        } catch (\Exception $e) {
195
+            return false;
196
+        }
197
+
198
+        $size = $file->getProperty(self::SP_PROPERTY_SIZE) ?: FileInfo::SPACE_UNKNOWN;
199
+        $mtimeValue = $file->getProperty(self::SP_PROPERTY_MTIME);
200
+        $mtime = $mtimeValue ? new \DateTime($mtimeValue) : null;
201
+
202
+        $stat = [
203
+            // int64, size in bytes, excluding the size of any Web Parts that are used in the file.
204
+            'size'  => $size,
205
+            'mtime' => $mtime->getTimestamp(),
206
+            // no property in SP 2013 & 2016, other storages do the same  :speak_no_evil:
207
+            'atime' => time(),
208
+        ];
209
+
210
+        if(!is_null($stat['mtime'])) {
211
+            return $stat;
212
+        }
213
+
214
+        // If we do not get a mtime from SP, we treat it as an error
215
+        // thus returning false, according to PHP documentation on stat()
216
+        return false;
217
+    }
218
+
219
+    /**
220
+     * see http://php.net/manual/en/function.filetype.php
221
+     *
222
+     * @param string $path
223
+     * @return false|string
224
+     * @throws \Exception
225
+     * @since 6.0.0
226
+     */
227
+    public function filetype($path) {
228
+        try {
229
+            $serverUrl = $this->formatPath($path);
230
+            $object = $this->getFileOrFolder($serverUrl);
231
+        } catch (NotFoundException $e) {
232
+            return false;
233
+        }
234
+        if($object instanceof File) {
235
+            return 'file';
236
+        } else if($object instanceof Folder) {
237
+            return 'dir';
238
+        } else {
239
+            return false;
240
+        }
241
+    }
242
+
243
+    /**
244
+     * see http://php.net/manual/en/function.file_exists.php
245
+     *
246
+     * @param string $path
247
+     * @return bool
248
+     * @since 6.0.0
249
+     */
250
+    public function file_exists($path) {
251
+        try {
252
+            $serverUrl = $this->formatPath($path);
253
+            // alternative approach is to use a CAML query instead of querying
254
+            // for file and folder. It is not necessarily faster, though.
255
+            // Would need evaluation of typical use cases (I assume most often
256
+            // existing files are checked) and measurements.
257
+            $this->getFileOrFolder($serverUrl);
258
+            return true;
259
+        } catch (NotFoundException $e) {
260
+            return false;
261
+        }
262
+    }
263
+
264
+    /**
265
+     * see http://php.net/manual/en/function.unlink.php
266
+     *
267
+     * @param string $path
268
+     * @return bool
269
+     * @since 6.0.0
270
+     */
271
+    public function unlink($path) {
272
+        //  FIXME:: all is totally wrong
273
+        /*$path = trim($path);
274 274
 		if($path === '/' || $path === '') {
275 275
 			return false;
276 276
 		}
@@ -283,28 +283,28 @@  discard block
 block discarded – undo
283 283
 				// NOOP
284 284
 			}
285 285
 		}*/
286
-		return false;
287
-	}
288
-
289
-	/**
290
-	 * see http://php.net/manual/en/function.fopen.php
291
-	 *
292
-	 * @param string $path
293
-	 * @param string $mode
294
-	 * @return resource|false
295
-	 * @since 6.0.0
296
-	 */
297
-	public function fopen($path, $mode) {
298
-		$serverUrl = $this->formatPath($path);
299
-
300
-		switch ($mode) {
301
-			case 'r':
302
-			case 'rb':
303
-				$tmpFile = $this->tempManager->getTemporaryFile();
304
-
305
-				// TODO: when https://github.com/vgrem/phpSPO/pull/59 is merged,
306
-				// use getFileViaStream approach and remove the other code
307
-				/*$fp = fopen($tmpFile, 'w+');
286
+        return false;
287
+    }
288
+
289
+    /**
290
+     * see http://php.net/manual/en/function.fopen.php
291
+     *
292
+     * @param string $path
293
+     * @param string $mode
294
+     * @return resource|false
295
+     * @since 6.0.0
296
+     */
297
+    public function fopen($path, $mode) {
298
+        $serverUrl = $this->formatPath($path);
299
+
300
+        switch ($mode) {
301
+            case 'r':
302
+            case 'rb':
303
+                $tmpFile = $this->tempManager->getTemporaryFile();
304
+
305
+                // TODO: when https://github.com/vgrem/phpSPO/pull/59 is merged,
306
+                // use getFileViaStream approach and remove the other code
307
+                /*$fp = fopen($tmpFile, 'w+');
308 308
 				if(!$this->spClient->getFileViaStream($serverUrl, $fp)) {
309 309
 					fclose($fp);
310 310
 					return false;
@@ -312,148 +312,148 @@  discard block
 block discarded – undo
312 312
 				fseek($fp, 0);
313 313
 				return $fp;*/
314 314
 
315
-				$content = $this->spClient->getFile($serverUrl);
316
-				file_put_contents($tmpFile, $content);
317
-				return fopen($tmpFile, 'r');
318
-		}
319
-		return false;
320
-	}
321
-
322
-	/**
323
-	 * see http://php.net/manual/en/function.touch.php
324
-	 * If the backend does not support the operation, false should be returned
325
-	 *
326
-	 * @param string $path
327
-	 * @param int $mtime
328
-	 * @return bool
329
-	 * @since 6.0.0
330
-	 */
331
-	public function touch($path, $mtime = null) {
332
-		// TODO: Implement touch() method.
333
-		return true;
334
-	}
335
-
336
-
337
-	/**
338
-	 * work around dependency injection issues so we can test this class properly
339
-	 *
340
-	 * @param array $parameters
341
-	 */
342
-	private function fixDI(array $parameters) {
343
-		if(isset($parameters['contextFactory'])
344
-			&& $parameters['contextFactory'] instanceof ContextsFactory)
345
-		{
346
-			$this->contextsFactory = $parameters['contextFactory'];
347
-		} else {
348
-			$this->contextsFactory = new ContextsFactory();
349
-		}
350
-
351
-		if(isset($parameters['sharePointClientFactory'])
352
-			&& $parameters['sharePointClientFactory'] instanceof SharePointClientFactory)
353
-		{
354
-			$spcFactory = $parameters['sharePointClientFactory'];
355
-		} else {
356
-			$spcFactory = new SharePointClientFactory();
357
-		}
358
-		$this->spClient = $spcFactory->getClient(
359
-			$this->contextsFactory,
360
-			$this->server,
361
-			[ 'user' => $this->authUser, 'password' => $this->authPwd],
362
-			$this->documentLibrary
363
-		);
364
-
365
-		if(isset($parameters['cappedMemoryCache'])) {
366
-			$this->fileCache = $parameters['cappedMemoryCache'];
367
-		} else {
368
-			// there's no API to get such
369
-			$this->fileCache = new CappedMemoryCache();
370
-		}
371
-
372
-		if(isset($parameters['tempManager'])) {
373
-			$this->tempManager = $parameters['tempManager'];
374
-		} else {
375
-			$this->tempManager = \OC::$server->getTempManager();
376
-		}
377
-	}
378
-
379
-	/**
380
-	 * @param $serverUrl
381
-	 * @return ClientObjectCollection[]
382
-	 */
383
-	private function getFolderContents($serverUrl) {
384
-		$entry = $this->fileCache->get($serverUrl);
385
-		if($entry === null || !isset($entry['children'])) {
386
-			$folder = isset($entry['instance']) ? $entry['instance'] : null;
387
-			$contents = $this->spClient->fetchFolderContents($serverUrl, null, $folder);
388
-			$cacheItem = $entry ?: [];
389
-			$cacheItem['children'] = $contents;
390
-			$this->fileCache->set($serverUrl, $cacheItem);
391
-
392
-			// cache children instances
393
-			foreach ($contents as $collection) {
394
-				foreach ($collection->getData() as $item) {
395
-					/** @var  File|Folder $item */
396
-					$url = $item->getProperty(self::SP_PROPERTY_URL);
397
-					$itemEntry = $this->fileCache->get($url);
398
-					$itemEntry = $itemEntry ?: [];
399
-					if(!isset($itemEntry['instance'])) {
400
-						$itemEntry['instance'] = $item;
401
-						$this->fileCache->set($url, $itemEntry);
402
-					}
403
-				}
404
-			}
405
-		} else {
406
-			$contents = $entry['children'];
407
-		}
408
-		return $contents;
409
-	}
410
-
411
-	/**
412
-	 * @param $serverUrl
413
-	 * @return File|Folder
414
-	 * @throws NotFoundException
415
-	 */
416
-	private function getFileOrFolder($serverUrl) {
417
-		$entry = $this->fileCache->get($serverUrl);
418
-		if($entry === false) {
419
-			throw new NotFoundException('File or Folder not found');
420
-		} else if($entry === null || !isset($entry['instance'])) {
421
-			try {
422
-				$file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]);
423
-			} catch (NotFoundException $e) {
424
-				$this->fileCache->set($serverUrl, false);
425
-				throw $e;
426
-			}
427
-			$cacheItem = $entry ?: [];
428
-			$cacheItem['instance'] = $file;
429
-			$this->fileCache->set($serverUrl, $cacheItem);
430
-		} else {
431
-			$file = $entry['instance'];
432
-		}
433
-		return $file;
434
-	}
435
-
436
-	/**
437
-	 * creates the relative server "url" out of the provided path
438
-	 *
439
-	 * @param $path
440
-	 * @return string
441
-	 */
442
-	private function formatPath($path) {
443
-		$path = trim($path, '/');
444
-		$serverUrl = '/' . $this->documentLibrary;
445
-		if($path !== '') {
446
-			$serverUrl .= '/' . $path;
447
-		}
448
-
449
-		$pathParts = explode('/', $serverUrl);
450
-		$filename = array_pop($pathParts);
451
-		if($filename === '.') {
452
-			// remove /. from the end of the path
453
-			$serverUrl = mb_substr($serverUrl, 0, mb_strlen($serverUrl) - 2);
454
-		}
455
-
456
-		return $serverUrl;
457
-	}
315
+                $content = $this->spClient->getFile($serverUrl);
316
+                file_put_contents($tmpFile, $content);
317
+                return fopen($tmpFile, 'r');
318
+        }
319
+        return false;
320
+    }
321
+
322
+    /**
323
+     * see http://php.net/manual/en/function.touch.php
324
+     * If the backend does not support the operation, false should be returned
325
+     *
326
+     * @param string $path
327
+     * @param int $mtime
328
+     * @return bool
329
+     * @since 6.0.0
330
+     */
331
+    public function touch($path, $mtime = null) {
332
+        // TODO: Implement touch() method.
333
+        return true;
334
+    }
335
+
336
+
337
+    /**
338
+     * work around dependency injection issues so we can test this class properly
339
+     *
340
+     * @param array $parameters
341
+     */
342
+    private function fixDI(array $parameters) {
343
+        if(isset($parameters['contextFactory'])
344
+            && $parameters['contextFactory'] instanceof ContextsFactory)
345
+        {
346
+            $this->contextsFactory = $parameters['contextFactory'];
347
+        } else {
348
+            $this->contextsFactory = new ContextsFactory();
349
+        }
350
+
351
+        if(isset($parameters['sharePointClientFactory'])
352
+            && $parameters['sharePointClientFactory'] instanceof SharePointClientFactory)
353
+        {
354
+            $spcFactory = $parameters['sharePointClientFactory'];
355
+        } else {
356
+            $spcFactory = new SharePointClientFactory();
357
+        }
358
+        $this->spClient = $spcFactory->getClient(
359
+            $this->contextsFactory,
360
+            $this->server,
361
+            [ 'user' => $this->authUser, 'password' => $this->authPwd],
362
+            $this->documentLibrary
363
+        );
364
+
365
+        if(isset($parameters['cappedMemoryCache'])) {
366
+            $this->fileCache = $parameters['cappedMemoryCache'];
367
+        } else {
368
+            // there's no API to get such
369
+            $this->fileCache = new CappedMemoryCache();
370
+        }
371
+
372
+        if(isset($parameters['tempManager'])) {
373
+            $this->tempManager = $parameters['tempManager'];
374
+        } else {
375
+            $this->tempManager = \OC::$server->getTempManager();
376
+        }
377
+    }
378
+
379
+    /**
380
+     * @param $serverUrl
381
+     * @return ClientObjectCollection[]
382
+     */
383
+    private function getFolderContents($serverUrl) {
384
+        $entry = $this->fileCache->get($serverUrl);
385
+        if($entry === null || !isset($entry['children'])) {
386
+            $folder = isset($entry['instance']) ? $entry['instance'] : null;
387
+            $contents = $this->spClient->fetchFolderContents($serverUrl, null, $folder);
388
+            $cacheItem = $entry ?: [];
389
+            $cacheItem['children'] = $contents;
390
+            $this->fileCache->set($serverUrl, $cacheItem);
391
+
392
+            // cache children instances
393
+            foreach ($contents as $collection) {
394
+                foreach ($collection->getData() as $item) {
395
+                    /** @var  File|Folder $item */
396
+                    $url = $item->getProperty(self::SP_PROPERTY_URL);
397
+                    $itemEntry = $this->fileCache->get($url);
398
+                    $itemEntry = $itemEntry ?: [];
399
+                    if(!isset($itemEntry['instance'])) {
400
+                        $itemEntry['instance'] = $item;
401
+                        $this->fileCache->set($url, $itemEntry);
402
+                    }
403
+                }
404
+            }
405
+        } else {
406
+            $contents = $entry['children'];
407
+        }
408
+        return $contents;
409
+    }
410
+
411
+    /**
412
+     * @param $serverUrl
413
+     * @return File|Folder
414
+     * @throws NotFoundException
415
+     */
416
+    private function getFileOrFolder($serverUrl) {
417
+        $entry = $this->fileCache->get($serverUrl);
418
+        if($entry === false) {
419
+            throw new NotFoundException('File or Folder not found');
420
+        } else if($entry === null || !isset($entry['instance'])) {
421
+            try {
422
+                $file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]);
423
+            } catch (NotFoundException $e) {
424
+                $this->fileCache->set($serverUrl, false);
425
+                throw $e;
426
+            }
427
+            $cacheItem = $entry ?: [];
428
+            $cacheItem['instance'] = $file;
429
+            $this->fileCache->set($serverUrl, $cacheItem);
430
+        } else {
431
+            $file = $entry['instance'];
432
+        }
433
+        return $file;
434
+    }
435
+
436
+    /**
437
+     * creates the relative server "url" out of the provided path
438
+     *
439
+     * @param $path
440
+     * @return string
441
+     */
442
+    private function formatPath($path) {
443
+        $path = trim($path, '/');
444
+        $serverUrl = '/' . $this->documentLibrary;
445
+        if($path !== '') {
446
+            $serverUrl .= '/' . $path;
447
+        }
448
+
449
+        $pathParts = explode('/', $serverUrl);
450
+        $filename = array_pop($pathParts);
451
+        if($filename === '.') {
452
+            // remove /. from the end of the path
453
+            $serverUrl = mb_substr($serverUrl, 0, mb_strlen($serverUrl) - 2);
454
+        }
455
+
456
+        return $serverUrl;
457
+    }
458 458
 
459 459
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -70,14 +70,14 @@  discard block
 block discarded – undo
70 70
 		$this->server = $parameters['host'];
71 71
 		$this->documentLibrary = $parameters['documentLibrary'];
72 72
 
73
-		if(strpos($this->documentLibrary, '"') !== false) {
73
+		if (strpos($this->documentLibrary, '"') !== false) {
74 74
 			// they are, amongst others, not allowed and we use it in the filter
75 75
 			// cf. https://support.microsoft.com/en-us/kb/2933738
76 76
 			// TODO: verify, it talks about files and folders mostly
77 77
 			throw new \InvalidArgumentException('Illegal character in Document Library Name');
78 78
 		}
79 79
 
80
-		if(!isset($parameters['user']) || !isset($parameters['password'])) {
80
+		if (!isset($parameters['user']) || !isset($parameters['password'])) {
81 81
 			throw new \UnexpectedValueException('No user or password given');
82 82
 		}
83 83
 		$this->authUser = $parameters['user'];
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 	 * @since 6.0.0
96 96
 	 */
97 97
 	public function getId() {
98
-		return 'SharePoint::' . $this->server . '::' . $this->documentLibrary . '::' . $this->authUser;
98
+		return 'SharePoint::'.$this->server.'::'.$this->documentLibrary.'::'.$this->authUser;
99 99
 	}
100 100
 
101 101
 	/**
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
 		try {
137 137
 			$cacheEntry = $this->fileCache->get($serverUrl);
138 138
 			$folder = null;
139
-			if(is_array($cacheEntry) && isset($cacheEntry['instance'])) {
139
+			if (is_array($cacheEntry) && isset($cacheEntry['instance'])) {
140 140
 				$folder = $cacheEntry['instance'];
141 141
 			}
142 142
 			$this->spClient->deleteFolder($serverUrl, $folder);
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
 				$items = $collection->getData();
168 168
 				foreach ($items as $item) {
169 169
 					/** @var ListItem $fields */
170
-					if(!$this->spClient->isHidden($item)) {
170
+					if (!$this->spClient->isHidden($item)) {
171 171
 						$files[] = $item->getProperty('Name');
172 172
 					}
173 173
 				}
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
 			'atime' => time(),
208 208
 		];
209 209
 
210
-		if(!is_null($stat['mtime'])) {
210
+		if (!is_null($stat['mtime'])) {
211 211
 			return $stat;
212 212
 		}
213 213
 
@@ -231,9 +231,9 @@  discard block
 block discarded – undo
231 231
 		} catch (NotFoundException $e) {
232 232
 			return false;
233 233
 		}
234
-		if($object instanceof File) {
234
+		if ($object instanceof File) {
235 235
 			return 'file';
236
-		} else if($object instanceof Folder) {
236
+		} else if ($object instanceof Folder) {
237 237
 			return 'dir';
238 238
 		} else {
239 239
 			return false;
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
 	 * @param array $parameters
341 341
 	 */
342 342
 	private function fixDI(array $parameters) {
343
-		if(isset($parameters['contextFactory'])
343
+		if (isset($parameters['contextFactory'])
344 344
 			&& $parameters['contextFactory'] instanceof ContextsFactory)
345 345
 		{
346 346
 			$this->contextsFactory = $parameters['contextFactory'];
@@ -348,7 +348,7 @@  discard block
 block discarded – undo
348 348
 			$this->contextsFactory = new ContextsFactory();
349 349
 		}
350 350
 
351
-		if(isset($parameters['sharePointClientFactory'])
351
+		if (isset($parameters['sharePointClientFactory'])
352 352
 			&& $parameters['sharePointClientFactory'] instanceof SharePointClientFactory)
353 353
 		{
354 354
 			$spcFactory = $parameters['sharePointClientFactory'];
@@ -358,18 +358,18 @@  discard block
 block discarded – undo
358 358
 		$this->spClient = $spcFactory->getClient(
359 359
 			$this->contextsFactory,
360 360
 			$this->server,
361
-			[ 'user' => $this->authUser, 'password' => $this->authPwd],
361
+			['user' => $this->authUser, 'password' => $this->authPwd],
362 362
 			$this->documentLibrary
363 363
 		);
364 364
 
365
-		if(isset($parameters['cappedMemoryCache'])) {
365
+		if (isset($parameters['cappedMemoryCache'])) {
366 366
 			$this->fileCache = $parameters['cappedMemoryCache'];
367 367
 		} else {
368 368
 			// there's no API to get such
369 369
 			$this->fileCache = new CappedMemoryCache();
370 370
 		}
371 371
 
372
-		if(isset($parameters['tempManager'])) {
372
+		if (isset($parameters['tempManager'])) {
373 373
 			$this->tempManager = $parameters['tempManager'];
374 374
 		} else {
375 375
 			$this->tempManager = \OC::$server->getTempManager();
@@ -382,7 +382,7 @@  discard block
 block discarded – undo
382 382
 	 */
383 383
 	private function getFolderContents($serverUrl) {
384 384
 		$entry = $this->fileCache->get($serverUrl);
385
-		if($entry === null || !isset($entry['children'])) {
385
+		if ($entry === null || !isset($entry['children'])) {
386 386
 			$folder = isset($entry['instance']) ? $entry['instance'] : null;
387 387
 			$contents = $this->spClient->fetchFolderContents($serverUrl, null, $folder);
388 388
 			$cacheItem = $entry ?: [];
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
 					$url = $item->getProperty(self::SP_PROPERTY_URL);
397 397
 					$itemEntry = $this->fileCache->get($url);
398 398
 					$itemEntry = $itemEntry ?: [];
399
-					if(!isset($itemEntry['instance'])) {
399
+					if (!isset($itemEntry['instance'])) {
400 400
 						$itemEntry['instance'] = $item;
401 401
 						$this->fileCache->set($url, $itemEntry);
402 402
 					}
@@ -415,9 +415,9 @@  discard block
 block discarded – undo
415 415
 	 */
416 416
 	private function getFileOrFolder($serverUrl) {
417 417
 		$entry = $this->fileCache->get($serverUrl);
418
-		if($entry === false) {
418
+		if ($entry === false) {
419 419
 			throw new NotFoundException('File or Folder not found');
420
-		} else if($entry === null || !isset($entry['instance'])) {
420
+		} else if ($entry === null || !isset($entry['instance'])) {
421 421
 			try {
422 422
 				$file = $this->spClient->fetchFileOrFolder($serverUrl, [self::SP_PROPERTY_SIZE, self::SP_PROPERTY_MTIME]);
423 423
 			} catch (NotFoundException $e) {
@@ -441,14 +441,14 @@  discard block
 block discarded – undo
441 441
 	 */
442 442
 	private function formatPath($path) {
443 443
 		$path = trim($path, '/');
444
-		$serverUrl = '/' . $this->documentLibrary;
445
-		if($path !== '') {
446
-			$serverUrl .= '/' . $path;
444
+		$serverUrl = '/'.$this->documentLibrary;
445
+		if ($path !== '') {
446
+			$serverUrl .= '/'.$path;
447 447
 		}
448 448
 
449 449
 		$pathParts = explode('/', $serverUrl);
450 450
 		$filename = array_pop($pathParts);
451
-		if($filename === '.') {
451
+		if ($filename === '.') {
452 452
 			// remove /. from the end of the path
453 453
 			$serverUrl = mb_substr($serverUrl, 0, mb_strlen($serverUrl) - 2);
454 454
 		}
Please login to merge, or discard this patch.
apps/files_external/lib/Lib/SharePoint/SharePointClient.php 3 patches
Doc Comments   +9 added lines, -2 removed lines patch added patch discarded remove patch
@@ -54,6 +54,10 @@  discard block
 block discarded – undo
54 54
 	/** @var  string */
55 55
 	private $documentLibraryTitle;
56 56
 
57
+	/**
58
+	 * @param string $sharePointUrl
59
+	 * @param string $documentLibraryTitle
60
+	 */
57 61
 	public function __construct(ContextsFactory $contextsFactory, $sharePointUrl, array $credentials, $documentLibraryTitle) {
58 62
 		$this->contextsFactory = $contextsFactory;
59 63
 		$this->sharePointUrl = $sharePointUrl;
@@ -114,7 +118,7 @@  discard block
 block discarded – undo
114 118
 	 * adds a folder on the given server path
115 119
 	 *
116 120
 	 * @param string $relativeServerPath
117
-	 * @return Folder
121
+	 * @return string
118 122
 	 * @throws \Exception
119 123
 	 */
120 124
 	public function createFolder($relativeServerPath) {
@@ -166,13 +170,16 @@  discard block
 block discarded – undo
166 170
 	/**
167 171
 	 * fetches the file content (aka download)
168 172
 	 *
169
-	 * @param $relativeServerPath
173
+	 * @param string $relativeServerPath
170 174
 	 * @return string the file content
171 175
 	 */
172 176
 	public function getFile($relativeServerPath) {
173 177
 		return File::openBinary($this->context, $relativeServerPath);
174 178
 	}
175 179
 
180
+	/**
181
+	 * @param string $relativeServerPath
182
+	 */
176 183
 	public function deleteFolder($relativeServerPath, Folder $folder = null) {
177 184
 		$this->ensureConnection();
178 185
 
Please login to merge, or discard this patch.
Indentation   +257 added lines, -257 removed lines patch added patch discarded remove patch
@@ -33,261 +33,261 @@
 block discarded – undo
33 33
 use Office365\PHP\Client\SharePoint\SPList;
34 34
 
35 35
 class SharePointClient {
36
-	/** @var  ClientContext */
37
-	protected $context;
38
-
39
-	/** @var  AuthenticationContext */
40
-	protected $authContext;
41
-
42
-	/** @var  SPList */
43
-	protected $documentLibrary;
44
-
45
-	/** @var ContextsFactory */
46
-	private $contextsFactory;
47
-
48
-	/** @var  string */
49
-	private $sharePointUrl;
50
-
51
-	/** @var string[] */
52
-	private $credentials;
53
-
54
-	/** @var  string */
55
-	private $documentLibraryTitle;
56
-
57
-	public function __construct(ContextsFactory $contextsFactory, $sharePointUrl, array $credentials, $documentLibraryTitle) {
58
-		$this->contextsFactory = $contextsFactory;
59
-		$this->sharePointUrl = $sharePointUrl;
60
-		$this->credentials = $credentials;
61
-		$this->documentLibraryTitle = $documentLibraryTitle;
62
-	}
63
-
64
-	/**
65
-	 * @param string $path
66
-	 * @param array $properties
67
-	 * @return File|Folder
68
-	 * @throws \Exception
69
-	 */
70
-	public function fetchFileOrFolder($path, array $properties = null) {
71
-		$fetchFileFunc = function ($path, $props) { return $this->fetchFile($path, $props);};
72
-		$fetchFolderFunc = function ($path, $props) { return $this->fetchFolder($path, $props);};
73
-		$fetchers = [ $fetchFileFunc, $fetchFolderFunc ];
74
-		if(strpos($path, '.') === false) {
75
-			$fetchers = array_reverse($fetchers);
76
-		}
77
-
78
-		foreach ($fetchers as $fetchFunction) {
79
-			try {
80
-				$instance = call_user_func_array($fetchFunction, [$path, $properties]);
81
-				return $instance;
82
-			} catch (\Exception $e) {
83
-				if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1
84
-					&& $e->getMessage() !== 'Unknown Error'
85
-					&& $e->getMessage() !== 'File Not Found.'
86
-				) {
87
-					$this->createClientContext();
88
-					# Unexpected Exception, pass it on
89
-					throw $e;
90
-				}
91
-			}
92
-			$this->createClientContext();
93
-		}
94
-
95
-		# Nothing succeeded, quit with not found
96
-		throw new NotFoundException('File or Folder not found');
97
-	}
98
-
99
-	public function fetchFile($relativeServerPath, array $properties = null) {
100
-		$this->ensureConnection();
101
-		$file = $this->context->getWeb()->getFileByServerRelativeUrl($relativeServerPath);
102
-		$this->loadAndExecute($file, $properties);
103
-		return $file;
104
-	}
105
-
106
-	public function fetchFolder($relativeServerPath, array $properties = null) {
107
-		$this->ensureConnection();
108
-		$folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
109
-		$this->loadAndExecute($folder, $properties);
110
-		return $folder;
111
-	}
112
-
113
-	/**
114
-	 * adds a folder on the given server path
115
-	 *
116
-	 * @param string $relativeServerPath
117
-	 * @return Folder
118
-	 * @throws \Exception
119
-	 */
120
-	public function createFolder($relativeServerPath) {
121
-		$this->ensureConnection();
122
-
123
-		$serverUrlParts = explode('/', $relativeServerPath);
124
-		$newFolderName = array_pop($serverUrlParts);
125
-		$parentUrl =  implode('/', $serverUrlParts);
126
-
127
-		$parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl($parentUrl);
128
-		$folder = $parentFolder->getFolders()->add($newFolderName);
129
-
130
-		try {
131
-			$this->context->executeQuery();
132
-			return $folder;
133
-		} catch (\Exception $e) {
134
-			$this->createClientContext();
135
-			throw $e;
136
-		}
137
-	}
138
-
139
-	/**
140
-	 * downloads a file by passing it directly into a file resource
141
-	 *
142
-	 * @param $relativeServerPath
143
-	 * @param resource $fp a file resource open for writing
144
-	 * @return \Office365\PHP\Client\Runtime\OData\ODataPayload
145
-	 * @throws \Exception
146
-	 */
147
-	public function getFileViaStream($relativeServerPath, $fp) {
148
-		if(!is_resource($fp)) {
149
-			throw new \InvalidArgumentException('file resource expected');
150
-		}
151
-		$relativeServerPath = rawurlencode($relativeServerPath);
152
-		$url = $this->context->getServiceRootUrl() .
153
-			"web/getfilebyserverrelativeurl('$relativeServerPath')/\$value";
154
-		$options = new RequestOptions($url);
155
-		$options->addCurlOption(CURLOPT_FILE, $fp);
156
-
157
-		try {
158
-			$ok = $this->context->executeQueryDirect($options);
159
-		} catch(\Exception $e) {
160
-			$this->createClientContext();
161
-			throw $e;
162
-		}
163
-		return $ok;
164
-	}
165
-
166
-	/**
167
-	 * fetches the file content (aka download)
168
-	 *
169
-	 * @param $relativeServerPath
170
-	 * @return string the file content
171
-	 */
172
-	public function getFile($relativeServerPath) {
173
-		return File::openBinary($this->context, $relativeServerPath);
174
-	}
175
-
176
-	public function deleteFolder($relativeServerPath, Folder $folder = null) {
177
-		$this->ensureConnection();
178
-
179
-		try {
180
-			if($folder === null) {
181
-				$folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
182
-			}
183
-			$folder->deleteObject();
184
-			$this->context->executeQuery();
185
-		} catch (\Exception $e) {
186
-			$this->createClientContext();
187
-			throw $e;
188
-		}
189
-	}
190
-
191
-	/**
192
-	 * @param $relativeServerPath
193
-	 * @param null $properties
194
-	 * @param Folder $folder
195
-	 * @return ClientObjectCollection[]
196
-	 */
197
-	public function fetchFolderContents($relativeServerPath, $properties = null, Folder $folder = null) {
198
-		$this->ensureConnection();
199
-		if($folder === null) {
200
-			$folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
201
-		}
202
-
203
-		$folderCollection = $folder->getFolders();
204
-		$fileCollection = $folder->getFiles();
205
-		$this->context->load($folderCollection, $properties);
206
-		$this->context->load($fileCollection, $properties);
207
-		$this->context->executeQuery();
208
-
209
-		$collections = ['folders' => $folderCollection, 'files' => $fileCollection];
210
-
211
-		return $collections;
212
-	}
213
-
214
-	public function isHidden(ClientObject $file) {
215
-		// ClientObject itself does not have getListItemAllFields but is
216
-		// the common denominator of File and Folder
217
-		if(!$file instanceof File && !$file instanceof Folder) {
218
-			throw new \InvalidArgumentException('File or Folder expected');
219
-		}
220
-		if($file instanceof File) {
221
-			// it's expensive, we only check folders
222
-			return false;
223
-		}
224
-		$fields = $file->getListItemAllFields();
225
-		if($fields->getProperties() === []) {
226
-			$this->loadAndExecute($fields, ['Id', 'Hidden']);
227
-		}
228
-		$id = $fields->getProperty('Id');
229
-		$hidden = $fields->getProperty('Hidden'); // TODO: get someone to test this in SP 2013
230
-		if($hidden === false || $id !== null) {
231
-			// avoids listing hidden "Forms" folder (and its contents).
232
-			// Have not found a different mechanism to detect whether
233
-			// a file or folder is hidden. There used to be a Hidden
234
-			// field, but seems to have gone (since SP 2016?).
235
-			return false;
236
-		}
237
-		return true;
238
-	}
239
-
240
-	public function loadAndExecute(ClientObject $object, array $properties = null) {
241
-		$this->context->load($object, $properties);
242
-		$this->context->executeQuery();
243
-	}
244
-
245
-	/**
246
-	 * @return SPList
247
-	 * @throws NotFoundException
248
-	 */
249
-	private function getDocumentLibrary() {
250
-		if(!is_null($this->documentLibrary)) {
251
-			return $this->documentLibrary;
252
-		}
253
-
254
-		$lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibraryTitle . '\'')->top(1);
255
-		$this->context->load($lists)->executeQuery();
256
-		if ($lists->getCount() === 1 && $lists->getData()[0] instanceof SPList) {
257
-			$this->documentLibrary = $lists->getData()[0];
258
-			return $this->documentLibrary;
259
-		}
260
-
261
-		throw new NotFoundException('List not found');
262
-	}
263
-
264
-	/**
265
-	 * Set up necessary contexts for authentication and access to SharePoint
266
-	 *
267
-	 * @throws \InvalidArgumentException
268
-	 */
269
-	private function ensureConnection() {
270
-		if($this->context instanceof ClientContext) {
271
-			return;
272
-		}
273
-
274
-		if(!is_string($this->credentials['user']) || empty($this->credentials['user'])) {
275
-			throw new \InvalidArgumentException('No user given');
276
-		}
277
-		if(!is_string($this->credentials['password']) || empty($this->credentials['password'])) {
278
-			throw new \InvalidArgumentException('No password given');
279
-		}
280
-		$this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']);
281
-		$this->authContext->AuthType = CURLAUTH_NTLM;		# Basic auth does not work somehow…
282
-		$this->createClientContext();
283
-		# Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand), e.g.:
284
-	}
285
-
286
-	/**
287
-	 * (re)creates the sharepoint client context
288
-	 */
289
-	private function createClientContext() {
290
-		$this->context = null;
291
-		$this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext);
292
-	}
36
+    /** @var  ClientContext */
37
+    protected $context;
38
+
39
+    /** @var  AuthenticationContext */
40
+    protected $authContext;
41
+
42
+    /** @var  SPList */
43
+    protected $documentLibrary;
44
+
45
+    /** @var ContextsFactory */
46
+    private $contextsFactory;
47
+
48
+    /** @var  string */
49
+    private $sharePointUrl;
50
+
51
+    /** @var string[] */
52
+    private $credentials;
53
+
54
+    /** @var  string */
55
+    private $documentLibraryTitle;
56
+
57
+    public function __construct(ContextsFactory $contextsFactory, $sharePointUrl, array $credentials, $documentLibraryTitle) {
58
+        $this->contextsFactory = $contextsFactory;
59
+        $this->sharePointUrl = $sharePointUrl;
60
+        $this->credentials = $credentials;
61
+        $this->documentLibraryTitle = $documentLibraryTitle;
62
+    }
63
+
64
+    /**
65
+     * @param string $path
66
+     * @param array $properties
67
+     * @return File|Folder
68
+     * @throws \Exception
69
+     */
70
+    public function fetchFileOrFolder($path, array $properties = null) {
71
+        $fetchFileFunc = function ($path, $props) { return $this->fetchFile($path, $props);};
72
+        $fetchFolderFunc = function ($path, $props) { return $this->fetchFolder($path, $props);};
73
+        $fetchers = [ $fetchFileFunc, $fetchFolderFunc ];
74
+        if(strpos($path, '.') === false) {
75
+            $fetchers = array_reverse($fetchers);
76
+        }
77
+
78
+        foreach ($fetchers as $fetchFunction) {
79
+            try {
80
+                $instance = call_user_func_array($fetchFunction, [$path, $properties]);
81
+                return $instance;
82
+            } catch (\Exception $e) {
83
+                if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1
84
+                    && $e->getMessage() !== 'Unknown Error'
85
+                    && $e->getMessage() !== 'File Not Found.'
86
+                ) {
87
+                    $this->createClientContext();
88
+                    # Unexpected Exception, pass it on
89
+                    throw $e;
90
+                }
91
+            }
92
+            $this->createClientContext();
93
+        }
94
+
95
+        # Nothing succeeded, quit with not found
96
+        throw new NotFoundException('File or Folder not found');
97
+    }
98
+
99
+    public function fetchFile($relativeServerPath, array $properties = null) {
100
+        $this->ensureConnection();
101
+        $file = $this->context->getWeb()->getFileByServerRelativeUrl($relativeServerPath);
102
+        $this->loadAndExecute($file, $properties);
103
+        return $file;
104
+    }
105
+
106
+    public function fetchFolder($relativeServerPath, array $properties = null) {
107
+        $this->ensureConnection();
108
+        $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
109
+        $this->loadAndExecute($folder, $properties);
110
+        return $folder;
111
+    }
112
+
113
+    /**
114
+     * adds a folder on the given server path
115
+     *
116
+     * @param string $relativeServerPath
117
+     * @return Folder
118
+     * @throws \Exception
119
+     */
120
+    public function createFolder($relativeServerPath) {
121
+        $this->ensureConnection();
122
+
123
+        $serverUrlParts = explode('/', $relativeServerPath);
124
+        $newFolderName = array_pop($serverUrlParts);
125
+        $parentUrl =  implode('/', $serverUrlParts);
126
+
127
+        $parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl($parentUrl);
128
+        $folder = $parentFolder->getFolders()->add($newFolderName);
129
+
130
+        try {
131
+            $this->context->executeQuery();
132
+            return $folder;
133
+        } catch (\Exception $e) {
134
+            $this->createClientContext();
135
+            throw $e;
136
+        }
137
+    }
138
+
139
+    /**
140
+     * downloads a file by passing it directly into a file resource
141
+     *
142
+     * @param $relativeServerPath
143
+     * @param resource $fp a file resource open for writing
144
+     * @return \Office365\PHP\Client\Runtime\OData\ODataPayload
145
+     * @throws \Exception
146
+     */
147
+    public function getFileViaStream($relativeServerPath, $fp) {
148
+        if(!is_resource($fp)) {
149
+            throw new \InvalidArgumentException('file resource expected');
150
+        }
151
+        $relativeServerPath = rawurlencode($relativeServerPath);
152
+        $url = $this->context->getServiceRootUrl() .
153
+            "web/getfilebyserverrelativeurl('$relativeServerPath')/\$value";
154
+        $options = new RequestOptions($url);
155
+        $options->addCurlOption(CURLOPT_FILE, $fp);
156
+
157
+        try {
158
+            $ok = $this->context->executeQueryDirect($options);
159
+        } catch(\Exception $e) {
160
+            $this->createClientContext();
161
+            throw $e;
162
+        }
163
+        return $ok;
164
+    }
165
+
166
+    /**
167
+     * fetches the file content (aka download)
168
+     *
169
+     * @param $relativeServerPath
170
+     * @return string the file content
171
+     */
172
+    public function getFile($relativeServerPath) {
173
+        return File::openBinary($this->context, $relativeServerPath);
174
+    }
175
+
176
+    public function deleteFolder($relativeServerPath, Folder $folder = null) {
177
+        $this->ensureConnection();
178
+
179
+        try {
180
+            if($folder === null) {
181
+                $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
182
+            }
183
+            $folder->deleteObject();
184
+            $this->context->executeQuery();
185
+        } catch (\Exception $e) {
186
+            $this->createClientContext();
187
+            throw $e;
188
+        }
189
+    }
190
+
191
+    /**
192
+     * @param $relativeServerPath
193
+     * @param null $properties
194
+     * @param Folder $folder
195
+     * @return ClientObjectCollection[]
196
+     */
197
+    public function fetchFolderContents($relativeServerPath, $properties = null, Folder $folder = null) {
198
+        $this->ensureConnection();
199
+        if($folder === null) {
200
+            $folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
201
+        }
202
+
203
+        $folderCollection = $folder->getFolders();
204
+        $fileCollection = $folder->getFiles();
205
+        $this->context->load($folderCollection, $properties);
206
+        $this->context->load($fileCollection, $properties);
207
+        $this->context->executeQuery();
208
+
209
+        $collections = ['folders' => $folderCollection, 'files' => $fileCollection];
210
+
211
+        return $collections;
212
+    }
213
+
214
+    public function isHidden(ClientObject $file) {
215
+        // ClientObject itself does not have getListItemAllFields but is
216
+        // the common denominator of File and Folder
217
+        if(!$file instanceof File && !$file instanceof Folder) {
218
+            throw new \InvalidArgumentException('File or Folder expected');
219
+        }
220
+        if($file instanceof File) {
221
+            // it's expensive, we only check folders
222
+            return false;
223
+        }
224
+        $fields = $file->getListItemAllFields();
225
+        if($fields->getProperties() === []) {
226
+            $this->loadAndExecute($fields, ['Id', 'Hidden']);
227
+        }
228
+        $id = $fields->getProperty('Id');
229
+        $hidden = $fields->getProperty('Hidden'); // TODO: get someone to test this in SP 2013
230
+        if($hidden === false || $id !== null) {
231
+            // avoids listing hidden "Forms" folder (and its contents).
232
+            // Have not found a different mechanism to detect whether
233
+            // a file or folder is hidden. There used to be a Hidden
234
+            // field, but seems to have gone (since SP 2016?).
235
+            return false;
236
+        }
237
+        return true;
238
+    }
239
+
240
+    public function loadAndExecute(ClientObject $object, array $properties = null) {
241
+        $this->context->load($object, $properties);
242
+        $this->context->executeQuery();
243
+    }
244
+
245
+    /**
246
+     * @return SPList
247
+     * @throws NotFoundException
248
+     */
249
+    private function getDocumentLibrary() {
250
+        if(!is_null($this->documentLibrary)) {
251
+            return $this->documentLibrary;
252
+        }
253
+
254
+        $lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibraryTitle . '\'')->top(1);
255
+        $this->context->load($lists)->executeQuery();
256
+        if ($lists->getCount() === 1 && $lists->getData()[0] instanceof SPList) {
257
+            $this->documentLibrary = $lists->getData()[0];
258
+            return $this->documentLibrary;
259
+        }
260
+
261
+        throw new NotFoundException('List not found');
262
+    }
263
+
264
+    /**
265
+     * Set up necessary contexts for authentication and access to SharePoint
266
+     *
267
+     * @throws \InvalidArgumentException
268
+     */
269
+    private function ensureConnection() {
270
+        if($this->context instanceof ClientContext) {
271
+            return;
272
+        }
273
+
274
+        if(!is_string($this->credentials['user']) || empty($this->credentials['user'])) {
275
+            throw new \InvalidArgumentException('No user given');
276
+        }
277
+        if(!is_string($this->credentials['password']) || empty($this->credentials['password'])) {
278
+            throw new \InvalidArgumentException('No password given');
279
+        }
280
+        $this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']);
281
+        $this->authContext->AuthType = CURLAUTH_NTLM;		# Basic auth does not work somehow…
282
+        $this->createClientContext();
283
+        # Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand), e.g.:
284
+    }
285
+
286
+    /**
287
+     * (re)creates the sharepoint client context
288
+     */
289
+    private function createClientContext() {
290
+        $this->context = null;
291
+        $this->context = $this->contextsFactory->getClientContext($this->sharePointUrl, $this->authContext);
292
+    }
293 293
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -68,10 +68,10 @@  discard block
 block discarded – undo
68 68
 	 * @throws \Exception
69 69
 	 */
70 70
 	public function fetchFileOrFolder($path, array $properties = null) {
71
-		$fetchFileFunc = function ($path, $props) { return $this->fetchFile($path, $props);};
72
-		$fetchFolderFunc = function ($path, $props) { return $this->fetchFolder($path, $props);};
73
-		$fetchers = [ $fetchFileFunc, $fetchFolderFunc ];
74
-		if(strpos($path, '.') === false) {
71
+		$fetchFileFunc = function($path, $props) { return $this->fetchFile($path, $props); };
72
+		$fetchFolderFunc = function($path, $props) { return $this->fetchFolder($path, $props); };
73
+		$fetchers = [$fetchFileFunc, $fetchFolderFunc];
74
+		if (strpos($path, '.') === false) {
75 75
 			$fetchers = array_reverse($fetchers);
76 76
 		}
77 77
 
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
 				$instance = call_user_func_array($fetchFunction, [$path, $properties]);
81 81
 				return $instance;
82 82
 			} catch (\Exception $e) {
83
-				if(preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1
83
+				if (preg_match('/^The file \/.* does not exist\.$/', $e->getMessage()) !== 1
84 84
 					&& $e->getMessage() !== 'Unknown Error'
85 85
 					&& $e->getMessage() !== 'File Not Found.'
86 86
 				) {
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
 
123 123
 		$serverUrlParts = explode('/', $relativeServerPath);
124 124
 		$newFolderName = array_pop($serverUrlParts);
125
-		$parentUrl =  implode('/', $serverUrlParts);
125
+		$parentUrl = implode('/', $serverUrlParts);
126 126
 
127 127
 		$parentFolder = $this->context->getWeb()->getFolderByServerRelativeUrl($parentUrl);
128 128
 		$folder = $parentFolder->getFolders()->add($newFolderName);
@@ -145,18 +145,18 @@  discard block
 block discarded – undo
145 145
 	 * @throws \Exception
146 146
 	 */
147 147
 	public function getFileViaStream($relativeServerPath, $fp) {
148
-		if(!is_resource($fp)) {
148
+		if (!is_resource($fp)) {
149 149
 			throw new \InvalidArgumentException('file resource expected');
150 150
 		}
151 151
 		$relativeServerPath = rawurlencode($relativeServerPath);
152
-		$url = $this->context->getServiceRootUrl() .
152
+		$url = $this->context->getServiceRootUrl().
153 153
 			"web/getfilebyserverrelativeurl('$relativeServerPath')/\$value";
154 154
 		$options = new RequestOptions($url);
155 155
 		$options->addCurlOption(CURLOPT_FILE, $fp);
156 156
 
157 157
 		try {
158 158
 			$ok = $this->context->executeQueryDirect($options);
159
-		} catch(\Exception $e) {
159
+		} catch (\Exception $e) {
160 160
 			$this->createClientContext();
161 161
 			throw $e;
162 162
 		}
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
 		$this->ensureConnection();
178 178
 
179 179
 		try {
180
-			if($folder === null) {
180
+			if ($folder === null) {
181 181
 				$folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
182 182
 			}
183 183
 			$folder->deleteObject();
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
 	 */
197 197
 	public function fetchFolderContents($relativeServerPath, $properties = null, Folder $folder = null) {
198 198
 		$this->ensureConnection();
199
-		if($folder === null) {
199
+		if ($folder === null) {
200 200
 			$folder = $this->context->getWeb()->getFolderByServerRelativeUrl($relativeServerPath);
201 201
 		}
202 202
 
@@ -214,20 +214,20 @@  discard block
 block discarded – undo
214 214
 	public function isHidden(ClientObject $file) {
215 215
 		// ClientObject itself does not have getListItemAllFields but is
216 216
 		// the common denominator of File and Folder
217
-		if(!$file instanceof File && !$file instanceof Folder) {
217
+		if (!$file instanceof File && !$file instanceof Folder) {
218 218
 			throw new \InvalidArgumentException('File or Folder expected');
219 219
 		}
220
-		if($file instanceof File) {
220
+		if ($file instanceof File) {
221 221
 			// it's expensive, we only check folders
222 222
 			return false;
223 223
 		}
224 224
 		$fields = $file->getListItemAllFields();
225
-		if($fields->getProperties() === []) {
225
+		if ($fields->getProperties() === []) {
226 226
 			$this->loadAndExecute($fields, ['Id', 'Hidden']);
227 227
 		}
228 228
 		$id = $fields->getProperty('Id');
229 229
 		$hidden = $fields->getProperty('Hidden'); // TODO: get someone to test this in SP 2013
230
-		if($hidden === false || $id !== null) {
230
+		if ($hidden === false || $id !== null) {
231 231
 			// avoids listing hidden "Forms" folder (and its contents).
232 232
 			// Have not found a different mechanism to detect whether
233 233
 			// a file or folder is hidden. There used to be a Hidden
@@ -247,11 +247,11 @@  discard block
 block discarded – undo
247 247
 	 * @throws NotFoundException
248 248
 	 */
249 249
 	private function getDocumentLibrary() {
250
-		if(!is_null($this->documentLibrary)) {
250
+		if (!is_null($this->documentLibrary)) {
251 251
 			return $this->documentLibrary;
252 252
 		}
253 253
 
254
-		$lists = $this->context->getWeb()->getLists()->filter('Title eq \'' . $this->documentLibraryTitle . '\'')->top(1);
254
+		$lists = $this->context->getWeb()->getLists()->filter('Title eq \''.$this->documentLibraryTitle.'\'')->top(1);
255 255
 		$this->context->load($lists)->executeQuery();
256 256
 		if ($lists->getCount() === 1 && $lists->getData()[0] instanceof SPList) {
257 257
 			$this->documentLibrary = $lists->getData()[0];
@@ -267,18 +267,18 @@  discard block
 block discarded – undo
267 267
 	 * @throws \InvalidArgumentException
268 268
 	 */
269 269
 	private function ensureConnection() {
270
-		if($this->context instanceof ClientContext) {
270
+		if ($this->context instanceof ClientContext) {
271 271
 			return;
272 272
 		}
273 273
 
274
-		if(!is_string($this->credentials['user']) || empty($this->credentials['user'])) {
274
+		if (!is_string($this->credentials['user']) || empty($this->credentials['user'])) {
275 275
 			throw new \InvalidArgumentException('No user given');
276 276
 		}
277
-		if(!is_string($this->credentials['password']) || empty($this->credentials['password'])) {
277
+		if (!is_string($this->credentials['password']) || empty($this->credentials['password'])) {
278 278
 			throw new \InvalidArgumentException('No password given');
279 279
 		}
280 280
 		$this->authContext = $this->contextsFactory->getAuthContext($this->credentials['user'], $this->credentials['password']);
281
-		$this->authContext->AuthType = CURLAUTH_NTLM;		# Basic auth does not work somehow…
281
+		$this->authContext->AuthType = CURLAUTH_NTLM; # Basic auth does not work somehow…
282 282
 		$this->createClientContext();
283 283
 		# Auth is not triggered yet. This will happen when something is requested from SharePoint (on demand), e.g.:
284 284
 	}
Please login to merge, or discard this patch.