Completed
Push — master ( 7a2d81...3eba37 )
by Morris
22:43 queued 10:29
created

SMB::rmdir()   C

Complexity

Conditions 7
Paths 27

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 19
nc 27
nop 1
dl 0
loc 25
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Jesús Macias <[email protected]>
7
 * @author Jörn Friedrich Dreyer <[email protected]>
8
 * @author Michael Gapczynski <[email protected]>
9
 * @author Morris Jobke <[email protected]>
10
 * @author Philipp Kapfer <[email protected]>
11
 * @author Robin Appelman <[email protected]>
12
 * @author Robin McCorkell <[email protected]>
13
 * @author Thomas Müller <[email protected]>
14
 * @author Vincent Petry <[email protected]>
15
 *
16
 * @license AGPL-3.0
17
 *
18
 * This code is free software: you can redistribute it and/or modify
19
 * it under the terms of the GNU Affero General Public License, version 3,
20
 * as published by the Free Software Foundation.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
 * GNU Affero General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU Affero General Public License, version 3,
28
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
29
 *
30
 */
31
32
namespace OCA\Files_External\Lib\Storage;
33
34
use Icewind\SMB\Exception\AlreadyExistsException;
35
use Icewind\SMB\Exception\ConnectException;
36
use Icewind\SMB\Exception\Exception;
37
use Icewind\SMB\Exception\ForbiddenException;
38
use Icewind\SMB\Exception\NotFoundException;
39
use Icewind\SMB\IFileInfo;
40
use Icewind\SMB\NativeServer;
41
use Icewind\SMB\Server;
42
use Icewind\Streams\CallbackWrapper;
43
use Icewind\Streams\IteratorDirectory;
44
use OC\Cache\CappedMemoryCache;
45
use OC\Files\Filesystem;
46
use OC\Files\Storage\Common;
47
use OCA\Files_External\Lib\Notify\SMBNotifyHandler;
48
use OCP\Files\Notify\IChange;
49
use OCP\Files\Notify\IRenameChange;
50
use OCP\Files\Storage\INotifyStorage;
51
use OCP\Files\StorageNotAvailableException;
52
53
class SMB extends Common implements INotifyStorage {
54
	/**
55
	 * @var \Icewind\SMB\Server
56
	 */
57
	protected $server;
58
59
	/**
60
	 * @var \Icewind\SMB\Share
61
	 */
62
	protected $share;
63
64
	/**
65
	 * @var string
66
	 */
67
	protected $root;
68
69
	/**
70
	 * @var \Icewind\SMB\FileInfo[]
71
	 */
72
	protected $statCache;
73
74
	public function __construct($params) {
75
		if (isset($params['host']) && isset($params['user']) && isset($params['password']) && isset($params['share'])) {
76
			if (Server::NativeAvailable()) {
77
				$this->server = new NativeServer($params['host'], $params['user'], $params['password']);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Icewind\SMB\NativeS...], $params['password']) of type object<Icewind\SMB\NativeServer> is incompatible with the declared type object<Icewind\SMB\Server> of property $server.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
78
			} else {
79
				$this->server = new Server($params['host'], $params['user'], $params['password']);
80
			}
81
			$this->share = $this->server->getShare(trim($params['share'], '/'));
82
83
			$this->root = isset($params['root']) ? $params['root'] : '/';
84 View Code Duplication
			if (!$this->root || $this->root[0] != '/') {
85
				$this->root = '/' . $this->root;
86
			}
87
			if (substr($this->root, -1, 1) != '/') {
88
				$this->root .= '/';
89
			}
90
		} else {
91
			throw new \Exception('Invalid configuration');
92
		}
93
		$this->statCache = new CappedMemoryCache();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \OC\Cache\CappedMemoryCache() of type object<OC\Cache\CappedMemoryCache> is incompatible with the declared type array<integer,object<Icewind\SMB\FileInfo>> of property $statCache.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
94
		parent::__construct($params);
95
	}
96
97
	/**
98
	 * @return string
99
	 */
100
	public function getId() {
101
		// FIXME: double slash to keep compatible with the old storage ids,
102
		// failure to do so will lead to creation of a new storage id and
103
		// loss of shares from the storage
104
		return 'smb::' . $this->server->getUser() . '@' . $this->server->getHost() . '//' . $this->share->getName() . '/' . $this->root;
105
	}
106
107
	/**
108
	 * @param string $path
109
	 * @return string
110
	 */
111
	protected function buildPath($path) {
112
		return Filesystem::normalizePath($this->root . '/' . $path, true, false, true);
113
	}
114
115 View Code Duplication
	protected function relativePath($fullPath) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
116
		if ($fullPath === $this->root) {
117
			return '';
118
		} else if (substr($fullPath, 0, strlen($this->root)) === $this->root) {
119
			return substr($fullPath, strlen($this->root));
120
		} else {
121
			return null;
122
		}
123
	}
124
125
	/**
126
	 * @param string $path
127
	 * @return \Icewind\SMB\IFileInfo
128
	 * @throws StorageNotAvailableException
129
	 */
130
	protected function getFileInfo($path) {
131
		try {
132
			$path = $this->buildPath($path);
133
			if (!isset($this->statCache[$path])) {
134
				$this->statCache[$path] = $this->share->stat($path);
135
			}
136
			return $this->statCache[$path];
137
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
138
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
139
		}
140
	}
141
142
	/**
143
	 * @param string $path
144
	 * @return \Icewind\SMB\IFileInfo[]
145
	 * @throws StorageNotAvailableException
146
	 */
147
	protected function getFolderContents($path) {
148
		try {
149
			$path = $this->buildPath($path);
150
			$files = $this->share->dir($path);
151
			foreach ($files as $file) {
152
				$this->statCache[$path . '/' . $file->getName()] = $file;
153
			}
154
			return array_filter($files, function (IFileInfo $file) {
155
				return !$file->isHidden();
156
			});
157
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
158
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
159
		}
160
	}
161
162
	/**
163
	 * @param \Icewind\SMB\IFileInfo $info
164
	 * @return array
165
	 */
166
	protected function formatInfo($info) {
167
		$result = [
168
			'size' => $info->getSize(),
169
			'mtime' => $info->getMTime(),
170
		];
171
		if ($info->isDirectory()) {
172
			$result['type'] = 'dir';
173
		} else {
174
			$result['type'] = 'file';
175
		}
176
		return $result;
177
	}
178
179
	/**
180
	 * Rename the files. If the source or the target is the root, the rename won't happen.
181
	 *
182
	 * @param string $source the old name of the path
183
	 * @param string $target the new name of the path
184
	 * @return bool true if the rename is successful, false otherwise
185
	 */
186
	public function rename($source, $target) {
187
		if ($this->isRootDir($source) || $this->isRootDir($target)) {
188
			return false;
189
		}
190
191
		$absoluteSource = $this->buildPath($source);
192
		$absoluteTarget = $this->buildPath($target);
193
		try {
194
			$result = $this->share->rename($absoluteSource, $absoluteTarget);
195
		} catch (AlreadyExistsException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\AlreadyExistsException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
196
			$this->remove($target);
197
			$result = $this->share->rename($absoluteSource, $absoluteTarget);
198
		} catch (\Exception $e) {
199
			return false;
200
		}
201
		unset($this->statCache[$absoluteSource], $this->statCache[$absoluteTarget]);
202
		return $result;
203
	}
204
205
	/**
206
	 * @param string $path
207
	 * @return array
208
	 */
209
	public function stat($path) {
210
		$result = $this->formatInfo($this->getFileInfo($path));
211
		if ($this->remoteIsShare() && $this->isRootDir($path)) {
212
			$result['mtime'] = $this->shareMTime();
213
		}
214
		return $result;
215
	}
216
217
	/**
218
	 * get the best guess for the modification time of the share
219
	 *
220
	 * @return int
221
	 */
222
	private function shareMTime() {
223
		$highestMTime = 0;
224
		$files = $this->share->dir($this->root);
225
		foreach ($files as $fileInfo) {
226
			if ($fileInfo->getMTime() > $highestMTime) {
227
				$highestMTime = $fileInfo->getMTime();
228
			}
229
		}
230
		return $highestMTime;
231
	}
232
233
	/**
234
	 * Check if the path is our root dir (not the smb one)
235
	 *
236
	 * @param string $path the path
237
	 * @return bool
238
	 */
239
	private function isRootDir($path) {
240
		return $path === '' || $path === '/' || $path === '.';
241
	}
242
243
	/**
244
	 * Check if our root points to a smb share
245
	 *
246
	 * @return bool true if our root points to a share false otherwise
247
	 */
248
	private function remoteIsShare() {
249
		return $this->share->getName() && (!$this->root || $this->root === '/');
250
	}
251
252
	/**
253
	 * @param string $path
254
	 * @return bool
255
	 */
256
	public function unlink($path) {
257
		if ($this->isRootDir($path)) {
258
			return false;
259
		}
260
261
		try {
262
			if ($this->is_dir($path)) {
263
				return $this->rmdir($path);
264
			} else {
265
				$path = $this->buildPath($path);
266
				unset($this->statCache[$path]);
267
				$this->share->del($path);
268
				return true;
269
			}
270
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
271
			return false;
272
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
273
			return false;
274
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
275
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
276
		}
277
	}
278
279
	/**
280
	 * check if a file or folder has been updated since $time
281
	 *
282
	 * @param string $path
283
	 * @param int $time
284
	 * @return bool
285
	 */
286
	public function hasUpdated($path, $time) {
287
		if (!$path and $this->root === '/') {
288
			// mtime doesn't work for shares, but giving the nature of the backend,
289
			// doing a full update is still just fast enough
290
			return true;
291
		} else {
292
			$actualTime = $this->filemtime($path);
293
			return $actualTime > $time;
294
		}
295
	}
296
297
	/**
298
	 * @param string $path
299
	 * @param string $mode
300
	 * @return resource|false
301
	 */
302
	public function fopen($path, $mode) {
303
		$fullPath = $this->buildPath($path);
304
		try {
305
			switch ($mode) {
306
				case 'r':
307
				case 'rb':
308
					if (!$this->file_exists($path)) {
309
						return false;
310
					}
311
					return $this->share->read($fullPath);
312
				case 'w':
313
				case 'wb':
314
					$source = $this->share->write($fullPath);
315
					return CallBackWrapper::wrap($source, null, null, function () use ($fullPath) {
316
						unset($this->statCache[$fullPath]);
317
					});
318
				case 'a':
319
				case 'ab':
320
				case 'r+':
321
				case 'w+':
322
				case 'wb+':
323
				case 'a+':
324
				case 'x':
325
				case 'x+':
326
				case 'c':
327
				case 'c+':
328
					//emulate these
329
					if (strrpos($path, '.') !== false) {
330
						$ext = substr($path, strrpos($path, '.'));
331
					} else {
332
						$ext = '';
333
					}
334 View Code Duplication
					if ($this->file_exists($path)) {
335
						if (!$this->isUpdatable($path)) {
336
							return false;
337
						}
338
						$tmpFile = $this->getCachedFile($path);
339
					} else {
340
						if (!$this->isCreatable(dirname($path))) {
341
							return false;
342
						}
343
						$tmpFile = \OCP\Files::tmpFile($ext);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\Files::tmpFile() has been deprecated with message: 8.1.0 use getTemporaryFile() of \OCP\ITempManager - \OC::$server->getTempManager()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
344
					}
345
					$source = fopen($tmpFile, $mode);
346
					$share = $this->share;
347
					return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $fullPath, $share) {
348
						unset($this->statCache[$fullPath]);
349
						$share->put($tmpFile, $fullPath);
350
						unlink($tmpFile);
351
					});
352
			}
353
			return false;
354
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
355
			return false;
356
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
357
			return false;
358
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
359
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
360
		}
361
	}
362
363
	public function rmdir($path) {
364
		if ($this->isRootDir($path)) {
365
			return false;
366
		}
367
368
		try {
369
			$this->statCache = array();
370
			$content = $this->share->dir($this->buildPath($path));
371
			foreach ($content as $file) {
372
				if ($file->isDirectory()) {
373
					$this->rmdir($path . '/' . $file->getName());
374
				} else {
375
					$this->share->del($file->getPath());
376
				}
377
			}
378
			$this->share->rmdir($this->buildPath($path));
379
			return true;
380
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
381
			return false;
382
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
383
			return false;
384
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
385
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
386
		}
387
	}
388
389 View Code Duplication
	public function touch($path, $time = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
390
		try {
391
			if (!$this->file_exists($path)) {
392
				$fh = $this->share->write($this->buildPath($path));
393
				fclose($fh);
394
				return true;
395
			}
396
			return false;
397
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
398
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
399
		}
400
	}
401
402
	public function opendir($path) {
403
		try {
404
			$files = $this->getFolderContents($path);
405
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
406
			return false;
407
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
408
			return false;
409
		}
410
		$names = array_map(function ($info) {
411
			/** @var \Icewind\SMB\IFileInfo $info */
412
			return $info->getName();
413
		}, $files);
414
		return IteratorDirectory::wrap($names);
415
	}
416
417
	public function filetype($path) {
418
		try {
419
			return $this->getFileInfo($path)->isDirectory() ? 'dir' : 'file';
420
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
421
			return false;
422
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
423
			return false;
424
		}
425
	}
426
427 View Code Duplication
	public function mkdir($path) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
428
		$path = $this->buildPath($path);
429
		try {
430
			$this->share->mkdir($path);
431
			return true;
432
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
433
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
434
		} catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
435
			return false;
436
		}
437
	}
438
439
	public function file_exists($path) {
440
		try {
441
			$this->getFileInfo($path);
442
			return true;
443
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
444
			return false;
445
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
446
			return false;
447
		} catch (ConnectException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ConnectException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
448
			throw new StorageNotAvailableException($e->getMessage(), $e->getCode(), $e);
449
		}
450
	}
451
452 View Code Duplication
	public function isReadable($path) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
453
		try {
454
			$info = $this->getFileInfo($path);
455
			return !$info->isHidden();
456
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
457
			return false;
458
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
459
			return false;
460
		}
461
	}
462
463 View Code Duplication
	public function isUpdatable($path) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
464
		try {
465
			$info = $this->getFileInfo($path);
466
			// following windows behaviour for read-only folders: they can be written into
467
			// (https://support.microsoft.com/en-us/kb/326549 - "cause" section)
468
			return !$info->isHidden() && (!$info->isReadOnly() || $this->is_dir($path));
469
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
470
			return false;
471
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
472
			return false;
473
		}
474
	}
475
476 View Code Duplication
	public function isDeletable($path) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
477
		try {
478
			$info = $this->getFileInfo($path);
479
			return !$info->isHidden() && !$info->isReadOnly();
480
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
481
			return false;
482
		} catch (ForbiddenException $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\ForbiddenException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
483
			return false;
484
		}
485
	}
486
487
	/**
488
	 * check if smbclient is installed
489
	 */
490
	public static function checkDependencies() {
491
		return (
492
			(bool)\OC_Helper::findBinaryPath('smbclient')
493
			|| Server::NativeAvailable()
494
		) ? true : ['smbclient'];
495
	}
496
497
	/**
498
	 * Test a storage for availability
499
	 *
500
	 * @return bool
501
	 */
502
	public function test() {
503
		try {
504
			return parent::test();
505
		} catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class Icewind\SMB\Exception\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
506
			return false;
507
		}
508
	}
509
510
	public function listen($path, callable $callback) {
511
		$this->notify($path)->listen(function (IChange $change) use ($callback) {
512
			if ($change instanceof IRenameChange) {
513
				return $callback($change->getType(), $change->getPath(), $change->getTargetPath());
514
			} else {
515
				return $callback($change->getType(), $change->getPath());
516
			}
517
		});
518
	}
519
520
	public function notify($path) {
521
		$path = '/' . ltrim($path, '/');
522
		$shareNotifyHandler = $this->share->notify($this->buildPath($path));
523
		return new SMBNotifyHandler($shareNotifyHandler, $this->root);
524
	}
525
}
526