Вопрос или проблема
У меня есть следующая проблема:
<?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
вместо прямого доступа к старым методам.
Вот как вы можете изменить свой код:
-
Использовать
ConfigurationManager
: Вместо прямого использованияBackendConfigurationManager
, вам следует использоватьConfigurationManager
, который будет автоматически выбирать между фронтенд- и бэкенд-менеджерами в зависимости от переданногоServerRequestInterface
. - Создать запрос: Вам необходимо создать
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 и обеспечивает правильное управление зависимостями и состоянием запроса. Если у вас есть дополнительные вопросы или дальнейшая настройка, не стесняйтесь спрашивать.