Passed
Push — master ( 9d1d4d...58de24 )
by Morris
12:22
created
lib/private/Files/Node/Folder.php 2 patches
Indentation   +422 added lines, -422 removed lines patch added patch discarded remove patch
@@ -37,426 +37,426 @@
 block discarded – undo
37 37
 use OCP\Files\Search\ISearchOperator;
38 38
 
39 39
 class Folder extends Node implements \OCP\Files\Folder {
40
-	/**
41
-	 * Creates a Folder that represents a non-existing path
42
-	 *
43
-	 * @param string $path path
44
-	 * @return string non-existing node class
45
-	 */
46
-	protected function createNonExistingNode($path) {
47
-		return new NonExistingFolder($this->root, $this->view, $path);
48
-	}
49
-
50
-	/**
51
-	 * @param string $path path relative to the folder
52
-	 * @return string
53
-	 * @throws \OCP\Files\NotPermittedException
54
-	 */
55
-	public function getFullPath($path) {
56
-		if (!$this->isValidPath($path)) {
57
-			throw new NotPermittedException('Invalid path');
58
-		}
59
-		return $this->path . $this->normalizePath($path);
60
-	}
61
-
62
-	/**
63
-	 * @param string $path
64
-	 * @return string
65
-	 */
66
-	public function getRelativePath($path) {
67
-		if ($this->path === '' or $this->path === '/') {
68
-			return $this->normalizePath($path);
69
-		}
70
-		if ($path === $this->path) {
71
-			return '/';
72
-		} else if (strpos($path, $this->path . '/') !== 0) {
73
-			return null;
74
-		} else {
75
-			$path = substr($path, strlen($this->path));
76
-			return $this->normalizePath($path);
77
-		}
78
-	}
79
-
80
-	/**
81
-	 * check if a node is a (grand-)child of the folder
82
-	 *
83
-	 * @param \OC\Files\Node\Node $node
84
-	 * @return bool
85
-	 */
86
-	public function isSubNode($node) {
87
-		return strpos($node->getPath(), $this->path . '/') === 0;
88
-	}
89
-
90
-	/**
91
-	 * get the content of this directory
92
-	 *
93
-	 * @throws \OCP\Files\NotFoundException
94
-	 * @return Node[]
95
-	 */
96
-	public function getDirectoryListing() {
97
-		$folderContent = $this->view->getDirectoryContent($this->path);
98
-
99
-		return array_map(function (FileInfo $info) {
100
-			if ($info->getMimetype() === 'httpd/unix-directory') {
101
-				return new Folder($this->root, $this->view, $info->getPath(), $info);
102
-			} else {
103
-				return new File($this->root, $this->view, $info->getPath(), $info);
104
-			}
105
-		}, $folderContent);
106
-	}
107
-
108
-	/**
109
-	 * @param string $path
110
-	 * @param FileInfo $info
111
-	 * @return File|Folder
112
-	 */
113
-	protected function createNode($path, FileInfo $info = null) {
114
-		if (is_null($info)) {
115
-			$isDir = $this->view->is_dir($path);
116
-		} else {
117
-			$isDir = $info->getType() === FileInfo::TYPE_FOLDER;
118
-		}
119
-		if ($isDir) {
120
-			return new Folder($this->root, $this->view, $path, $info);
121
-		} else {
122
-			return new File($this->root, $this->view, $path, $info);
123
-		}
124
-	}
125
-
126
-	/**
127
-	 * Get the node at $path
128
-	 *
129
-	 * @param string $path
130
-	 * @return \OC\Files\Node\Node
131
-	 * @throws \OCP\Files\NotFoundException
132
-	 */
133
-	public function get($path) {
134
-		return $this->root->get($this->getFullPath($path));
135
-	}
136
-
137
-	/**
138
-	 * @param string $path
139
-	 * @return bool
140
-	 */
141
-	public function nodeExists($path) {
142
-		try {
143
-			$this->get($path);
144
-			return true;
145
-		} catch (NotFoundException $e) {
146
-			return false;
147
-		}
148
-	}
149
-
150
-	/**
151
-	 * @param string $path
152
-	 * @return \OC\Files\Node\Folder
153
-	 * @throws \OCP\Files\NotPermittedException
154
-	 */
155
-	public function newFolder($path) {
156
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
157
-			$fullPath = $this->getFullPath($path);
158
-			$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
159
-			$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
160
-			$this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
161
-			$this->view->mkdir($fullPath);
162
-			$node = new Folder($this->root, $this->view, $fullPath);
163
-			$this->root->emit('\OC\Files', 'postWrite', array($node));
164
-			$this->root->emit('\OC\Files', 'postCreate', array($node));
165
-			return $node;
166
-		} else {
167
-			throw new NotPermittedException('No create permission for folder');
168
-		}
169
-	}
170
-
171
-	/**
172
-	 * @param string $path
173
-	 * @return \OC\Files\Node\File
174
-	 * @throws \OCP\Files\NotPermittedException
175
-	 */
176
-	public function newFile($path) {
177
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
178
-			$fullPath = $this->getFullPath($path);
179
-			$nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
180
-			$this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
181
-			$this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
182
-			$this->view->touch($fullPath);
183
-			$node = new File($this->root, $this->view, $fullPath);
184
-			$this->root->emit('\OC\Files', 'postWrite', array($node));
185
-			$this->root->emit('\OC\Files', 'postCreate', array($node));
186
-			return $node;
187
-		} else {
188
-			throw new NotPermittedException('No create permission for path');
189
-		}
190
-	}
191
-
192
-	/**
193
-	 * search for files with the name matching $query
194
-	 *
195
-	 * @param string|ISearchOperator $query
196
-	 * @return \OC\Files\Node\Node[]
197
-	 */
198
-	public function search($query) {
199
-		if (is_string($query)) {
200
-			return $this->searchCommon('search', array('%' . $query . '%'));
201
-		} else {
202
-			return $this->searchCommon('searchQuery', array($query));
203
-		}
204
-	}
205
-
206
-	/**
207
-	 * search for files by mimetype
208
-	 *
209
-	 * @param string $mimetype
210
-	 * @return Node[]
211
-	 */
212
-	public function searchByMime($mimetype) {
213
-		return $this->searchCommon('searchByMime', array($mimetype));
214
-	}
215
-
216
-	/**
217
-	 * search for files by tag
218
-	 *
219
-	 * @param string|int $tag name or tag id
220
-	 * @param string $userId owner of the tags
221
-	 * @return Node[]
222
-	 */
223
-	public function searchByTag($tag, $userId) {
224
-		return $this->searchCommon('searchByTag', array($tag, $userId));
225
-	}
226
-
227
-	/**
228
-	 * @param string $method cache method
229
-	 * @param array $args call args
230
-	 * @return \OC\Files\Node\Node[]
231
-	 */
232
-	private function searchCommon($method, $args) {
233
-		$files = array();
234
-		$rootLength = strlen($this->path);
235
-		$mount = $this->root->getMount($this->path);
236
-		$storage = $mount->getStorage();
237
-		$internalPath = $mount->getInternalPath($this->path);
238
-		$internalPath = rtrim($internalPath, '/');
239
-		if ($internalPath !== '') {
240
-			$internalPath = $internalPath . '/';
241
-		}
242
-		$internalRootLength = strlen($internalPath);
243
-
244
-		$cache = $storage->getCache('');
245
-
246
-		$results = call_user_func_array(array($cache, $method), $args);
247
-		foreach ($results as $result) {
248
-			if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
249
-				$result['internalPath'] = $result['path'];
250
-				$result['path'] = substr($result['path'], $internalRootLength);
251
-				$result['storage'] = $storage;
252
-				$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
253
-			}
254
-		}
255
-
256
-		$mounts = $this->root->getMountsIn($this->path);
257
-		foreach ($mounts as $mount) {
258
-			$storage = $mount->getStorage();
259
-			if ($storage) {
260
-				$cache = $storage->getCache('');
261
-
262
-				$relativeMountPoint = ltrim(substr($mount->getMountPoint(), $rootLength), '/');
263
-				$results = call_user_func_array(array($cache, $method), $args);
264
-				foreach ($results as $result) {
265
-					$result['internalPath'] = $result['path'];
266
-					$result['path'] = $relativeMountPoint . $result['path'];
267
-					$result['storage'] = $storage;
268
-					$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
269
-				}
270
-			}
271
-		}
272
-
273
-		return array_map(function (FileInfo $file) {
274
-			return $this->createNode($file->getPath(), $file);
275
-		}, $files);
276
-	}
277
-
278
-	/**
279
-	 * @param int $id
280
-	 * @return \OC\Files\Node\Node[]
281
-	 */
282
-	public function getById($id) {
283
-		$mountCache = $this->root->getUserMountCache();
284
-		if (strpos($this->getPath(), '/', 1) > 0) {
285
-			list(, $user) = explode('/', $this->getPath());
286
-		} else {
287
-			$user = null;
288
-		}
289
-		$mountsContainingFile = $mountCache->getMountsForFileId((int)$id, $user);
290
-		$mounts = $this->root->getMountsIn($this->path);
291
-		$mounts[] = $this->root->getMount($this->path);
292
-		/** @var IMountPoint[] $folderMounts */
293
-		$folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) {
294
-			return $mountPoint->getMountPoint();
295
-		}, $mounts), $mounts);
296
-
297
-		/** @var ICachedMountInfo[] $mountsContainingFile */
298
-		$mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
299
-			return isset($folderMounts[$cachedMountInfo->getMountPoint()]);
300
-		}));
301
-
302
-		if (count($mountsContainingFile) === 0) {
303
-			return [];
304
-		}
305
-
306
-		$nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($folderMounts, $id) {
307
-			$mount = $folderMounts[$cachedMountInfo->getMountPoint()];
308
-			$cacheEntry = $mount->getStorage()->getCache()->get((int)$id);
309
-			if (!$cacheEntry) {
310
-				return null;
311
-			}
312
-
313
-			// cache jails will hide the "true" internal path
314
-			$internalPath = ltrim($cachedMountInfo->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/');
315
-			$pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath()));
316
-			$pathRelativeToMount = ltrim($pathRelativeToMount, '/');
317
-			$absolutePath = rtrim($cachedMountInfo->getMountPoint() . $pathRelativeToMount, '/');
318
-			return $this->root->createNode($absolutePath, new \OC\Files\FileInfo(
319
-				$absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
320
-				\OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
321
-			));
322
-		}, $mountsContainingFile);
323
-
324
-		$nodes = array_filter($nodes);
325
-
326
-		return array_filter($nodes, function (Node $node) {
327
-			return $this->getRelativePath($node->getPath());
328
-		});
329
-	}
330
-
331
-	public function getFreeSpace() {
332
-		return $this->view->free_space($this->path);
333
-	}
334
-
335
-	public function delete() {
336
-		if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
337
-			$this->sendHooks(array('preDelete'));
338
-			$fileInfo = $this->getFileInfo();
339
-			$this->view->rmdir($this->path);
340
-			$nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
341
-			$this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
342
-			$this->exists = false;
343
-		} else {
344
-			throw new NotPermittedException('No delete permission for path');
345
-		}
346
-	}
347
-
348
-	/**
349
-	 * Add a suffix to the name in case the file exists
350
-	 *
351
-	 * @param string $name
352
-	 * @return string
353
-	 * @throws NotPermittedException
354
-	 */
355
-	public function getNonExistingName($name) {
356
-		$uniqueName = \OC_Helper::buildNotExistingFileNameForView($this->getPath(), $name, $this->view);
357
-		return trim($this->getRelativePath($uniqueName), '/');
358
-	}
359
-
360
-	/**
361
-	 * @param int $limit
362
-	 * @param int $offset
363
-	 * @return \OCP\Files\Node[]
364
-	 */
365
-	public function getRecent($limit, $offset = 0) {
366
-		$mimetypeLoader = \OC::$server->getMimeTypeLoader();
367
-		$mounts = $this->root->getMountsIn($this->path);
368
-		$mounts[] = $this->getMountPoint();
369
-
370
-		$mounts = array_filter($mounts, function (IMountPoint $mount) {
371
-			return $mount->getStorage();
372
-		});
373
-		$storageIds = array_map(function (IMountPoint $mount) {
374
-			return $mount->getStorage()->getCache()->getNumericStorageId();
375
-		}, $mounts);
376
-		/** @var IMountPoint[] $mountMap */
377
-		$mountMap = array_combine($storageIds, $mounts);
378
-		$folderMimetype = $mimetypeLoader->getId(FileInfo::MIMETYPE_FOLDER);
379
-
380
-		// Search in batches of 500 entries
381
-		$searchLimit = 500;
382
-		$results = [];
383
-		do {
384
-			$searchResult = $this->recentSearch($searchLimit, $offset, $storageIds, $folderMimetype);
385
-
386
-			// Exit condition if there are no more results
387
-			if (count($searchResult) === 0) {
388
-				break;
389
-			}
390
-
391
-			$parseResult = $this->recentParse($searchResult, $mountMap, $mimetypeLoader);
392
-
393
-			foreach ($parseResult as $result) {
394
-				$results[] = $result;
395
-			}
396
-
397
-			$offset += $searchLimit;
398
-		} while (count($results) < $limit);
399
-
400
-		return array_slice($results, 0, $limit);
401
-	}
402
-
403
-	private function recentSearch($limit, $offset, $storageIds, $folderMimetype) {
404
-		$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
405
-		$query = $builder
406
-			->select('f.*')
407
-			->from('filecache', 'f')
408
-			->andWhere($builder->expr()->in('f.storage', $builder->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)))
409
-			->andWhere($builder->expr()->orX(
410
-			// handle non empty folders separate
411
-				$builder->expr()->neq('f.mimetype', $builder->createNamedParameter($folderMimetype, IQueryBuilder::PARAM_INT)),
412
-				$builder->expr()->eq('f.size', new Literal(0))
413
-			))
414
-			->andWhere($builder->expr()->notLike('f.path', $builder->createNamedParameter('files_versions/%')))
415
-			->andWhere($builder->expr()->notLike('f.path', $builder->createNamedParameter('files_trashbin/%')))
416
-			->orderBy('f.mtime', 'DESC')
417
-			->setMaxResults($limit)
418
-			->setFirstResult($offset);
419
-		return $query->execute()->fetchAll();
420
-	}
421
-
422
-	private function recentParse($result, $mountMap, $mimetypeLoader) {
423
-		$files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
424
-			$mount = $mountMap[$entry['storage']];
425
-			$entry['internalPath'] = $entry['path'];
426
-			$entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
427
-			$entry['mimepart'] = $mimetypeLoader->getMimetypeById($entry['mimepart']);
428
-			$path = $this->getAbsolutePath($mount, $entry['path']);
429
-			if (is_null($path)) {
430
-				return null;
431
-			}
432
-			$fileInfo = new \OC\Files\FileInfo($path, $mount->getStorage(), $entry['internalPath'], $entry, $mount);
433
-			return $this->root->createNode($fileInfo->getPath(), $fileInfo);
434
-		}, $result));
435
-
436
-		return array_values(array_filter($files, function (Node $node) {
437
-			$relative = $this->getRelativePath($node->getPath());
438
-			return $relative !== null && $relative !== '/';
439
-		}));
440
-	}
441
-
442
-	private function getAbsolutePath(IMountPoint $mount, $path) {
443
-		$storage = $mount->getStorage();
444
-		if ($storage->instanceOfStorage('\OC\Files\Storage\Wrapper\Jail')) {
445
-			if ($storage->instanceOfStorage(SharedStorage::class)) {
446
-				$storage->getSourceStorage();
447
-			}
448
-			/** @var \OC\Files\Storage\Wrapper\Jail $storage */
449
-			$jailRoot = $storage->getUnjailedPath('');
450
-			$rootLength = strlen($jailRoot) + 1;
451
-			if ($path === $jailRoot) {
452
-				return $mount->getMountPoint();
453
-			} else if (substr($path, 0, $rootLength) === $jailRoot . '/') {
454
-				return $mount->getMountPoint() . substr($path, $rootLength);
455
-			} else {
456
-				return null;
457
-			}
458
-		} else {
459
-			return $mount->getMountPoint() . $path;
460
-		}
461
-	}
40
+    /**
41
+     * Creates a Folder that represents a non-existing path
42
+     *
43
+     * @param string $path path
44
+     * @return string non-existing node class
45
+     */
46
+    protected function createNonExistingNode($path) {
47
+        return new NonExistingFolder($this->root, $this->view, $path);
48
+    }
49
+
50
+    /**
51
+     * @param string $path path relative to the folder
52
+     * @return string
53
+     * @throws \OCP\Files\NotPermittedException
54
+     */
55
+    public function getFullPath($path) {
56
+        if (!$this->isValidPath($path)) {
57
+            throw new NotPermittedException('Invalid path');
58
+        }
59
+        return $this->path . $this->normalizePath($path);
60
+    }
61
+
62
+    /**
63
+     * @param string $path
64
+     * @return string
65
+     */
66
+    public function getRelativePath($path) {
67
+        if ($this->path === '' or $this->path === '/') {
68
+            return $this->normalizePath($path);
69
+        }
70
+        if ($path === $this->path) {
71
+            return '/';
72
+        } else if (strpos($path, $this->path . '/') !== 0) {
73
+            return null;
74
+        } else {
75
+            $path = substr($path, strlen($this->path));
76
+            return $this->normalizePath($path);
77
+        }
78
+    }
79
+
80
+    /**
81
+     * check if a node is a (grand-)child of the folder
82
+     *
83
+     * @param \OC\Files\Node\Node $node
84
+     * @return bool
85
+     */
86
+    public function isSubNode($node) {
87
+        return strpos($node->getPath(), $this->path . '/') === 0;
88
+    }
89
+
90
+    /**
91
+     * get the content of this directory
92
+     *
93
+     * @throws \OCP\Files\NotFoundException
94
+     * @return Node[]
95
+     */
96
+    public function getDirectoryListing() {
97
+        $folderContent = $this->view->getDirectoryContent($this->path);
98
+
99
+        return array_map(function (FileInfo $info) {
100
+            if ($info->getMimetype() === 'httpd/unix-directory') {
101
+                return new Folder($this->root, $this->view, $info->getPath(), $info);
102
+            } else {
103
+                return new File($this->root, $this->view, $info->getPath(), $info);
104
+            }
105
+        }, $folderContent);
106
+    }
107
+
108
+    /**
109
+     * @param string $path
110
+     * @param FileInfo $info
111
+     * @return File|Folder
112
+     */
113
+    protected function createNode($path, FileInfo $info = null) {
114
+        if (is_null($info)) {
115
+            $isDir = $this->view->is_dir($path);
116
+        } else {
117
+            $isDir = $info->getType() === FileInfo::TYPE_FOLDER;
118
+        }
119
+        if ($isDir) {
120
+            return new Folder($this->root, $this->view, $path, $info);
121
+        } else {
122
+            return new File($this->root, $this->view, $path, $info);
123
+        }
124
+    }
125
+
126
+    /**
127
+     * Get the node at $path
128
+     *
129
+     * @param string $path
130
+     * @return \OC\Files\Node\Node
131
+     * @throws \OCP\Files\NotFoundException
132
+     */
133
+    public function get($path) {
134
+        return $this->root->get($this->getFullPath($path));
135
+    }
136
+
137
+    /**
138
+     * @param string $path
139
+     * @return bool
140
+     */
141
+    public function nodeExists($path) {
142
+        try {
143
+            $this->get($path);
144
+            return true;
145
+        } catch (NotFoundException $e) {
146
+            return false;
147
+        }
148
+    }
149
+
150
+    /**
151
+     * @param string $path
152
+     * @return \OC\Files\Node\Folder
153
+     * @throws \OCP\Files\NotPermittedException
154
+     */
155
+    public function newFolder($path) {
156
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
157
+            $fullPath = $this->getFullPath($path);
158
+            $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
159
+            $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
160
+            $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
161
+            $this->view->mkdir($fullPath);
162
+            $node = new Folder($this->root, $this->view, $fullPath);
163
+            $this->root->emit('\OC\Files', 'postWrite', array($node));
164
+            $this->root->emit('\OC\Files', 'postCreate', array($node));
165
+            return $node;
166
+        } else {
167
+            throw new NotPermittedException('No create permission for folder');
168
+        }
169
+    }
170
+
171
+    /**
172
+     * @param string $path
173
+     * @return \OC\Files\Node\File
174
+     * @throws \OCP\Files\NotPermittedException
175
+     */
176
+    public function newFile($path) {
177
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
178
+            $fullPath = $this->getFullPath($path);
179
+            $nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
180
+            $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
181
+            $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
182
+            $this->view->touch($fullPath);
183
+            $node = new File($this->root, $this->view, $fullPath);
184
+            $this->root->emit('\OC\Files', 'postWrite', array($node));
185
+            $this->root->emit('\OC\Files', 'postCreate', array($node));
186
+            return $node;
187
+        } else {
188
+            throw new NotPermittedException('No create permission for path');
189
+        }
190
+    }
191
+
192
+    /**
193
+     * search for files with the name matching $query
194
+     *
195
+     * @param string|ISearchOperator $query
196
+     * @return \OC\Files\Node\Node[]
197
+     */
198
+    public function search($query) {
199
+        if (is_string($query)) {
200
+            return $this->searchCommon('search', array('%' . $query . '%'));
201
+        } else {
202
+            return $this->searchCommon('searchQuery', array($query));
203
+        }
204
+    }
205
+
206
+    /**
207
+     * search for files by mimetype
208
+     *
209
+     * @param string $mimetype
210
+     * @return Node[]
211
+     */
212
+    public function searchByMime($mimetype) {
213
+        return $this->searchCommon('searchByMime', array($mimetype));
214
+    }
215
+
216
+    /**
217
+     * search for files by tag
218
+     *
219
+     * @param string|int $tag name or tag id
220
+     * @param string $userId owner of the tags
221
+     * @return Node[]
222
+     */
223
+    public function searchByTag($tag, $userId) {
224
+        return $this->searchCommon('searchByTag', array($tag, $userId));
225
+    }
226
+
227
+    /**
228
+     * @param string $method cache method
229
+     * @param array $args call args
230
+     * @return \OC\Files\Node\Node[]
231
+     */
232
+    private function searchCommon($method, $args) {
233
+        $files = array();
234
+        $rootLength = strlen($this->path);
235
+        $mount = $this->root->getMount($this->path);
236
+        $storage = $mount->getStorage();
237
+        $internalPath = $mount->getInternalPath($this->path);
238
+        $internalPath = rtrim($internalPath, '/');
239
+        if ($internalPath !== '') {
240
+            $internalPath = $internalPath . '/';
241
+        }
242
+        $internalRootLength = strlen($internalPath);
243
+
244
+        $cache = $storage->getCache('');
245
+
246
+        $results = call_user_func_array(array($cache, $method), $args);
247
+        foreach ($results as $result) {
248
+            if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
249
+                $result['internalPath'] = $result['path'];
250
+                $result['path'] = substr($result['path'], $internalRootLength);
251
+                $result['storage'] = $storage;
252
+                $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
253
+            }
254
+        }
255
+
256
+        $mounts = $this->root->getMountsIn($this->path);
257
+        foreach ($mounts as $mount) {
258
+            $storage = $mount->getStorage();
259
+            if ($storage) {
260
+                $cache = $storage->getCache('');
261
+
262
+                $relativeMountPoint = ltrim(substr($mount->getMountPoint(), $rootLength), '/');
263
+                $results = call_user_func_array(array($cache, $method), $args);
264
+                foreach ($results as $result) {
265
+                    $result['internalPath'] = $result['path'];
266
+                    $result['path'] = $relativeMountPoint . $result['path'];
267
+                    $result['storage'] = $storage;
268
+                    $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
269
+                }
270
+            }
271
+        }
272
+
273
+        return array_map(function (FileInfo $file) {
274
+            return $this->createNode($file->getPath(), $file);
275
+        }, $files);
276
+    }
277
+
278
+    /**
279
+     * @param int $id
280
+     * @return \OC\Files\Node\Node[]
281
+     */
282
+    public function getById($id) {
283
+        $mountCache = $this->root->getUserMountCache();
284
+        if (strpos($this->getPath(), '/', 1) > 0) {
285
+            list(, $user) = explode('/', $this->getPath());
286
+        } else {
287
+            $user = null;
288
+        }
289
+        $mountsContainingFile = $mountCache->getMountsForFileId((int)$id, $user);
290
+        $mounts = $this->root->getMountsIn($this->path);
291
+        $mounts[] = $this->root->getMount($this->path);
292
+        /** @var IMountPoint[] $folderMounts */
293
+        $folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) {
294
+            return $mountPoint->getMountPoint();
295
+        }, $mounts), $mounts);
296
+
297
+        /** @var ICachedMountInfo[] $mountsContainingFile */
298
+        $mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
299
+            return isset($folderMounts[$cachedMountInfo->getMountPoint()]);
300
+        }));
301
+
302
+        if (count($mountsContainingFile) === 0) {
303
+            return [];
304
+        }
305
+
306
+        $nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($folderMounts, $id) {
307
+            $mount = $folderMounts[$cachedMountInfo->getMountPoint()];
308
+            $cacheEntry = $mount->getStorage()->getCache()->get((int)$id);
309
+            if (!$cacheEntry) {
310
+                return null;
311
+            }
312
+
313
+            // cache jails will hide the "true" internal path
314
+            $internalPath = ltrim($cachedMountInfo->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/');
315
+            $pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath()));
316
+            $pathRelativeToMount = ltrim($pathRelativeToMount, '/');
317
+            $absolutePath = rtrim($cachedMountInfo->getMountPoint() . $pathRelativeToMount, '/');
318
+            return $this->root->createNode($absolutePath, new \OC\Files\FileInfo(
319
+                $absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
320
+                \OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
321
+            ));
322
+        }, $mountsContainingFile);
323
+
324
+        $nodes = array_filter($nodes);
325
+
326
+        return array_filter($nodes, function (Node $node) {
327
+            return $this->getRelativePath($node->getPath());
328
+        });
329
+    }
330
+
331
+    public function getFreeSpace() {
332
+        return $this->view->free_space($this->path);
333
+    }
334
+
335
+    public function delete() {
336
+        if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
337
+            $this->sendHooks(array('preDelete'));
338
+            $fileInfo = $this->getFileInfo();
339
+            $this->view->rmdir($this->path);
340
+            $nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
341
+            $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
342
+            $this->exists = false;
343
+        } else {
344
+            throw new NotPermittedException('No delete permission for path');
345
+        }
346
+    }
347
+
348
+    /**
349
+     * Add a suffix to the name in case the file exists
350
+     *
351
+     * @param string $name
352
+     * @return string
353
+     * @throws NotPermittedException
354
+     */
355
+    public function getNonExistingName($name) {
356
+        $uniqueName = \OC_Helper::buildNotExistingFileNameForView($this->getPath(), $name, $this->view);
357
+        return trim($this->getRelativePath($uniqueName), '/');
358
+    }
359
+
360
+    /**
361
+     * @param int $limit
362
+     * @param int $offset
363
+     * @return \OCP\Files\Node[]
364
+     */
365
+    public function getRecent($limit, $offset = 0) {
366
+        $mimetypeLoader = \OC::$server->getMimeTypeLoader();
367
+        $mounts = $this->root->getMountsIn($this->path);
368
+        $mounts[] = $this->getMountPoint();
369
+
370
+        $mounts = array_filter($mounts, function (IMountPoint $mount) {
371
+            return $mount->getStorage();
372
+        });
373
+        $storageIds = array_map(function (IMountPoint $mount) {
374
+            return $mount->getStorage()->getCache()->getNumericStorageId();
375
+        }, $mounts);
376
+        /** @var IMountPoint[] $mountMap */
377
+        $mountMap = array_combine($storageIds, $mounts);
378
+        $folderMimetype = $mimetypeLoader->getId(FileInfo::MIMETYPE_FOLDER);
379
+
380
+        // Search in batches of 500 entries
381
+        $searchLimit = 500;
382
+        $results = [];
383
+        do {
384
+            $searchResult = $this->recentSearch($searchLimit, $offset, $storageIds, $folderMimetype);
385
+
386
+            // Exit condition if there are no more results
387
+            if (count($searchResult) === 0) {
388
+                break;
389
+            }
390
+
391
+            $parseResult = $this->recentParse($searchResult, $mountMap, $mimetypeLoader);
392
+
393
+            foreach ($parseResult as $result) {
394
+                $results[] = $result;
395
+            }
396
+
397
+            $offset += $searchLimit;
398
+        } while (count($results) < $limit);
399
+
400
+        return array_slice($results, 0, $limit);
401
+    }
402
+
403
+    private function recentSearch($limit, $offset, $storageIds, $folderMimetype) {
404
+        $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
405
+        $query = $builder
406
+            ->select('f.*')
407
+            ->from('filecache', 'f')
408
+            ->andWhere($builder->expr()->in('f.storage', $builder->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY)))
409
+            ->andWhere($builder->expr()->orX(
410
+            // handle non empty folders separate
411
+                $builder->expr()->neq('f.mimetype', $builder->createNamedParameter($folderMimetype, IQueryBuilder::PARAM_INT)),
412
+                $builder->expr()->eq('f.size', new Literal(0))
413
+            ))
414
+            ->andWhere($builder->expr()->notLike('f.path', $builder->createNamedParameter('files_versions/%')))
415
+            ->andWhere($builder->expr()->notLike('f.path', $builder->createNamedParameter('files_trashbin/%')))
416
+            ->orderBy('f.mtime', 'DESC')
417
+            ->setMaxResults($limit)
418
+            ->setFirstResult($offset);
419
+        return $query->execute()->fetchAll();
420
+    }
421
+
422
+    private function recentParse($result, $mountMap, $mimetypeLoader) {
423
+        $files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
424
+            $mount = $mountMap[$entry['storage']];
425
+            $entry['internalPath'] = $entry['path'];
426
+            $entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
427
+            $entry['mimepart'] = $mimetypeLoader->getMimetypeById($entry['mimepart']);
428
+            $path = $this->getAbsolutePath($mount, $entry['path']);
429
+            if (is_null($path)) {
430
+                return null;
431
+            }
432
+            $fileInfo = new \OC\Files\FileInfo($path, $mount->getStorage(), $entry['internalPath'], $entry, $mount);
433
+            return $this->root->createNode($fileInfo->getPath(), $fileInfo);
434
+        }, $result));
435
+
436
+        return array_values(array_filter($files, function (Node $node) {
437
+            $relative = $this->getRelativePath($node->getPath());
438
+            return $relative !== null && $relative !== '/';
439
+        }));
440
+    }
441
+
442
+    private function getAbsolutePath(IMountPoint $mount, $path) {
443
+        $storage = $mount->getStorage();
444
+        if ($storage->instanceOfStorage('\OC\Files\Storage\Wrapper\Jail')) {
445
+            if ($storage->instanceOfStorage(SharedStorage::class)) {
446
+                $storage->getSourceStorage();
447
+            }
448
+            /** @var \OC\Files\Storage\Wrapper\Jail $storage */
449
+            $jailRoot = $storage->getUnjailedPath('');
450
+            $rootLength = strlen($jailRoot) + 1;
451
+            if ($path === $jailRoot) {
452
+                return $mount->getMountPoint();
453
+            } else if (substr($path, 0, $rootLength) === $jailRoot . '/') {
454
+                return $mount->getMountPoint() . substr($path, $rootLength);
455
+            } else {
456
+                return null;
457
+            }
458
+        } else {
459
+            return $mount->getMountPoint() . $path;
460
+        }
461
+    }
462 462
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -56,7 +56,7 @@  discard block
 block discarded – undo
