192 lines
6.1 KiB
ReStructuredText
192 lines
6.1 KiB
ReStructuredText
.. include:: /Includes.rst.txt
|
|
|
|
.. _feature-98375-1663598746:
|
|
|
|
==============================================
|
|
Feature: #98375 - PSR-14 events in Page Module
|
|
==============================================
|
|
|
|
See :issue:`98375`
|
|
|
|
Description
|
|
===========
|
|
|
|
Three new PSR-14 events have been added to TYPO3's page module to modify
|
|
the preparation and rendering of content elements:
|
|
|
|
* :php:`TYPO3\CMS\Backend\View\Event\IsContentUsedOnPageLayoutEvent`
|
|
* :php:`TYPO3\CMS\Backend\View\Event\ModifyDatabaseQueryForContentEvent`
|
|
* :php:`TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent`
|
|
|
|
They are drop-in replacement to the removed hooks:
|
|
|
|
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['record_is_used']`
|
|
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][PageLayoutView::class]['modifyQuery']`
|
|
* :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']`
|
|
|
|
Example for :php:`IsContentUsedOnPageLayoutEvent`
|
|
-------------------------------------------------
|
|
|
|
Registration of the event in your extension's :file:`Services.yaml`:
|
|
|
|
.. code-block:: yaml
|
|
:caption: EXT:my_extension/Configuration/Services.yaml
|
|
|
|
MyVendor\MyExtension\Listener\ContentUsedOnPage:
|
|
tags:
|
|
- name: event.listener
|
|
identifier: 'my-extension/view/content-used-on-page'
|
|
|
|
The corresponding event listener class:
|
|
|
|
.. code-block:: php
|
|
:caption: EXT:my_extension/Classes/Listener/ContentUsedOnPage.php
|
|
|
|
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MyVendor\MyExtension\Listener;
|
|
|
|
use TYPO3\CMS\Backend\View\Event\IsContentUsedOnPageLayoutEvent;
|
|
|
|
final class ContentUsedOnPage
|
|
{
|
|
public function __invoke(IsContentUsedOnPageLayoutEvent $event): void
|
|
{
|
|
// Get the current record from the event.
|
|
$record = $event->getRecord();
|
|
|
|
// This code will be your domain logic to indicate if content
|
|
// should be hidden in the page module.
|
|
if ((int)($record['colPos'] ?? 0) === 999
|
|
&& !empty($record['tx_myext_content_parent'])
|
|
) {
|
|
// Flag the current element as not used. Set it to true, if you
|
|
// want to flag it as used and hide it from the page module.
|
|
$event->setUsed(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
Example for :php:`ModifyDatabaseQueryForContentEvent`
|
|
-----------------------------------------------------
|
|
|
|
Registration of the event in your extension's :file:`Services.yaml`:
|
|
|
|
.. code-block:: yaml
|
|
:caption: EXT:my_extension/Configuration/Services.yaml
|
|
|
|
MyVendor\MyExtension\Listener\ModifyDatabaseQueryForContent:
|
|
tags:
|
|
- name: event.listener
|
|
identifier: 'my-extension/view/modify-database-query-for-content'
|
|
|
|
The corresponding event listener class:
|
|
|
|
.. code-block:: php
|
|
:caption: EXT:my_extension/Classes/Listener/ModifyDatabaseQueryForContent.php
|
|
|
|
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MyVendor\MyExtension\Listener;
|
|
|
|
use TYPO3\CMS\Backend\View\Event\ModifyDatabaseQueryForContentEvent;
|
|
use TYPO3\CMS\Core\Database\Connection;
|
|
|
|
final class ModifyDatabaseQueryForContent
|
|
{
|
|
public function __invoke(ModifyDatabaseQueryForContentEvent $event): void
|
|
{
|
|
// early return if we do not need to react
|
|
if ($event->getTable() !== 'tt_content') {
|
|
return;
|
|
}
|
|
|
|
// Retrieve QueryBuilder instance from event
|
|
$queryBuilder = $event->getQueryBuilder();
|
|
|
|
// Add an additional condition to the QueryBuilder for the table
|
|
// Note: This is only an example, modify the QueryBuilder instance
|
|
// here to your needs.
|
|
$queryBuilder = $queryBuilder->andWhere(
|
|
$queryBuilder->expr()->neq(
|
|
'some_field',
|
|
$queryBuilder->createNamedParameter(1, Connection::PARAM_INT)
|
|
)
|
|
);
|
|
|
|
// set updated QueryBuilder to event
|
|
$event->setQueryBuilder($queryBuilder);
|
|
}
|
|
}
|
|
|
|
Example :php:`PageContentPreviewRenderingEvent`
|
|
-----------------------------------------------
|
|
|
|
Registration of the event in your extension's :file:`Services.yaml`:
|
|
|
|
.. code-block:: yaml
|
|
:caption: EXT:my_extension/Configuration/Services.yaml
|
|
|
|
MyVendor\MyExtension\Listener\PageContentPreviewRendering:
|
|
tags:
|
|
- name: event.listener
|
|
identifier: 'my-extension/view/page-content-preview-rendering'
|
|
|
|
The corresponding event listener class:
|
|
|
|
.. code-block:: php
|
|
:caption: EXT:my_extension/Classes/Listener/PageContentPreviewRendering.php
|
|
|
|
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MyVendor\MyExtension\Listener;
|
|
|
|
use TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent;
|
|
|
|
final class PageContentPreviewRendering
|
|
{
|
|
public function __invoke(PageContentPreviewRenderingEvent $event): void
|
|
{
|
|
$tableName = $event->getTable();
|
|
$record = $event->getRecord();
|
|
|
|
// early return if we do not need to react
|
|
if (
|
|
$tableName !== 'tt_content'
|
|
|| (string)($record['CType'] ?? '') !== 'my-content-element'
|
|
) {
|
|
return;
|
|
}
|
|
|
|
// Create custom preview content
|
|
$previewContent = sprintf(
|
|
'<div class="alert alert-notice">No preview available for %s:%s</div>',
|
|
$event->getTable(),
|
|
($event->getRecord()['uid'] ?? 0)
|
|
);
|
|
|
|
// Set (override) preview content with custom content.
|
|
$event->setPreviewContent($previewContent);
|
|
}
|
|
}
|
|
|
|
Impact
|
|
======
|
|
|
|
Use :php:`IsContentUsedOnPageLayoutEvent` to identify if a content has been used
|
|
in a column that isn't on a Backend Layout.
|
|
|
|
Use :php:`ModifyDatabaseQueryForContentEvent` to filter out certain content elements
|
|
from being shown in the Page Module.
|
|
|
|
Use :php:`PageContentPreviewRenderingEvent` to ship an alternative rendering for
|
|
a specific content type or to manipulate the content elements' record data.
|
|
|
|
.. index:: Backend, PHP-API, ext:backend
|