From b403b05765897ed3d3c68e8e36f7ec82ea92658d Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 6 Jul 2026 11:06:15 -0400 Subject: [PATCH 1/3] perf(files_sharing): simplify tag population in ShareAPIController Signed-off-by: Josh --- .../lib/Controller/ShareAPIController.php | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index 64845f15cf541..36f5a1f33f7da 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -2227,29 +2227,30 @@ public function generateToken(): DataResponse { * @return list file list populated with tags */ private function populateTags(array $fileList): array { + if ($fileList === []) { + return []; + } + $tagger = $this->tagManager->load('files'); - $tags = $tagger->getTagsForObjects(array_map(static fn (array $fileData) => $fileData['file_source'], $fileList)); + $tags = $tagger->getTagsForObjects(array_map( + static fn (array $fileData) => $fileData['file_source'], + $fileList + )); if (!is_array($tags)) { throw new \UnexpectedValueException('$tags must be an array'); } - // Set empty tag array - foreach ($fileList as &$fileData) { - $fileData['tags'] = []; + $index = []; + foreach ($fileList as $i => $fileData) { + $fileList[$i]['tags'] = []; + // Multiple share rows can point to the same file_source, so store all positions. + $index[$fileData['file_source']][] = $i; } - unset($fileData); - if (!empty($tags)) { - foreach ($tags as $fileId => $fileTags) { - foreach ($fileList as &$fileData) { - if ($fileId !== $fileData['file_source']) { - continue; - } - - $fileData['tags'] = $fileTags; - } - unset($fileData); + foreach ($tags as $fileSource => $fileTags) { + foreach ($index[$fileSource] ?? [] as $i) { + $fileList[$i]['tags'] = $fileTags; } } From 0fd8479d35b21572cd17ae06e856d884d8932d67 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 6 Jul 2026 11:40:04 -0400 Subject: [PATCH 2/3] test(files_sharing): cover duplicate file_source entries in populateTags Signed-off-by: Josh --- .../Controller/ShareAPIControllerTest.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php index 097de4fa43740..984b0cb02c9d0 100644 --- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php @@ -5257,6 +5257,31 @@ public function testPopulateTags(): void { ], $result); } + public function testPopulateTagsWithDuplicateFileSource(): void { + $tagger = $this->createMock(ITags::class); + $this->tagManager->method('load') + ->with('files') + ->willReturn($tagger); + $data = [ + ['file_source' => 42, 'foo' => 'bar'], + ['file_source' => 10], + ['file_source' => 42, 'x' => 'y'], + ]; + $tags = [ + 42 => ['tag1', 'tag2'], + ]; + $tagger->method('getTagsForObjects') + ->with([42, 10, 42]) + ->willReturn($tags); + + $result = self::invokePrivate($this->ocs, 'populateTags', [$data]); + $this->assertSame([ + ['file_source' => 42, 'foo' => 'bar', 'tags' => ['tag1', 'tag2']], + ['file_source' => 10, 'tags' => []], + ['file_source' => 42, 'x' => 'y', 'tags' => ['tag1', 'tag2']], + ], $result); + } + public static function trustedServerProvider(): array { return [ 'Trusted server' => [true, true], From 8dec059db1c4fb2bede35d29fe7f1cf26904dc5f Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 7 Jul 2026 07:50:26 -0400 Subject: [PATCH 3/3] fix(files_sharing): adjust populateTags Psalm return type Adjust the Psalm docblock for populateTags() to reflect the internal implementation change without changing the returned data shape. Signed-off-by: Josh --- apps/files_sharing/lib/Controller/ShareAPIController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index 36f5a1f33f7da..b084691db72ca 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -2224,7 +2224,7 @@ public function generateToken(): DataResponse { * * @psalm-template T of array{tags?: list, file_source: int, ...array} * @param list $fileList - * @return list file list populated with tags + * @return list}> file list populated with tags */ private function populateTags(array $fileList): array { if ($fileList === []) {