56 56
 		if (!$this->isValidPath($path)) {
57 57
 			throw new NotPermittedException('Invalid path');
58 58
 		}
59
-		return $this->path . $this->normalizePath($path);
59
+		return $this->path.$this->normalizePath($path);
60 60
 	}
61 61
 
62 62
 	/**
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 		}
70 70
 		if ($path === $this->path) {
71 71
 			return '/';
72
-		} else if (strpos($path, $this->path . '/') !== 0) {
72
+		} else if (strpos($path, $this->path.'/') !== 0) {
73 73
 			return null;
74 74
 		} else {
75 75
 			$path = substr($path, strlen($this->path));
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
 	 * @return bool
85 85
 	 */
86 86
 	public function isSubNode($node) {
87
-		return strpos($node->getPath(), $this->path . '/') === 0;
87
+		return strpos($node->getPath(), $this->path.'/') === 0;
88 88
 	}
89 89
 
90 90
 	/**
@@ -96,7 +96,7 @@  discard block
 block discarded – undo
96 96
 	public function getDirectoryListing() {
97 97
 		$folderContent = $this->view->getDirectoryContent($this->path);
98 98
 
99
-		return array_map(function (FileInfo $info) {
99
+		return array_map(function(FileInfo $info) {
100 100
 			if ($info->getMimetype() === 'httpd/unix-directory') {
101 101
 				return new Folder($this->root, $this->view, $info->getPath(), $info);
102 102
 			} else {
@@ -197,7 +197,7 @@  discard block
 block discarded – undo
197 197
 	 */
