Skip to content

Support TYPO3 14 cms-redirects' QR code and Short URL feature #899

Description

@thopra

Is your feature request related to a problem? Please describe.

TYPO3 14 comes with a new QR code and short url generator within the redirect module, if the sysext cms-redirects is installed.

These redirects are stored in the sys_redirects table and will always contain a base url (which is not the frontend base).

If combined with headless and with the feature headless.redirectMiddlewares enabled, URLs generated here will always point to the JSON response instead of a redirect to a frontend url, making this feature kind of unusable.

Describe the solution you'd like

I'd see two potential ways of addressing this:

  1. In the redirect middleware, check if the redirect record is of type qrcodeor short_url and respond with a redirect directly to the corresponding frontend url instead of returning the JSON response.
  2. Modify generated QR codes and short links shown in the backend module, so that users will copy a url with the frontend base and redirects will be handled by the frontend like normal.

Describe alternatives you've considered

There is currently no real alternative if this feature is required.

However I was able to implement a workaround, using the RedirectUrlEvent that is dispatched from the middleware:

<?php

declare(strict_types=1);

namespace MyPackage\MyProject\EventListener;

use FriendsOfTYPO3\Headless\Event\RedirectUrlEvent;
use FriendsOfTYPO3\Headless\Utility\UrlUtility;
use Psr\Http\Message\ResponseFactoryInterface;
use \TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Http\ImmediateResponseException;
use TYPO3\CMS\Core\Site\Entity\Site;

/**
 * This event listener redirects qr codes and short urls to frontend url instead of responding with JSON redirect response
 */

#[AsEventListener(
    identifier: 'my-package/redirect-url',
)]
class RedirectUrlEventListener
{
    public function __construct(
        private readonly ResponseFactoryInterface $responseFactory,
        private readonly UrlUtility $urlUtility,
    )
    {}

    public function __invoke(RedirectUrlEvent $event): void
    {
        $record = $event->getRedirectRecord();
        $site = $event->getRequest()->getAttribute('site');

        if (!($site instanceof Site) || !in_array($record['redirect_type'] ?? '', ['short_url', 'qrcode'])) {
            return;
        }

        $response = $this->responseFactory
            ->createResponse((int)$record['target_statuscode'] ?? 307)
            ->withHeader('location', $this->urlUtility->getFrontendUrlWithSite($event->getTargetUrl(), $site));

        throw new ImmediateResponseException($response);
    }
}

This goes wit the first option from above and is both very simple and very ugly - but it works.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions