Feature: #102337 - PSR-14 event for modifying record list export data
See forge#102337
Description
A new PSR-14 event
\TYPO3\
has been introduced to modify the result of a download / export initiated in
the Web > List module.
This replaces the
$GLOBALS
and
$GLOBALS
,
hooks, which have been deprecated.
The event allows body and header sections of the data dump to be modified, so that they can e.g. be used to redact specific data for GDPR compliance, transform / translate specific data, trigger creation of archives or web hooks, log export access and more.
The event offers the following methods:
get
: Return the current header row of the dataset.Header Row () set
: Sets the modified header row of the dataset.Header Row () get
: Returns the current body rows of the dataset.Records () set
: Sets the modified body rows of the dataset.Records () get
: Returns the PSR request context.Request () get
: Returns the name of the database table of the dataset.Table () get
: Returns the format of the download action (CSV/JSON).Format () get
: Returns the name of the download filename (for browser output).Filename () get
: Returns the page UID of the download origin.Id () get
: Returns the active module TSconfig of the download origin.Mod TSconfig () get
: Returns the list of header columns for the triggered download.Columns To Render () is
: Returns whether translations are hidden or not.Hide Translations ()
Example
The corresponding event listener class:
<?php
declare(strict_types=1);
namespace Vendor\MyPackage\Core\EventListener;
use TYPO3\CMS\Backend\RecordList\Event\BeforeRecordDownloadIsExecutedEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
#[AsEventListener(identifier: 'my-package/record-list-download-data')]
final readonly class DataListener
{
public function __invoke(BeforeRecordDownloadIsExecutedEvent $event): void
{
// List of redactable fields.
$gdprFields = ['title', 'author'];
$headerRow = $event->getHeaderRow();
$records = $event->getRecords();
// Iterate header to mark redacted fields...
foreach ($headerRow as $headerRowKey => $headerRowValue) {
if (in_array($headerRowKey, $gdprFields, true)) {
$headerRow[$headerRowKey] .= ' (REDACTED)';
}
}
// Redact actual content...
foreach ($records as $uid => $record) {
foreach ($gdprFields as $gdprField) {
if (isset($record[$gdprField])) {
$records[$uid][$gdprField] = '(REDACTED)';
}
}
}
$event->setHeaderRow($headerRow);
$event->setRecords($records);
}
}
Migration
The functionality of both hooks
customize
and
customize
are now handled by the new PSR-14 event.
Migrating
customizeCsvHeader
The prior hook parameter/variable
fields
is now available via
$event->get
. The actual record data
(previously
$this->record
, submitted to the hook as its object
reference) is accessible via
$event->get
.
Migrating
customizeCsvRow
The prior hook parameters/variables have the following substitutes:
database
is now available viaRow $event->get
(see note below).Records () table
is now available viaName $event->get
.Table () page
is now available viaId $event->get
.Id ()
The actual record data
(previously
$this->record
, submitted to the hook as its object
reference) is accessible via
$event->get
.
Please note that the hook was previously executed once per row retrieved from the database. The PSR-14 event however - due to performance reasons - is only executed for the full record list after database retrieval, thus allowing post-processing on the whole dataset.
Impact
Using the PSR-14 event
Before
it is
now possible to modify all of the data available when downloading / exporting
a list of records via the Web > List module.