diff --git a/EMS/common-bundle/src/Storage/Archive.php b/EMS/common-bundle/src/Storage/Archive.php index 76e47874c..10ad5cf44 100644 --- a/EMS/common-bundle/src/Storage/Archive.php +++ b/EMS/common-bundle/src/Storage/Archive.php @@ -113,6 +113,16 @@ private function parseFile(array $file): ArchiveItem ); } + /** + * @return iterable + */ + public function iterator(): iterable + { + foreach ($this->files as $path => $file) { + yield $path => $file; + } + } + /** * @param mixed[] $file * @return array{filename: string, hash: string, type: string, size: int} diff --git a/EMS/common-bundle/src/Storage/Service/AbstractUrlStorage.php b/EMS/common-bundle/src/Storage/Service/AbstractUrlStorage.php index c5f9335d2..b2350dfac 100644 --- a/EMS/common-bundle/src/Storage/Service/AbstractUrlStorage.php +++ b/EMS/common-bundle/src/Storage/Service/AbstractUrlStorage.php @@ -249,4 +249,9 @@ public function addFileInArchiveCache(string $hash, SplFileInfo $file, string $m { return false; } + + public function copyFileInArchiveCache(string $archiveHash, string $fileHash, string $path, string $mimeType): bool + { + return false; + } } diff --git a/EMS/common-bundle/src/Storage/Service/EntityStorage.php b/EMS/common-bundle/src/Storage/Service/EntityStorage.php index 20986bf8d..47aed1f2f 100644 --- a/EMS/common-bundle/src/Storage/Service/EntityStorage.php +++ b/EMS/common-bundle/src/Storage/Service/EntityStorage.php @@ -245,4 +245,9 @@ public function addFileInArchiveCache(string $hash, SplFileInfo $file, string $m { return false; } + + public function copyFileInArchiveCache(string $archiveHash, string $fileHash, string $path, string $mimeType): bool + { + return false; + } } diff --git a/EMS/common-bundle/src/Storage/Service/FileSystemStorage.php b/EMS/common-bundle/src/Storage/Service/FileSystemStorage.php index 3e7b56573..214e0b10a 100644 --- a/EMS/common-bundle/src/Storage/Service/FileSystemStorage.php +++ b/EMS/common-bundle/src/Storage/Service/FileSystemStorage.php @@ -108,6 +108,11 @@ public function addFileInArchiveCache(string $hash, SplFileInfo $file, string $m return \copy($file->getPathname(), $filename); } + public function copyFileInArchiveCache(string $archiveHash, string $fileHash, string $path, string $mimeType): bool + { + return false; + } + protected function getCachePath(Config $config): string { return \join(DIRECTORY_SEPARATOR, [ diff --git a/EMS/common-bundle/src/Storage/Service/S3Storage.php b/EMS/common-bundle/src/Storage/Service/S3Storage.php index cfe9d4b80..9807371d0 100644 --- a/EMS/common-bundle/src/Storage/Service/S3Storage.php +++ b/EMS/common-bundle/src/Storage/Service/S3Storage.php @@ -330,6 +330,25 @@ public function addFileInArchiveCache(string $hash, SplFileInfo $file, string $m return $result->hasKey('ETag'); } + public function copyFileInArchiveCache(string $archiveHash, string $fileHash, string $path, string $mimeType): bool + { + $sourceKey = $this->key($fileHash); + $result = $this->getS3Client()->copyObject([ + 'Bucket' => $this->bucket, + 'ContentType' => $mimeType, + 'Key' => \implode('/', [ + 'cache', + \substr($archiveHash, 0, 3), + \substr($archiveHash, 3), + $path, + ]), + 'CopySource' => "$this->bucket/$sourceKey", + 'MetadataDirective' => 'REPLACE', + ]); + + return $result->hasKey('ETag'); + } + public function heads(string ...$hashes): array { $client = $this->getS3Client(); diff --git a/EMS/common-bundle/src/Storage/Service/StorageInterface.php b/EMS/common-bundle/src/Storage/Service/StorageInterface.php index cbf8843c4..040463795 100644 --- a/EMS/common-bundle/src/Storage/Service/StorageInterface.php +++ b/EMS/common-bundle/src/Storage/Service/StorageInterface.php @@ -84,4 +84,6 @@ public function clearCache(): bool; public function readFromArchiveInCache(string $hash, string $path): ?StreamWrapper; public function addFileInArchiveCache(string $hash, SplFileInfo $file, string $mimeType): bool; + + public function copyFileInArchiveCache(string $archiveHash, string $fileHash, string $path, string $mimeType): bool; } diff --git a/EMS/common-bundle/src/Storage/StorageManager.php b/EMS/common-bundle/src/Storage/StorageManager.php index d93a0ff9a..29152349e 100644 --- a/EMS/common-bundle/src/Storage/StorageManager.php +++ b/EMS/common-bundle/src/Storage/StorageManager.php @@ -583,10 +583,27 @@ private function getStreamFromZipArchive(string $hash, string $path, TempFile $z private function getStreamFromJsonArchive(string $hash, string $path, TempFile $archiveFile): StreamWrapper { - $file = Archive::fromStructure($archiveFile->getContents(), $this->hashAlgo)->getByPath($path); + $archive = Archive::fromStructure($archiveFile->getContents(), $this->hashAlgo); + $file = $archive->getByPath($path); if (null === $file) { throw new NotFoundHttpException(\sprintf('File %s not found in archive %s', $path, $hash)); } + $counter = 0; + foreach ($archive->iterator() as $item) { + foreach ($this->adapters as $adapter) { + if ($adapter->copyFileInArchiveCache($hash, $item->getHash(), $item->getFilename(), $item->getType())) { + ++$counter; + break; + } + } + } + if ($archive->getSize() === $counter) { + $this->logger->debug(\sprintf('%d files have been successfully saved in cache', $counter)); + } elseif (0 === $counter) { + $this->logger->warning(\sprintf('None of the %d files have been successfully saved in cache', $archive->getSize())); + } else { + $this->logger->warning(\sprintf('%d files, on a total of %d, have been successfully saved in cache', $counter, $archive->getSize())); + } return new StreamWrapper($this->getStream($file->getHash()), $file->getType(), $file->getSize()); }