Commit 8dde7f04 authored by Benni Mack's avatar Benni Mack
Browse files

[!!!][FEATURE] Add PSR-14 event for manipulating Page Links via typolink

A new PSR-14 event is added, where the old hook is removed
to modify links to generated Page Links.

Resolves: #87616
Releases: main
Change-Id: Iee7c078078fe1f7af6365774162dd2cc7cab321a
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72948

Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Tested-by: Jochen's avatarJochen <rothjochen@gmail.com>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: Jochen's avatarJochen <rothjochen@gmail.com>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 6fa0a49b
.. include:: ../../Includes.txt
=======================================================
Breaking: #87616 - Removed hook for altering Page Links
=======================================================
See :issue:`87616`
Description
===========
The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typolinkProcessing']['typolinkModifyParameterForPageLinks']`
has been removed in favor of a new PSR-14 Event :php:`TYPO3\CMS\Frontend\Event\ModifyPageLinkConfigurationEvent`.
The event is called after TYPO3 has already prepared some functionality
within the :php:`PageLinkBuilder`. This therefore allows to modify more
properties, if needed.
Impact
======
Any hook implementation registered is not executed anymore
in TYPO3 v12.0+.
Affected Installations
======================
TYPO3 installations with custom extensions using this hook.
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-87616-PSR-14EventForModifyingPageLinkGeneration>`
to allow greater influence in the functionality.
.. index:: Frontend, FullyScanned, ext:frontend
.. include:: ../../Includes.txt
===================================================================================
Deprecation: #87616 - Unused Interface for TypolinkModifyLinkConfigForPageLinksHook
===================================================================================
See :issue:`87616`
Description
===========
The hook :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typolinkProcessing']['typolinkModifyParameterForPageLinks']`
required hook implementations to implement :php:`TypolinkModifyLinkConfigForPageLinksHookInterface`.
Since the mentioned hook is :doc:`removed <../12.0/Breaking-87616-RemovedHookForAlteringPageLinks.rst>`,
the interface is not in use anymore and has been marked as deprecated.
Impact
======
The extension scanner will now notify any extension, which might still use
the PHP interface.
Affected Installations
======================
TYPO3 installations using the PHP interface in custom extension code.
Migration
=========
The PHP interface is still available for TYPO3 v12.x, so extensions can
provide a version which is compatible with TYPO3 v11 (using the hook)
and TYPO3 v12.x (using the new PSR-14 ModifyPageLinkConfigurationEvent),
at the same time.
Remove any usage of the PHP interface and use the new PSR-14
Event to avoid any further problems in TYPO3 v13+.
.. index:: Frontend, FullyScanned, ext:frontend
.. include:: ../../Includes.txt
=================================================================
Feature: #87616 - PSR-14 Event for modifying Page Link Generation
=================================================================
See :issue:`87616`
Description
===========
A new PSR-14 Event :php:`TYPO3\CMS\Frontend\Event\ModifyPageLinkConfigurationEvent`
has been introduced which serves as a more powerful and flexible alternative
for the now removed hook
:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typolinkProcessing']['typolinkModifyParameterForPageLinks']`.
The event is called after a page has already been resolved, and includes much
more arguments such as the generated fragment or the to-be-used query parameters.
The page to be linked to can also be modified to e.g. link to a different page.
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-page-link-configuration'
The corresponding event listener class:
.. code-block:: php
use TYPO3\CMS\Frontend\Event\ModifyPageLinkConfigurationEvent;
class MyEventListener {
public function __invoke(ModifyPageLinkConfigurationEvent $event): void
{
// Do your magic here
}
}
Impact
======
The main advantage of the PSR-14 Event is that it is fired after TYPO3 has
already prepared some functionality within the :php:`PageLinkBuilder`, allowing
to modify more properties, if needed.
.. index:: Frontend, ext:frontend
......@@ -18,6 +18,7 @@ namespace TYPO3\CMS\Frontend\ContentObject;
/**
* interface for classes which hook into \TYPO3\CMS\Frontend\ContentObjectRenderer and wish to modify the typolink
* configuration of the page link.
* @deprecated not in use anymore since TYPO3 v12, will be removed in TYPO3 13. Only stays for adding compatibility for TYPO3 v11+v12 compatible extensions
*/
interface TypolinkModifyLinkConfigForPageLinksHookInterface
{
......
<?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\Frontend\Event;
/**
* A generic PSR 14 Event to allow modifying the incoming (and resolved) page when building a "page link".
*
* This event allows Event Listener to change the page to be linked to, or add/remove possible query
* parameters / fragments to be generated.
*/
final class ModifyPageLinkConfigurationEvent
{
private array $configuration;
private array $linkDetails;
private array $page;
private array $queryParameters;
private string $fragment;
public function __construct(
array $configuration,
array $linkDetails,
array $page,
array $queryParameters,
string $fragment
) {
$this->configuration = $configuration;
$this->linkDetails = $linkDetails;
$this->page = $page;
$this->queryParameters = $queryParameters;
$this->fragment = $fragment;
}
public function getConfiguration(): array
{
return $this->configuration;
}
public function setConfiguration(array $configuration): void
{
$this->configuration = $configuration;
}
public function getLinkDetails(): array
{
return $this->linkDetails;
}
public function getPage(): array
{
return $this->page;
}
public function setPage(array $page): void
{
$this->page = $page;
}
public function getQueryParameters(): array
{
return $this->queryParameters;
}
public function setQueryParameters(array $queryParameters): void
{
$this->queryParameters = $queryParameters;
}
public function getFragment(): string
{
return $this->fragment;
}
public function setFragment(string $fragment): void
{
$this->fragment = $fragment;
}
}
......@@ -17,6 +17,7 @@ declare(strict_types=1);
namespace TYPO3\CMS\Frontend\Typolink;
use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use TYPO3\CMS\Core\Cache\CacheManager;
......@@ -40,8 +41,8 @@ use TYPO3\CMS\Core\Type\Bitmask\PageTranslationVisibility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
use TYPO3\CMS\Frontend\ContentObject\TypolinkModifyLinkConfigForPageLinksHookInterface;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
use TYPO3\CMS\Frontend\Event\ModifyPageLinkConfigurationEvent;
/**
* Builds a TypoLink to a certain page
......@@ -52,6 +53,7 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
{
$linkResultType = LinkService::TYPE_PAGE;
$tsfe = $this->getTypoScriptFrontendController();
$conf['additionalParams'] ??= '';
if (empty($linkDetails['pageuid']) || $linkDetails['pageuid'] === 'current') {
// If no id is given
$linkDetails['pageuid'] = $tsfe->id;
......@@ -71,16 +73,6 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
throw new UnableToLinkException('Page id "' . $linkDetails['typoLinkParameter'] . '" was not found, so "' . $linkText . '" was not linked.', 1490987336, null, $linkText);
}
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typolinkProcessing']['typolinkModifyParameterForPageLinks'] ?? [] as $classData) {
$hookObject = GeneralUtility::makeInstance($classData);
if (!$hookObject instanceof TypolinkModifyLinkConfigForPageLinksHookInterface) {
throw new \UnexpectedValueException('$hookObject must implement interface ' . TypolinkModifyLinkConfigForPageLinksHookInterface::class, 1483114905);
}
/** @var TypolinkModifyLinkConfigForPageLinksHookInterface $hookObject */
$conf = $hookObject->modifyPageLinkConfiguration($conf, $linkDetails, $page);
}
$conf['additionalParams'] ??= '';
$fragment = $this->calculateUrlFragment($conf, $linkDetails);
$queryParameters = $this->calculateQueryParameters($conf, $linkDetails);
// Add MP parameter
......@@ -89,6 +81,13 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
$queryParameters['MP'] = $mountPointParameter;
}
$event = new ModifyPageLinkConfigurationEvent($conf, $linkDetails, $page, $queryParameters, $fragment);
$event = GeneralUtility::getContainer()->get(EventDispatcherInterface::class)->dispatch($event);
$conf = $event->getConfiguration();
$page = $event->getPage();
$queryParameters = $event->getQueryParameters();
$fragment = $event->getFragment();
// Check if the target page has a site configuration
try {
$siteOfTargetPage = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId((int)$page['uid'], null, $queryParameters['MP'] ?? '');
......
......@@ -583,4 +583,10 @@ return [
'Feature-96526-PSR-14EventForModifyingPageModuleContent.rst',
],
],
'$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'typolinkProcessing\'][\'typolinkModifyParameterForPageLinks\']' => [
'restFiles' => [
'Breaking-87616-RemovedHookForAlteringPageLinks.rst',
'Feature-87616-PSR-14EventForModifyingPageLinkGeneration.rst',
],
],
];
......@@ -1885,11 +1885,18 @@ return [
'Breaking-96107-DeprecatedFunctionalityRemoved.rst',
],
],
'TYPO3\CMS\Core\Frontend\ContentObject\Menu\AbstractMenuFilterPagesHookInterface' => [
'TYPO3\CMS\Frontend\ContentObject\Menu\AbstractMenuFilterPagesHookInterface' => [
'restFiles' => [
'Deprecation-92508-UnusedInterfaceForFilterMenuPagesHook.rst',
'Breaking-92508-RemovedHookForFilteringHMENUItems.rst',
'Feature-92508-PSR-14EventForModifyingMenuItems.rst',
],
],
'TYPO3\CMS\Frontend\ContentObject\TypolinkModifyLinkConfigForPageLinksHookInterface' => [
'restFiles' => [
'Deprecation-87616-UnusedInterfaceForTypolinkModifyLinkConfigForPageLinksHook.rst',
'Breaking-87616-RemovedHookForAlteringPageLinks.rst',
'Feature-87616-PSR-14EventForModifyingPageLinkGeneration.rst',
],
],
];
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment