Skip to content

Conversation

@christen90
Copy link

Hi ervaude,
I tried to use the extension with current LTS version of typo3. I did not get it running.

@christen90
Copy link
Author

Extension scanner findings after my adaptations

ext_localconf.php
Access to array key "tt_content_drawItem"
weak
11: $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['fs_code_snippet']

Breaking: #98375 - Removed hooks in Page Module
12.0
.. include:: /Includes.rst.txt

.. _breaking-98375-1663598608:

===============================================
Breaking: #98375 - Removed hooks in Page Module

See :issue:98375

Description

Since TYPO3 v10, TYPO3 Backend's Page Module is based on Fluid and custom
rendering functionality. The internal class "PageLayoutView" is now removed,
along with its interfaces and hooks.

The following hooks are removed with a PSR-14 equivalent:

  • :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']

The following hooks have been removed without substitution:

  • :php:$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['list_type_Info']
  • :php:$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawFooter']

Existing patterns such as the PreviewRenderer concept can be used instead of
the latter hooks.

Impact

Registering one of the hooks above in TYPO3 v12+ has no effect anymore.

Affected installations

TYPO3 installations with modifications to the page module in third-party
extensions via one of the hooks.

Migration

Use :php:TYPO3\CMS\Backend\View\Event\IsContentUsedOnPageLayoutEvent as a
drop-in alternative for :php:$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['record_is_used']

Use :php:TYPO3\CMS\Backend\View\Event\ModifyDatabaseQueryForContentEvent
as a drop-in replacement for :php:$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][PageLayoutView::class]['modifyQuery']

Use :php:TYPO3\CMS\Backend\View\Event\PageContentPreviewRenderingEvent as a
drop-in replacement for :php:$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']

Extension authors that use these hooks can register a new event listener
and keep the hook registration to stay compatible with TYPO3 v11 and TYPO3 v12
at the same time.

.. index:: Backend, PHP-API, FullyScanned, ext:backend

Feature: #98375 - PSR-14 events in Page Module
12.0
.. 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

@christen90
Copy link
Author

Frontend seems to work but backend still problematic:

Core: Exception handler (WEB): Uncaught TYPO3 Exception: Typed property TYPO3\CMS\Backend\Form\Element\AbstractFormElement::$nodeFactory must not be accessed before initialization | Error thrown in file /var/www/typo3/typo3_src-13.4.15/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php in line 86.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant