Skip to content

Commit

Permalink
[FEATURE] Introduce PSR-14 event to modify form data for edit file form
Browse files Browse the repository at this point in the history
This introduces a new PSR-14 event, enabling
extension authors to modify the form data, used
by FormEngine to generate the edit file form in
the filelist module.

TYPO3 internally makes use of this event to
initialize t3editor with the suitable format options
for the file to be edited. This functionality was
previously done in a hook (#98494), which
however did no longer work due to the removal
of said hook in #97452.

Effectively this means, the new Event is an
improved replacement for the removed hook,
since the Event now provides the whole form
data array as well as the resolved FileInterface
and the current PSR-7 Request.

Resolves: #98521
Related: #98494
Related: #97452
Releases: main
Change-Id: I5de9f8ea72fcb4296f6539449f991347cbef17b6
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75982
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
  • Loading branch information
o-ba authored and sbuerk committed Oct 4, 2022
1 parent 8de54ab commit 564b3f6
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 7 deletions.
1 change: 1 addition & 0 deletions composer.json
Expand Up @@ -269,6 +269,7 @@
"TYPO3\\CMS\\Extbase\\Tests\\": "typo3/sysext/extbase/Tests/",
"TYPO3\\CMS\\Extensionmanager\\Tests\\": "typo3/sysext/extensionmanager/Tests/",
"TYPO3\\CMS\\FrontendLogin\\Tests\\": "typo3/sysext/felogin/Tests/",
"TYPO3\\CMS\\Filelist\\Tests\\": "typo3/sysext/filelist/Tests/",
"TYPO3\\CMS\\Filemetadata\\Tests\\": "typo3/sysext/filemetadata/Tests/",
"TYPO3\\CMS\\Fluid\\Tests\\": "typo3/sysext/fluid/Tests/",
"TYPO3\\CMS\\FluidStyledContent\\Tests\\": "typo3/sysext/fluid_styled_content/Tests/",
Expand Down
Expand Up @@ -11,9 +11,11 @@ See :issue:`97452`
Description
===========

The hooks :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']` and
:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['postOutputProcessingHook']` have been removed.
The same behavior may be achieved using template overrides.
The hooks :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']`
and :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['postOutputProcessingHook']`
have been removed, since adjusting the generated content can be achieved using template overrides
and modifing the form data, used to generate the edit file form, can be done
using the PSR-14 :php:`TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent`.

Impact
======
Expand All @@ -24,14 +26,14 @@ The extension scanner will report possible usages.
Affected Installations
======================

All TYPO3 installations using these hook in custom extension code. This is pretty
unlikely, since both hooks were of limited use.
All TYPO3 installations using these hook in custom extension code. This is
pretty unlikely, since both hooks were of limited use.

Migration
=========

The content preparation allowed by :php:`preOutputProcessingHook` can be achieved with
:ref:`FormEngine data providers <t3coreapi:FormEngine-DataCompiling>`.
The form data modification, allowed by :php:`preOutputProcessingHook`, can be
achieved with the new :doc:`PSR-14 ModifyEditFileFormDataEvent <Feature-98521-PSR-14EventToModifyFormDataForEditFileForm>`.

The content manipulation :php:`postOutputProcessingHook` hook can be substituted with a template override
as outlined in :doc:`this changelog entry <Feature-96812-OverrideBackendTemplatesWithTSconfig>`.
Expand Down
@@ -0,0 +1,71 @@
.. include:: /Includes.rst.txt

.. _feature-98521-1664890745:

=====================================================================
Feature: #98521 - PSR-14 event to modify form data for edit file form
=====================================================================

See :issue:`98521`

Description
===========

A new PSR-14 :php:`TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent`
has been added, which allows to modify the form data, used to render the
file edit form in the :guilabel:`File => Filelist` module using
:ref:`FormEngine data compiling <t3coreapi:FormEngine-DataCompiling>`.

The new event can be used as an improved alternative for the removed
:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']`
hook.

The event features the following methods:

- :php:`getFormData()`: Returns the current :php:`$formData` array
- :php:`setFormData()`: Sets the :php:`$formData` array
- :php:`getFile()`: Returns the corresponding :php:`FileInterface`
- :php:`getRequest()`: Returns the full PSR-7 :php:`ServerRequestInterface`

Registration of the event in your extensions' :file:`Services.yaml`:

.. code-block:: yaml
MyVendor\MyPackage\EventListener\ModifyEditFileFormDataEventListener:
tags:
- name: event.listener
identifier: 'my-package/modify-edit-file-form-data-event-listener'
The corresponding event listener class:

.. code-block:: php
use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent;
final class ModifyEditFileFormDataEventListener
{
public function __invoke(ModifyEditFileFormDataEvent $event): void
{
// Get current form data
$formData = $event->getFormData();
// Change TCA "renderType" based on the file extension
$fileExtension = $event->getFile()->getExtension();
if ($fileExtension === 'ts') {
$formData['processedTca']['columns']['data']['config']['renderType'] = 'tsRenderer';
}
// Set updated form data
$event->setFormData($formData);
}
}
Impact
======

It's now possible to modify the whole :php:`$formData` array, used to generate
the edit file form in the :guilabel:`File => Filelist` module, while having the
resolved :php:`FileInterface` and the current PSR-7 :php:`ServerRequestInterface`
available.

.. index:: Backend, PHP-API, ext:filelist
Expand Up @@ -17,6 +17,7 @@

namespace TYPO3\CMS\Filelist\Controller\File;

use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamFactoryInterface;
Expand All @@ -37,6 +38,7 @@
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent;

/**
* Edit text files via FormEngine. Reachable via FileList module "Edit content".
Expand Down Expand Up @@ -98,6 +100,7 @@ public function __construct(
protected readonly ModuleTemplateFactory $moduleTemplateFactory,
protected readonly ResponseFactory $responseFactory,
protected readonly StreamFactoryInterface $streamFactory,
protected readonly EventDispatcherInterface $eventDispatcher,
) {
}

Expand Down Expand Up @@ -146,6 +149,10 @@ public function mainAction(ServerRequestInterface $request): ResponseInterface
$formData['databaseRow']['redirect'] = (string)$this->uriBuilder->buildUriFromRoute('file_edit', ['target' => $combinedIdentifier]);
$formData['processedTca']['columns']['data'] = $dataColumnDefinition;

$formData = $this->eventDispatcher->dispatch(
new ModifyEditFileFormDataEvent($formData, $file, $request)
)->getFormData();

$resultArray = GeneralUtility::makeInstance(NodeFactory::class)->create($formData)->render();
$formResultCompiler = GeneralUtility::makeInstance(FormResultCompiler::class);
$formResultCompiler->mergeResult($resultArray);
Expand Down
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\Filelist\Event;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Resource\FileInterface;

/**
* Listeners to this event are be able to modify the form data,
* used to render the edit file form in the filelist module.
*/
final class ModifyEditFileFormDataEvent
{
public function __construct(
private array $formData,
private readonly FileInterface $file,
private readonly ServerRequestInterface $request
) {
}

public function getFormData(): array
{
return $this->formData;
}

public function setFormData(array $formData): void
{
$this->formData = $formData;
}

public function getFile(): FileInterface
{
return $this->file;
}

public function getRequest(): ServerRequestInterface
{
return $this->request;
}
}
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\Filelist\Tests\Unit\Event;

use Prophecy\PhpUnit\ProphecyTrait;
use TYPO3\CMS\Core\Http\ServerRequest;
use TYPO3\CMS\Core\Http\Uri;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\ResourceStorage;
use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

class ModifyEditFileFormDataEventTest extends UnitTestCase
{
use ProphecyTrait;

/**
* @test
*/
public function gettersReturnInitializedObjects(): void
{
$formData = [
'databaseRow' => [
'uid' => 123,
],
'tableName' => 'editfile',
'processedTca' => [
'columns' => [
'data' => [
'config' => [
'type' => 'someType',
],
],
],
],
];
$resourceStorageProphecy = $this->prophesize(ResourceStorage::class);
$file = new File([], $resourceStorageProphecy->reveal());
$request = new ServerRequest(new Uri('https://example.com'));

$event = new ModifyEditFileFormDataEvent($formData, $file, $request);

self::assertEquals($formData, $event->getFormData());
self::assertEquals($file, $event->getFile());
self::assertEquals($request, $event->getRequest());

$modifyFormData = $event->getFormData();
$modifyFormData['processedTca']['columns']['data']['config']['type'] = 'newType';
$event->setFormData($modifyFormData);

self::assertEquals($modifyFormData, $event->getFormData());
}
}
Expand Up @@ -904,6 +904,7 @@
'$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'typo3/file_edit.php\'][\'preOutputProcessingHook\']' => [
'restFiles' => [
'Breaking-97452-RemovedEditFileControllerHooks.rst',
'Feature-98521-PSR-14EventToModifyFormDataForEditFileForm.rst',
],
],
'$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'typo3/file_edit.php\'][\'postOutputProcessingHook\']' => [
Expand Down
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

namespace TYPO3\CMS\T3editor\EventListener;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent;
use TYPO3\CMS\T3editor\Exception\InvalidModeException;
use TYPO3\CMS\T3editor\Registry\ModeRegistry;
use TYPO3\CMS\T3editor\T3editor;

/**
* Listener which modifies the form data to initialize t3editor with
* the resolved format option (based on the file extension).
*/
final class InitializeT3editorInEditFileForm
{
public function __construct(private readonly ModeRegistry $modeRegistry)
{
}

public function __invoke(ModifyEditFileFormDataEvent $event): void
{
// Compile and register t3editor configuration
GeneralUtility::makeInstance(T3editor::class)->registerConfiguration();

$fileExtension = $event->getFile()->getExtension();

try {
$mode = $this->modeRegistry->getByFileExtension($fileExtension);
} catch (InvalidModeException $e) {
$mode = $this->modeRegistry->getDefaultMode();
}

$formData = $event->getFormData();
$formData['processedTca']['columns']['data']['config']['renderType'] = 't3editor';
$formData['processedTca']['columns']['data']['config']['format'] = $mode->getFormatCode();
$event->setFormData($formData);
}
}
5 changes: 5 additions & 0 deletions typo3/sysext/t3editor/Configuration/Services.yaml
Expand Up @@ -6,3 +6,8 @@ services:

TYPO3\CMS\T3editor\:
resource: '../Classes/*'

TYPO3\CMS\T3editor\EventListener\InitializeT3editorInEditFileForm:
tags:
- name: event.listener
identifier: 'typo3-t3editor/initialize-t3editor-in-edit-file-form'

0 comments on commit 564b3f6

Please sign in to comment.