Skip to content

[FEATURE] Add getRequest method to SendMailServiceCreateEmailBodyEvent #1386

Description

@sypets

In the event listener for SendMailServiceCreateEmailBodyEvent it might be necessary to use the current request object (e.g. for accessing the rootline).

It is still possible to use the global $GLOBALS['TYPO3_REQUEST'] but this is highly discouraged, see

The global request variable is a compatibility layer and is no longer guaranteed to be available in all execution contexts. In particular, it may not be set yet in early PSR-15 middlewares.

Always prefer the PSR-7 request object passed explicitly to the current execution context.

https://docs.typo3.org/m/typo3/reference-coreapi/14.3/en-us/ApiOverview/RequestLifeCycle/Typo3Request.html#last-resort-global-variable

My use case

I am using an event listener for SendMailServiceCreateEmailBodyEvent in my extension. This will add a logo to the email sent by powermail (if logo is configured in the page). For this it will get the rootline as the logo is inherited from ancestor pages. Since I am getting rid of mostly deprecated code, it currently looks like this (I need the request to get the rootline):

final class SendMailServiceCreateEmailBodyEventListener
{
    public function __construct(private readonly FileRepository $fileRepository)
    {
    }

    public function __invoke(SendMailServiceCreateEmailBodyEvent $event): void
    {
        $view = $event->getStandaloneView();

        $request = $this->getRequest();

        if ($request && ApplicationType::fromRequest($request)->isFrontend()) {
            $rootline = $request->getAttribute('frontend.page.information')->getRootLine();
            foreach ($rootline as $pageInRootline) {
                $results = $this->fileRepository->findByRelation(
                    'pages',
                    'uniol_logoimage',
                    (int)($pageInRootline['uid'] ?? 0)
                );
                if ($results) {
                    $imageRef = $results[0];
                    if ($imageRef instanceof FileReference) {
                        if ($imageRef->getExtension() === 'svg' || $imageRef->getMimeType() === 'image/svg+xml ') {
                            $view->assign('headerImageTargetExtension', 'png');
                        }
                    }
                    $view->assign('headerImage', $results[0]);
                    break;
                }
            }
        }
        $event->setStandaloneView($view);
    }

    /**
     * The request is not passed in event listener so we use the global variable even though that is not recommended
     * @see https://docs.typo3.org/m/typo3/reference-coreapi/13.4/en-us/ApiOverview/RequestLifeCycle/Typo3Request.html
     */
    private function getRequest(): ServerRequestInterface|null
    {
        return $GLOBALS['TYPO3_REQUEST'] ?? null;
    }
}

Ideally I would like to not use $GLOBALS['TYPO3_REQUEST'] for future compatibility.

Additional context

TYPO3 often provides getRequest() method in own events, e.g.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions