Passed
Push — master ( 405b5d...06340b )
by Julius
15:58 queued 12s
created
lib/private/Files/Node/Node.php 1 patch
Indentation   +426 added lines, -426 removed lines patch added patch discarded remove patch
@@ -41,430 +41,430 @@
 block discarded – undo
41 41
 
42 42
 // FIXME: this class really should be abstract
43 43
 class Node implements \OCP\Files\Node {
44
-	/**
45
-	 * @var \OC\Files\View $view
46
-	 */
47
-	protected $view;
48
-
49
-	/**
50
-	 * @var \OC\Files\Node\Root $root
51
-	 */
52
-	protected $root;
53
-
54
-	/**
55
-	 * @var string $path
56
-	 */
57
-	protected $path;
58
-
59
-	/**
60
-	 * @var \OCP\Files\FileInfo
61
-	 */
62
-	protected $fileInfo;
63
-
64
-	/**
65
-	 * @var Node|null
66
-	 */
67
-	protected $parent;
68
-
69
-	/**
70
-	 * @param \OC\Files\View $view
71
-	 * @param \OCP\Files\IRootFolder $root
72
-	 * @param string $path
73
-	 * @param FileInfo $fileInfo
74
-	 */
75
-	public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null) {
76
-		$this->view = $view;
77
-		$this->root = $root;
78
-		$this->path = $path;
79
-		$this->fileInfo = $fileInfo;
80
-		$this->parent = $parent;
81
-	}
82
-
83
-	/**
84
-	 * Creates a Node of the same type that represents a non-existing path
85
-	 *
86
-	 * @param string $path path
87
-	 * @return string non-existing node class
88
-	 * @throws \Exception
89
-	 */
90
-	protected function createNonExistingNode($path) {
91
-		throw new \Exception('Must be implemented by subclasses');
92
-	}
93
-
94
-	/**
95
-	 * Returns the matching file info
96
-	 *
97
-	 * @return FileInfo
98
-	 * @throws InvalidPathException
99
-	 * @throws NotFoundException
100
-	 */
101
-	public function getFileInfo() {
102
-		if (!Filesystem::isValidPath($this->path)) {
103
-			throw new InvalidPathException();
104
-		}
105
-		if (!$this->fileInfo) {
106
-			$fileInfo = $this->view->getFileInfo($this->path);
107
-			if ($fileInfo instanceof FileInfo) {
108
-				$this->fileInfo = $fileInfo;
109
-			} else {
110
-				throw new NotFoundException();
111
-			}
112
-		}
113
-		return $this->fileInfo;
114
-	}
115
-
116
-	/**
117
-	 * @param string[] $hooks
118
-	 */
119
-	protected function sendHooks($hooks, array $args = null) {
120
-		$args = !empty($args) ? $args : [$this];
121
-		$dispatcher = \OC::$server->getEventDispatcher();
122
-		foreach ($hooks as $hook) {
123
-			$this->root->emit('\OC\Files', $hook, $args);
124
-			$dispatcher->dispatch('\OCP\Files::' . $hook, new GenericEvent($args));
125
-		}
126
-	}
127
-
128
-	/**
129
-	 * @param int $permissions
130
-	 * @return bool
131
-	 * @throws InvalidPathException
132
-	 * @throws NotFoundException
133
-	 */
134
-	protected function checkPermissions($permissions) {
135
-		return ($this->getPermissions() & $permissions) === $permissions;
136
-	}
137
-
138
-	public function delete() {
139
-	}
140
-
141
-	/**
142
-	 * @param int $mtime
143
-	 * @throws InvalidPathException
144
-	 * @throws NotFoundException
145
-	 * @throws NotPermittedException
146
-	 */
147
-	public function touch($mtime = null) {
148
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
149
-			$this->sendHooks(['preTouch']);
150
-			$this->view->touch($this->path, $mtime);
151
-			$this->sendHooks(['postTouch']);
152
-			if ($this->fileInfo) {
153
-				if (is_null($mtime)) {
154
-					$mtime = time();
155
-				}
156
-				$this->fileInfo['mtime'] = $mtime;
157
-			}
158
-		} else {
159
-			throw new NotPermittedException();
160
-		}
161
-	}
162
-
163
-	public function getStorage() {
164
-		$storage = $this->getMountPoint()->getStorage();
165
-		if (!$storage) {
166
-			throw new \Exception("No storage for node");
167
-		}
168
-		return $storage;
169
-	}
170
-
171
-	/**
172
-	 * @return string
173
-	 */
174
-	public function getPath() {
175
-		return $this->path;
176
-	}
177
-
178
-	/**
179
-	 * @return string
180
-	 */
181
-	public function getInternalPath() {
182
-		return $this->getFileInfo()->getInternalPath();
183
-	}
184
-
185
-	/**
186
-	 * @return int
187
-	 * @throws InvalidPathException
188
-	 * @throws NotFoundException
189
-	 */
190
-	public function getId() {
191
-		return $this->getFileInfo()->getId();
192
-	}
193
-
194
-	/**
195
-	 * @return array
196
-	 */
197
-	public function stat() {
198
-		return $this->view->stat($this->path);
199
-	}
200
-
201
-	/**
202
-	 * @return int
203
-	 * @throws InvalidPathException
204
-	 * @throws NotFoundException
205
-	 */
206
-	public function getMTime() {
207
-		return $this->getFileInfo()->getMTime();
208
-	}
209
-
210
-	/**
211
-	 * @param bool $includeMounts
212
-	 * @return int
213
-	 * @throws InvalidPathException
214
-	 * @throws NotFoundException
215
-	 */
216
-	public function getSize($includeMounts = true) {
217
-		return $this->getFileInfo()->getSize($includeMounts);
218
-	}
219
-
220
-	/**
221
-	 * @return string
222
-	 * @throws InvalidPathException
223
-	 * @throws NotFoundException
224
-	 */
225
-	public function getEtag() {
226
-		return $this->getFileInfo()->getEtag();
227
-	}
228
-
229
-	/**
230
-	 * @return int
231
-	 * @throws InvalidPathException
232
-	 * @throws NotFoundException
233
-	 */
234
-	public function getPermissions() {
235
-		return $this->getFileInfo()->getPermissions();
236
-	}
237
-
238
-	/**
239
-	 * @return bool
240
-	 * @throws InvalidPathException
241
-	 * @throws NotFoundException
242
-	 */
243
-	public function isReadable() {
244
-		return $this->getFileInfo()->isReadable();
245
-	}
246
-
247
-	/**
248
-	 * @return bool
249
-	 * @throws InvalidPathException
250
-	 * @throws NotFoundException
251
-	 */
252
-	public function isUpdateable() {
253
-		return $this->getFileInfo()->isUpdateable();
254
-	}
255
-
256
-	/**
257
-	 * @return bool
258
-	 * @throws InvalidPathException
259
-	 * @throws NotFoundException
260
-	 */
261
-	public function isDeletable() {
262
-		return $this->getFileInfo()->isDeletable();
263
-	}
264
-
265
-	/**
266
-	 * @return bool
267
-	 * @throws InvalidPathException
268
-	 * @throws NotFoundException
269
-	 */
270
-	public function isShareable() {
271
-		return $this->getFileInfo()->isShareable();
272
-	}
273
-
274
-	/**
275
-	 * @return bool
276
-	 * @throws InvalidPathException
277
-	 * @throws NotFoundException
278
-	 */
279
-	public function isCreatable() {
280
-		return $this->getFileInfo()->isCreatable();
281
-	}
282
-
283
-	/**
284
-	 * @return Node
285
-	 */
286
-	public function getParent() {
287
-		if ($this->parent === null) {
288
-			$newPath = dirname($this->path);
289
-			if ($newPath === '' || $newPath === '.' || $newPath === '/') {
290
-				return $this->root;
291
-			}
292
-
293
-			$this->parent = $this->root->get($newPath);
294
-		}
295
-
296
-		return $this->parent;
297
-	}
298
-
299
-	/**
300
-	 * @return string
301
-	 */
302
-	public function getName() {
303
-		return basename($this->path);
304
-	}
305
-
306
-	/**
307
-	 * @param string $path
308
-	 * @return string
309
-	 */
310
-	protected function normalizePath($path) {
311
-		return PathHelper::normalizePath($path);
312
-	}
313
-
314
-	/**
315
-	 * check if the requested path is valid
316
-	 *
317
-	 * @param string $path
318
-	 * @return bool
319
-	 */
320
-	public function isValidPath($path) {
321
-		if (!$path || $path[0] !== '/') {
322
-			$path = '/' . $path;
323
-		}
324
-		if (strstr($path, '/../') || strrchr($path, '/') === '/..') {
325
-			return false;
326
-		}
327
-		return true;
328
-	}
329
-
330
-	public function isMounted() {
331
-		return $this->getFileInfo()->isMounted();
332
-	}
333
-
334
-	public function isShared() {
335
-		return $this->getFileInfo()->isShared();
336
-	}
337
-
338
-	public function getMimeType() {
339
-		return $this->getFileInfo()->getMimetype();
340
-	}
341
-
342
-	public function getMimePart() {
343
-		return $this->getFileInfo()->getMimePart();
344
-	}
345
-
346
-	public function getType() {
347
-		return $this->getFileInfo()->getType();
348
-	}
349
-
350
-	public function isEncrypted() {
351
-		return $this->getFileInfo()->isEncrypted();
352
-	}
353
-
354
-	public function getMountPoint() {
355
-		return $this->getFileInfo()->getMountPoint();
356
-	}
357
-
358
-	public function getOwner() {
359
-		return $this->getFileInfo()->getOwner();
360
-	}
361
-
362
-	public function getChecksum() {
363
-	}
364
-
365
-	public function getExtension(): string {
366
-		return $this->getFileInfo()->getExtension();
367
-	}
368
-
369
-	/**
370
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
371
-	 * @throws LockedException
372
-	 */
373
-	public function lock($type) {
374
-		$this->view->lockFile($this->path, $type);
375
-	}
376
-
377
-	/**
378
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
379
-	 * @throws LockedException
380
-	 */
381
-	public function changeLock($type) {
382
-		$this->view->changeLock($this->path, $type);
383
-	}
384
-
385
-	/**
386
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
387
-	 * @throws LockedException
388
-	 */
389
-	public function unlock($type) {
390
-		$this->view->unlockFile($this->path, $type);
391
-	}
392
-
393
-	/**
394
-	 * @param string $targetPath
395
-	 * @return \OC\Files\Node\Node
396
-	 * @throws InvalidPathException
397
-	 * @throws NotFoundException
398
-	 * @throws NotPermittedException if copy not allowed or failed
399
-	 */
400
-	public function copy($targetPath) {
401
-		$targetPath = $this->normalizePath($targetPath);
402
-		$parent = $this->root->get(dirname($targetPath));
403
-		if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
404
-			$nonExisting = $this->createNonExistingNode($targetPath);
405
-			$this->sendHooks(['preCopy'], [$this, $nonExisting]);
406
-			$this->sendHooks(['preWrite'], [$nonExisting]);
407
-			if (!$this->view->copy($this->path, $targetPath)) {
408
-				throw new NotPermittedException('Could not copy ' . $this->path . ' to ' . $targetPath);
409
-			}
410
-			$targetNode = $this->root->get($targetPath);
411
-			$this->sendHooks(['postCopy'], [$this, $targetNode]);
412
-			$this->sendHooks(['postWrite'], [$targetNode]);
413
-			return $targetNode;
414
-		} else {
415
-			throw new NotPermittedException('No permission to copy to path ' . $targetPath);
416
-		}
417
-	}
418
-
419
-	/**
420
-	 * @param string $targetPath
421
-	 * @return \OC\Files\Node\Node
422
-	 * @throws InvalidPathException
423
-	 * @throws NotFoundException
424
-	 * @throws NotPermittedException if move not allowed or failed
425
-	 * @throws LockedException
426
-	 */
427
-	public function move($targetPath) {
428
-		$targetPath = $this->normalizePath($targetPath);
429
-		$parent = $this->root->get(dirname($targetPath));
430
-		if (
431
-			$parent instanceof Folder and
432
-			$this->isValidPath($targetPath) and
433
-			(
434
-				$parent->isCreatable() ||
435
-				($parent->getInternalPath() === '' && $parent->getMountPoint() instanceof MoveableMount)
436
-			)
437
-		) {
438
-			$nonExisting = $this->createNonExistingNode($targetPath);
439
-			$this->sendHooks(['preRename'], [$this, $nonExisting]);
440
-			$this->sendHooks(['preWrite'], [$nonExisting]);
441
-			if (!$this->view->rename($this->path, $targetPath)) {
442
-				throw new NotPermittedException('Could not move ' . $this->path . ' to ' . $targetPath);
443
-			}
444
-
445
-			$mountPoint = $this->getMountPoint();
446
-			if ($mountPoint) {
447
-				// update the cached fileinfo with the new (internal) path
448
-				/** @var \OC\Files\FileInfo $oldFileInfo */
449
-				$oldFileInfo = $this->getFileInfo();
450
-				$this->fileInfo = new \OC\Files\FileInfo($targetPath, $oldFileInfo->getStorage(), $mountPoint->getInternalPath($targetPath), $oldFileInfo->getData(), $mountPoint, $oldFileInfo->getOwner());
451
-			}
452
-
453
-			$targetNode = $this->root->get($targetPath);
454
-			$this->sendHooks(['postRename'], [$this, $targetNode]);
455
-			$this->sendHooks(['postWrite'], [$targetNode]);
456
-			$this->path = $targetPath;
457
-			return $targetNode;
458
-		} else {
459
-			throw new NotPermittedException('No permission to move to path ' . $targetPath);
460
-		}
461
-	}
462
-
463
-	public function getCreationTime(): int {
464
-		return $this->getFileInfo()->getCreationTime();
465
-	}
466
-
467
-	public function getUploadTime(): int {
468
-		return $this->getFileInfo()->getUploadTime();
469
-	}
44
+    /**
45
+     * @var \OC\Files\View $view
46
+     */
47
+    protected $view;
48
+
49
+    /**
50
+     * @var \OC\Files\Node\Root $root
51
+     */
52
+    protected $root;
53
+
54
+    /**
55
+     * @var string $path
56
+     */
57
+    protected $path;
58
+
59
+    /**
60
+     * @var \OCP\Files\FileInfo
61
+     */
62
+    protected $fileInfo;
63
+
64
+    /**
65
+     * @var Node|null
66
+     */
67
+    protected $parent;
68
+
69
+    /**
70
+     * @param \OC\Files\View $view
71
+     * @param \OCP\Files\IRootFolder $root
72
+     * @param string $path
73
+     * @param FileInfo $fileInfo
74
+     */
75
+    public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null) {
76
+        $this->view = $view;
77
+        $this->root = $root;
78
+        $this->path = $path;
79
+        $this->fileInfo = $fileInfo;
80
+        $this->parent = $parent;
81
+    }
82
+
83
+    /**
84
+     * Creates a Node of the same type that represents a non-existing path
85
+     *
86
+     * @param string $path path
87
+     * @return string non-existing node class
88
+     * @throws \Exception
89
+     */
90
+    protected function createNonExistingNode($path) {
91
+        throw new \Exception('Must be implemented by subclasses');
92
+    }
93
+
94
+    /**
95
+     * Returns the matching file info
96
+     *
97
+     * @return FileInfo
98
+     * @throws InvalidPathException
99
+     * @throws NotFoundException
100
+     */
101
+    public function getFileInfo() {
102
+        if (!Filesystem::isValidPath($this->path)) {
103
+            throw new InvalidPathException();
104
+        }
105
+        if (!$this->fileInfo) {
106
+            $fileInfo = $this->view->getFileInfo($this->path);
107
+            if ($fileInfo instanceof FileInfo) {
108
+                $this->fileInfo = $fileInfo;
109
+            } else {
110
+                throw new NotFoundException();
111
+            }
112
+        }
113
+        return $this->fileInfo;
114
+    }
115
+
116
+    /**
117
+     * @param string[] $hooks
118
+     */
119
+    protected function sendHooks($hooks, array $args = null) {
120
+        $args = !empty($args) ? $args : [$this];
121
+        $dispatcher = \OC::$server->getEventDispatcher();
122
+        foreach ($hooks as $hook) {
123
+            $this->root->emit('\OC\Files', $hook, $args);
124
+            $dispatcher->dispatch('\OCP\Files::' . $hook, new GenericEvent($args));
125
+        }
126
+    }
127
+
128
+    /**
129
+     * @param int $permissions
130
+     * @return bool
131
+     * @throws InvalidPathException
132
+     * @throws NotFoundException
133
+     */
134
+    protected function checkPermissions($permissions) {
135
+        return ($this->getPermissions() & $permissions) === $permissions;
136
+    }
137
+
138
+    public function delete() {
139
+    }
140
+
141
+    /**
142
+     * @param int $mtime
143
+     * @throws InvalidPathException
144
+     * @throws NotFoundException
145
+     * @throws NotPermittedException
146
+     */
147
+    public function touch($mtime = null) {
148
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
149
+            $this->sendHooks(['preTouch']);
150
+            $this->view->touch($this->path, $mtime);
151
+            $this->sendHooks(['postTouch']);
152
+            if ($this->fileInfo) {
153
+                if (is_null($mtime)) {
154
+                    $mtime = time();
155
+                }
156
+                $this->fileInfo['mtime'] = $mtime;
157
+            }
158
+        } else {
159
+            throw new NotPermittedException();
160
+        }
161
+    }
162
+
163
+    public function getStorage() {
164
+        $storage = $this->getMountPoint()->getStorage();
165
+        if (!$storage) {
166
+            throw new \Exception("No storage for node");
167
+        }
168
+        return $storage;
169
+    }
170
+
171
+    /**
172
+     * @return string
173
+     */
174
+    public function getPath() {
175
+        return $this->path;
176
+    }
177
+
178
+    /**
179
+     * @return string
180
+     */
181
+    public function getInternalPath() {
182
+        return $this->getFileInfo()->getInternalPath();
183
+    }
184
+
185
+    /**
186
+     * @return int
187
+     * @throws InvalidPathException
188
+     * @throws NotFoundException
189
+     */
190
+    public function getId() {
191
+        return $this->getFileInfo()->getId();
192
+    }
193
+
194
+    /**
195
+     * @return array
196
+     */
197
+    public function stat() {
198
+        return $this->view->stat($this->path);
199
+    }
200
+
201
+    /**
202
+     * @return int
203
+     * @throws InvalidPathException
204
+     * @throws NotFoundException
205
+     */
206
+    public function getMTime() {
207
+        return $this->getFileInfo()->getMTime();
208
+    }
209
+
210
+    /**
211
+     * @param bool $includeMounts
212
+     * @return int
213
+     * @throws InvalidPathException
214
+     * @throws NotFoundException
215
+     */
216
+    public function getSize($includeMounts = true) {
217
+        return $this->getFileInfo()->getSize($includeMounts);
218
+    }
219
+
220
+    /**
221
+     * @return string
222
+     * @throws InvalidPathException
223
+     * @throws NotFoundException
224
+     */
225
+    public function getEtag() {
226
+        return $this->getFileInfo()->getEtag();
227
+    }
228
+
229
+    /**
230
+     * @return int
231
+     * @throws InvalidPathException
232
+     * @throws NotFoundException
233
+     */
234
+    public function getPermissions() {
235
+        return $this->getFileInfo()->getPermissions();
236
+    }
237
+
238
+    /**
239
+     * @return bool
240
+     * @throws InvalidPathException
241
+     * @throws NotFoundException
242
+     */
243
+    public function isReadable() {
244
+        return $this->getFileInfo()->isReadable();
245
+    }
246
+
247
+    /**
248
+     * @return bool
249
+     * @throws InvalidPathException
250
+     * @throws NotFoundException
251
+     */
252
+    public function isUpdateable() {
253
+        return $this->getFileInfo()->isUpdateable();
254
+    }
255
+
256
+    /**
257
+     * @return bool
258
+     * @throws InvalidPathException
259
+     * @throws NotFoundException
260
+     */
261
+    public function isDeletable() {
262
+        return $this->getFileInfo()->isDeletable();
263
+    }
264
+
265
+    /**
266
+     * @return bool
267
+     * @throws InvalidPathException
268
+     * @throws NotFoundException
269
+     */
270
+    public function isShareable() {
271
+        return $this->getFileInfo()->isShareable();
272
+    }
273
+
274
+    /**
275
+     * @return bool
276
+     * @throws InvalidPathException
277
+     * @throws NotFoundException
278
+     */
279
+    public function isCreatable() {
280
+        return $this->getFileInfo()->isCreatable();
281
+    }
282
+
283
+    /**
284
+     * @return Node
285
+     */
286
+    public function getParent() {
287
+        if ($this->parent === null) {
288
+            $newPath = dirname($this->path);
289
+            if ($newPath === '' || $newPath === '.' || $newPath === '/') {
290
+                return $this->root;
291
+            }
292
+
293
+            $this->parent = $this->root->get($newPath);
294
+        }
295
+
296
+        return $this->parent;
297
+    }
298
+
299
+    /**
300
+     * @return string
301
+     */
302
+    public function getName() {
303
+        return basename($this->path);
304
+    }
305
+
306
+    /**
307
+     * @param string $path
308
+     * @return string
309
+     */
310
+    protected function normalizePath($path) {
311
+        return PathHelper::normalizePath($path);
312
+    }
313
+
314
+    /**
315
+     * check if the requested path is valid
316
+     *
317
+     * @param string $path
318
+     * @return bool
319
+     */
320
+    public function isValidPath($path) {
321
+        if (!$path || $path[0] !== '/') {
322
+            $path = '/' . $path;
323
+        }
324
+        if (strstr($path, '/../') || strrchr($path, '/') === '/..') {
325
+            return false;
326
+        }
327
+        return true;
328
+    }
329
+
330
+    public function isMounted() {
331
+        return $this->getFileInfo()->isMounted();
332
+    }
333
+
334
+    public function isShared() {
335
+        return $this->getFileInfo()->isShared();
336
+    }
337
+
338
+    public function getMimeType() {
339
+        return $this->getFileInfo()->getMimetype();
340
+    }
341
+
342
+    public function getMimePart() {
343
+        return $this->getFileInfo()->getMimePart();
344
+    }
345
+
346
+    public function getType() {
347
+        return $this->getFileInfo()->getType();
348
+    }
349
+
350
+    public function isEncrypted() {
351
+        return $this->getFileInfo()->isEncrypted();
352
+    }
353
+
354
+    public function getMountPoint() {
355
+        return $this->getFileInfo()->getMountPoint();
356
+    }
357
+
358
+    public function getOwner() {
359
+        return $this->getFileInfo()->getOwner();
360
+    }
361
+
362
+    public function getChecksum() {
363
+    }
364
+
365
+    public function getExtension(): string {
366
+        return $this->getFileInfo()->getExtension();
367
+    }
368
+
369
+    /**
370
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
371
+     * @throws LockedException
372
+     */
373
+    public function lock($type) {
374
+        $this->view->lockFile($this->path, $type);
375
+    }
376
+
377
+    /**
378
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
379
+     * @throws LockedException
380
+     */
381
+    public function changeLock($type) {
382
+        $this->view->changeLock($this->path, $type);
383
+    }
384
+
385
+    /**
386
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
387
+     * @throws LockedException
388
+     */
389
+    public function unlock($type) {
390
+        $this->view->unlockFile($this->path, $type);
391
+    }
392
+
393
+    /**
394
+     * @param string $targetPath
395
+     * @return \OC\Files\Node\Node
396
+     * @throws InvalidPathException
397
+     * @throws NotFoundException
398
+     * @throws NotPermittedException if copy not allowed or failed
399
+     */
400
+    public function copy($targetPath) {
401
+        $targetPath = $this->normalizePath($targetPath);
402
+        $parent = $this->root->get(dirname($targetPath));
403
+        if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
404
+            $nonExisting = $this->createNonExistingNode($targetPath);
405
+            $this->sendHooks(['preCopy'], [$this, $nonExisting]);
406
+            $this->sendHooks(['preWrite'], [$nonExisting]);
407
+            if (!$this->view->copy($this->path, $targetPath)) {
408
+                throw new NotPermittedException('Could not copy ' . $this->path . ' to ' . $targetPath);
409
+            }
410
+            $targetNode = $this->root->get($targetPath);
411
+            $this->sendHooks(['postCopy'], [$this, $targetNode]);
412
+            $this->sendHooks(['postWrite'], [$targetNode]);
413
+            return $targetNode;
414
+        } else {
415
+            throw new NotPermittedException('No permission to copy to path ' . $targetPath);
416
+        }
417
+    }
418
+
419
+    /**
420
+     * @param string $targetPath
421
+     * @return \OC\Files\Node\Node
422
+     * @throws InvalidPathException
423
+     * @throws NotFoundException
424
+     * @throws NotPermittedException if move not allowed or failed
425
+     * @throws LockedException
426
+     */
427
+    public function move($targetPath) {
428
+        $targetPath = $this->normalizePath($targetPath);
429
+        $parent = $this->root->get(dirname($targetPath));
430
+        if (
431
+            $parent instanceof Folder and
432
+            $this->isValidPath($targetPath) and
433
+            (
434
+                $parent->isCreatable() ||
435
+                ($parent->getInternalPath() === '' && $parent->getMountPoint() instanceof MoveableMount)
436
+            )
437
+        ) {
438
+            $nonExisting = $this->createNonExistingNode($targetPath);
439
+            $this->sendHooks(['preRename'], [$this, $nonExisting]);
440
+            $this->sendHooks(['preWrite'], [$nonExisting]);
441
+            if (!$this->view->rename($this->path, $targetPath)) {
442
+                throw new NotPermittedException('Could not move ' . $this->path . ' to ' . $targetPath);
443
+            }
444
+
445
+            $mountPoint = $this->getMountPoint();
446
+            if ($mountPoint) {
447
+                // update the cached fileinfo with the new (internal) path
448
+                /** @var \OC\Files\FileInfo $oldFileInfo */
449
+                $oldFileInfo = $this->getFileInfo();
450
+                $this->fileInfo = new \OC\Files\FileInfo($targetPath, $oldFileInfo->getStorage(), $mountPoint->getInternalPath($targetPath), $oldFileInfo->getData(), $mountPoint, $oldFileInfo->getOwner());
451
+            }
452
+
453
+            $targetNode = $this->root->get($targetPath);
454
+            $this->sendHooks(['postRename'], [$this, $targetNode]);
455
+            $this->sendHooks(['postWrite'], [$targetNode]);
456
+            $this->path = $targetPath;
457
+            return $targetNode;
458
+        } else {
459
+            throw new NotPermittedException('No permission to move to path ' . $targetPath);
460
+        }
461
+    }
462
+
463
+    public function getCreationTime(): int {
464
+        return $this->getFileInfo()->getCreationTime();
465
+    }
466
+
467
+    public function getUploadTime(): int {
468
+        return $this->getFileInfo()->getUploadTime();
469
+    }
470 470
 }
