Skip to content

Commit

Permalink
feat(files): Allow advanced search for files
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
  • Loading branch information
Altahrim committed Oct 17, 2023
1 parent d7bf2bd commit 20b0b65
Showing 1 changed file with 60 additions and 17 deletions.
77 changes: 60 additions & 17 deletions apps/files/lib/Search/FilesSearchProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,25 @@
*/
namespace OCA\Files\Search;

use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchOrder;
use OC\Files\Search\SearchQuery;
use OCP\Files\FileInfo;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\IRootFolder;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Node;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOrder;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\Search\IProvider;
use OCP\Search\IProviderV2;
use OCP\Search\ISearchQuery;
use OCP\Search\SearchResult;
use OCP\Search\SearchResultEntry;

class FilesSearchProvider implements IProvider {

class FilesSearchProvider implements IProviderV2 {
/** @var IL10N */
private $l10n;

Expand Down Expand Up @@ -97,21 +97,39 @@ public function getOrder(string $route, array $routeParameters): int {
return 5;
}

/**
* @inheritDoc
*/
public function getSupportedFilters(): array {
return [
'term',
'since',
'until',
'person',
'min-size',
'max-size',
'mime',
'type',
'is-favorite',
'title-only',
];
}

public function getAlternateIds(): array {
return [];
}

public function registerCustomFilters(): array {
return [
'min-size' => 'integer',
'max-size' => 'integer',
'mime' => 'string',
'type' => 'string',
'is-favorite' => 'boolean',
'title-only' => 'boolean',
];
}

public function search(IUser $user, ISearchQuery $query): SearchResult {
$userFolder = $this->rootFolder->getUserFolder($user->getUID());
$fileQuery = new SearchQuery(
new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query->getTerm() . '%'),
$query->getLimit(),
(int)$query->getCursor(),
$query->getSortOrder() === ISearchQuery::SORT_DATE_DESC ? [
new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'mtime'),
] : [],
$user
);

$fileQuery = $this->buildSearchQuery($query, $user);
return SearchResult::paginated(
$this->l10n->t('Files'),
array_map(function (Node $result) use ($userFolder) {
Expand Down Expand Up @@ -141,6 +159,31 @@ public function search(IUser $user, ISearchQuery $query): SearchResult {
);
}

private function buildSearchQuery(ISearchQuery $query, IUser $user): SearchQuery {
$comparisons = [];
foreach ($query->getFilters() as $name => $filter) {
$comparisons[] = match ($name) {
'term' => new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $filter->get() . '%'),
'since' => new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN_EQUAL, 'mtime', $filter->get()->getTimestamp()),
'until' => new SearchComparison(ISearchComparison::COMPARE_LESS_THAN_EQUAL, 'mtime', $filter->get()->getTimestamp()),
'min-size' => new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN_EQUAL, 'size', $filter->get()),
'max-size' => new SearchComparison(ISearchComparison::COMPARE_LESS_THAN_EQUAL, 'size', $filter->get()),
'mime' => new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', $filter->get()),
'type' => new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', $filter->get() . '/%'),
};
}

return new SearchQuery(
new SearchBinaryOperator(SearchBinaryOperator::OPERATOR_AND, $comparisons),
$query->getLimit(),
(int) $query->getCursor(),
$query->getSortOrder() === ISearchQuery::SORT_DATE_DESC
? [new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'mtime')]
: [],
$user
);
}

/**
* Format subline for files
*
Expand Down

0 comments on commit 20b0b65

Please sign in to comment.