aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Files/Node/Folder.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Files/Node/Folder.php')
-rw-r--r--lib/private/Files/Node/Folder.php72
1 files changed, 53 insertions, 19 deletions
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index 51b205d545b..7453b553119 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -12,6 +13,7 @@ use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchOrder;
use OC\Files\Search\SearchQuery;
use OC\Files\Utils\PathHelper;
+use OC\User\LazyUser;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\FileInfo;
use OCP\Files\Mount\IMountPoint;
@@ -26,6 +28,9 @@ use OCP\Files\Search\ISearchQuery;
use OCP\IUserManager;
class Folder extends Node implements \OCP\Files\Folder {
+
+ private ?IUserManager $userManager = null;
+
/**
* Creates a Folder that represents a non-existing path
*
@@ -99,26 +104,15 @@ class Folder extends Node implements \OCP\Files\Folder {
}
}
- /**
- * Get the node at $path
- *
- * @param string $path
- * @return \OC\Files\Node\Node
- * @throws \OCP\Files\NotFoundException
- */
public function get($path) {
return $this->root->get($this->getFullPath($path));
}
- /**
- * @param string $path
- * @return bool
- */
public function nodeExists($path) {
try {
$this->get($path);
return true;
- } catch (NotFoundException $e) {
+ } catch (NotFoundException|NotPermittedException) {
return false;
}
}
@@ -133,8 +127,21 @@ class Folder extends Node implements \OCP\Files\Folder {
$fullPath = $this->getFullPath($path);
$nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
$this->sendHooks(['preWrite', 'preCreate'], [$nonExisting]);
- if (!$this->view->mkdir($fullPath) && !$this->view->is_dir($fullPath)) {
- throw new NotPermittedException('Could not create folder "' . $fullPath . '"');
+ if (!$this->view->mkdir($fullPath)) {
+ // maybe another concurrent process created the folder already
+ if (!$this->view->is_dir($fullPath)) {
+ throw new NotPermittedException('Could not create folder "' . $fullPath . '"');
+ } else {
+ // we need to ensure we don't return before the concurrent request has finished updating the cache
+ $tries = 5;
+ while (!$this->view->getFileInfo($fullPath)) {
+ if ($tries < 1) {
+ throw new NotPermittedException('Could not create folder "' . $fullPath . '", folder exists but unable to get cache entry');
+ }
+ usleep(5 * 1000);
+ $tries--;
+ }
+ }
}
$parent = dirname($fullPath) === $this->getPath() ? $this : null;
$node = new Folder($this->root, $this->view, $fullPath, null, $parent);
@@ -218,9 +225,9 @@ class Folder extends Node implements \OCP\Files\Folder {
}, array_values($resultsPerCache), array_keys($resultsPerCache)));
// don't include this folder in the results
- $files = array_filter($files, function (FileInfo $file) {
+ $files = array_values(array_filter($files, function (FileInfo $file) {
return $file->getPath() !== $this->getPath();
- });
+ }));
// since results were returned per-cache, they are no longer fully sorted
$order = $query->getOrder();
@@ -245,7 +252,26 @@ class Folder extends Node implements \OCP\Files\Folder {
$cacheEntry['internalPath'] = $cacheEntry['path'];
$cacheEntry['path'] = rtrim($appendRoot . $cacheEntry->getPath(), '/');
$subPath = $cacheEntry['path'] !== '' ? '/' . $cacheEntry['path'] : '';
- return new \OC\Files\FileInfo($this->path . $subPath, $mount->getStorage(), $cacheEntry['internalPath'], $cacheEntry, $mount);
+ $storage = $mount->getStorage();
+
+ $owner = null;
+ $ownerId = $storage->getOwner($cacheEntry['internalPath']);
+ if ($ownerId !== false) {
+ // Cache the user manager (for performance)
+ if ($this->userManager === null) {
+ $this->userManager = \OCP\Server::get(IUserManager::class);
+ }
+ $owner = new LazyUser($ownerId, $this->userManager);
+ }
+
+ return new \OC\Files\FileInfo(
+ $this->path . $subPath,
+ $storage,
+ $cacheEntry['internalPath'],
+ $cacheEntry,
+ $mount,
+ $owner,
+ );
}
/**
@@ -289,7 +315,7 @@ class Folder extends Node implements \OCP\Files\Folder {
}
public function getFirstNodeById(int $id): ?\OCP\Files\Node {
- return current($this->getById($id)) ?: null;
+ return $this->root->getFirstNodeByIdInPath($id, $this->getPath());
}
public function getAppDataDirectoryName(): string {
@@ -399,7 +425,7 @@ class Folder extends Node implements \OCP\Files\Folder {
$filterNonRecentFiles = new SearchComparison(
ISearchComparison::COMPARE_GREATER_THAN,
'mtime',
- strtotime("-2 week")
+ strtotime('-2 week')
);
if ($offset === 0 && $limit <= 100) {
$query = new SearchQuery(
@@ -435,4 +461,12 @@ class Folder extends Node implements \OCP\Files\Folder {
return $this->search($query);
}
+
+ public function verifyPath($fileName, $readonly = false): void {
+ $this->view->verifyPath(
+ $this->getPath(),
+ $fileName,
+ $readonly,
+ );
+ }
}