Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
93.62% |
44 / 47 |
|
50.00% |
2 / 4 |
CRAP | |
0.00% |
0 / 1 |
| MetadataLoader | |
93.62% |
44 / 47 |
|
50.00% |
2 / 4 |
13.04 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| loadMetadata | |
92.31% |
24 / 26 |
|
0.00% |
0 / 1 |
6.02 | |||
| getFileNode | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
4.05 | |||
| getPages | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | /** |
| 6 | * SPDX-FileCopyrightText: 2025 LibreCode coop and contributors |
| 7 | * SPDX-License-Identifier: AGPL-3.0-or-later |
| 8 | */ |
| 9 | |
| 10 | namespace OCA\Libresign\Service\File; |
| 11 | |
| 12 | use OCA\Libresign\Db\File; |
| 13 | use OCA\Libresign\Service\FolderService; |
| 14 | use OCP\Files\IMimeTypeDetector; |
| 15 | use OCP\IURLGenerator; |
| 16 | use Psr\Log\LoggerInterface; |
| 17 | use stdClass; |
| 18 | |
| 19 | class MetadataLoader { |
| 20 | public function __construct( |
| 21 | private FolderService $folderService, |
| 22 | private IMimeTypeDetector $mimeTypeDetector, |
| 23 | private IURLGenerator $urlGenerator, |
| 24 | private FileContentProvider $contentProvider, |
| 25 | private LoggerInterface $logger, |
| 26 | ) { |
| 27 | } |
| 28 | |
| 29 | public function loadMetadata(?File $file, stdClass $fileData): void { |
| 30 | if (!$file) { |
| 31 | return; |
| 32 | } |
| 33 | |
| 34 | $rawMetadata = $file->getMetadata() ?? []; |
| 35 | |
| 36 | try { |
| 37 | $fileNode = $this->getFileNode($file); |
| 38 | $metadata = $rawMetadata; |
| 39 | |
| 40 | if (method_exists($fileNode, 'getSize')) { |
| 41 | $fileData->size = $fileNode->getSize(); |
| 42 | } |
| 43 | |
| 44 | if (method_exists($fileNode, 'getMimeType')) { |
| 45 | $fileData->mime = $fileNode->getMimeType(); |
| 46 | } else { |
| 47 | $content = $this->contentProvider->getContentFromLibresignFile($file); |
| 48 | $fileData->mime = $this->mimeTypeDetector->detectString($content); |
| 49 | } |
| 50 | |
| 51 | $fileData->pages = $this->getPages($file); |
| 52 | $fileData->totalPages = (int)($metadata['p'] ?? count($fileData->pages ?? [])); |
| 53 | $fileData->pdfVersion = (string)($metadata['pdfVersion'] ?? ''); |
| 54 | |
| 55 | $metadata = ValidationMetadataNormalizer::normalize($metadata, $file->getName(), $fileData->totalPages); |
| 56 | $fileData->metadata = $metadata; |
| 57 | } catch (\Throwable $e) { |
| 58 | $this->logger->warning('Failed to load file metadata: ' . $e->getMessage()); |
| 59 | } |
| 60 | |
| 61 | $fileData->size ??= 0; |
| 62 | $fileData->totalPages ??= 0; |
| 63 | $fileData->pdfVersion ??= ''; |
| 64 | $fileData->metadata = ValidationMetadataNormalizer::normalize( |
| 65 | is_array($fileData->metadata ?? null) ? $fileData->metadata : $rawMetadata, |
| 66 | $file->getName(), |
| 67 | (int)$fileData->totalPages, |
| 68 | ); |
| 69 | } |
| 70 | |
| 71 | /** |
| 72 | * Get file node from File entity |
| 73 | * |
| 74 | * @throws \OCA\Libresign\Exception\LibresignException |
| 75 | */ |
| 76 | private function getFileNode(File $file): \OCP\Files\File|\OCP\Files\Folder { |
| 77 | $nodeId = $file->getSignedNodeId(); |
| 78 | if (!$nodeId) { |
| 79 | $nodeId = $file->getNodeId(); |
| 80 | } |
| 81 | |
| 82 | $fileNode = $this->folderService->getReadableNodeById($file->getUserId(), $nodeId); |
| 83 | |
| 84 | if (!$fileNode instanceof \OCP\Files\File && !$fileNode instanceof \OCP\Files\Folder) { |
| 85 | throw new \OCA\Libresign\Exception\LibresignException('File not found', 404); |
| 86 | } |
| 87 | |
| 88 | return $fileNode; |
| 89 | } |
| 90 | |
| 91 | /** |
| 92 | * Get pages array with URLs and resolutions |
| 93 | * |
| 94 | * @return array<int, array{number: int, url: string, resolution: mixed}> |
| 95 | */ |
| 96 | private function getPages(File $file): array { |
| 97 | $return = []; |
| 98 | |
| 99 | $metadata = $file->getMetadata(); |
| 100 | $pageCount = $metadata['p'] ?? 0; |
| 101 | |
| 102 | for ($page = 1; $page <= $pageCount; $page++) { |
| 103 | $return[] = [ |
| 104 | 'number' => $page, |
| 105 | 'url' => $this->urlGenerator->linkToRoute('libresign.page.getPdf', [ |
| 106 | 'uuid' => $file->getUuid(), |
| 107 | 'page' => $page, |
| 108 | ]), |
| 109 | 'resolution' => $metadata['d'][$page - 1] ?? null, |
| 110 | ]; |
| 111 | } |
| 112 | |
| 113 | return $return; |
| 114 | } |
| 115 | } |