Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle limit offset and sorting in files search #26198

Merged
merged 10 commits into from
Mar 22, 2021
77 changes: 46 additions & 31 deletions apps/files/lib/Search/FilesSearchProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@

namespace OCA\Files\Search;

use OC\Search\Provider\File;
use OC\Search\Result\File as FileResult;
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\ISearchOrder;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
Expand All @@ -43,9 +48,6 @@

class FilesSearchProvider implements IProvider {

/** @var File */
private $fileSearch;

/** @var IL10N */
private $l10n;

Expand All @@ -58,13 +60,13 @@ class FilesSearchProvider implements IProvider {
/** @var IRootFolder */
private $rootFolder;

public function __construct(File $fileSearch,
IL10N $l10n,
IURLGenerator $urlGenerator,
IMimeTypeDetector $mimeTypeDetector,
IRootFolder $rootFolder) {
public function __construct(
IL10N $l10n,
IURLGenerator $urlGenerator,
IMimeTypeDetector $mimeTypeDetector,
IRootFolder $rootFolder
) {
$this->l10n = $l10n;
$this->fileSearch = $fileSearch;
$this->urlGenerator = $urlGenerator;
$this->mimeTypeDetector = $mimeTypeDetector;
$this->rootFolder = $rootFolder;
Expand Down Expand Up @@ -99,46 +101,59 @@ public function getOrder(string $route, array $routeParameters): int {
* @inheritDoc
*/
public function search(IUser $user, ISearchQuery $query): SearchResult {

// Make sure we setup the users filesystem
$this->rootFolder->getUserFolder($user->getUID());
$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
);

return SearchResult::paginated(
$this->l10n->t('Files'),
array_map(function (FileResult $result) {
array_map(function (Node $result) use ($userFolder) {
// Generate thumbnail url
$thumbnailUrl = $result->has_preview
? $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreviewByFileId', ['x' => 32, 'y' => 32, 'fileId' => $result->id])
: '';
$thumbnailUrl = $this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreviewByFileId', ['x' => 32, 'y' => 32, 'fileId' => $result->getId()]);
$path = $userFolder->getRelativePath($result->getPath());
$link = $this->urlGenerator->linkToRoute(
'files.view.index',
[
'dir' => dirname($path),
'scrollto' => $result->getName(),
]
);

$searchResultEntry = new SearchResultEntry(
$thumbnailUrl,
$result->name,
$this->formatSubline($result),
$this->urlGenerator->getAbsoluteURL($result->link),
$result->type === 'folder' ? 'icon-folder' : $this->mimeTypeDetector->mimeTypeIcon($result->mime_type)
$result->getName(),
$this->formatSubline($path),
$this->urlGenerator->getAbsoluteURL($link),
$result->getMimetype() === FileInfo::MIMETYPE_FOLDER ? 'icon-folder' : $this->mimeTypeDetector->mimeTypeIcon($result->getMimetype())
);
$searchResultEntry->addAttribute('fileId', (string)$result->id);
$searchResultEntry->addAttribute('path', $result->path);
$searchResultEntry->addAttribute('fileId', (string)$result->getId());
$searchResultEntry->addAttribute('path', $path);
return $searchResultEntry;
}, $this->fileSearch->search($query->getTerm(), $query->getLimit(), (int)$query->getCursor())),
}, $userFolder->search($fileQuery)),
$query->getCursor() + $query->getLimit()
);
}

/**
* Format subline for files
*
* @param FileResult $result
* @param string $path
* @return string
*/
private function formatSubline($result): string {
private function formatSubline(string $path): string {
// Do not show the location if the file is in root
if ($result->path === '/' . $result->name) {
if (strrpos($path, '/') > 0) {
$path = ltrim(dirname($path), '/');
return $this->l10n->t('in %s', [$path]);
} else {
return '';
}

$path = ltrim(dirname($result->path), '/');
return $this->l10n->t('in %s', [$path]);
}
}
1 change: 1 addition & 0 deletions core/Controller/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public function __construct(

/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function search(string $query, array $inApps = [], int $page = 1, int $size = 30): JSONResponse {
$results = $this->searcher->searchPaged($query, $inApps, $page, $size);
Expand Down
12 changes: 8 additions & 4 deletions lib/private/Files/Cache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,10 @@ public static function cacheEntryFromData($data, IMimeTypeLoader $mimetypeLoader
}
$data['permissions'] = (int)$data['permissions'];
if (isset($data['creation_time'])) {
$data['creation_time'] = (int) $data['creation_time'];
$data['creation_time'] = (int)$data['creation_time'];
}
if (isset($data['upload_time'])) {
$data['upload_time'] = (int) $data['upload_time'];
$data['upload_time'] = (int)$data['upload_time'];
}
return new CacheEntry($data);
}
Expand Down Expand Up @@ -841,14 +841,18 @@ public function searchQuery(ISearchQuery $searchQuery) {
$query->whereStorageId();

if ($this->querySearchHelper->shouldJoinTags($searchQuery->getSearchOperation())) {
$user = $searchQuery->getUser();
if ($user === null) {
throw new \InvalidArgumentException("Searching by tag requires the user to be set in the query");
}
$query
->innerJoin('file', 'vcategory_to_object', 'tagmap', $builder->expr()->eq('file.fileid', 'tagmap.objid'))
->innerJoin('tagmap', 'vcategory', 'tag', $builder->expr()->andX(
$builder->expr()->eq('tagmap.type', 'tag.type'),
$builder->expr()->eq('tagmap.categoryid', 'tag.id')
))
->andWhere($builder->expr()->eq('tag.type', $builder->createNamedParameter('files')))
->andWhere($builder->expr()->eq('tag.uid', $builder->createNamedParameter($searchQuery->getUser()->getUID())));
->andWhere($builder->expr()->eq('tag.uid', $builder->createNamedParameter($user->getUID())));
}

$searchExpr = $this->querySearchHelper->searchOperatorToDBExpr($builder, $searchQuery->getSearchOperation());
Expand Down Expand Up @@ -1031,7 +1035,7 @@ public function getPathById($id) {
return null;
}

return (string) $path;
return (string)$path;
}

/**
Expand Down
Loading