Handle destination.one files without file name. (#67)

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
This commit is contained in:
Daniel Siepmann (Codappix) 2024-09-17 11:04:19 +02:00 committed by GitHub
parent 17fae724df
commit 674014e8fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 122 additions and 2 deletions

View file

@ -29,6 +29,7 @@ use SplFileInfo;
use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Resource\DuplicationBehavior; use TYPO3\CMS\Core\Resource\DuplicationBehavior;
use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Folder;
use TYPO3\CMS\Core\Resource\Index\MetaDataRepository; use TYPO3\CMS\Core\Resource\Index\MetaDataRepository;
use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
@ -67,7 +68,7 @@ final class FilesAssignment
} }
$fileUrl = urldecode((string)$mediaObject['url']); $fileUrl = urldecode((string)$mediaObject['url']);
$orgFileNameSanitized = $importFolder->getStorage()->sanitizeFileName(basename($fileUrl)); $orgFileNameSanitized = $this->createFileName($fileUrl, $importFolder);
$this->logger->info('File attached.', [$fileUrl, $orgFileNameSanitized]); $this->logger->info('File attached.', [$fileUrl, $orgFileNameSanitized]);
@ -75,7 +76,7 @@ final class FilesAssignment
$this->logger->info('File already exists.', [$orgFileNameSanitized]); $this->logger->info('File already exists.', [$orgFileNameSanitized]);
} elseif ($filename = $this->loadFile($fileUrl)) { } elseif ($filename = $this->loadFile($fileUrl)) {
$this->logger->info('Adding file to FAL.', [$filename]); $this->logger->info('Adding file to FAL.', [$filename]);
$importFolder->addFile($filename, basename($fileUrl), DuplicationBehavior::REPLACE); $importFolder->addFile($filename, $orgFileNameSanitized, DuplicationBehavior::REPLACE);
} else { } else {
continue; continue;
} }
@ -98,6 +99,18 @@ final class FilesAssignment
return $images; 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 private function loadFile(string $fileUrl): string
{ {
$this->logger->info('Getting file.', [$fileUrl]); $this->logger->info('Getting file.', [$fileUrl]);

View file

@ -28,6 +28,13 @@ Fixes
back to `date_default_timezone_get()` call. back to `date_default_timezone_get()` call.
That way it should be useful for most systems out of the box. That way it should be useful for most systems out of the box.
* 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 Tasks
----- -----

View file

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Resource\File;
return [
'sys_file' => [
[
'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' => null,
],
],
];

View file

@ -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"
}
}
]
}

View file

@ -60,6 +60,31 @@ class ImportHandlesImagesTest extends AbstractTestCase
$this->assertEmptyLog(); $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] #[Test]
public function addsMultipleImagesToSingleEvent(): void public function addsMultipleImagesToSingleEvent(): void
{ {