From f279ceb4d067cf49250598fa75a5d4f75d5268c2 Mon Sep 17 00:00:00 2001 From: Oliver Bartsch <bo@cedev.de> Date: Wed, 9 Feb 2022 16:47:04 +0100 Subject: [PATCH] [!!!][FEATURE] Add PSR-14 ModifyButtonBarEvent The new PSR-14 event ModifyButtonBarEvent is added as a direct replacement for the now removed hook $TYPO3_CONF_VARS[SC_OPTIONS][Backend\Template\Components\ButtonBar][getButtonsHook] Resolves: #96806 Releases: main Change-Id: Ib743cc532a78a3e38c96e7a89ba2e3856d8cbd0d Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/73380 Tested-by: core-ci <typo3@b13.com> Tested-by: Jochen <rothjochen@gmail.com> Tested-by: Benni Mack <benni@typo3.org> Tested-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Jochen <rothjochen@gmail.com> Reviewed-by: Benni Mack <benni@typo3.org> Reviewed-by: Oliver Bartsch <bo@cedev.de> --- .../Classes/Template/Components/ButtonBar.php | 16 +++--- .../Components/ModifyButtonBarEvent.php | 54 +++++++++++++++++++ ...06-RemovedHookForForModifyingButtonBar.rst | 38 +++++++++++++ ...96806-PSR-14EventForModifyingButtonBar.rst | 50 +++++++++++++++++ .../Php/ArrayDimensionMatcher.php | 5 ++ .../ButtonBarProvider.php} | 23 ++++---- .../sys_note/Configuration/Services.yaml | 4 ++ typo3/sysext/sys_note/ext_localconf.php | 3 -- 8 files changed, 169 insertions(+), 24 deletions(-) create mode 100644 typo3/sysext/backend/Classes/Template/Components/ModifyButtonBarEvent.php create mode 100644 typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96806-RemovedHookForForModifyingButtonBar.rst create mode 100644 typo3/sysext/core/Documentation/Changelog/12.0/Feature-96806-PSR-14EventForModifyingButtonBar.rst rename typo3/sysext/sys_note/Classes/{Hook/ButtonBarHook.php => Provider/ButtonBarProvider.php} (89%) diff --git a/typo3/sysext/backend/Classes/Template/Components/ButtonBar.php b/typo3/sysext/backend/Classes/Template/Components/ButtonBar.php index 02852a8d7283..783682d788a4 100644 --- a/typo3/sysext/backend/Classes/Template/Components/ButtonBar.php +++ b/typo3/sysext/backend/Classes/Template/Components/ButtonBar.php @@ -15,6 +15,7 @@ namespace TYPO3\CMS\Backend\Template\Components; +use Psr\EventDispatcher\EventDispatcherInterface; use TYPO3\CMS\Backend\Template\Components\Buttons\Action\HelpButton; use TYPO3\CMS\Backend\Template\Components\Buttons\Action\ShortcutButton; use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface; @@ -160,19 +161,18 @@ class ButtonBar * * @return array */ - public function getButtons() + public function getButtons(): array { // here we need to call the sorting methods and stuff. foreach ($this->buttons as $position => $_) { ksort($this->buttons[$position]); } - // Hook for manipulating the docHeaderButtons - foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['Backend\Template\Components\ButtonBar']['getButtonsHook'] ?? [] as $funcRef) { - $params = [ - 'buttons' => $this->buttons, - ]; - $this->buttons = GeneralUtility::callUserFunction($funcRef, $params, $this); - } + + // Dispatch event for manipulating the docHeaderButtons + $this->buttons = GeneralUtility::makeInstance(EventDispatcherInterface::class)->dispatch( + new ModifyButtonBarEvent($this->buttons, $this) + )->getButtons(); + return $this->buttons; } } diff --git a/typo3/sysext/backend/Classes/Template/Components/ModifyButtonBarEvent.php b/typo3/sysext/backend/Classes/Template/Components/ModifyButtonBarEvent.php new file mode 100644 index 000000000000..5c198ae69d48 --- /dev/null +++ b/typo3/sysext/backend/Classes/Template/Components/ModifyButtonBarEvent.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Backend\Template\Components; + +use TYPO3\CMS\Backend\Template\Components\Buttons\ButtonInterface; + +/** + * Listeners can modify the buttons of the button bar in the backend module docheader + */ +final class ModifyButtonBarEvent +{ + /** + * @var ButtonInterface[] + */ + private array $buttons; + + private ButtonBar $buttonBar; + + public function __construct(array $buttons, ButtonBar $buttonBar) + { + $this->buttons = $buttons; + $this->buttonBar = $buttonBar; + } + + public function getButtons(): array + { + return $this->buttons; + } + + public function setButtons(array $buttons): void + { + $this->buttons = $buttons; + } + + public function getButtonBar(): ButtonBar + { + return $this->buttonBar; + } +} diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96806-RemovedHookForForModifyingButtonBar.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96806-RemovedHookForForModifyingButtonBar.rst new file mode 100644 index 000000000000..7f8bdd739724 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96806-RemovedHookForForModifyingButtonBar.rst @@ -0,0 +1,38 @@ +.. include:: ../../Includes.txt + +============================================================ +Breaking: #96806 - Removed hook for for modifying button bar +============================================================ + +See :issue:`96806` + +Description +=========== + +The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['Backend\Template\Components\ButtonBar']['getButtonsHook']` +has been removed in favor of a new PSR-14 Event :php:`\TYPO3\CMS\Backend\Template\Components\ModifyButtonBarEvent`. + +Impact +====== + +Any hook implementation registered is not executed anymore in +TYPO3 v12.0+. The extension scanner will report possible usages. + + +Affected Installations +====================== + +All TYPO3 installations using this hook in custom extension code. + + +Migration +========= + +The hook is removed without deprecation in order to allow extensions +to work with TYPO3 v11 (using the hook) and v12+ (using the new Event) +when implementing the Event as well without any further deprecations. + +Use the :doc:`PSR-14 Event <../12.0/Feature-96806-PSR-14EventForModifyingButtonBar>` +as a direct replacement. + +.. index:: Backend, PHP-API, FullyScanned, ext:backend diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Feature-96806-PSR-14EventForModifyingButtonBar.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-96806-PSR-14EventForModifyingButtonBar.rst new file mode 100644 index 000000000000..8a58e64a1bdb --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-96806-PSR-14EventForModifyingButtonBar.rst @@ -0,0 +1,50 @@ +.. include:: ../../Includes.txt + +======================================================= +Feature: #96806 - PSR-14 Event for modifying button bar +======================================================= + +See :issue:`96806` + +Description +=========== + +A new PSR-14 Event :php:`\TYPO3\CMS\Backend\Template\Components\ModifyButtonBarEvent` +has been introduced. It serves as direct replacement for the now removed hook +:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['Backend\Template\Components\ButtonBar']['getButtonsHook']`. + +It can be used to modify the button bar in the TYPO3 backend module docheader. + +Example +======= + +Registration of the Event in your extensions' :file:`Services.yaml`: + +.. code-block:: yaml + + MyVendor\MyPackage\Frontend\MyEventListener: + tags: + - name: event.listener + identifier: 'my-package/frontend/modify-button-bar' + +The corresponding event listener class: + +.. code-block:: php + + use TYPO3\CMS\Backend\Template\Components\ModifyButtonBarEvent; + + class MyEventListener { + + public function __invoke(ModifyButtonBarEvent $event): void + { + // Do your magic here + } + } + +Impact +====== + +It's now possible to modify the TYPO3 backend button bar, using the +new PSR-14 event. + +.. index:: Backend, PHP-API, ext:backend diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php index 4ea68235f1dd..31481a041260 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php @@ -599,4 +599,9 @@ return [ 'Breaking-96659-RegistrationOfCObjectsViaTYPO3_CONF_VARS.rst', ], ], + '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'Backend\Template\Components\ButtonBar\'][\'getButtonsHook\']' => [ + 'restFiles' => [ + 'Breaking-96806-RemovedHookForForModifyingButtonBar.rst', + ], + ], ]; diff --git a/typo3/sysext/sys_note/Classes/Hook/ButtonBarHook.php b/typo3/sysext/sys_note/Classes/Provider/ButtonBarProvider.php similarity index 89% rename from typo3/sysext/sys_note/Classes/Hook/ButtonBarHook.php rename to typo3/sysext/sys_note/Classes/Provider/ButtonBarProvider.php index db2bbd62f82d..e2195501929d 100644 --- a/typo3/sysext/sys_note/Classes/Hook/ButtonBarHook.php +++ b/typo3/sysext/sys_note/Classes/Provider/ButtonBarProvider.php @@ -15,12 +15,13 @@ declare(strict_types=1); * The TYPO3 project - inspiring people to share! */ -namespace TYPO3\CMS\SysNote\Hook; +namespace TYPO3\CMS\SysNote\Provider; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Backend\Template\Components\ButtonBar; +use TYPO3\CMS\Backend\Template\Components\ModifyButtonBarEvent; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Imaging\Icon; @@ -30,11 +31,11 @@ use TYPO3\CMS\Core\Type\Bitmask\Permission; use TYPO3\CMS\Core\Utility\GeneralUtility; /** - * Hook for the button bar + * Event listener to add the sys_note button to the button bar * - * @internal This is a specific hook implementation and is not considered part of the Public TYPO3 API. + * @internal This is a specific listener implementation and is not considered part of the Public TYPO3 API. */ -class ButtonBarHook +final class ButtonBarProvider { private const TABLE_NAME = 'sys_note'; private const ALLOWED_MODULES = ['web_layout', 'web_list', 'web_info']; @@ -42,15 +43,11 @@ class ButtonBarHook /** * Add a sys_note creation button to the button bar of defined modules * - * @param array $params - * @param ButtonBar $buttonBar - * - * @return array * @throws RouteNotFoundException */ - public function getButtons(array $params, ButtonBar $buttonBar): array + public function __invoke(ModifyButtonBarEvent $event): void { - $buttons = $params['buttons']; + $buttons = $event->getButtons(); $request = $this->getRequest(); $id = (int)($request->getParsedBody()['id'] ?? $request->getQueryParams()['id'] ?? 0); @@ -66,7 +63,7 @@ class ButtonBarHook || !in_array($module->getIdentifier(), self::ALLOWED_MODULES, true) || ($module->getIdentifier() === 'web_list' && !$this->isCreationAllowed($pageTSconfig['mod.']['web_list.'] ?? [])) ) { - return $buttons; + return; } $uri = (string)GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute( @@ -81,7 +78,7 @@ class ButtonBarHook ] ); - $buttons[ButtonBar::BUTTON_POSITION_RIGHT][2][] = $buttonBar + $buttons[ButtonBar::BUTTON_POSITION_RIGHT][2][] = $event->getButtonBar() ->makeLinkButton() ->setTitle(htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:sys_note/Resources/Private/Language/locallang.xlf:new_internal_note'))) ->setIcon(GeneralUtility::makeInstance(IconFactory::class)->getIcon('sysnote-type-0', Icon::SIZE_SMALL)) @@ -89,7 +86,7 @@ class ButtonBarHook ksort($buttons[ButtonBar::BUTTON_POSITION_RIGHT]); - return $buttons; + $event->setButtons($buttons); } /** diff --git a/typo3/sysext/sys_note/Configuration/Services.yaml b/typo3/sysext/sys_note/Configuration/Services.yaml index 5de200e5e6ee..1859b6ef463e 100644 --- a/typo3/sysext/sys_note/Configuration/Services.yaml +++ b/typo3/sysext/sys_note/Configuration/Services.yaml @@ -18,3 +18,7 @@ services: tags: - name: event.listener identifier: 'note-to-page-module' + TYPO3\CMS\SysNote\Provider\ButtonBarProvider: + tags: + - name: event.listener + identifier: 'note-to-button-bar' diff --git a/typo3/sysext/sys_note/ext_localconf.php b/typo3/sysext/sys_note/ext_localconf.php index 8282c212f060..d074f5e1f200 100644 --- a/typo3/sysext/sys_note/ext_localconf.php +++ b/typo3/sysext/sys_note/ext_localconf.php @@ -2,12 +2,9 @@ declare(strict_types=1); -use TYPO3\CMS\SysNote\Hook\ButtonBarHook; use TYPO3\CMS\SysNote\Hook\InfoModuleHook; defined('TYPO3') or die(); // Hook into the info module $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/web_info/class.tx_cms_webinfo.php']['drawFooterHook']['sys_note'] = InfoModuleHook::class . '->render'; -// Hook into the button bar -$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['Backend\Template\Components\ButtonBar']['getButtonsHook']['sys_note'] = ButtonBarHook::class . '->getButtons'; -- GitLab