Please login to merge, or discard this patch.
lib/private/Files/Node/Folder.php 2 patches
Indentation   +396 added lines, -396 removed lines patch added patch discarded remove patch
@@ -50,400 +50,400 @@
 block discarded – undo
50 50
 use OCP\IUserManager;
51 51
 
52 52
 class Folder extends Node implements \OCP\Files\Folder {
53
-	/**
54
-	 * Creates a Folder that represents a non-existing path
55
-	 *
56
-	 * @param string $path path
57
-	 * @return string non-existing node class
58
-	 */
59
-	protected function createNonExistingNode($path) {
60
-		return new NonExistingFolder($this->root, $this->view, $path);
61
-	}
62
-
63
-	/**
64
-	 * @param string $path path relative to the folder
65
-	 * @return string
66
-	 * @throws \OCP\Files\NotPermittedException
67
-	 */
68
-	public function getFullPath($path) {
69
-		if (!$this->isValidPath($path)) {
70
-			throw new NotPermittedException('Invalid path');
71
-		}
72
-		return $this->path . $this->normalizePath($path);
73
-	}
74
-
75
-	/**
76
-	 * @param string $path
77
-	 * @return string|null
78
-	 */
79
-	public function getRelativePath($path) {
80
-		return PathHelper::getRelativePath($this->getPath(), $path);
81
-	}
82
-
83
-	/**
84
-	 * check if a node is a (grand-)child of the folder
85
-	 *
86
-	 * @param \OC\Files\Node\Node $node
87
-	 * @return bool
88
-	 */
89
-	public function isSubNode($node) {
90
-		return strpos($node->getPath(), $this->path . '/') === 0;
91
-	}
92
-
93
-	/**
94
-	 * get the content of this directory
95
-	 *
96
-	 * @return Node[]
97
-	 * @throws \OCP\Files\NotFoundException
98
-	 */
99
-	public function getDirectoryListing() {
100
-		$folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo());
101
-
102
-		return array_map(function (FileInfo $info) {
103
-			if ($info->getMimetype() === FileInfo::MIMETYPE_FOLDER) {
104
-				return new Folder($this->root, $this->view, $info->getPath(), $info, $this);
105
-			} else {
106
-				return new File($this->root, $this->view, $info->getPath(), $info, $this);
107
-			}
108
-		}, $folderContent);
109
-	}
110
-
111
-	/**
112
-	 * @param string $path
113
-	 * @param FileInfo $info
114
-	 * @return File|Folder
115
-	 */
116
-	protected function createNode($path, FileInfo $info = null) {
117
-		if (is_null($info)) {
118
-			$isDir = $this->view->is_dir($path);
119
-		} else {
120
-			$isDir = $info->getType() === FileInfo::TYPE_FOLDER;
121
-		}
122
-		$parent = dirname($path) === $this->getPath() ? $this : null;
123
-		if ($isDir) {
124
-			return new Folder($this->root, $this->view, $path, $info, $parent);
125
-		} else {
126
-			return new File($this->root, $this->view, $path, $info, $parent);
127
-		}
128
-	}
129
-
130
-	/**
131
-	 * Get the node at $path
132
-	 *
133
-	 * @param string $path
134
-	 * @return \OC\Files\Node\Node
135
-	 * @throws \OCP\Files\NotFoundException
136
-	 */
137
-	public function get($path) {
138
-		return $this->root->get($this->getFullPath($path));
139
-	}
140
-
141
-	/**
142
-	 * @param string $path
143
-	 * @return bool
144
-	 */
145
-	public function nodeExists($path) {
146
-		try {
147
-			$this->get($path);
148
-			return true;
149
-		} catch (NotFoundException $e) {
150
-			return false;
151
-		}
152
-	}
153
-
154
-	/**
155
-	 * @param string $path
156
-	 * @return \OC\Files\Node\Folder
157
-	 * @throws \OCP\Files\NotPermittedException
158
-	 */
159
-	public function newFolder($path) {
160
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
161
-			$fullPath = $this->getFullPath($path);
162
-			$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
163
-			$this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
164
-			if (!$this->view->mkdir($fullPath)) {
165
-				throw new NotPermittedException('Could not create folder');
166
-			}
167
-			$parent = dirname($fullPath) === $this->getPath() ? $this : null;
168
-			$node = new Folder($this->root, $this->view, $fullPath, null, $parent);
169
-			$this->sendHooks(['postWrite', 'postCreate'], [$node]);
170
-			return $node;
171
-		} else {
172
-			throw new NotPermittedException('No create permission for folder');
173
-		}
174
-	}
175
-
176
-	/**
177
-	 * @param string $path
178
-	 * @param string | resource | null $content
179
-	 * @return \OC\Files\Node\File
180
-	 * @throws \OCP\Files\NotPermittedException
181
-	 */
182
-	public function newFile($path, $content = null) {
183
-		if (empty($path)) {
184
-			throw new NotPermittedException('Could not create as provided path is empty');
185
-		}
186
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
187
-			$fullPath = $this->getFullPath($path);
188
-			$nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
189
-			$this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
190
-			if ($content !== null) {
191
-				$result = $this->view->file_put_contents($fullPath, $content);
192
-			} else {
193
-				$result = $this->view->touch($fullPath);
194
-			}
195
-			if ($result === false) {
196
-				throw new NotPermittedException('Could not create path');
197
-			}
198
-			$node = new File($this->root, $this->view, $fullPath, null, $this);
199
-			$this->sendHooks(['postWrite', 'postCreate'], [$node]);
200
-			return $node;
201
-		}
202
-		throw new NotPermittedException('No create permission for path');
203
-	}
204
-
205
-	private function queryFromOperator(ISearchOperator $operator, string $uid = null): ISearchQuery {
206
-		if ($uid === null) {
207
-			$user = null;
208
-		} else {
209
-			/** @var IUserManager $userManager */
210
-			$userManager = \OC::$server->query(IUserManager::class);
211
-			$user = $userManager->get($uid);
212
-		}
213
-		return new SearchQuery($operator, 0, 0, [], $user);
214
-	}
215
-
216
-	/**
217
-	 * search for files with the name matching $query
218
-	 *
219
-	 * @param string|ISearchQuery $query
220
-	 * @return \OC\Files\Node\Node[]
221
-	 */
222
-	public function search($query) {
223
-		if (is_string($query)) {
224
-			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query . '%'));
225
-		}
226
-
227
-		// search is handled by a single query covering all caches that this folder contains
228
-		// this is done by collect
229
-
230
-		$limitToHome = $query->limitToHome();
231
-		if ($limitToHome && count(explode('/', $this->path)) !== 3) {
232
-			throw new \InvalidArgumentException('searching by owner is only allows on the users home folder');
233
-		}
234
-
235
-		$rootLength = strlen($this->path);
236
-		$mount = $this->root->getMount($this->path);
237
-		$storage = $mount->getStorage();
238
-		$internalPath = $mount->getInternalPath($this->path);
239
-
240
-		// collect all caches for this folder, indexed by their mountpoint relative to this folder
241
-		// and save the mount which is needed later to construct the FileInfo objects
242
-
243
-		if ($internalPath !== '') {
244
-			// a temporary CacheJail is used to handle filtering down the results to within this folder
245
-			$caches = ['' => new CacheJail($storage->getCache(''), $internalPath)];
246
-		} else {
247
-			$caches = ['' => $storage->getCache('')];
248
-		}
249
-		$mountByMountPoint = ['' => $mount];
250
-
251
-		if (!$limitToHome) {
252
-			$mounts = $this->root->getMountsIn($this->path);
253
-			foreach ($mounts as $mount) {
254
-				$storage = $mount->getStorage();
255
-				if ($storage) {
256
-					$relativeMountPoint = ltrim(substr($mount->getMountPoint(), $rootLength), '/');
257
-					$caches[$relativeMountPoint] = $storage->getCache('');
258
-					$mountByMountPoint[$relativeMountPoint] = $mount;
259
-				}
260
-			}
261
-		}
262
-
263
-		/** @var QuerySearchHelper $searchHelper */
264
-		$searchHelper = \OC::$server->get(QuerySearchHelper::class);
265
-		$resultsPerCache = $searchHelper->searchInCaches($query, $caches);
266
-
267
-		// loop through all results per-cache, constructing the FileInfo object from the CacheEntry and merge them all
268
-		$files = array_merge(...array_map(function (array $results, $relativeMountPoint) use ($mountByMountPoint) {
269
-			$mount = $mountByMountPoint[$relativeMountPoint];
270
-			return array_map(function (ICacheEntry $result) use ($relativeMountPoint, $mount) {
271
-				return $this->cacheEntryToFileInfo($mount, $relativeMountPoint, $result);
272
-			}, $results);
273
-		}, array_values($resultsPerCache), array_keys($resultsPerCache)));
274
-
275
-		// don't include this folder in the results
276
-		$files = array_filter($files, function (FileInfo $file) {
277
-			return $file->getPath() !== $this->getPath();
278
-		});
279
-
280
-		// since results were returned per-cache, they are no longer fully sorted
281
-		$order = $query->getOrder();
282
-		if ($order) {
283
-			usort($files, function (FileInfo $a, FileInfo $b) use ($order) {
284
-				foreach ($order as $orderField) {
285
-					$cmp = $orderField->sortFileInfo($a, $b);
286
-					if ($cmp !== 0) {
287
-						return $cmp;
288
-					}
289
-				}
290
-				return 0;
291
-			});
292
-		}
293
-
294
-		return array_map(function (FileInfo $file) {
295
-			return $this->createNode($file->getPath(), $file);
296
-		}, $files);
297
-	}
298
-
299
-	private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, ICacheEntry $cacheEntry): FileInfo {
300
-		$cacheEntry['internalPath'] = $cacheEntry['path'];
301
-		$cacheEntry['path'] = $appendRoot . $cacheEntry->getPath();
302
-		$subPath = $cacheEntry['path'] !== '' ? '/' . $cacheEntry['path'] : '';
303
-		return new \OC\Files\FileInfo($this->path . $subPath, $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount);
304
-	}
305
-
306
-	/**
307
-	 * search for files by mimetype
308
-	 *
309
-	 * @param string $mimetype
310
-	 * @return Node[]
311
-	 */
312
-	public function searchByMime($mimetype) {
313
-		if (strpos($mimetype, '/') === false) {
314
-			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', $mimetype . '/%'));
315
-		} else {
316
-			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', $mimetype));
317
-		}
318
-		return $this->search($query);
319
-	}
320
-
321
-	/**
322
-	 * search for files by tag
323
-	 *
324
-	 * @param string|int $tag name or tag id
325
-	 * @param string $userId owner of the tags
326
-	 * @return Node[]
327
-	 */
328
-	public function searchByTag($tag, $userId) {
329
-		$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'tagname', $tag), $userId);
330
-		return $this->search($query);
331
-	}
332
-
333
-	/**
334
-	 * @param int $id
335
-	 * @return \OC\Files\Node\Node[]
336
-	 */
337
-	public function getById($id) {
338
-		return $this->root->getByIdInPath((int)$id, $this->getPath());
339
-	}
340
-
341
-	protected function getAppDataDirectoryName(): string {
342
-		$instanceId = \OC::$server->getConfig()->getSystemValueString('instanceid');
343
-		return 'appdata_' . $instanceId;
344
-	}
345
-
346
-	/**
347
-	 * In case the path we are currently in is inside the appdata_* folder,
348
-	 * the original getById method does not work, because it can only look inside
349
-	 * the user's mount points. But the user has no mount point for the root storage.
350
-	 *
351
-	 * So in that case we directly check the mount of the root if it contains
352
-	 * the id. If it does we check if the path is inside the path we are working
353
-	 * in.
354
-	 *
355
-	 * @param int $id
356
-	 * @return array
357
-	 */
358
-	protected function getByIdInRootMount(int $id): array {
359
-		$mount = $this->root->getMount('');
360
-		$cacheEntry = $mount->getStorage()->getCache($this->path)->get($id);
361
-		if (!$cacheEntry) {
362
-			return [];
363
-		}
364
-
365
-		$absolutePath = '/' . ltrim($cacheEntry->getPath(), '/');
366
-		$currentPath = rtrim($this->path, '/') . '/';
367
-
368
-		if (strpos($absolutePath, $currentPath) !== 0) {
369
-			return [];
370
-		}
371
-
372
-		return [$this->root->createNode(
373
-			$absolutePath, new \OC\Files\FileInfo(
374
-			$absolutePath,
375
-			$mount->getStorage(),
376
-			$cacheEntry->getPath(),
377
-			$cacheEntry,
378
-			$mount
379
-		))];
380
-	}
381
-
382
-	public function getFreeSpace() {
383
-		return $this->view->free_space($this->path);
384
-	}
385
-
386
-	public function delete() {
387
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
388
-			$this->sendHooks(['preDelete']);
389
-			$fileInfo = $this->getFileInfo();
390
-			$this->view->rmdir($this->path);
391
-			$nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
392
-			$this->sendHooks(['postDelete'], [$nonExisting]);
393
-		} else {
394
-			throw new NotPermittedException('No delete permission for path');
395
-		}
396
-	}
397
-
398
-	/**
399
-	 * Add a suffix to the name in case the file exists
400
-	 *
401
-	 * @param string $name
402
-	 * @return string
403
-	 * @throws NotPermittedException
404
-	 */
405
-	public function getNonExistingName($name) {
406
-		$uniqueName = \OC_Helper::buildNotExistingFileNameForView($this->getPath(), $name, $this->view);
407
-		return trim($this->getRelativePath($uniqueName), '/');
408
-	}
409
-
410
-	/**
411
-	 * @param int $limit
412
-	 * @param int $offset
413
-	 * @return \OCP\Files\Node[]
414
-	 */
415
-	public function getRecent($limit, $offset = 0) {
416
-		$query = new SearchQuery(
417
-			new SearchBinaryOperator(
418
-				// filter out non empty folders
419
-				ISearchBinaryOperator::OPERATOR_OR,
420
-				[
421
-					new SearchBinaryOperator(
422
-						ISearchBinaryOperator::OPERATOR_NOT,
423
-						[
424
-							new SearchComparison(
425
-								ISearchComparison::COMPARE_EQUAL,
426
-								'mimetype',
427
-								FileInfo::MIMETYPE_FOLDER
428
-							),
429
-						]
430
-					),
431
-					new SearchComparison(
432
-						ISearchComparison::COMPARE_EQUAL,
433
-						'size',
434
-						0
435
-					),
436
-				]
437
-			),
438
-			$limit,
439
-			$offset,
440
-			[
441
-				new SearchOrder(
442
-					ISearchOrder::DIRECTION_DESCENDING,
443
-					'mtime'
444
-				),
445
-			]
446
-		);
447
-		return $this->search($query);
448
-	}
53
+    /**
54
+     * Creates a Folder that represents a non-existing path
55
+     *
56
+     * @param string $path path
57
+     * @return string non-existing node class
58
+     */
59
+    protected function createNonExistingNode($path) {
60
+        return new NonExistingFolder($this->root, $this->view, $path);
61
+    }
62
+
63
+    /**
64
+     * @param string $path path relative to the folder
65
+     * @return string
66
+     * @throws \OCP\Files\NotPermittedException
67
+     */
68
+    public function getFullPath($path) {
69
+        if (!$this->isValidPath($path)) {
70
+            throw new NotPermittedException('Invalid path');
71
+        }
72
+        return $this->path . $this->normalizePath($path);
73
+    }
74
+
75
+    /**
76
+     * @param string $path
77
+     * @return string|null
78
+     */
79
+    public function getRelativePath($path) {
80
+        return PathHelper::getRelativePath($this->getPath(), $path);
81
+    }
82
+
83
+    /**
84
+     * check if a node is a (grand-)child of the folder
85
+     *
86
+     * @param \OC\Files\Node\Node $node
87
+     * @return bool
88
+     */
89
+    public function isSubNode($node) {
90
+        return strpos($node->getPath(), $this->path . '/') === 0;
91
+    }
92
+
93
+    /**
94
+     * get the content of this directory
95
+     *
96
+     * @return Node[]
97
+     * @throws \OCP\Files\NotFoundException
98
+     */
99
+    public function getDirectoryListing() {
100
+        $folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo());
101
+
102
+        return array_map(function (FileInfo $info) {
103
+            if ($info->getMimetype() === FileInfo::MIMETYPE_FOLDER) {
104
+                return new Folder($this->root, $this->view, $info->getPath(), $info, $this);
105
+            } else {
106
+                return new File($this->root, $this->view, $info->getPath(), $info, $this);
107
+            }
108
+        }, $folderContent);
109
+    }
110
+
111
+    /**
112
+     * @param string $path
113
+     * @param FileInfo $info
114
+     * @return File|Folder
115
+     */
116
+    protected function createNode($path, FileInfo $info = null) {
117
+        if (is_null($info)) {
118
+            $isDir = $this->view->is_dir($path);
119
+        } else {
120
+            $isDir = $info->getType() === FileInfo::TYPE_FOLDER;
121
+        }
122
+        $parent = dirname($path) === $this->getPath() ? $this : null;
123
+        if ($isDir) {
124
+            return new Folder($this->root, $this->view, $path, $info, $parent);
125
+        } else {
126
+            return new File($this->root, $this->view, $path, $info, $parent);
127
+        }
128
+    }
129
+
130
+    /**
131
+     * Get the node at $path
132
+     *
133
+     * @param string $path
134
+     * @return \OC\Files\Node\Node
135
+     * @throws \OCP\Files\NotFoundException
136
+     */
137
+    public function get($path) {
138
+        return $this->root->get($this->getFullPath($path));
139
+    }
140
+
141
+    /**
142
+     * @param string $path
143
+     * @return bool
144
+     */
145
+    public function nodeExists($path) {
146
+        try {
147
+            $this->get($path);
148
+            return true;
149
+        } catch (NotFoundException $e) {
150
+            return false;
151
+        }
152
+    }
153
+
154
+    /**
155
+     * @param string $path
156
+     * @return \OC\Files\Node\Folder
157
+     * @throws \OCP\Files\NotPermittedException
158
+     */
159
+    public function newFolder($path) {
160
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
161
+            $fullPath = $this->getFullPath($path);
162
+            $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
163
+            $this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
164
+            if (!$this->view->mkdir($fullPath)) {
165
+                throw new NotPermittedException('Could not create folder');
166
+            }
167
+            $parent = dirname($fullPath) === $this->getPath() ? $this : null;
168
+            $node = new Folder($this->root, $this->view, $fullPath, null, $parent);
169
+            $this->sendHooks(['postWrite', 'postCreate'], [$node]);
170
+            return $node;
171
+        } else {
172
+            throw new NotPermittedException('No create permission for folder');
173
+        }
174
+    }
175
+
176
+    /**
177
+     * @param string $path
178
+     * @param string | resource | null $content
179
+     * @return \OC\Files\Node\File
180
+     * @throws \OCP\Files\NotPermittedException
181
+     */
182
+    public function newFile($path, $content = null) {
183
+        if (empty($path)) {
184
+            throw new NotPermittedException('Could not create as provided path is empty');
185
+        }
186
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
187
+            $fullPath = $this->getFullPath($path);
188
+            $nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
189
+            $this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
190
+            if ($content !== null) {
191
+                $result = $this->view->file_put_contents($fullPath, $content);
192
+            } else {
193
+                $result = $this->view->touch($fullPath);
194
+            }
195
+            if ($result === false) {
196
+                throw new NotPermittedException('Could not create path');
197
+            }
198
+            $node = new File($this->root, $this->view, $fullPath, null, $this);
199
+            $this->sendHooks(['postWrite', 'postCreate'], [$node]);
200
+            return $node;
201
+        }
202
+        throw new NotPermittedException('No create permission for path');
203
+    }
204
+
205
+    private function queryFromOperator(ISearchOperator $operator, string $uid = null): ISearchQuery {
206
+        if ($uid === null) {
207
+            $user = null;
208
+        } else {
209
+            /** @var IUserManager $userManager */
210
+            $userManager = \OC::$server->query(IUserManager::class);
211
+            $user = $userManager->get($uid);
212
+        }
213
+        return new SearchQuery($operator, 0, 0, [], $user);
214
+    }
215
+
216
+    /**
217
+     * search for files with the name matching $query
218
+     *
219
+     * @param string|ISearchQuery $query
220
+     * @return \OC\Files\Node\Node[]
221
+     */
222
+    public function search($query) {
223
+        if (is_string($query)) {
224
+            $query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query . '%'));
225
+        }
226
+
227
+        // search is handled by a single query covering all caches that this folder contains
228
+        // this is done by collect
229
+
230
+        $limitToHome = $query->limitToHome();
231
+        if ($limitToHome && count(explode('/', $this->path)) !== 3) {
232
+            throw new \InvalidArgumentException('searching by owner is only allows on the users home folder');
233
+        }
234
+
235
+        $rootLength = strlen($this->path);
236
+        $mount = $this->root->getMount($this->path);
237
+        $storage = $mount->getStorage();
238
+        $internalPath = $mount->getInternalPath($this->path);
239
+
240
+        // collect all caches for this folder, indexed by their mountpoint relative to this folder
241
+        // and save the mount which is needed later to construct the FileInfo objects
242
+
243
+        if ($internalPath !== '') {
244
+            // a temporary CacheJail is used to handle filtering down the results to within this folder
245
+            $caches = ['' => new CacheJail($storage->getCache(''), $internalPath)];
246
+        } else {
247
+            $caches = ['' => $storage->getCache('')];
248
+        }
249
+        $mountByMountPoint = ['' => $mount];
250
+
251
+        if (!$limitToHome) {
252
+            $mounts = $this->root->getMountsIn($this->path);
253
+            foreach ($mounts as $mount) {
254
+                $storage = $mount->getStorage();
255
+                if ($storage) {
256
+                    $relativeMountPoint = ltrim(substr($mount->getMountPoint(), $rootLength), '/');
257
+                    $caches[$relativeMountPoint] = $storage->getCache('');
258
+                    $mountByMountPoint[$relativeMountPoint] = $mount;
259
+                }
260
+            }
261
+        }
262
+
263
+        /** @var QuerySearchHelper $searchHelper */
264
+        $searchHelper = \OC::$server->get(QuerySearchHelper::class);
265
+        $resultsPerCache = $searchHelper->searchInCaches($query, $caches);
266
+
267
+        // loop through all results per-cache, constructing the FileInfo object from the CacheEntry and merge them all
268
+        $files = array_merge(...array_map(function (array $results, $relativeMountPoint) use ($mountByMountPoint) {
269
+            $mount = $mountByMountPoint[$relativeMountPoint];
270
+            return array_map(function (ICacheEntry $result) use ($relativeMountPoint, $mount) {
271
+                return $this->cacheEntryToFileInfo($mount, $relativeMountPoint, $result);
272
+            }, $results);
273
+        }, array_values($resultsPerCache), array_keys($resultsPerCache)));
274
+
275
+        // don't include this folder in the results
276
+        $files = array_filter($files, function (FileInfo $file) {
277
+            return $file->getPath() !== $this->getPath();
278
+        });
279
+
280
+        // since results were returned per-cache, they are no longer fully sorted
281
+        $order = $query->getOrder();
282
+        if ($order) {
283
+            usort($files, function (FileInfo $a, FileInfo $b) use ($order) {
284
+                foreach ($order as $orderField) {
285
+                    $cmp = $orderField->sortFileInfo($a, $b);
286
+                    if ($cmp !== 0) {
287
+                        return $cmp;
288
+                    }
289
+                }
290
+                return 0;
291
+            });
292
+        }
293
+
294
+        return array_map(function (FileInfo $file) {
295
+            return $this->createNode($file->getPath(), $file);
296
+        }, $files);
297
+    }
298
+
299
+    private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, ICacheEntry $cacheEntry): FileInfo {
300
+        $cacheEntry['internalPath'] = $cacheEntry['path'];
301
+        $cacheEntry['path'] = $appendRoot . $cacheEntry->getPath();
302
+        $subPath = $cacheEntry['path'] !== '' ? '/' . $cacheEntry['path'] : '';
303
+        return new \OC\Files\FileInfo($this->path . $subPath, $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount);
304
+    }
305
+
306
+    /**
307
+     * search for files by mimetype
308
+     *
309
+     * @param string $mimetype
310
+     * @return Node[]
311
+     */
312
+    public function searchByMime($mimetype) {
313
+        if (strpos($mimetype, '/') === false) {
314
+            $query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', $mimetype . '/%'));
315
+        } else {
316
+            $query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', $mimetype));
317
+        }
318
+        return $this->search($query);
319
+    }
320
+
321
+    /**
322
+     * search for files by tag
323
+     *
324
+     * @param string|int $tag name or tag id
325
+     * @param string $userId owner of the tags
326
+     * @return Node[]
327
+     */
328
+    public function searchByTag($tag, $userId) {
329
+        $query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'tagname', $tag), $userId);
330
+        return $this->search($query);
331
+    }
332
+
333
+    /**
334
+     * @param int $id
335
+     * @return \OC\Files\Node\Node[]
336
+     */
337
+    public function getById($id) {
338
+        return $this->root->getByIdInPath((int)$id, $this->getPath());
339
+    }
340
+
341
+    protected function getAppDataDirectoryName(): string {
342
+        $instanceId = \OC::$server->getConfig()->getSystemValueString('instanceid');
343
+        return 'appdata_' . $instanceId;
344
+    }
345
+
346
+    /**
347
+     * In case the path we are currently in is inside the appdata_* folder,
348
+     * the original getById method does not work, because it can only look inside
349
+     * the user's mount points. But the user has no mount point for the root storage.
350
+     *
351
+     * So in that case we directly check the mount of the root if it contains
352
+     * the id. If it does we check if the path is inside the path we are working
353
+     * in.
354
+     *
355
+     * @param int $id
356
+     * @return array
357
+     */
358
+    protected function getByIdInRootMount(int $id): array {
359
+        $mount = $this->root->getMount('');
360
+        $cacheEntry = $mount->getStorage()->getCache($this->path)->get($id);
361
+        if (!$cacheEntry) {
362
+            return [];
363
+        }
364
+
365
+        $absolutePath = '/' . ltrim($cacheEntry->getPath(), '/');
366
+        $currentPath = rtrim($this->path, '/') . '/';
367
+
368
+        if (strpos($absolutePath, $currentPath) !== 0) {
369
+            return [];
370
+        }
371
+
372
+        return [$this->root->createNode(
373
+            $absolutePath, new \OC\Files\FileInfo(
374
+            $absolutePath,
375
+            $mount->getStorage(),
376
+            $cacheEntry->getPath(),
377
+            $cacheEntry,
378
+            $mount
379
+        ))];
380
+    }
381
+
382
+    public function getFreeSpace() {
383
+        return $this->view->free_space($this->path);
384
+    }
385
+
386
+    public function delete() {
387
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
388
+            $this->sendHooks(['preDelete']);
389
+            $fileInfo = $this->getFileInfo();
390
+            $this->view->rmdir($this->path);
391
+            $nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
392
+            $this->sendHooks(['postDelete'], [$nonExisting]);
393
+        } else {
394
+            throw new NotPermittedException('No delete permission for path');
395
+        }
396
+    }
397
+
398
+    /**
399
+     * Add a suffix to the name in case the file exists
400
+     *
401
+     * @param string $name
402
+     * @return string
403
+     * @throws NotPermittedException
404
+     */
405
+    public function getNonExistingName($name) {
406
+        $uniqueName = \OC_Helper::buildNotExistingFileNameForView($this->getPath(), $name, $this->view);
407
+        return trim($this->getRelativePath($uniqueName), '/');
408
+    }
409
+
410
+    /**
411
+     * @param int $limit
412
+     * @param int $offset
413
+     * @return \OCP\Files\Node[]
414
+     */
415
+    public function getRecent($limit, $offset = 0) {
416
+        $query = new SearchQuery(
417
+            new SearchBinaryOperator(
418
+                // filter out non empty folders
419
+                ISearchBinaryOperator::OPERATOR_OR,
420
+                [
421
+                    new SearchBinaryOperator(
422
+                        ISearchBinaryOperator::OPERATOR_NOT,
423
+                        [
424
+                            new SearchComparison(
425
+                                ISearchComparison::COMPARE_EQUAL,
426
+                                'mimetype',
427
+                                FileInfo::MIMETYPE_FOLDER
428
+                            ),
429
+                        ]
430
+                    ),
431
+                    new SearchComparison(
432
+                        ISearchComparison::COMPARE_EQUAL,
433
+                        'size',
434
+                        0
435
+                    ),
436
+                ]
437
+            ),
438
+            $limit,
439
+            $offset,
440
+            [
441
+                new SearchOrder(
442
+                    ISearchOrder::DIRECTION_DESCENDING,
443
+                    'mtime'
444
+                ),
445
+            ]
446
+        );
447
+        return $this->search($query);
448
+    }
449 449
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 		if (!$this->isValidPath($path)) {
70 70
 			throw new NotPermittedException('Invalid path');
71 71
 		}
