From 5f6c6eef0e6fb0461f3ae6b6bac5e0fede5ff7e5 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 17 Sep 2024 11:04:22 +0200 Subject: [PATCH] Handle destination.one files without file name. (#68) It is possible to have files such as `https://dam.destination.one/2675868/3dc0a9dccd0dad46c73e669ece428c634ff8324ea3d01a4858a1c43169deed41/.jpg`. Those were not handled correctly yet. We now also handle those cases. We will generate a hash from the URL as file name in order to still use those files. Relates: #11396 --- .../FilesAssignment.php | 19 +++++++-- Documentation/Changelog/3.9.1.rst | 32 ++++++++++++++ .../ImportHandlesImageWithoutFileName.php | 42 +++++++++++++++++++ .../ResponseWithNewImageWithoutFileName.json | 33 +++++++++++++++ .../ImportHandlesImagesTest.php | 27 ++++++++++++ ext_emconf.php | 2 +- 6 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 Documentation/Changelog/3.9.1.rst create mode 100644 Tests/Functional/Import/DestinationDataTest/Assertions/ImportHandlesImageWithoutFileName.php create mode 100644 Tests/Functional/Import/DestinationDataTest/Fixtures/ResponseWithNewImageWithoutFileName.json diff --git a/Classes/Service/DestinationDataImportService/FilesAssignment.php b/Classes/Service/DestinationDataImportService/FilesAssignment.php index 6cad16c5..604d19ab 100644 --- a/Classes/Service/DestinationDataImportService/FilesAssignment.php +++ b/Classes/Service/DestinationDataImportService/FilesAssignment.php @@ -28,6 +28,7 @@ use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\Resource\DuplicationBehavior; use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Resource\Folder; use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -86,8 +87,8 @@ public function getImages( continue; } - $fileUrl = urldecode($mediaObject['url']); - $orgFileNameSanitized = $importFolder->getStorage()->sanitizeFileName(basename($fileUrl)); + $fileUrl = urldecode((string)$mediaObject['url']); + $orgFileNameSanitized = $this->createFileName($fileUrl, $importFolder); $this->logger->info('File attached.', [$fileUrl, $orgFileNameSanitized]); @@ -95,7 +96,7 @@ public function getImages( $this->logger->info('File already exists.', [$orgFileNameSanitized]); } elseif ($filename = $this->loadFile($fileUrl)) { $this->logger->info('Adding file to FAL.', [$filename]); - $importFolder->addFile($filename, basename($fileUrl), DuplicationBehavior::REPLACE); + $importFolder->addFile($filename, $orgFileNameSanitized, DuplicationBehavior::REPLACE); } else { continue; } @@ -118,6 +119,18 @@ public function getImages( return $images; } + private function createFileName(string $url, Folder $importFolder): string + { + $extension = pathinfo($url, PATHINFO_EXTENSION); + + $fileName = basename($url); + if ($fileName === '.' . $extension) { + $fileName = hash('sha256', $url) . '.' . $extension; + } + + return $importFolder->getStorage()->sanitizeFileName($fileName); + } + private function loadFile(string $fileUrl): string { $this->logger->info('Getting file.', [$fileUrl]); diff --git a/Documentation/Changelog/3.9.1.rst b/Documentation/Changelog/3.9.1.rst new file mode 100644 index 00000000..805a5b98 --- /dev/null +++ b/Documentation/Changelog/3.9.1.rst @@ -0,0 +1,32 @@ +3.9.1 +===== + +Breaking +-------- + +Nothing + +Features +-------- + +Nothing + +Fixes +----- + +* Handle destination.one files without file name. + + It is possible to have files such as `https://dam.destination.one/2675868/3dc0a9dccd0dad46c73e669ece428c634ff8324ea3d01a4858a1c43169deed41/.jpg`. + Those were not handled correctly yet. + We now also handle those cases. + We will generate a hash from the URL as file name in order to still use those files. + +Tasks +----- + +* Add image handling support in nix shell. + +Deprecation +----------- + +Nothing diff --git a/Tests/Functional/Import/DestinationDataTest/Assertions/ImportHandlesImageWithoutFileName.php b/Tests/Functional/Import/DestinationDataTest/Assertions/ImportHandlesImageWithoutFileName.php new file mode 100644 index 00000000..55864350 --- /dev/null +++ b/Tests/Functional/Import/DestinationDataTest/Assertions/ImportHandlesImageWithoutFileName.php @@ -0,0 +1,42 @@ + [ + [ + 'uid' => 1, + 'pid' => 0, + 'missing' => 0, + 'storage' => 1, + 'type' => File::FILETYPE_IMAGE, + 'identifier' => '/staedte/beispielstadt/events/bf126089c94f95031fa07bf9d7d9b10c3e58aafebdef31f0b60604da13019b8d.jpg', + 'extension' => 'jpg', + 'name' => 'bf126089c94f95031fa07bf9d7d9b10c3e58aafebdef31f0b60604da13019b8d.jpg', + ], + ], + 'sys_file_reference' => [ + [ + 'uid' => 1, + 'pid' => 2, + 'uid_local' => 1, + 'uid_foreign' => 1, + 'tablenames' => 'tx_events_domain_model_event', + 'fieldname' => 'images', + 'sorting_foreign' => 1, + 'title' => null, + 'description' => null, + 'alternative' => null, + ], + ], + 'sys_file_metadata' => [ + [ + 'uid' => 1, + 'pid' => 0, + 'file' => 1, + 'title' => '', + ], + ], +]; diff --git a/Tests/Functional/Import/DestinationDataTest/Fixtures/ResponseWithNewImageWithoutFileName.json b/Tests/Functional/Import/DestinationDataTest/Fixtures/ResponseWithNewImageWithoutFileName.json new file mode 100644 index 00000000..99498bcb --- /dev/null +++ b/Tests/Functional/Import/DestinationDataTest/Fixtures/ResponseWithNewImageWithoutFileName.json @@ -0,0 +1,33 @@ +{ + "items": [ + { + "global_id": "e_100347853", + "title": "Allerlei Weihnachtliches (Heute mit Johannes Geißer)", + "media_objects": [ + { + "rel": "default", + "url": "https://dam.destination.one/849917/279ac45b3fc701a7197131f627164fffd9f8cc77bc75165e2fc2b864ed606920/.jpg", + "type": "image/jpeg", + "latitude": null, + "longitude": null, + "width": 1920, + "height": 1080, + "value": "" + } + ], + "timeIntervals": [ + { + "weekdays": [], + "start": "2022-12-19T15:00:00+01:00", + "end": "2022-12-19T16:30:00+01:00", + "tz": "Europe/Berlin", + "interval": 1 + } + ], + "source": { + "url": "http://destination.one/", + "value": "destination.one" + } + } + ] +} diff --git a/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php b/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php index 2f7815b4..330f306b 100644 --- a/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php +++ b/Tests/Functional/Import/DestinationDataTest/ImportHandlesImagesTest.php @@ -60,6 +60,33 @@ public function addsNewImages(): void $this->assertEmptyLog(); } + /** + * @test + */ + public function addsNewImageWithoutFileName(): void + { + $this->setUpResponses([ + new Response(200, [], file_get_contents(__DIR__ . '/Fixtures/ResponseWithNewImageWithoutFileName.json') ?: ''), + new Response(200, [], file_get_contents(__DIR__ . '/Fixtures/ExampleImage.jpg') ?: ''), + ]); + + $this->executeCommand(); + + $this->assertPHPDataSet(__DIR__ . '/Assertions/ImportHandlesImageWithoutFileName.php'); + + $importedFiles = GeneralUtility::getFilesInDir($this->fileImportPath); + self::assertIsArray($importedFiles, 'Failed to retrieve imported files from filesystem.'); + self::assertSame( + [ + 'bf126089c94f95031fa07bf9d7d9b10c3e58aafebdef31f0b60604da13019b8d.jpg', + ], + array_values($importedFiles), + 'Got unexpected number of files' + ); + + $this->assertEmptyLog(); + } + /** * @test */ diff --git a/ext_emconf.php b/ext_emconf.php index 60445de5..6745c7db 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -9,7 +9,7 @@ 'state' => 'stable', 'createDirs' => '', 'clearCacheOnLoad' => 0, - 'version' => '3.9.0', + 'version' => '3.9.1', 'constraints' => [ 'depends' => [ 'typo3' => '10.4.00-11.5.99',