Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 31 additions & 13 deletions apps/dav/lib/Connector/Sabre/TagsPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
$this->server = $server;
$this->server->on('propFind', [$this, 'handleGetProperties']);
$this->server->on('propPatch', [$this, 'handleUpdateProperties']);
$this->server->on('preloadProperties', [$this, 'handlePreloadProperties']);
}

/**
Expand Down Expand Up @@ -153,6 +154,24 @@
return null;
}

/**
* Prefetches tags for a list of file IDs and caches the results
*
* @param array $fileIds List of file IDs to prefetch tags for
* @return void
*/
private function prefetchTagsForFileIds(array $fileIds) {
$tags = $this->getTagger()->getTagsForObjects($fileIds);
if ($tags === false) {
// the tags API returns false on error...
$tags = [];
}

foreach ($fileIds as $fileId) {
$this->cachedTags[$fileId] = $tags[$fileId] ?? [];
}
}

/**
* Updates the tags of the given file id
*
Expand Down Expand Up @@ -203,22 +222,11 @@
)) {
// note: pre-fetching only supported for depth <= 1
$folderContent = $node->getChildren();
$fileIds[] = (int) $node->getId();
$fileIds = [(int) $node->getId()];

Check notice

Code scanning / Psalm

RedundantCastGivenDocblockType Note

Redundant cast to int given docblock-provided type
foreach ($folderContent as $info) {
$fileIds[] = (int) $info->getId();
}
$tags = $this->getTagger()->getTagsForObjects($fileIds);
if ($tags === false) {
// the tags API returns false on error...
$tags = [];
}

$this->cachedTags = $this->cachedTags + $tags;
$emptyFileIds = array_diff($fileIds, array_keys($tags));
// also cache the ones that were not found
foreach ($emptyFileIds as $fileId) {
$this->cachedTags[$fileId] = [];
}
$this->prefetchTagsForFileIds($fileIds);
}

$isFav = null;
Expand Down Expand Up @@ -274,4 +282,14 @@
return 200;
});
}

public function handlePreloadProperties(array $nodes, array $requestProperties): void {
if (
!in_array(self::FAVORITE_PROPERTYNAME, $requestProperties, true) &&
!in_array(self::TAGS_PROPERTYNAME, $requestProperties, true)
) {
return;
}
$this->prefetchTagsForFileIds(array_map(fn ($node) => $node->getId(), $nodes));

Check notice

Code scanning / Psalm

MissingClosureReturnType Note

Closure does not have a return type, expecting mixed
}
}
3 changes: 3 additions & 0 deletions apps/dav/lib/Files/FileSearchBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use OCA\DAV\Connector\Sabre\CachingTree;
use OCA\DAV\Connector\Sabre\Directory;
use OCA\DAV\Connector\Sabre\FilesPlugin;
use OCA\DAV\Connector\Sabre\Server;
use OCA\DAV\Connector\Sabre\TagsPlugin;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Folder;
Expand Down Expand Up @@ -44,6 +45,7 @@ class FileSearchBackend implements ISearchBackend {
public const OPERATOR_LIMIT = 100;

public function __construct(
private Server $server,
private CachingTree $tree,
private IUser $user,
private IRootFolder $rootFolder,
Expand Down Expand Up @@ -133,6 +135,7 @@ private function getPropertyDefinitionsForMetadata(): array {
* @param string[] $requestProperties
*/
public function preloadPropertyFor(array $nodes, array $requestProperties): void {
$this->server->emit('preloadProperties', [$nodes, $requestProperties]);
}

private function getFolderForPath(?string $path = null): Folder {
Expand Down
1 change: 1 addition & 0 deletions apps/dav/lib/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ public function __construct(IRequest $request, string $baseUri) {
\OC::$server->getAppManager()
));
$lazySearchBackend->setBackend(new \OCA\DAV\Files\FileSearchBackend(
$this->server,
$this->server->tree,
$user,
\OC::$server->getRootFolder(),
Expand Down
19 changes: 18 additions & 1 deletion apps/dav/tests/unit/Files/FileSearchBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use OCA\DAV\Connector\Sabre\File;
use OCA\DAV\Connector\Sabre\FilesPlugin;
use OCA\DAV\Connector\Sabre\ObjectTree;
use OCA\DAV\Connector\Sabre\Server;
use OCA\DAV\Files\FileSearchBackend;
use OCP\Files\FileInfo;
use OCP\Files\Folder;
Expand All @@ -33,6 +34,7 @@
class FileSearchBackendTest extends TestCase {
/** @var ObjectTree|\PHPUnit\Framework\MockObject\MockObject */
private $tree;
private Server&\PHPUnit\Framework\MockObject\MockObject $server;

/** @var IUser */
private $user;
Expand Down Expand Up @@ -67,6 +69,8 @@ protected function setUp(): void {
->disableOriginalConstructor()
->getMock();

$this->server = $this->createMock(Server::class);

$this->view = $this->createMock(View::class);

$this->view->expects($this->any())
Expand Down Expand Up @@ -97,7 +101,7 @@ protected function setUp(): void {

$filesMetadataManager = $this->createMock(IFilesMetadataManager::class);

$this->search = new FileSearchBackend($this->tree, $this->user, $this->rootFolder, $this->shareManager, $this->view, $filesMetadataManager);
$this->search = new FileSearchBackend($this->server, $this->tree, $this->user, $this->rootFolder, $this->shareManager, $this->view, $filesMetadataManager);
}

public function testSearchFilename(): void {
Expand Down Expand Up @@ -421,4 +425,17 @@ public function testSearchOperatorLimit(): void {
$this->expectException(\InvalidArgumentException::class);
$this->search->search($query);
}

public function testPreloadPropertyFor(): void {
$node1 = $this->createMock(File::class);
$node2 = $this->createMock(Directory::class);
$nodes = [$node1, $node2];
$requestProperties = ['{DAV:}getcontenttype', '{DAV:}getlastmodified'];

$this->server->expects($this->once())
->method('emit')
->with('preloadProperties', [$nodes, $requestProperties]);

$this->search->preloadPropertyFor($nodes, $requestProperties);
}
}
Loading