Расширение финальных классов в TYPO3

Вопрос или проблема

У меня есть следующая проблема:

<?php

declare(strict_types=1);

namespace Abc\Def\Services;

class TypoScriptProvider extends \TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager
{

    public function __construct()
    {
    }

    public function getTypoScriptSetupByPageid($pageId = null): array
    {
        $configurationManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\BackendConfigurationManager');
        $configurationManager->currentPageId = $pageId;
        $extbaseFrameworkConfiguration = $configurationManager->getTypoScriptSetup();
        return $extbaseFrameworkConfiguration;
    }
}

В TYPO3 v12 это работает, но теперь TYPO3 решило сделать BackendConfigurationManager финальным классом в v13. Как я могу расширить этот класс?

Я пробовал так:

<?php

declare(strict_types=1);

namespace Abc\Def\Services;

use TYPO3\CMS\Extbase\Configuration\BackendConfigurationManager;

class TypoScriptProvider
{
    protected BackendConfigurationManager $backendConfigurationManager;

    public function __construct(BackendConfigurationManager $backendConfigurationManager)
    {
        // Внедрение зависимостей
        $this->backendConfigurationManager = $backendConfigurationManager;
    }

    public function getTypoScriptSetupByPageid(int $pageId = null): array
    {
        // Используйте метод для установки ID страницы
        $this->backendConfigurationManager->getCurrentPageId($pageId);

        // Получение настройки TypoScript
        $typoScriptSetup = $this->backendConfigurationManager->getTypoScriptSetup();

        return $typoScriptSetup;
    }
}

Но затем currentPageId недоступен, поскольку он теперь защищен. Как мне это сделать?

@internal только для использования внутри Extbase, не является частью API TYPO3 Core.

Из PHP-DocBlock класса. Этот класс является внутренним и не является частью публичного API. Он может измениться в любое время без уведомления или документирования как публично доступный API.

Суть в том, что BackendConfigurationManager связан с ServerRequestInterface и использует эти атрибуты и аргументы запроса. Этот класс был переработан, чтобы быть совместимым с Symfony DI, и требуется, чтобы состояние было удалено из этого класса, так как он теперь становится настоящим сервисом. А DI-сервисы должны быть без состояния, что означает отсутствие свойств и методов установок/получений для текущей страницы. Оставшиеся приватные методы используют информацию запроса для получения значений, а также кэш времени выполнения для хранения состояния вне этого класса.

Также не следует использовать BackendConfigurationManager напрямую, вместо этого следует использовать ConfigurationManager, который использует Frontend или Backend manager на основе атрибутов в переданном объекте ServerRequestInterface $request.

public function getTypoScriptSetup(ServerRequestInterface $request): array

Это сигнатура метода в TYPO3 v13. Это означает, что вам необходимо передать объект запроса, который должен содержать необходимые атрибуты, поскольку этот класс считывает информацию о странице из запроса.

В случае бэкенда он использует значение id из тела пост-запроса или аргумента get в соответствующем контексте.

Не зная, какая ваша конкретная ситуация использования, трудно дать точные примеры и рекомендации для правильной реализации.

Вы можете попробовать создать фейковый запрос, как в следующем примере, взятом из тестов ядра TYPO3 (честно говоря, не протестировано в реальных условиях):

$request = (new ServerRequest())->withQueryParams(['id' => 123]);
$typoScriptSetup = $this->backendConfigurationManager->getTypoScriptSetup($request);

То же самое относится к другому методу BackendConfigurationManager, который требует передачи объекта ServerRequestInterface.

Ответ или решение

К сожалению, в TYPO3 v13 класс BackendConfigurationManager стал финальным (final), что делает невозможным его наследование. Ваша задача состоит в том, чтобы адаптировать свой код к новым требованиям TYPO3, а именно использовать класс ConfigurationManager, который принимает объект ServerRequestInterface вместо прямого доступа к старым методам.

Вот как вы можете изменить свой код:

  1. Использовать ConfigurationManager: Вместо прямого использования BackendConfigurationManager, вам следует использовать ConfigurationManager, который будет автоматически выбирать между фронтенд- и бэкенд-менеджерами в зависимости от переданного ServerRequestInterface.

  2. Создать запрос: Вам необходимо создать ServerRequestInterface, который будет содержать необходимую информацию о странице.

Вот переработанный вариант вашего класса TypoScriptProvider:

<?php

declare(strict_types=1);

namespace Abc\Def\Services;

use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use Psr\Http\Message\ServerRequestInterface;

class TypoScriptProvider
{
    protected ConfigurationManager $configurationManager;

    public function __construct(ConfigurationManager $configurationManager)
    {
        // Внедрение зависимостей
        $this->configurationManager = $configurationManager;
    }

    public function getTypoScriptSetupByPageid(int $pageId = null): array
    {
        // Создание запроса с параметрами
        // Замените ServerRequest на правильный класс, если используете другой
        $request = (new \Nyholm\Psr7\ServerRequest('GET', '')) // используйте подходящий класс запроса
            ->withQueryParams(['id' => $pageId]);

        // Получение TypoScript настройки
        $typoScriptSetup = $this->configurationManager->getTypoScriptSetup($request);

        return $typoScriptSetup;
    }
}

Объяснение изменений:

  • Объект ConfigurationManager теперь используется вместо BackendConfigurationManager.
  • Мы создаем запрос, который включает в себя параметры страницы. Убедитесь, что вы используете подходящий класс для создания запроса (Nyholm\Psr7\ServerRequest или другой).
  • Метод getTypoScriptSetup вызывается с формируемым ServerRequestInterface, что позволяет получать настройки TypoScript, соответствующие конкретной странице.

Таким образом, этот подход следует рекомендациям TYPO3 v13 и обеспечивает правильное управление зависимостями и состоянием запроса. Если у вас есть дополнительные вопросы или дальнейшая настройка, не стесняйтесь спрашивать.

Оцените материал
Добавить комментарий

Капча загружается...