72
-		return $this->path . $this->normalizePath($path);
72
+		return $this->path.$this->normalizePath($path);
73 73
 	}
74 74
 
75 75
 	/**
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 	 * @return bool
88 88
 	 */
89 89
 	public function isSubNode($node) {
90
-		return strpos($node->getPath(), $this->path . '/') === 0;
90
+		return strpos($node->getPath(), $this->path.'/') === 0;
91 91
 	}
92 92
 
93 93
 	/**
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
 	public function getDirectoryListing() {
100 100
 		$folderContent = $this->view->getDirectoryContent($this->path, '', $this->getFileInfo());
101 101
 
102
-		return array_map(function (FileInfo $info) {
102
+		return array_map(function(FileInfo $info) {
103 103
 			if ($info->getMimetype() === FileInfo::MIMETYPE_FOLDER) {
104 104
 				return new Folder($this->root, $this->view, $info->getPath(), $info, $this);
105 105
 			} else {
@@ -221,7 +221,7 @@  discard block
 block discarded – undo
221 221
 	 */
222 222
 	public function search($query) {
223 223
 		if (is_string($query)) {
224
-			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query . '%'));
224
+			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%'.$query.'%'));
225 225
 		}
226 226
 
227 227
 		// search is handled by a single query covering all caches that this folder contains
