Skip to content

Commit 3fd03fa

Browse files
authored
Merge pull request #38977 from nextcloud/backport/38625/stable26
[stable26] fix: expect interface, not a specific implementation
2 parents e36c9d6 + 013d349 commit 3fd03fa

File tree

9 files changed

+61
-44
lines changed

9 files changed

+61
-44
lines changed

lib/private/Files/Cache/QuerySearchHelper.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@
2626
namespace OC\Files\Cache;
2727

2828
use OC\Files\Cache\Wrapper\CacheJail;
29-
use OC\Files\Node\Root;
3029
use OC\Files\Search\QueryOptimizer\QueryOptimizer;
3130
use OC\Files\Search\SearchBinaryOperator;
3231
use OC\SystemConfig;
3332
use OCP\DB\QueryBuilder\IQueryBuilder;
3433
use OCP\Files\Cache\ICache;
3534
use OCP\Files\Cache\ICacheEntry;
36-
use OCP\Files\Folder;
3735
use OCP\Files\IMimeTypeLoader;
36+
use OCP\Files\IRootFolder;
3837
use OCP\Files\Mount\IMountPoint;
3938
use OCP\Files\Search\ISearchBinaryOperator;
4039
use OCP\Files\Search\ISearchQuery;
@@ -196,24 +195,29 @@ public function searchInCaches(ISearchQuery $searchQuery, array $caches): array
196195
}
197196

198197
/**
199-
* @return array{array<string, ICache>, array<string, IMountPoint>}
198+
* @return array{0?: array<array-key, ICache>, 1?: array<array-key, IMountPoint>}
200199
*/
201-
public function getCachesAndMountPointsForSearch(Root $root, string $path, bool $limitToHome = false): array {
200+
public function getCachesAndMountPointsForSearch(IRootFolder $root, string $path, bool $limitToHome = false): array {
202201
$rootLength = strlen($path);
203202
$mount = $root->getMount($path);
204203
$storage = $mount->getStorage();
204+
if ($storage === null) {
205+
return [];
206+
}
205207
$internalPath = $mount->getInternalPath($path);
206208

207209
if ($internalPath !== '') {
208210
// a temporary CacheJail is used to handle filtering down the results to within this folder
211+
/** @var ICache[] $caches */
209212
$caches = ['' => new CacheJail($storage->getCache(''), $internalPath)];
210213
} else {
214+
/** @var ICache[] $caches */
211215
$caches = ['' => $storage->getCache('')];
212216
}
217+
/** @var IMountPoint[] $mountByMountPoint */
213218
$mountByMountPoint = ['' => $mount];
214219

215220
if (!$limitToHome) {
216-
/** @var IMountPoint[] $mounts */
217221
$mounts = $root->getMountsIn($path);
218222
foreach ($mounts as $mount) {
219223
$storage = $mount->getStorage();

lib/private/Files/FileInfo.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,6 @@ public function getPath() {
147147
return $this->path;
148148
}
149149

150-
/**
151-
* @return \OCP\Files\Storage
152-
*/
153150
public function getStorage() {
154151
return $this->storage;
155152
}

lib/private/Files/Node/Folder.php

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
use OCP\Files\Cache\ICacheEntry;
4040
use OCP\Files\FileInfo;
4141
use OCP\Files\Mount\IMountPoint;
42+
use OCP\Files\Node as INode;
4243
use OCP\Files\NotFoundException;
4344
use OCP\Files\NotPermittedException;
4445
use OCP\Files\Search\ISearchBinaryOperator;
@@ -108,12 +109,7 @@ public function getDirectoryListing() {
108109
}, $folderContent);
109110
}
110111

111-
/**
112-
* @param string $path
113-
* @param FileInfo $info
114-
* @return File|Folder
115-
*/
116-
protected function createNode($path, FileInfo $info = null, bool $infoHasSubMountsIncluded = true) {
112+
protected function createNode(string $path, ?FileInfo $info = null, bool $infoHasSubMountsIncluded = true): INode {
117113
if (is_null($info)) {
118114
$isDir = $this->view->is_dir($path);
119115
} else {
@@ -234,6 +230,8 @@ public function search($query) {
234230

235231
/** @var QuerySearchHelper $searchHelper */
236232
$searchHelper = \OC::$server->get(QuerySearchHelper::class);
233+
/** @var \OCP\Files\Cache\ICache[] $caches */
234+
/** @var \OCP\Files\Mount\IMountPoint[] $mountByMountPoint */
237235
[$caches, $mountByMountPoint] = $searchHelper->getCachesAndMountPointsForSearch($this->root, $this->path, $limitToHome);
238236
$resultsPerCache = $searchHelper->searchInCaches($query, $caches);
239237

@@ -329,8 +327,15 @@ protected function getAppDataDirectoryName(): string {
329327
* @return array
330328
*/
331329
protected function getByIdInRootMount(int $id): array {
330+
if (!method_exists($this->root, 'createNode')) {
331+
// Always expected to be false. Being a method of Folder, this is
332+
// always implemented. For it is an internal method and should not
333+
// be exposed and made public, it is not part of an interface.
334+
return [];
335+
}
332336
$mount = $this->root->getMount('');
333-
$cacheEntry = $mount->getStorage()->getCache($this->path)->get($id);
337+
$storage = $mount->getStorage();
338+
$cacheEntry = $storage?->getCache($this->path)->get($id);
334339
if (!$cacheEntry) {
335340
return [];
336341
}
@@ -345,7 +350,7 @@ protected function getByIdInRootMount(int $id): array {
345350
return [$this->root->createNode(
346351
$absolutePath, new \OC\Files\FileInfo(
347352
$absolutePath,
348-
$mount->getStorage(),
353+
$storage,
349354
$cacheEntry->getPath(),
350355
$cacheEntry,
351356
$mount
@@ -383,7 +388,7 @@ public function getNonExistingName($name) {
383388
/**
384389
* @param int $limit
385390
* @param int $offset
386-
* @return \OCP\Files\Node[]
391+
* @return INode[]
387392
*/
388393
public function getRecent($limit, $offset = 0) {
389394
$filterOutNonEmptyFolder = new SearchBinaryOperator(

lib/private/Files/Node/LazyFolder.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
use OC\Files\Utils\PathHelper;
3030
use OCP\Constants;
31+
use OCP\Files\Mount\IMountPoint;
3132

3233
/**
3334
* Class LazyFolder
@@ -110,14 +111,14 @@ public function mount($storage, $mountPoint, $arguments = []) {
110111
/**
111112
* @inheritDoc
112113
*/
113-
public function getMount($mountPoint) {
114+
public function getMount(string $mountPoint): IMountPoint {
114115
return $this->__call(__FUNCTION__, func_get_args());
115116
}
116117

117118
/**
118-
* @inheritDoc
119+
* @return IMountPoint[]
119120
*/
120-
public function getMountsIn($mountPoint) {
121+
public function getMountsIn(string $mountPoint): array {
121122
return $this->__call(__FUNCTION__, func_get_args());
122123
}
123124

lib/private/Files/Node/Node.php

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,22 @@
3434
use OC\Files\Utils\PathHelper;
3535
use OCP\Files\FileInfo;
3636
use OCP\Files\InvalidPathException;
37+
use OCP\Files\IRootFolder;
38+
use OCP\Files\Node as INode;
3739
use OCP\Files\NotFoundException;
3840
use OCP\Files\NotPermittedException;
3941
use OCP\Lock\LockedException;
4042
use OCP\PreConditionNotMetException;
4143
use Symfony\Component\EventDispatcher\GenericEvent;
4244

4345
// FIXME: this class really should be abstract
44-
class Node implements \OCP\Files\Node {
46+
class Node implements INode {
4547
/**
4648
* @var \OC\Files\View $view
4749
*/
4850
protected $view;
4951

50-
/**
51-
* @var \OC\Files\Node\Root $root
52-
*/
53-
protected $root;
52+
protected IRootFolder $root;
5453

5554
/**
5655
* @var string $path Absolute path to the node (e.g. /admin/files/folder/file)
@@ -72,7 +71,7 @@ class Node implements \OCP\Files\Node {
7271
* @param string $path
7372
* @param FileInfo $fileInfo
7473
*/
75-
public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null, bool $infoHasSubMountsIncluded = true) {
74+
public function __construct(IRootFolder $root, $view, $path, $fileInfo = null, ?Node $parent = null, bool $infoHasSubMountsIncluded = true) {
7675
if (Filesystem::normalizePath($view->getRoot()) !== '/') {
7776
throw new PreConditionNotMetException('The view passed to the node should not have any fake root set');
7877
}
@@ -130,7 +129,9 @@ protected function sendHooks($hooks, array $args = null) {
130129
$args = !empty($args) ? $args : [$this];
131130
$dispatcher = \OC::$server->getEventDispatcher();
132131
foreach ($hooks as $hook) {
133-
$this->root->emit('\OC\Files', $hook, $args);
132+
if (method_exists($this->root, 'emit')) {
133+
$this->root->emit('\OC\Files', $hook, $args);
134+
}
134135
$dispatcher->dispatch('\OCP\Files::' . $hook, new GenericEvent($args));
135136
}
136137
}
@@ -290,10 +291,7 @@ public function isCreatable() {
290291
return $this->getFileInfo(false)->isCreatable();
291292
}
292293

293-
/**
294-
* @return Node
295-
*/
296-
public function getParent() {
294+
public function getParent(): INode|IRootFolder {
297295
if ($this->parent === null) {
298296
$newPath = dirname($this->path);
299297
if ($newPath === '' || $newPath === '.' || $newPath === '/') {
@@ -402,7 +400,7 @@ public function unlock($type) {
402400

403401
/**
404402
* @param string $targetPath
405-
* @return \OC\Files\Node\Node
403+
* @return INode
406404
* @throws InvalidPathException
407405
* @throws NotFoundException
408406
* @throws NotPermittedException if copy not allowed or failed
@@ -428,7 +426,7 @@ public function copy($targetPath) {
428426

429427
/**
430428
* @param string $targetPath
431-
* @return \OC\Files\Node\Node
429+
* @return INode
432430
* @throws InvalidPathException
433431
* @throws NotFoundException
434432
* @throws NotPermittedException if move not allowed or failed

lib/private/Files/Node/Root.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
use OCP\Files\Events\Node\FilesystemTornDownEvent;
4646
use OCP\Files\IRootFolder;
4747
use OCP\Files\Mount\IMountPoint;
48+
use OCP\Files\Node as INode;
4849
use OCP\Files\NotFoundException;
4950
use OCP\Files\NotPermittedException;
5051
use OCP\IUser;
@@ -153,19 +154,15 @@ public function mount($storage, $mountPoint, $arguments = []) {
153154
$this->mountManager->addMount($mount);
154155
}
155156

156-
/**
157-
* @param string $mountPoint
158-
* @return \OC\Files\Mount\MountPoint
159-
*/
160-
public function getMount($mountPoint) {
157+
public function getMount(string $mountPoint): IMountPoint {
161158
return $this->mountManager->find($mountPoint);
162159
}
163160

164161
/**
165162
* @param string $mountPoint
166163
* @return \OC\Files\Mount\MountPoint[]
167164
*/
168-
public function getMountsIn($mountPoint) {
165+
public function getMountsIn(string $mountPoint): array {
169166
return $this->mountManager->findIn($mountPoint);
170167
}
171168

@@ -339,10 +336,9 @@ public function isShareable() {
339336
}
340337

341338
/**
342-
* @return Node
343339
* @throws \OCP\Files\NotFoundException
344340
*/
345-
public function getParent() {
341+
public function getParent(): INode|IRootFolder {
346342
throw new NotFoundException();
347343
}
348344

lib/private/SystemTag/SystemTagsInFilesDetector.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public function detectAssignedSystemTagsIn(
5454
}
5555

5656
$query = new SearchQuery($operator, $limit, $offset, []);
57+
/** @var \OCP\Files\Cache\ICache[] $caches */
5758
[$caches, ] = $this->searchHelper->getCachesAndMountPointsForSearch(
5859
$this->getRootFolder($folder),
5960
$folder->getPath(),

lib/public/Files/IRootFolder.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
use OC\Hooks\Emitter;
2828
use OC\User\NoUserException;
29+
use OCP\Files\Mount\IMountPoint;
2930

3031
/**
3132
* Interface IRootFolder
@@ -55,4 +56,16 @@ public function getUserFolder($userId);
5556
* @since 24.0.0
5657
*/
5758
public function getByIdInPath(int $id, string $path);
59+
60+
/**
61+
* @return IMountPoint[]
62+
*
63+
* @since 26.0.4
64+
*/
65+
public function getMountsIn(string $mountPoint): array;
66+
67+
/**
68+
* @since 26.0.4
69+
*/
70+
public function getMount(string $mountPoint): IMountPoint;
5871
}

tests/lib/Files/Node/FolderTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use OC\Files\Storage\Temporary;
2525
use OC\Files\Storage\Wrapper\Jail;
2626
use OCP\Files\Cache\ICacheEntry;
27+
use OCP\Files\IRootFolder;
2728
use OCP\Files\Mount\IMountPoint;
2829
use OCP\Files\NotFoundException;
2930
use OCP\Files\Search\ISearchComparison;
@@ -462,12 +463,13 @@ public function testSearchSubStorages() {
462463
}
463464

464465
public function testIsSubNode() {
465-
$file = new Node(null, $this->view, '/foo/bar');
466-
$folder = new Folder(null, $this->view, '/foo');
466+
$rootFolderMock = $this->createMock(IRootFolder::class);
467+
$file = new Node($rootFolderMock, $this->view, '/foo/bar');
468+
$folder = new Folder($rootFolderMock, $this->view, '/foo');
467469
$this->assertTrue($folder->isSubNode($file));
468470
$this->assertFalse($folder->isSubNode($folder));
469471

470-
$file = new Node(null, $this->view, '/foobar');
472+
$file = new Node($rootFolderMock, $this->view, '/foobar');
471473
$this->assertFalse($folder->isSubNode($file));
472474
}
473475

0 commit comments

Comments
 (0)