198 198
 	public function search($query) {
199 199
 		if (is_string($query)) {
200
-			return $this->searchCommon('search', array('%' . $query . '%'));
200
+			return $this->searchCommon('search', array('%'.$query.'%'));
201 201
 		} else {
202 202
 			return $this->searchCommon('searchQuery', array($query));
203 203
 		}
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
 		$internalPath = $mount->getInternalPath($this->path);
238 238
 		$internalPath = rtrim($internalPath, '/');
239 239
 		if ($internalPath !== '') {
240
-			$internalPath = $internalPath . '/';
240
+			$internalPath = $internalPath.'/';
241 241
 		}
242 242
 		$internalRootLength = strlen($internalPath);
243 243
 
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
 				$result['internalPath'] = $result['path'];
250 250
 				$result['path'] = substr($result['path'], $internalRootLength);
251 251
 				$result['storage'] = $storage;
252
-				$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
252
+				$files[] = new \OC\Files\FileInfo($this->path.'/'.$result['path'], $storage, $result['internalPath'], $result, $mount);
253 253
 			}
254 254
 		}
255 255
 
@@ -263,14 +263,14 @@  discard block
 block discarded – undo
263 263
 				$results = call_user_func_array(array($cache, $method), $args);
264 264
 				foreach ($results as $result) {
265 265
 					$result['internalPath'] = $result['path'];
266
-					$result['path'] = $relativeMountPoint . $result['path'];
266
+					$result['path'] = $relativeMountPoint.$result['path'];
267 267
 					$result['storage'] = $storage;
268
-					$files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
268
+					$files[] = new \OC\Files\FileInfo($this->path.'/'.$result['path'], $storage, $result['internalPath'], $result, $mount);
269 269
 				}
