Rolf//Thomas

ist ein Internetentwickler bei idee[x] digitale dienste

Migrate Typo3 Powermail SignalSlots to PSR-14 events

Adam Whitlock

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

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');