Search code examples
shopwareshopware6

Override mail recipients for order state enter flow action and add data


I want to add data for the mail that is sent via the flow action on state_enter.* events and override the recipients. But it doesn't seem to be possible by just listening to the OrderStateMachineStateChangeEvent class since the dispatched event gets an explicit name.

So my desired solution doesn't work:

public static function getSubscribedEvents(): array
{
    return [
        OrderStateMachineStateChangeEvent::class => 'methodName'
    ];
}

As far as I know, I would need to create a listener for each state_enter event, which is a massive hustle and an issue if there are other states added afterward (eg. by store plugins).

public static function getSubscribedEvents(): array
{
    return [
        'state_enter.order.state.cancelled' => 'methodName',
        'state_enter.order.state.completed' => 'methodName',
        'state_enter.order.state.in_progress' => 'methodName',
        'state_enter.order.state.open' => 'methodName',
        'state_enter.order.state.open_release' => 'methodName',
        'state_enter.order_delivery.state.cancelled' => 'methodName',
        ......
        ...
    ];
}

Is there a better way I might not know about? So I basically want to override the recipients in the Event and add some additional data.

Listening to state_machine.order.state_changed, state_machine.order_delivery.state_changed and state_machine.order_transaction.state_changed doesn't work since the recipient and order data aren't forwarded to the OrderStateMachineStateChangeEvent


Solution

  • You could listen to FlowSendMailActionEvent and change the recipients on the fly based on the prefix of the event name.

    class FlowSendMailActionEventSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                FlowSendMailActionEvent::class => 'onFlowSendMailAction',
            ];
        }
    
        public function onFlowSendMailAction(FlowSendMailActionEvent $event): void
        {
            if (!str_starts_with($event->getStorableFlow()->getName(), 'state_enter.')) {
                return;
            }
    
            $recipients = $event->getDataBag()->get('recipients');
    
            $recipients['[email protected]'] = 'John Doe';
            // ...
    
            $event->getDataBag()->set('recipients', $recipients);
        }
    }