270 270
 			}
271 271
 		}
272 272
 
273
-		return array_map(function (FileInfo $file) {
273
+		return array_map(function(FileInfo $file) {
274 274
 			return $this->createNode($file->getPath(), $file);
275 275
 		}, $files);
276 276
 	}
@@ -286,16 +286,16 @@  discard block
 block discarded – undo
286 286
 		} else {
287 287
 			$user = null;
288 288
 		}
289
-		$mountsContainingFile = $mountCache->getMountsForFileId((int)$id, $user);
289
+		$mountsContainingFile = $mountCache->getMountsForFileId((int) $id, $user);
290 290
 		$mounts = $this->root->getMountsIn($this->path);
291 291
 		$mounts[] = $this->root->getMount($this->path);
292 292
 		/** @var IMountPoint[] $folderMounts */
293
-		$folderMounts = array_combine(array_map(function (IMountPoint $mountPoint) {
293
+		$folderMounts = array_combine(array_map(function(IMountPoint $mountPoint) {
294 294
 			return $mountPoint->getMountPoint();
295 295
 		}, $mounts), $mounts);
296 296
 
297 297
 		/** @var ICachedMountInfo[] $mountsContainingFile */
298
-		$mountsContainingFile = array_values(array_filter($mountsContainingFile, function (ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
298
+		$mountsContainingFile = array_values(array_filter($mountsContainingFile, function(ICachedMountInfo $cachedMountInfo) use ($folderMounts) {
299 299
 			return isset($folderMounts[$cachedMountInfo->getMountPoint()]);
300 300
 		}));
301 301
 
@@ -303,18 +303,18 @@  discard block
 block discarded – undo
303 303
 			return [];
304 304
 		}
305 305
 
306
-		$nodes = array_map(function (ICachedMountInfo $cachedMountInfo) use ($folderMounts, $id) {
306
+		$nodes = array_map(function(ICachedMountInfo $cachedMountInfo) use ($folderMounts, $id) {
307 307
 			$mount = $folderMounts[$cachedMountInfo->getMountPoint()];
308
-			$cacheEntry = $mount->getStorage()->getCache()->get((int)$id);
308
+			$cacheEntry = $mount->getStorage()->getCache()->get((int) $id);
309 309
 			if (!$cacheEntry) {
310 310
 				return null;
311 311
 			}
312 312
 
313 313
 			// cache jails will hide the "true" internal path
314
-			$internalPath = ltrim($cachedMountInfo->getRootInternalPath() . '/' . $cacheEntry->getPath(), '/');
314
+			$internalPath = ltrim($cachedMountInfo->getRootInternalPath().'/'.$cacheEntry->getPath(), '/');
315 315
 			$pathRelativeToMount = substr($internalPath, strlen($cachedMountInfo->getRootInternalPath()));
316 316
 			$pathRelativeToMount = ltrim($pathRelativeToMount, '/');
317
-			$absolutePath = rtrim($cachedMountInfo->getMountPoint() . $pathRelativeToMount, '/');
317
+			$absolutePath = rtrim($cachedMountInfo->getMountPoint().$pathRelativeToMount, '/');
318 318
 			return $this->root->createNode($absolutePath, new \OC\Files\FileInfo(
319 319
 				$absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
320 320
 				\OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
 
324 324
 		$nodes = array_filter($nodes);
325 325
 
326
-		return array_filter($nodes, function (Node $node) {
326
+		return array_filter($nodes, function(Node $node) {
327 327
 			return $this->getRelativePath($node->getPath());
328 328
 		});
329 329
 	}
@@ -367,10 +367,10 @@  discard block
 block discarded – undo
367 367
 		$mounts = $this->root->getMountsIn($this->path);
368 368
 		$mounts[] = $this->getMountPoint();
369 369
 
370
-		$mounts = array_filter($mounts, function (IMountPoint $mount) {
370
+		$mounts = array_filter($mounts, function(IMountPoint $mount) {
371 371
 			return $mount->getStorage();
372 372
 		});
373
-		$storageIds = array_map(function (IMountPoint $mount) {
373
+		$storageIds = array_map(function(IMountPoint $mount) {
374 374
 			return $mount->getStorage()->getCache()->getNumericStorageId();
375 375
 		}, $mounts);
376 376
 		/** @var IMountPoint[] $mountMap */
@@ -420,7 +420,7 @@  discard block
 block discarded – undo
420 420
 	}
421 421
 
422 422
 	private function recentParse($result, $mountMap, $mimetypeLoader) {
423
-		$files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
423
+		$files = array_filter(array_map(function(array $entry) use ($mountMap, $mimetypeLoader) {
424 424
 			$mount = $mountMap[$entry['storage']];
425 425
 			$entry['internalPath'] = $entry['path'];
426 426
 			$entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
 			return $this->root->createNode($fileInfo->getPath(), $fileInfo);
434 434
 		}, $result));
435 435
 
436
-		return array_values(array_filter($files, function (Node $node) {
436
+		return array_values(array_filter($files, function(Node $node) {
437 437
 			$relative = $this->getRelativePath($node->getPath());
438 438
 			return $relative !== null && $relative !== '/';
439 439
 		}));
@@ -450,13 +450,13 @@  discard block
 block discarded – undo
450 450
 			$rootLength = strlen($jailRoot) + 1;
451 451
 			if ($path === $jailRoot) {
452 452
 				return $mount->getMountPoint();
453
-			} else if (substr($path, 0, $rootLength) === $jailRoot . '/') {
454
-				return $mount->getMountPoint() . substr($path, $rootLength);
453
+			} else if (substr($path, 0, $rootLength) === $jailRoot.'/') {
454
+				return $mount->getMountPoint().substr($path, $rootLength);
455 455
 			} else {
456 456
 				return null;
457 457
 			}
458 458
 		} else {
459
-			return $mount->getMountPoint() . $path;
459
+			return $mount->getMountPoint().$path;
460 460
 		}
461 461
 	}
462 462
 }
Please login to merge, or discard this patch.