@@ -265,22 +265,22 @@  discard block
 block discarded – undo
265 265
 		$resultsPerCache = $searchHelper->searchInCaches($query, $caches);
266 266
 
267 267
 		// loop through all results per-cache, constructing the FileInfo object from the CacheEntry and merge them all
268
-		$files = array_merge(...array_map(function (array $results, $relativeMountPoint) use ($mountByMountPoint) {
268
+		$files = array_merge(...array_map(function(array $results, $relativeMountPoint) use ($mountByMountPoint) {
269 269
 			$mount = $mountByMountPoint[$relativeMountPoint];
270
-			return array_map(function (ICacheEntry $result) use ($relativeMountPoint, $mount) {
270
+			return array_map(function(ICacheEntry $result) use ($relativeMountPoint, $mount) {
271 271
 				return $this->cacheEntryToFileInfo($mount, $relativeMountPoint, $result);
272 272
 			}, $results);
273 273
 		}, array_values($resultsPerCache), array_keys($resultsPerCache)));
274 274
 
275 275
 		// don't include this folder in the results
276
-		$files = array_filter($files, function (FileInfo $file) {
276
+		$files = array_filter($files, function(FileInfo $file) {
277 277
 			return $file->getPath() !== $this->getPath();
278 278
 		});
279 279
 
280 280
 		// since results were returned per-cache, they are no longer fully sorted
281 281
 		$order = $query->getOrder();
282 282
 		if ($order) {
283
-			usort($files, function (FileInfo $a, FileInfo $b) use ($order) {
283
+			usort($files, function(FileInfo $a, FileInfo $b) use ($order) {
284 284
 				foreach ($order as $orderField) {
285 285
 					$cmp = $orderField->sortFileInfo($a, $b);
286 286
 					if ($cmp !== 0) {
@@ -291,16 +291,16 @@  discard block
 block discarded – undo
291 291
 			});
292 292
 		}
293 293
 
294
-		return array_map(function (FileInfo $file) {
294
+		return array_map(function(FileInfo $file) {
295 295
 			return $this->createNode($file->getPath(), $file);
296 296
 		}, $files);
297 297
 	}
298 298
 
299 299
 	private function cacheEntryToFileInfo(IMountPoint $mount, string $appendRoot, ICacheEntry $cacheEntry): FileInfo {
300 300
 		$cacheEntry['internalPath'] = $cacheEntry['path'];
301
-		$cacheEntry['path'] = $appendRoot . $cacheEntry->getPath();
302
-		$subPath = $cacheEntry['path'] !== '' ? '/' . $cacheEntry['path'] : '';
303
-		return new \OC\Files\FileInfo($this->path . $subPath, $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount);
301
+		$cacheEntry['path'] = $appendRoot.$cacheEntry->getPath();
302
+		$subPath = $cacheEntry['path'] !== '' ? '/'.$cacheEntry['path'] : '';
303
+		return new \OC\Files\FileInfo($this->path.$subPath, $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount);
304 304
 	}
305 305
 
306 306
 	/**
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
 	 */
312 312
 	public function searchByMime($mimetype) {
313 313
 		if (strpos($mimetype, '/') === false) {
314
-			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', $mimetype . '/%'));
314
+			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', $mimetype.'/%'));
315 315
 		} else {
316 316
 			$query = $this->queryFromOperator(new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', $mimetype));
317 317
 		}
@@ -335,12 +335,12 @@  discard block
 block discarded – undo
335 335
 	 * @return \OC\Files\Node\Node[]
336 336
 	 */
337 337
 	public function getById($id) {
338
-		return $this->root->getByIdInPath((int)$id, $this->getPath());
338
+		return $this->root->getByIdInPath((int) $id, $this->getPath());
339 339
 	}
340 340
 
341 341
 	protected function getAppDataDirectoryName(): string {
342 342
 		$instanceId = \OC::$server->getConfig()->getSystemValueString('instanceid');
343
-		return 'appdata_' . $instanceId;
343
+		return 'appdata_'.$instanceId;
344 344
 	}
345 345
 
346 346
 	/**
@@ -362,8 +362,8 @@  discard block
 block discarded – undo
362 362
 			return [];
363 363
 		}
364 364
 
365
-		$absolutePath = '/' . ltrim($cacheEntry->getPath(), '/');
366
-		$currentPath = rtrim($this->path, '/') . '/';
365
+		$absolutePath = '/'.ltrim($cacheEntry->getPath(), '/');
366
+		$currentPath = rtrim($this->path, '/').'/';
367 367
 
368 368
 		if (strpos($absolutePath, $currentPath) !== 0) {
369 369
 			return [];
Please login to merge, or discard this patch.
lib/private/Preview/ProviderV1Adapter.php 1 patch
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -34,30 +34,30 @@
 block discarded – undo
34 34
 use OCP\Preview\IProviderV2;
35 35
 
36 36
 class ProviderV1Adapter implements IProviderV2 {
37
-	private $providerV1;
37
+    private $providerV1;
38 38
 
39
-	public function __construct(IProvider $providerV1) {
40
-		$this->providerV1 = $providerV1;
41
-	}
39
+    public function __construct(IProvider $providerV1) {
40
+        $this->providerV1 = $providerV1;
41
+    }
42 42
 
43
-	public function getMimeType(): string {
44
-		return (string)$this->providerV1->getMimeType();
45
-	}
43
+    public function getMimeType(): string {
44
+        return (string)$this->providerV1->getMimeType();
45
+    }
46 46
 
47
-	public function isAvailable(FileInfo $file): bool {
48
-		return (bool)$this->providerV1->isAvailable($file);
49
-	}
47
+    public function isAvailable(FileInfo $file): bool {
48
+        return (bool)$this->providerV1->isAvailable($file);
49
+    }
50 50
 
51
-	public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
52
-		[$view, $path] = $this->getViewAndPath($file);
53
-		$thumbnail = $this->providerV1->getThumbnail($path, $maxX, $maxY, false, $view);
54
-		return $thumbnail === false ? null: $thumbnail;
55
-	}
51
+    public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
52
+        [$view, $path] = $this->getViewAndPath($file);
53
+        $thumbnail = $this->providerV1->getThumbnail($path, $maxX, $maxY, false, $view);
54
+        return $thumbnail === false ? null: $thumbnail;
55
+    }
56 56
 
57
-	private function getViewAndPath(File $file) {
58
-		$view = new View(dirname($file->getPath()));
59
-		$path = $file->getName();
57
+    private function getViewAndPath(File $file) {
58
+        $view = new View(dirname($file->getPath()));
59
+        $path = $file->getName();
60 60
 
61
-		return [$view, $path];
62
-	}
61
+        return [$view, $path];
62
+    }
63 63
 }
Please login to merge, or discard this patch.