Skip to content

Using the Action Subscribers

Iltar van der Berg edited this page Apr 6, 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.

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