Skip to content

Using the Action Subscribers

Yannick de Lange edited this page May 19, 2017 · 3 revisions

In some cases you might want to the use ActionSubscriberInterface instead of registering your onSuccess and onFailure callbacks. This provides a more traditional form handler and allows for easier unit testing of your code. Internally we do not differentiate between ways of registering, so they have the same signature as te callbacks.

To do so, your handler need to also implement the ActionSubscriberInterface which requires a single static method called ::getSubscribedActions(). This method returns an array indexed by action names and whose values are the method name to call.

For action names, see the HandlerActions class.

A simple example of a HandlerType which implements the ActionSubscriberInterface is shown below.

<?php
namespace App\FormHandler;

use App\Entity\Account;
use App\FormType\EditUserType;
use Doctrine\ORM\EntityManagerInterface;
use Hostnet\Component\FormHandler\ActionSubscriberInterface;
use Hostnet\Component\FormHandler\HandlerActions;
use Hostnet\Component\FormHandler\HandlerConfigInterface;
use Hostnet\Component\FormHandler\HandlerTypeInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

final class EditUserFormHandler implements HandlerTypeInterface, ActionSubscriberInterface
{
    private $em;
    private $token_storage;
    private $flash_bag;
    private $url_generator;

    public function __construct(
        EntityManagerInterface $em,
        TokenStorageInterface  $token_storage,
        FlashBagInterface      $flash_bag,
        UrlGeneratorInterface  $url_generator
    ) {
        $this->em            = $em;
        $this->token_storage = $token_storage;
        $this->flash_bag     = $flash_bag;
        $this->url_generator = $url_generator;
    }

    public function configure(HandlerConfigInterface $config)
    {
        $config->setType(EditUserType::class);
        $config->registerActionSubscriber($this);
    }

    public function getSubscribedActions()
    {
        // all possible actions to subscribe to
        return [
            HandlerActions::SUCCESS => 'onSuccess',
            HandlerActions::FAILURE => 'onFailure',
        ];
    }

    public function onSuccess(Account $user)
    {
        $by = $this->token_storage->getToken()->getUsername();

        $log = new ActionLog($user, $by, 'Updated the user account.');

        $this->em->persist($log);
        $this->em->flush();

        $this->flash_bag->add('success', 'The user has been updated.');

        return new RedirectResponse($this->url_generator->generate('app.user-list'));
    }

    public function onFailure()
    {
        $this->flash_bag->add('error', 'Something went wrong.');
    }
}

To register a subscriber with the handler, use the ::registerActionSubscriber() method in the HandlerConfigInterface. You should do this in the ::configure() method of the HandlerType.

Clone this wiki locally