diff --git a/apps/files/lib/Search/FilesSearchProvider.php b/apps/files/lib/Search/FilesSearchProvider.php index 2361b8a2d0708..c5befe397e8b2 100644 --- a/apps/files/lib/Search/FilesSearchProvider.php +++ b/apps/files/lib/Search/FilesSearchProvider.php @@ -29,6 +29,7 @@ */ namespace OCA\Files\Search; +use OC\Files\Search\SearchBinaryOperator; use OC\Files\Search\SearchComparison; use OC\Files\Search\SearchOrder; use OC\Files\Search\SearchQuery; @@ -103,7 +104,11 @@ public function getOrder(string $route, array $routeParameters): int { 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() . '%'), + new SearchBinaryOperator(SearchBinaryOperator::OPERATOR_OR, [ + new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query->getTerm() . '%'), + new SearchComparison(ISearchComparison::COMPARE_LIKE, 'tagname', '%' . $query->getTerm() . '%'), + new SearchComparison(ISearchComparison::COMPARE_LIKE, 'systemtag', '%' . $query->getTerm() . '%'), + ]), $query->getLimit(), (int)$query->getCursor(), $query->getSortOrder() === ISearchQuery::SORT_DATE_DESC ? [ diff --git a/lib/private/Files/Cache/CacheQueryBuilder.php b/lib/private/Files/Cache/CacheQueryBuilder.php index 774691ebc3189..bd17e944224e1 100644 --- a/lib/private/Files/Cache/CacheQueryBuilder.php +++ b/lib/private/Files/Cache/CacheQueryBuilder.php @@ -43,7 +43,7 @@ public function __construct(IDBConnection $connection, SystemConfig $systemConfi public function selectFileCache(string $alias = null) { $name = $alias ? $alias : 'filecache'; - $this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", 'name', 'mimetype', 'mimepart', 'size', 'mtime', + $this->select("$name.fileid", 'storage', 'path', 'path_hash', "$name.parent", "$name.name", 'mimetype', 'mimepart', 'size', 'mtime', 'storage_mtime', 'encrypted', 'etag', 'permissions', 'checksum', 'metadata_etag', 'creation_time', 'upload_time') ->from('filecache', $name) ->leftJoin($name, 'filecache_extended', 'fe', $this->expr()->eq("$name.fileid", 'fe.fileid')); diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php index 683b580d9d1ff..b7b47643ab16b 100644 --- a/lib/private/Files/Cache/QuerySearchHelper.php +++ b/lib/private/Files/Cache/QuerySearchHelper.php @@ -27,6 +27,7 @@ use OC\Files\Search\SearchBinaryOperator; use OC\SystemConfig; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Cache\ICache; use OCP\Files\Cache\ICacheEntry; use OCP\Files\IMimeTypeLoader; @@ -106,13 +107,21 @@ public function searchInCaches(ISearchQuery $searchQuery, array $caches): array 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( + ->leftJoin('file', 'vcategory_to_object', 'tagmap', $builder->expr()->eq('file.fileid', 'tagmap.objid')) + ->leftJoin('tagmap', 'vcategory', 'tag', $builder->expr()->andX( $builder->expr()->eq('tagmap.type', 'tag.type'), - $builder->expr()->eq('tagmap.categoryid', 'tag.id') + $builder->expr()->eq('tagmap.categoryid', 'tag.id'), + $builder->expr()->eq('tag.type', $builder->createNamedParameter('files')), + $builder->expr()->eq('tag.uid', $builder->createNamedParameter($user->getUID())) )) - ->andWhere($builder->expr()->eq('tag.type', $builder->createNamedParameter('files'))) - ->andWhere($builder->expr()->eq('tag.uid', $builder->createNamedParameter($user->getUID()))); + ->leftJoin('file', 'systemtag_object_mapping', 'systemtagmap', $builder->expr()->andX( + $builder->expr()->eq('file.fileid', $builder->expr()->castColumn('systemtagmap.objectid', IQueryBuilder::PARAM_INT)), + $builder->expr()->eq('systemtagmap.objecttype', $builder->createNamedParameter('files')) + )) + ->leftJoin('systemtagmap', 'systemtag', 'systemtag', $builder->expr()->andX( + $builder->expr()->eq('systemtag.id', 'systemtagmap.systemtagid'), + $builder->expr()->eq('systemtag.visibility', $builder->createNamedParameter(true)) + )); } $searchExpr = $this->searchBuilder->searchOperatorToDBExpr($builder, $searchQuery->getSearchOperation()); diff --git a/lib/private/Files/Cache/SearchBuilder.php b/lib/private/Files/Cache/SearchBuilder.php index 7e1fbe08492fd..e12087dc8c573 100644 --- a/lib/private/Files/Cache/SearchBuilder.php +++ b/lib/private/Files/Cache/SearchBuilder.php @@ -78,7 +78,7 @@ public function shouldJoinTags(ISearchOperator $operator) { return $shouldJoin || $this->shouldJoinTags($operator); }, false); } elseif ($operator instanceof ISearchComparison) { - return $operator->getField() === 'tagname' || $operator->getField() === 'favorite'; + return $operator->getField() === 'tagname' || $operator->getField() === 'favorite' || $operator->getField() === 'systemtag'; } return false; } @@ -160,8 +160,12 @@ private function getOperatorFieldAndValue(ISearchComparison $operator) { } elseif ($field === 'favorite') { $field = 'tag.category'; $value = self::TAG_FAVORITE; + } elseif ($field === 'name') { + $field = 'file.name'; } elseif ($field === 'tagname') { $field = 'tag.category'; + } elseif ($field === 'systemntag') { + $field = 'systemtag.name'; } elseif ($field === 'fileid') { $field = 'file.fileid'; } elseif ($field === 'path' && $type === ISearchComparison::COMPARE_EQUAL) { @@ -179,6 +183,7 @@ private function validateComparison(ISearchComparison $operator) { 'path' => 'string', 'size' => 'integer', 'tagname' => 'string', + 'systemtag' => 'string', 'favorite' => 'boolean', 'fileid' => 'integer', 'storage' => 'integer', @@ -190,6 +195,7 @@ private function validateComparison(ISearchComparison $operator) { 'path' => ['eq', 'like'], 'size' => ['eq', 'gt', 'lt', 'gte', 'lte'], 'tagname' => ['eq', 'like'], + 'systemtag' => ['eq', 'like'], 'favorite' => ['eq'], 'fileid' => ['eq'], 'storage' => ['eq'], diff --git a/tests/lib/Files/Cache/SearchBuilderTest.php b/tests/lib/Files/Cache/SearchBuilderTest.php index 82c4dbaa27f77..5eb1a0252f0d3 100644 --- a/tests/lib/Files/Cache/SearchBuilderTest.php +++ b/tests/lib/Files/Cache/SearchBuilderTest.php @@ -79,7 +79,7 @@ protected function setUp(): void { $this->numericStorageId = 10000; $this->builder->select(['fileid']) - ->from('filecache') + ->from('filecache', 'file') // alias needed for QuerySearchHelper#getOperatorFieldAndValue ->where($this->builder->expr()->eq('storage', new Literal($this->numericStorageId))); }