Skip to content

Commit

Permalink
Merge remote-tracking branch 'ezpublish/7.5' into 1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
barw4 committed Jan 18, 2022
2 parents 7dda628 + 04451df commit f95a4b7
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
use Doctrine\DBAL\Driver\Connection;
use eZ\Publish\Core\FieldType\Image\ImageStorage\Gateway as ImageStorageGateway;
use eZ\Publish\Core\IO\FilePathNormalizerInterface;
use eZ\Publish\Core\IO\IOServiceInterface;
use eZ\Publish\Core\IO\Values\BinaryFile;
use eZ\Publish\Core\IO\Values\BinaryFileCreateStruct;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand Down Expand Up @@ -40,16 +43,21 @@ final class NormalizeImagesPathsCommand extends Command
/** @var \Doctrine\DBAL\Driver\Connection */
private $connection;

/** @var \eZ\Publish\Core\IO\IOServiceInterface */
private $ioService;

public function __construct(
ImageStorageGateway $imageGateway,
FilePathNormalizerInterface $filePathNormalizer,
Connection $connection
Connection $connection,
IOServiceInterface $ioService
) {
parent::__construct();

$this->imageGateway = $imageGateway;
$this->filePathNormalizer = $filePathNormalizer;
$this->connection = $connection;
$this->ioService = $ioService;
}

protected function configure()
Expand Down Expand Up @@ -163,5 +171,29 @@ private function updateImagePath(int $fieldId, string $oldPath, string $newPath)
$this->imageGateway->updateImagePath($fieldId, $oldPath, $newPath);
}
}

$this->moveFile($oldFileName, $newFilename, $oldPath);
}

private function moveFile(string $oldFileName, string $newFileName, string $oldPath): void
{
$oldBinaryFile = $this->ioService->loadBinaryFileByUri(\DIRECTORY_SEPARATOR . $oldPath);
$newId = str_replace($oldFileName, $newFileName, $oldBinaryFile->id);
$inputStream = $this->ioService->getFileInputStream($oldBinaryFile);

$binaryCreateStruct = new BinaryFileCreateStruct(
[
'id' => $newId,
'size' => $oldBinaryFile->size,
'inputStream' => $inputStream,
'mimeType' => $this->ioService->getMimeType($oldBinaryFile->id),
]
);

$newBinaryFile = $this->ioService->createBinaryFile($binaryCreateStruct);

if ($newBinaryFile instanceof BinaryFile) {
$this->ioService->deleteBinaryFile($oldBinaryFile);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ services:
arguments:
$connection: '@ezpublish.persistence.connection'
$imageGateway: '@ezpublish.fieldType.ezimage.storage_gateway'
$ioService: '@ezpublish.fieldType.ezimage.io_service'
tags:
- { name: console.command }
22 changes: 12 additions & 10 deletions eZ/Publish/API/Repository/Tests/FieldType/ImageIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,10 @@ public function getFieldName()
*
* Asserts that the data provided by {@link getValidCreationFieldData()}
* was stored and loaded correctly.
*
* @param \eZ\Publish\API\Repository\Values\Content\Field $field
*/
public function assertFieldDataLoadedCorrect(Field $field)
public function assertFieldDataLoadedCorrect(Field $field): void
{
$this->assertInstanceOf(
self::assertInstanceOf(
'eZ\\Publish\\Core\\FieldType\\Image\\Value',
$field->value
);
Expand All @@ -197,12 +195,15 @@ public function assertFieldDataLoadedCorrect(Field $field)
// Will be nullified by external storage
$expectedData['inputUri'] = null;

// Will be changed by external storage as fileName will be decorated with a hash
$expectedData['fileName'] = $field->value->fileName;

$this->assertPropertiesCorrect(
$expectedData,
$field->value
);

$this->assertTrue(
self::assertTrue(
$this->uriExistsOnIO($field->value->uri),
"Asserting that {$field->value->uri} exists."
);
Expand Down Expand Up @@ -262,12 +263,10 @@ public function getValidUpdateFieldData()
* Get externals updated field data values.
*
* This is a PHPUnit data provider
*
* @return array
*/
public function assertUpdatedFieldDataLoadedCorrect(Field $field)
public function assertUpdatedFieldDataLoadedCorrect(Field $field): void
{
$this->assertInstanceOf(
self::assertInstanceOf(
'eZ\\Publish\\Core\\FieldType\\Image\\Value',
$field->value
);
Expand All @@ -278,14 +277,17 @@ public function assertUpdatedFieldDataLoadedCorrect(Field $field)
// Will change during storage
$expectedData['inputUri'] = null;

// Will change during storage as fileName will be decorated with a hash
$expectedData['fileName'] = $field->value->fileName;

$expectedData['uri'] = $field->value->uri;

$this->assertPropertiesCorrect(
$expectedData,
$field->value
);

$this->assertTrue(
self::assertTrue(
$this->uriExistsOnIO($field->value->uri),
"Asserting that file {$field->value->uri} exists"
);
Expand Down
20 changes: 20 additions & 0 deletions eZ/Publish/Core/IO/FilePathNormalizer/Flysystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,32 @@
namespace eZ\Publish\Core\IO\FilePathNormalizer;

use eZ\Publish\Core\IO\FilePathNormalizerInterface;
use eZ\Publish\Core\Persistence\Legacy\Content\UrlAlias\SlugConverter;
use League\Flysystem\Util;

final class Flysystem implements FilePathNormalizerInterface
{
private const HASH_PATTERN = '/^[0-9a-f]{12}-/';

/** @var \eZ\Publish\Core\Persistence\Legacy\Content\UrlAlias\SlugConverter */
private $slugConverter;

public function __construct(SlugConverter $slugConverter)
{
$this->slugConverter = $slugConverter;
}

public function normalizePath(string $filePath): string
{
$fileName = pathinfo($filePath, PATHINFO_BASENAME);
$directory = pathinfo($filePath, PATHINFO_DIRNAME);

$fileName = $this->slugConverter->convert($fileName);

$hash = preg_match(self::HASH_PATTERN, $fileName) ? '' : bin2hex(random_bytes(6)) . '-';

$filePath = $directory . \DIRECTORY_SEPARATOR . $hash . $fileName;

return Util::normalizePath($filePath);
}
}
87 changes: 87 additions & 0 deletions eZ/Publish/Core/IO/Tests/FilePathNormalizer/FlysystemTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Core\IO\FilePathNormalizer;

use eZ\Publish\Core\IO\FilePathNormalizer\Flysystem;
use eZ\Publish\Core\Persistence\Legacy\Content\UrlAlias\SlugConverter;
use PHPUnit\Framework\TestCase;

final class FlysystemTest extends TestCase
{
/** @var \eZ\Publish\Core\IO\FilePathNormalizer\Flysystem */
private $filePathNormalizer;

/** @var \eZ\Publish\Core\Persistence\Legacy\Content\UrlAlias\SlugConverter|\PHPUnit\Framework\MockObject\MockObject */
private $slugConverter;

public function setUp(): void
{
$this->slugConverter = $this->createMock(SlugConverter::class);
$this->filePathNormalizer = new Flysystem($this->slugConverter);
}

/**
* @dataProvider providerForTestNormalizePath
*/
public function testNormalizePath(
string $originalPath,
string $fileName,
string $sluggedFileName,
string $regex
): void {
$this->slugConverter
->expects(self::once())
->method('convert')
->with($fileName)
->willReturn($sluggedFileName);

$normalizedPath = $this->filePathNormalizer->normalizePath($originalPath);

self::assertStringEndsWith($sluggedFileName, $normalizedPath);
self::assertRegExp($regex, $normalizedPath);
}

public function providerForTestNormalizePath(): array
{
$defaultPattern = '/\/[0-9a-f]{12}-';

return [
'No special chars' => [
'4/3/2/234/1/image.jpg',
'image.jpg',
'image.jpg',
$defaultPattern . 'image.jpg/',
],
'Spaces in the filename' => [
'4/3/2/234/1/image with spaces.jpg',
'image with spaces.jpg',
'image-with-spaces.jpg',
$defaultPattern . 'image-with-spaces.jpg/',
],
'Encoded spaces in the name' => [
'4/3/2/234/1/image%20+no+spaces.jpg',
'image%20+no+spaces.jpg',
'image-20-nospaces.jpg',
$defaultPattern . 'image-20-nospaces.jpg/',
],
'Special chars in the name' => [
'4/3/2/234/1/image%20+no+spaces?.jpg',
'image%20+no+spaces?.jpg',
'image-20-nospaces.jpg',
$defaultPattern . 'image-20-nospaces.jpg/',
],
'Already hashed name' => [
'4/3/2/234/1/14ff44718877-hashed.jpg',
'14ff44718877-hashed.jpg',
'14ff44718877-hashed.jpg',
'/^4\/3\/2\/234\/1\/14ff44718877-hashed.jpg$/',
],
];
}
}
5 changes: 4 additions & 1 deletion eZ/Publish/Core/settings/io.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,8 @@ services:
- ~
- "@ezpublish.core.io.image_fieldtype.legacy_url_decorator"

eZ\Publish\Core\IO\FilePathNormalizer\Flysystem: ~
eZ\Publish\Core\IO\FilePathNormalizer\Flysystem:
arguments:
$slugConverter: '@ezpublish.persistence.slug_converter'

eZ\Publish\Core\IO\FilePathNormalizerInterface: '@eZ\Publish\Core\IO\FilePathNormalizer\Flysystem'

0 comments on commit f95a4b7

Please sign in to comment.