Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/files/lib/Controller/ApiController.php82
-rw-r--r--apps/files_sharing/lib/Controller/ShareAPIController.php4
-rw-r--r--apps/files_trashbin/lib/Storage.php2
-rw-r--r--apps/settings/lib/Controller/AuthSettingsController.php20
-rw-r--r--build/package-lock.json56
-rw-r--r--build/package.json2
-rw-r--r--lib/private/Files/Node/Folder.php197
-rw-r--r--tests/lib/Files/Node/FolderTest.php13
8 files changed, 150 insertions, 226 deletions
diff --git a/apps/files/lib/Controller/ApiController.php b/apps/files/lib/Controller/ApiController.php
index 0cf261af726..20f60cde30d 100644
--- a/apps/files/lib/Controller/ApiController.php
+++ b/apps/files/lib/Controller/ApiController.php
@@ -177,9 +177,9 @@ class ApiController extends Controller {
* @return array
*/
private function formatNodes(array $nodes) {
- return array_values(array_map(function (Node $node) {
- /** @var \OC\Files\Node\Node $shareTypes */
- $shareTypes = $this->getShareTypes($node);
+ $shareTypesForNodes = $this->getShareTypesForNodes($nodes);
+ return array_values(array_map(function (Node $node) use ($shareTypesForNodes) {
+ $shareTypes = $shareTypesForNodes[$node->getId()] ?? [];
$file = \OCA\Files\Helper::formatFileInfo($node->getFileInfo());
$file['hasPreview'] = $this->previewManager->isAvailable($node);
$parts = explode('/', dirname($node->getPath()), 4);
@@ -196,28 +196,13 @@ class ApiController extends Controller {
}
/**
- * Returns a list of recently modifed files.
- *
- * @NoAdminRequired
+ * Get the share types for each node
*
- * @return DataResponse
- */
- public function getRecentFiles() {
- $nodes = $this->userFolder->getRecent(100);
- $files = $this->formatNodes($nodes);
- return new DataResponse(['files' => $files]);
- }
-
- /**
- * Return a list of share types for outgoing shares
- *
- * @param Node $node file node
- *
- * @return int[] array of share types
+ * @param \OCP\Files\Node[] $nodes
+ * @return array<int, int[]> list of share types for each fileid
*/
- private function getShareTypes(Node $node) {
+ private function getShareTypesForNodes(array $nodes): array {
$userId = $this->userSession->getUser()->getUID();
- $shareTypes = [];
$requestedShareTypes = [
IShare::TYPE_USER,
IShare::TYPE_GROUP,
@@ -227,23 +212,54 @@ class ApiController extends Controller {
IShare::TYPE_ROOM,
IShare::TYPE_DECK,
];
- foreach ($requestedShareTypes as $requestedShareType) {
- // one of each type is enough to find out about the types
- $shares = $this->shareManager->getSharesBy(
- $userId,
- $requestedShareType,
- $node,
- false,
- 1
- );
- if (!empty($shares)) {
- $shareTypes[] = $requestedShareType;
+ $shareTypes = [];
+
+ $nodeIds = array_map(function (Node $node) {
+ return $node->getId();
+ }, $nodes);
+
+ foreach ($requestedShareTypes as $shareType) {
+ $nodesLeft = array_combine($nodeIds, array_fill(0, count($nodeIds), true));
+ $offset = 0;
+
+ // fetch shares until we've either found shares for all nodes or there are no more shares left
+ while (count($nodesLeft) > 0) {
+ $shares = $this->shareManager->getSharesBy($userId, $shareType, null, false, 100, $offset);
+ foreach ($shares as $share) {
+ $fileId = $share->getNodeId();
+ if (isset($nodesLeft[$fileId])) {
+ if (!isset($shareTypes[$fileId])) {
+ $shareTypes[$fileId] = [];
+ }
+ $shareTypes[$fileId][] = $shareType;
+ unset($nodesLeft[$fileId]);
+ }
+ }
+
+ if (count($shares) < 100) {
+ break;
+ } else {
+ $offset += count($shares);
+ }
}
}
return $shareTypes;
}
/**
+ * Returns a list of recently modifed files.
+ *
+ * @NoAdminRequired
+ *
+ * @return DataResponse
+ */
+ public function getRecentFiles() {
+ $nodes = $this->userFolder->getRecent(100);
+ $files = $this->formatNodes($nodes);
+ return new DataResponse(['files' => $files]);
+ }
+
+ /**
* Change the default sort mode
*
* @NoAdminRequired
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php
index e8d48c42cd0..0ddee32f7d0 100644
--- a/apps/files_sharing/lib/Controller/ShareAPIController.php
+++ b/apps/files_sharing/lib/Controller/ShareAPIController.php
@@ -588,7 +588,7 @@ class ShareAPIController extends OCSController {
}
if ($shareWith === null) {
- throw new OCSNotFoundException($this->l->t('Please specify a valid federated user id'));
+ throw new OCSNotFoundException($this->l->t('Please specify a valid federated user ID'));
}
$share->setSharedWith($shareWith);
@@ -607,7 +607,7 @@ class ShareAPIController extends OCSController {
}
if ($shareWith === null) {
- throw new OCSNotFoundException($this->l->t('Please specify a valid federated group id'));
+ throw new OCSNotFoundException($this->l->t('Please specify a valid federated group ID'));
}
$share->setSharedWith($shareWith);
diff --git a/apps/files_trashbin/lib/Storage.php b/apps/files_trashbin/lib/Storage.php
index 08dc052fa5c..415f8a183b2 100644
--- a/apps/files_trashbin/lib/Storage.php
+++ b/apps/files_trashbin/lib/Storage.php
@@ -237,7 +237,7 @@ class Storage extends Wrapper {
/** @var Storage $sourceStorage */
$sourceStorage->disableTrash();
}
- $result = $this->getWrapperStorage()->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
+ $result = parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
if ($sourceIsTrashbin) {
/** @var Storage $sourceStorage */
$sourceStorage->enableTrash();
diff --git a/apps/settings/lib/Controller/AuthSettingsController.php b/apps/settings/lib/Controller/AuthSettingsController.php
index 9535b3bec67..11e1be7fd47 100644
--- a/apps/settings/lib/Controller/AuthSettingsController.php
+++ b/apps/settings/lib/Controller/AuthSettingsController.php
@@ -121,6 +121,10 @@ class AuthSettingsController extends Controller {
* @return JSONResponse
*/
public function create($name) {
+ if ($this->checkAppToken()) {
+ return $this->getServiceNotAvailableResponse();
+ }
+
try {
$sessionId = $this->session->getId();
} catch (SessionNotAvailableException $ex) {
@@ -181,6 +185,10 @@ class AuthSettingsController extends Controller {
return implode('-', $groups);
}
+ private function checkAppToken(): bool {
+ return $this->session->exists('app_password');
+ }
+
/**
* @NoAdminRequired
* @NoSubAdminRequired
@@ -189,6 +197,10 @@ class AuthSettingsController extends Controller {
* @return array|JSONResponse
*/
public function destroy($id) {
+ if ($this->checkAppToken()) {
+ return new JSONResponse([], Http::STATUS_BAD_REQUEST);
+ }
+
try {
$token = $this->findTokenByIdAndUser($id);
} catch (WipeTokenException $e) {
@@ -213,6 +225,10 @@ class AuthSettingsController extends Controller {
* @return array|JSONResponse
*/
public function update($id, array $scope, string $name) {
+ if ($this->checkAppToken()) {
+ return new JSONResponse([], Http::STATUS_BAD_REQUEST);
+ }
+
try {
$token = $this->findTokenByIdAndUser($id);
} catch (InvalidTokenException $e) {
@@ -286,6 +302,10 @@ class AuthSettingsController extends Controller {
* @throws \OC\Authentication\Exceptions\ExpiredTokenException
*/
public function wipe(int $id): JSONResponse {
+ if ($this->checkAppToken()) {
+ return new JSONResponse([], Http::STATUS_BAD_REQUEST);
+ }
+
try {
$token = $this->findTokenByIdAndUser($id);
} catch (InvalidTokenException $e) {
diff --git a/build/package-lock.json b/build/package-lock.json
index 01078d2eead..d4eccd18b17 100644
--- a/build/package-lock.json
+++ b/build/package-lock.json
@@ -1028,9 +1028,9 @@
"dev": true
},
"env-paths": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
- "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"dev": true
},
"error-ex": {
@@ -2503,18 +2503,18 @@
"dev": true
},
"mime-db": {
- "version": "1.44.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
- "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+ "version": "1.47.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
+ "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
"dev": true
},
"mime-types": {
- "version": "2.1.27",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
- "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+ "version": "2.1.30",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
+ "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"dev": true,
"requires": {
- "mime-db": "1.44.0"
+ "mime-db": "1.47.0"
}
},
"minimatch": {
@@ -2657,9 +2657,9 @@
},
"dependencies": {
"glob": {
- "version": "7.1.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
- "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -2671,9 +2671,9 @@
}
},
"graceful-fs": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
"dev": true
},
"nopt": {
@@ -2686,9 +2686,9 @@
}
},
"semver": {
- "version": "7.3.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
- "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -2706,9 +2706,9 @@
}
},
"node-sass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz",
- "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-6.0.0.tgz",
+ "integrity": "sha512-GDzDmNgWNc9GNzTcSLTi6DU6mzSPupVJoStIi7cF3GjwSE9q1cVakbvAAVSt59vzUjV9JJoSZFKoo9krbjKd2g==",
"dev": true,
"requires": {
"async-foreach": "^0.1.3",
@@ -3746,9 +3746,9 @@
"dev": true
},
"tar": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz",
- "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
+ "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
"dev": true,
"requires": {
"chownr": "^2.0.0",
@@ -3994,9 +3994,9 @@
"dev": true
},
"uri-js": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
- "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
diff --git a/build/package.json b/build/package.json
index 9abd800348e..1b9aacbb7a7 100644
--- a/build/package.json
+++ b/build/package.json
@@ -21,7 +21,7 @@
"karma-jasmine-sinon": "^1.0.4",
"karma-spec-reporter": "^0.0.32",
"karma-viewport": "^1.0.8",
- "node-sass": "~5.0.0",
+ "node-sass": "~6.0.0",
"puppeteer": "^5.5.0",
"sinon": "<= 5.0.7"
},
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index 14b663d4e16..f77c90b65a9 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -31,14 +31,10 @@
namespace OC\Files\Node;
-use OC\DB\QueryBuilder\Literal;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
+use OC\Files\Search\SearchOrder;
use OC\Files\Search\SearchQuery;
-use OC\Files\Storage\Wrapper\Jail;
-use OC\Files\Storage\Storage;
-use OCA\Files_Sharing\SharedStorage;
-use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Config\ICachedMountInfo;
use OCP\Files\FileInfo;
@@ -48,6 +44,7 @@ use OCP\Files\NotPermittedException;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
+use OCP\Files\Search\ISearchOrder;
use OCP\Files\Search\ISearchQuery;
use OCP\IUserManager;
@@ -266,8 +263,7 @@ class Folder extends Node implements \OCP\Files\Folder {
new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
new SearchComparison(ISearchComparison::COMPARE_LIKE, 'path', $internalPath . '%'),
$query->getSearchOperation(),
- ]
- ),
+ ]),
$subQueryLimit,
0,
$query->getOrder(),
@@ -309,7 +305,7 @@ class Folder extends Node implements \OCP\Files\Folder {
$order = $query->getOrder();
if ($order) {
- usort($files, function (FileInfo $a,FileInfo $b) use ($order) {
+ usort($files, function (FileInfo $a, FileInfo $b) use ($order) {
foreach ($order as $orderField) {
$cmp = $orderField->sortFileInfo($a, $b);
if ($cmp !== 0) {
@@ -492,158 +488,37 @@ class Folder extends Node implements \OCP\Files\Folder {
* @return \OCP\Files\Node[]
*/
public function getRecent($limit, $offset = 0) {
- $mimetypeLoader = \OC::$server->getMimeTypeLoader();
- $mounts = $this->root->getMountsIn($this->path);
- $mounts[] = $this->getMountPoint();
-
- $mounts = array_filter($mounts, function (IMountPoint $mount) {
- return $mount->getStorage() !== null;
- });
- $storageIds = array_map(function (IMountPoint $mount) {
- return $mount->getStorage()->getCache()->getNumericStorageId();
- }, $mounts);
- /** @var IMountPoint[] $mountMap */
- $mountMap = array_combine($storageIds, $mounts);
- $folderMimetype = $mimetypeLoader->getId(FileInfo::MIMETYPE_FOLDER);
-
- /*
- * Construct an array of the storage id with their prefix path
- * This helps us to filter in the final query
- */
- $filters = array_map(function (IMountPoint $mount) {
- $storage = $mount->getStorage();
-
- $storageId = $storage->getCache()->getNumericStorageId();
- $prefix = '';
-
- if ($storage->instanceOfStorage(Jail::class)) {
- $prefix = $storage->getUnJailedPath('');
- }
-
- return [
- 'storageId' => $storageId,
- 'pathPrefix' => $prefix,
- ];
- }, $mounts);
-
- // Search in batches of 500 entries
- $searchLimit = 500;
- $results = [];
- $searchResultCount = 0;
- $count = 0;
- do {
- $searchResult = $this->recentSearch($searchLimit, $offset, $folderMimetype, $filters);
-
- // Exit condition if there are no more results
- if (count($searchResult) === 0) {
- break;
- }
-
- $searchResultCount += count($searchResult);
-
- $parseResult = $this->recentParse($searchResult, $mountMap, $mimetypeLoader);
-
- foreach ($parseResult as $result) {
- $results[] = $result;
- }
-
- $offset += $searchLimit;
- $count++;
- } while (count($results) < $limit && ($searchResultCount < (3 * $limit) || $count < 5));
-
- return array_slice($results, 0, $limit);
- }
-
- private function recentSearch($limit, $offset, $folderMimetype, $filters) {
- $dbconn = \OC::$server->getDatabaseConnection();
- $builder = $dbconn->getQueryBuilder();
- $query = $builder
- ->select('f.*')
- ->from('filecache', 'f');
-
- /*
- * Here is where we construct the filtering.
- * Note that this is expensive filtering as it is a lot of like queries.
- * However the alternative is we do this filtering and parsing later in php with the risk of looping endlessly
- */
- $storageFilters = $builder->expr()->orX();
- foreach ($filters as $filter) {
- $storageFilter = $builder->expr()->andX(
- $builder->expr()->eq('f.storage', $builder->createNamedParameter($filter['storageId']))
- );
-
- if ($filter['pathPrefix'] !== '') {
- $storageFilter->add(
- $builder->expr()->like('f.path', $builder->createNamedParameter($dbconn->escapeLikeParameter($filter['pathPrefix']) . '/%'))
- );
- }
-
- $storageFilters->add($storageFilter);
- }
-
- $query->andWhere($storageFilters);
-
- $query->andWhere($builder->expr()->orX(
- // handle non empty folders separate
- $builder->expr()->neq('f.mimetype', $builder->createNamedParameter($folderMimetype, IQueryBuilder::PARAM_INT)),
- $builder->expr()->eq('f.size', new Literal(0))
- ))
- ->andWhere($builder->expr()->notLike('f.path', $builder->createNamedParameter('files_versions/%')))
- ->andWhere($builder->expr()->notLike('f.path', $builder->createNamedParameter('files_trashbin/%')))
- ->orderBy('f.mtime', 'DESC')
- ->setMaxResults($limit)
- ->setFirstResult($offset);
-
- $result = $query->execute();
- $rows = $result->fetchAll();
- $result->closeCursor();
-
- return $rows;
- }
-
- private function recentParse($result, $mountMap, $mimetypeLoader) {
- $files = array_filter(array_map(function (array $entry) use ($mountMap, $mimetypeLoader) {
- $mount = $mountMap[$entry['storage']];
- $entry['internalPath'] = $entry['path'];
- $entry['mimetype'] = $mimetypeLoader->getMimetypeById($entry['mimetype']);
- $entry['mimepart'] = $mimetypeLoader->getMimetypeById($entry['mimepart']);
- $path = $this->getAbsolutePath($mount, $entry['path']);
- if (is_null($path)) {
- return null;
- }
- $fileInfo = new \OC\Files\FileInfo($path, $mount->getStorage(), $entry['internalPath'], $entry, $mount);
- return $this->root->createNode($fileInfo->getPath(), $fileInfo);
- }, $result));
-
- return array_values(array_filter($files, function (Node $node) {
- $cacheEntry = $node->getMountPoint()->getStorage()->getCache()->get($node->getId());
- if (!$cacheEntry) {
- return false;
- }
- $relative = $this->getRelativePath($node->getPath());
- return $relative !== null && $relative !== '/'
- && ($cacheEntry->getPermissions() & \OCP\Constants::PERMISSION_READ) === \OCP\Constants::PERMISSION_READ;
- }));
- }
-
- private function getAbsolutePath(IMountPoint $mount, $path) {
- $storage = $mount->getStorage();
- if ($storage->instanceOfStorage('\OC\Files\Storage\Wrapper\Jail')) {
- if ($storage->instanceOfStorage(SharedStorage::class)) {
- $storage->getSourceStorage();
- }
- /** @var \OC\Files\Storage\Wrapper\Jail $storage */
- $jailRoot = $storage->getUnjailedPath('');
- $rootLength = strlen($jailRoot) + 1;
- if ($path === $jailRoot) {
- return $mount->getMountPoint();
- } elseif (substr($path, 0, $rootLength) === $jailRoot . '/') {
- return $mount->getMountPoint() . substr($path, $rootLength);
- } else {
- return null;
- }
- } else {
- return $mount->getMountPoint() . $path;
- }
+ $query = new SearchQuery(
+ new SearchBinaryOperator(
+ // filter out non empty folders
+ ISearchBinaryOperator::OPERATOR_OR,
+ [
+ new SearchBinaryOperator(
+ ISearchBinaryOperator::OPERATOR_NOT,
+ [
+ new SearchComparison(
+ ISearchComparison::COMPARE_EQUAL,
+ 'mimetype',
+ FileInfo::MIMETYPE_FOLDER
+ ),
+ ]
+ ),
+ new SearchComparison(
+ ISearchComparison::COMPARE_EQUAL,
+ 'size',
+ 0
+ ),
+ ]
+ ),
+ $limit,
+ $offset,
+ [
+ new SearchOrder(
+ ISearchOrder::DIRECTION_DESCENDING,
+ 'mtime'
+ ),
+ ]
+ );
+ return $this->search($query);
}
}
diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php
index 1d541556c0b..36398171b1b 100644
--- a/tests/lib/Files/Node/FolderTest.php
+++ b/tests/lib/Files/Node/FolderTest.php
@@ -773,6 +773,10 @@ class FolderTest extends NodeTest {
$folderInfo->expects($this->any())
->method('getMountPoint')
->willReturn($mount);
+ $root->method('getMount')
+ ->willReturn($mount);
+ $root->method('getMountsIn')
+ ->willReturn([]);
$cache = $storage->getCache();
@@ -838,6 +842,11 @@ class FolderTest extends NodeTest {
->method('getMountPoint')
->willReturn($mount);
+ $root->method('getMount')
+ ->willReturn($mount);
+ $root->method('getMountsIn')
+ ->willReturn([]);
+
$cache = $storage->getCache();
$id1 = $cache->put('bar/foo/folder', [
@@ -903,6 +912,10 @@ class FolderTest extends NodeTest {
$folderInfo->expects($this->any())
->method('getMountPoint')
->willReturn($mount);
+ $root->method('getMount')
+ ->willReturn($mount);
+ $root->method('getMountsIn')
+ ->willReturn([]);
$cache = $storage->getCache();