Skip to content

Commit

Permalink
[FEATURE] add event listener to enrich file data. (#541)
Browse files Browse the repository at this point in the history
* [FEATURE] add event to enrich file data.

* [FEATURE] fix missing constructor DI.

* [FEATURE] add code review changes.

* [FEATURE] remove nullable option on EnrichFileDataEvent.

* [FEATURE] fix unit tests for FileUtility.

* [FEATURE] add php cs changes.

* [FEATURE] add PHP Unit test for EnrichFileDataEvent.

* [FEATURE] change php cs issue.
  • Loading branch information
Fanor51 authored Mar 1, 2023
1 parent dee571f commit 8ffd93f
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 8 deletions.
42 changes: 42 additions & 0 deletions Classes/Event/EnrichFileDataEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/*
* This file is part of the "headless" Extension for TYPO3 CMS.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/

declare(strict_types=1);

namespace FriendsOfTYPO3\Headless\Event;

use TYPO3\CMS\Core\Resource\FileInterface;

final class EnrichFileDataEvent
{
private FileInterface $fileReference;

private array $properties;

public function __construct(FileInterface $fileReference, array $properties = [])
{
$this->fileReference = $fileReference;
$this->properties = $properties;
}

public function getProperties(): array
{
return $this->properties;
}

public function setProperties(array $properties): void
{
$this->properties = $properties;
}

public function getFileReference(): FileInterface
{
return $this->fileReference;
}
}
36 changes: 29 additions & 7 deletions Classes/Utility/FileUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@

namespace FriendsOfTYPO3\Headless\Utility;

use FriendsOfTYPO3\Headless\Event\EnrichFileDataEvent;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\EventDispatcher\EventDispatcher;
use TYPO3\CMS\Core\Http\NormalizedParams;
use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
use TYPO3\CMS\Core\Resource\AbstractFile;
Expand Down Expand Up @@ -58,21 +61,30 @@ class FileUtility
protected $errors = [];

/**
* @param ContentObjectRenderer|null $contentObjectRenderer
* @param RendererRegistry|null $rendererRegistry
* @param ImageService|null $imageService
* @param ServerRequestInterface|null $serverRequest
* @var EventDispatcherInterface
*/
private EventDispatcherInterface $eventDispatcher;

/**
* @param ContentObjectRenderer|null $contentObjectRenderer
* @param RendererRegistry|null $rendererRegistry
* @param ImageService|null $imageService
* @param ServerRequestInterface|null $serverRequest
* @param EventDispatcherInterface|null $eventDispatcher
*/
public function __construct(
?ContentObjectRenderer $contentObjectRenderer = null,
?RendererRegistry $rendererRegistry = null,
?ImageService $imageService = null,
?ServerRequestInterface $serverRequest = null
?ServerRequestInterface $serverRequest = null,
?EventDispatcherInterface $eventDispatcher = null
) {
$this->contentObjectRenderer = $contentObjectRenderer ?? GeneralUtility::makeInstance(ContentObjectRenderer::class);
$this->contentObjectRenderer = $contentObjectRenderer ??
GeneralUtility::makeInstance(ContentObjectRenderer::class);
$this->rendererRegistry = $rendererRegistry ?? GeneralUtility::makeInstance(RendererRegistry::class);
$this->imageService = $imageService ?? GeneralUtility::makeInstance(ImageService::class);
$this->serverRequest = $serverRequest ?? ($GLOBALS['TYPO3_REQUEST'] ?? null);
$this->eventDispatcher = $eventDispatcher ?? GeneralUtility::makeInstance(EventDispatcher::class);
}

/**
Expand Down Expand Up @@ -139,9 +151,19 @@ public function processFile(FileInterface $fileReference, array $dimensions = []
? $fileReference->getProperty('extension') : null,
];

$properties = $this->eventDispatcher->dispatch(
new EnrichFileDataEvent(
$fileReference,
array_merge(
$originalProperties,
$processedProperties
)
)
)->getProperties();

return [
'publicUrl' => $publicUrl,
'properties' => array_merge($originalProperties, $processedProperties),
'properties' => $properties,
];
}

Expand Down
99 changes: 99 additions & 0 deletions Tests/Unit/Event/EnrichFileDataEventTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

/*
* This file is part of the "headless" Extension for TYPO3 CMS.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/

declare(strict_types=1);

namespace FriendsOfTYPO3\Headless\Test\Unit\Event;

use FriendsOfTYPO3\Headless\Event\EnrichFileDataEvent;
use Prophecy\PhpUnit\ProphecyTrait;
use TYPO3\CMS\Core\Resource\AbstractFile;
use TYPO3\CMS\Core\Resource\FileReference;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

class EnrichFileDataEventTest extends UnitTestCase
{
use ProphecyTrait;

/**
* @test
*/
public function eventTest()
{
$properties = [
'prop-1' => 'value-1',
'prop-2' => 'value-2'
];
$fileReferenceMock = $this->getMockFileReferenceForData($this->getFileReferenceBaselineData());
$enrichFileDataEvent = new EnrichFileDataEvent($fileReferenceMock, $properties);

self::assertSame($fileReferenceMock, $enrichFileDataEvent->getFileReference());
self::assertSame($properties, $enrichFileDataEvent->getProperties());

$overwriteProperties = $enrichFileDataEvent->getProperties();
$overwriteProperties['prop-1'] = 'value-overwritten';
$overwriteProperties['prop-3'] = 'value-3';
$enrichFileDataEvent->setProperties($overwriteProperties);

self::assertSame($overwriteProperties, $enrichFileDataEvent->getProperties());
}

protected function getFileReferenceBaselineData(): array
{
return [
'extension' => 'jpg',
'size' => 72392,
'title' => null,
'description' => null,
'alternative' => null,
'name' => 'test-file.jpg',
'link' => '',
'crop' => '{"default":{"cropArea":{"x":0,"y":0,"width":1,"height":1},"selectedRatio":"NaN","focusArea":null}}',
'autoplay' => 0,
'minWidth' => null,
'minHeight' => null,
'maxWidth' => null,
'maxHeight' => null,
'width' => 526,
'uid_local' => 103,
'height' => 526,
];
}

protected function getMockFileReferenceForData($data, $type = 'image')
{
$fileReference = $this->createPartialMock(
FileReference::class,
['getPublicUrl', 'getUid', 'getProperty', 'hasProperty', 'toArray', 'getType', 'getMimeType', 'getProperties', 'getSize']
);
$fileReference->method('getUid')->willReturn(103);
if ($type === 'video') {
$fileReference->method('getMimeType')->willReturn('video/youtube');
$fileReference->method('getType')->willReturn(AbstractFile::FILETYPE_VIDEO);
$fileReference->method('getPublicUrl')->willReturn('https://www.youtube.com/watch?v=123456789');
} else {
$fileReference->method('getType')->willReturn(AbstractFile::FILETYPE_IMAGE);
$fileReference->method('getPublicUrl')->willReturn('/fileadmin/test-file.jpg');
$fileReference->method('getMimeType')->willReturn('image/jpeg');
}

$fileReference->method('getProperty')->willReturnCallback(static function ($key) use ($data) {
return $data[$key] ?? null;
});

$fileReference->method('hasProperty')->willReturnCallback(static function ($key) use ($data) {
return array_key_exists($key, $data);
});

$fileReference->method('toArray')->willReturn($data);
$fileReference->method('getProperties')->willReturn($data);
$fileReference->method('getSize')->willReturn($data['size']);
return $fileReference;
}
}
10 changes: 9 additions & 1 deletion Tests/Unit/Utility/FileUtilityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\DependencyInjection\Container;
use TYPO3\CMS\Core\EventDispatcher\EventDispatcher;
use TYPO3\CMS\Core\EventDispatcher\ListenerProvider;
use TYPO3\CMS\Core\Http\NormalizedParams;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\LinkHandling\LinkService;
Expand Down Expand Up @@ -202,12 +205,17 @@ protected function getFileUtility(
$imageService = $imageService->reveal();
}

$container = new Container();
$listenerProvider = new ListenerProvider($container);
$eventDispatcher = new EventDispatcher($listenerProvider);

$fileUtility = $this->createPartialMock(FileUtility::class, ['translate']);
$fileUtility->__construct(
$contentObjectRenderer->reveal(),
$rendererRegistry->reveal(),
$imageService,
$serverRequest->reveal()
$serverRequest->reveal(),
$eventDispatcher
);

$fileUtility->method('translate')->willReturnCallback(static function ($key, $extension) {
Expand Down

0 comments on commit 8ffd93f

Please sign in to comment.