Events
Listen to these events to change what an export does without replacing the exporter service. They fall into three groups: events fired during an export, events fired when a configuration is saved or deleted, and pre-response events of the Pimcore Studio endpoints.
Export Events
These events surround an export run, from evaluating a save hook to delivering the finished file. They live in the
Pimcore\Bundle\DataHubFileExportBundle\Event namespace, and each one exposes the exporter through getExporter().
| Event | Dispatched | Use it to |
|---|---|---|
IsValidDataObjectTriggerEvent | When a data object change is evaluated for triggering an export. | Suppress an export run for a specific change. Read the triggering event with getTriggerEvent(), then setIsValid(false). |
RelevantItemListEvent | After the listing of items to export is built, before its IDs are loaded. | Narrow or extend the listing with getList() and setList(). |
IsValidExportItemEvent | For each item, before it is exported. | Skip a single item with setIsValid(false). |
FilterExistingDataEvent | On every run that is not a full export, after the previously exported rows are re-read and rows that are no longer valid have been dropped. | Remove further rows with getData() and setData(). |
PreWriteDataEvent | After new and existing rows are merged, before they are written to the output file. | Reshape the rows with getData() and setData(). |
FilenameEvent | After the filename and its date placeholder are resolved. | Change the name with getFilename() and setFilename(). |
TransmissionFailedEvent | When a transmitter fails to deliver the finished file. The original exception is re-thrown afterwards, so existing error handling still applies. | React to a failed delivery, for example by notifying an administrator. Read getTransmitterType() and getException(). |
A run counts as a full export only when it resolves the items itself: Run Full Export, Cron (Full Export), and the
CLI command without --only-queue-items. Queue-only runs and the Full Export on Save save hook both leave
isFullExport at false, so FilterExistingDataEvent fires for them as well.
Configuration Events
These two events fire when a configuration is saved or deleted in Pimcore Studio. They live in the
Pimcore\Bundle\DataHubFileExportBundle\Event\Admin namespace and do not carry an exporter.
| Event | Dispatched | Use it to |
|---|---|---|
ValidateConfigEvent | Before a configuration is saved. | Reject invalid settings. Read them with getConfigData() and throw an exception; it is converted into a validation error shown to the user. |
ResetConfigEvent | After a configuration is deleted, and after a save triggered by Save, reset and clear queue. | Clean up your own state. getConfig() returns the configuration, getContext() returns ['source' => 'delete'] or ['source' => 'save']. |
Studio API Events
The configuration panel is a Pimcore Studio plugin. Before one of its endpoints returns, the bundle dispatches a pre-response event carrying the response schema. Listen for it to add your own data to the response.
| Event name | Returned data |
|---|---|
pre_response.data_hub_file_export.configuration_detail | A single export configuration. |
pre_response.data_hub_file_export.configuration_update | The configuration after it was saved. |
pre_response.data_hub_file_export.cron_validation_result | The result of validating a cron expression. |
pre_response.data_hub_file_export.export_progress | The progress of a running export. |
pre_response.data_hub_file_export.exporter_service | One selectable custom exporter service. |
pre_response.data_hub_file_export.exporter_type | One selectable export file type. |
pre_response.data_hub_file_export.thumbnail_item | One selectable thumbnail. |
See the Studio Backend Additional and Custom Attributes documentation for the listener pattern.
The endpoints themselves are not a supported public API. Their controllers are marked @internal and may change in any
release without a deprecation path. Do not build integrations against them.
Registering a Listener
App\EventListener\DataHubFileExportListener:
tags:
- { name: kernel.event_listener, event: Pimcore\Bundle\DataHubFileExportBundle\Event\IsValidExportItemEvent, method: isValidExportItem }
- { name: kernel.event_listener, event: Pimcore\Bundle\DataHubFileExportBundle\Event\FilterExistingDataEvent, method: filterExistingData }
- { name: kernel.event_listener, event: Pimcore\Bundle\DataHubFileExportBundle\Event\PreWriteDataEvent, method: preWriteData }
- { name: kernel.event_listener, event: Pimcore\Bundle\DataHubFileExportBundle\Event\RelevantItemListEvent, method: relevantItemList }
- { name: kernel.event_listener, event: Pimcore\Bundle\DataHubFileExportBundle\Event\FilenameEvent, method: modifyFilename }
- { name: kernel.event_listener, event: Pimcore\Bundle\DataHubFileExportBundle\Event\TransmissionFailedEvent, method: transmissionFailed }
Sample Listener
<?php
/**
* This source file is available under the terms of the
* Pimcore Open Core License (POCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
* @license Pimcore Open Core License (POCL)
*/
namespace App\EventListener;
use Pimcore\Bundle\DataHubFileExportBundle\Event\FilenameEvent;
use Pimcore\Bundle\DataHubFileExportBundle\Event\FilterExistingDataEvent;
use Pimcore\Bundle\DataHubFileExportBundle\Event\IsValidExportItemEvent;
use Pimcore\Bundle\DataHubFileExportBundle\Event\PreWriteDataEvent;
use Pimcore\Bundle\DataHubFileExportBundle\Event\RelevantItemListEvent;
use Pimcore\Bundle\DataHubFileExportBundle\Event\TransmissionFailedEvent;
use Pimcore\Db;
use Pimcore\Log\ApplicationLogger;
use Pimcore\Model\DataObject;
class DataHubFileExportListener
{
// Uppercase the name of the exported file.
public function modifyFilename(FilenameEvent $event): void
{
$event->setFilename(strtoupper($event->getFilename()));
}
// Exclude one specific object from the export.
public function isValidExportItem(IsValidExportItemEvent $event): void
{
if ($event->getObject()->getId() === 82) {
$event->setIsValid(false);
}
}
// Restrict the exported listing with an additional SQL condition.
public function relevantItemList(RelevantItemListEvent $event): void
{
$list = $event->getList();
$db = Db::get();
$idColumn = DataObject\Service::getVersionDependentDatabaseColumnName('o_id');
$ownCondition = $db->quoteIdentifier($idColumn) . ' = 123';
$existing = $list->getCondition();
// The workspace condition is empty without workspaces and an unparenthesized OR chain with several of them,
// so it has to be grouped before an AND is appended.
$list->setCondition($existing ? '(' . $existing . ') AND ' . $ownCondition : $ownCondition);
$event->setList($list);
}
// Prefix every exported name before the rows are written.
public function preWriteData(PreWriteDataEvent $event): void
{
$data = $event->getData();
foreach ($data as $i => $row) {
// For CSV the first row is the numeric header row, and advanced schemas may omit the column entirely.
if (!array_key_exists('name', $row)) {
continue;
}
$row['name'] = 'hello - ' . $row['name'];
$data[$i] = $row;
}
$event->setData($data);
}
// Drop rows whose object no longer passes the export validation.
public function filterExistingData(FilterExistingDataEvent $event): void
{
$exporter = $event->getExporter();
$data = $event->getData();
foreach ($data as $i => $row) {
$object = DataObject\Concrete::getById($row['id']);
if (!$exporter->isValidExportItem($object)) {
unset($data[$i]);
}
}
$event->setData($data);
}
// Log a failed delivery of the finished file.
public function transmissionFailed(TransmissionFailedEvent $event): void
{
$configName = $event->getExporter()->getDataHubConfiguration()->getName();
ApplicationLogger::getInstance()->error(
sprintf(
'Transmission "%s" failed for config "%s": %s',
$event->getTransmitterType(),
$configName,
$event->getException()?->getMessage()
)
);
}
}