Bohdan Zhuravel
Bohdan Zhuravel

Reputation: 145

Symfony2: Execute some code after every action

I recently started a project in Symfony2 and I need to run some methods before and after every action to avoid code redundancy (like preDispatch/postDispatch from Zend Framework and PreExecute/PostExecute from Symfony1).

I created a base class from which all the controllers are inherited, and registered an event listener to run controller's preExecute() method before running requested action, but after reading tons of documentation and questions from here I still can't find how to run postExecute().

Foo/BarBundle/Controller/BaseController.php:

class BaseController extends Controller {
  protected $_user;
  protected $_em;

  public function preExecute() {
    $user = $this->get('security.context')->getToken()->getUser();
    $this->_user = $user instanceof User ? $user : null;
    $this->_em = $this->getDoctrine()->getEntityManager();
  }

  public function postExecute() {
    $this->_em->flush();
  }
}

Foo/BarBundle/Controller/FooController.php:

class FooController extends BaseController {
  public function indexAction() {
    $this->_user->setName('Eric');
    $this->_em->persist($this->_user);
  }
}

Foo/BarBundle/EventListener/PreExecute.php:

class PreExecute {
  public function onKernelController(FilterControllerEvent $event) {
    if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
      $controllers = $event->getController();
      if (is_array($controllers)) {
        $controller = $controllers[0];

        if (is_object($controller) && method_exists($controller, 'preExecute')) {
          $controller->preExecute();
        }
      }
    }
  }
}

Upvotes: 9

Views: 5141

Answers (1)

MDrollette
MDrollette

Reputation: 6927

There is a discussion of this here and this particular example by schmittjoh may lead you in the right direction.

<?php

class Listener
{
    public function onKernelController($event)
    {
        $currentController = $event->getController();
        $newController = function() use ($currentController) {
            // pre-execute
            $rs = call_user_func_array($currentController, func_get_args());
            // post-execute

            return $rs;
        };
        $event->setController($newController);
    }
}

Upvotes: 6

Related Questions