Rolf//Thomas

ist ein Internetentwickler bei idee[x] digitale dienste

Migrate Typo3 Powermail SignalSlots to PSR-14 events

02.01.2025

I stumbled about the need to migrate this breaking change while updateing TYPO3 v11 code to v12. Farewell SignalSlots 🙂

# composer.json
- "in2code/powermail": "^10.4"
+ "in2code/powermail": "^12.5"

Extension configuration

# packages/extensionname/ext_localconf.php
- /** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
- $signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
-     \TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class
- );
- // Adds signal slots for Powermail (s. https://github.com/in2code-de/powermail/blob/typo3-v11/Documentation/ForDevelopers/SignalSlots.md)
- // Slot is called before the form is rendered
- $signalSlotDispatcher->connect(
-     'In2code\Powermail\Controller\FormController',
-     'formActionBeforeRenderView',
-     'Vendor\Extensionname\Domain\Service\Powermail',
-     'formActionBeforeRenderViewSignalSlot',
-     false
- );

Service YAML

Find suitable Powermail PSR-14 event for old signal slot like In2code\Powermail\Events\FormControllerFormActionEvent in our example.

# packages/extensionname/Configuration/Services.yaml
+   Vendor\Extensionname\EventListener\Powermail:
+     tags:
+       - name: event.listener
+         identifier: 'Powermail/FormControllerFormActionEvent'
+         event: In2code\Powermail\Events\FormControllerFormActionEvent
+         method: 'onFormControllerFormActionEvent'

Implemention Behaviour

Move file to new place for class, eg:

- packages/extensionname/Classes/Domain/Service/Powermail.php
+ packages/extensionname/Classes/EventListener/Powermail.php

Add new namespace and classes. And transform old arguments to new single $events argument.

# packages/extensionname/Classes/EventListener/Powermail.php
- namespace Vendor\Extensionname\Domain\Service;
+ namespace Vendor\Extensionname\EventListener;

+  use In2code\Powermail\Events\FormControllerFormActionEvent;

final class Powermail {
// …
-    public function formActionBeforeRenderViewSignalSlot(Form $form, FormController $formController): void
+    public function onFormControllerFormActionEvent(FormControllerFormActionEvent $event): void
    {
+        $form = $event->getForm();
+        $formController = $event->getFormController();
        // make changes to powermail form/fields/whatever…
    }
}

Clear every cache you can

  • composer dumpautoload or in non-composer project Rebuild PHP Autoload Information
  • Flush TYPO3 and PHP Cache
  • Flush all caches in top navigation

On more tip

If you have to access protected objects 😎 inside powermail classes – this might be a pragmatic hack:

// helper to access protected class properties, credit https://stackoverflow.com/a/28352585/2054576
private function accessProtected($obj, $prop) {
    $reflection = new \ReflectionClass($obj);
    $property = $reflection->getProperty($prop);
    $property->setAccessible(true);
    return $property->getValue($obj);
}

// access protected class property
$answers = $this->accessProtected($mail, 'answers');