Skip to content

Commit

Permalink
feat(dav): Add result of getQueryFilterForStorage in path filtering
Browse files Browse the repository at this point in the history
Signed-off-by: Louis Chemineau <louis@chmn.me>
  • Loading branch information
artonge committed Apr 17, 2024
1 parent 817ac06 commit 8709037
Showing 1 changed file with 60 additions and 43 deletions.
103 changes: 60 additions & 43 deletions apps/dav/lib/Files/FileSearchBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,50 +160,63 @@ public function preloadPropertyFor(array $nodes, array $requestProperties): void
* @return SearchResult[]
*/
public function search(Query $search): array {
$scopes = [];
foreach ($search->from as $scope) {
if ($scope->path === null) {
throw new \InvalidArgumentException('Using uri\'s as scope is not supported, please use a path relative to the search arbiter instead');
}
$node = $this->tree->getNodeForPath($scope->path);
if (!$node instanceof Directory) {
throw new \InvalidArgumentException('Search is only supported on directories');
}
switch (count($search->from)) {
case 0:
throw new \InvalidArgumentException('You need to specify a scope for the search.');
break;
case 1:
$query = $this->transformQuery($search);
$scope = $search->from[0];

/** @var Folder $folder $results */
$results = $folder->search($query);
break;
default:
$scopes = [];
foreach ($search->from as $scope) {
if ($scope->path === null) {
throw new \InvalidArgumentException('Using uri\'s as scope is not supported, please use a path relative to the search arbiter instead');
}
$node = $this->tree->getNodeForPath($scope->path);
if (!$node instanceof Directory) {
throw new \InvalidArgumentException('Search is only supported on directories');
}

$fileInfo = $node->getFileInfo();
/** @var Folder $folder */
$folder = $this->rootFolder->get($fileInfo->getPath());
$folderStorage = $folder->getStorage();
if ($folderStorage->instanceOfStorage(Jail::class)) {
/** @var Jail $folderStorage */
$internalPath = $folderStorage->getUnjailedPath($folder->getInternalPath());
} else {
$internalPath = $folder->getInternalPath();
}
$fileInfo = $node->getFileInfo();
/** @var Folder $folder */
$folder = $this->rootFolder->get($fileInfo->getPath());
$folderStorage = $folder->getStorage();
if ($folderStorage->instanceOfStorage(Jail::class)) {
/** @var Jail $folderStorage */
$internalPath = $folderStorage->getUnjailedPath($folder->getInternalPath());
} else {
$internalPath = $folder->getInternalPath();
}

$scopes[] = new SearchBinaryOperator(
ISearchBinaryOperator::OPERATOR_AND,
[
new SearchComparison(
ISearchComparison::COMPARE_EQUAL,
'storage',
$folderStorage->getCache()->getNumericStorageId(),
''
),
new SearchComparison(
ISearchComparison::COMPARE_LIKE,
'path',
$internalPath . '/%',
''
),
]
);
}
$scopes[] = new SearchBinaryOperator(
ISearchBinaryOperator::OPERATOR_AND,
[
new SearchComparison(
ISearchComparison::COMPARE_EQUAL,
'storage',
$folderStorage->getCache()->getNumericStorageId(),
''
),
new SearchComparison(
ISearchComparison::COMPARE_LIKE,
'path',
$internalPath . '/%',
''
),
]
);
}

$scopeOperators = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $scopes);
$query = $this->transformQuery($search, $scopeOperators);
$userFolder = $this->rootFolder->getUserFolder($this->user->getUID());
$results = $userFolder->search($query);
$scopeOperators = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, $scopes);
$query = $this->transformQuery($search, $scopeOperators);
$userFolder = $this->rootFolder->getUserFolder($this->user->getUID());
$results = $userFolder->search($query);
}

/** @var SearchResult[] $nodes */
$nodes = array_map(function (Node $node) {
Expand Down Expand Up @@ -318,7 +331,7 @@ private function getHrefForNode(Node $node) {
*
* @return ISearchQuery
*/
private function transformQuery(Query $query, SearchBinaryOperator $scopeOperators): ISearchQuery {
private function transformQuery(Query $query, ?SearchBinaryOperator $scopeOperators = null): ISearchQuery {
$orders = array_map(function (Order $order): ISearchOrder {
$direction = $order->order === Order::ASC ? ISearchOrder::DIRECTION_ASCENDING : ISearchOrder::DIRECTION_DESCENDING;
if (str_starts_with($order->property->name, FilesPlugin::FILE_METADATA_PREFIX)) {
Expand Down Expand Up @@ -348,7 +361,11 @@ private function transformQuery(Query $query, SearchBinaryOperator $scopeOperato

/** @var SearchBinaryOperator|SearchComparison */
$queryOperators = $this->transformSearchOperation($query->where);
$operators = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [$queryOperators, $scopeOperators]);
if ($scopeOperators === null) {
$operators = $queryOperators;
} else {
$operators = new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [$queryOperators, $scopeOperators]);
}

return new SearchQuery(
$operators,
Expand Down

0 comments on commit 8709037

Please sign in to comment.