Monday, June 4, 2012

Event Listener Example

Here is an event listener example. I made a little game using Symfony2 framework and I needed to check if the user chose a hero(character) to play before trying to make some actions like view inventory etc.
src/HungryCoders/HeroGameBundle/EventListener/BeforeControllerListener.php:
<?php
namespace HungryCoders\HeroGameBundle\EventListener;

use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class BeforeControllerListener
{
  
    protected $session;
    protected $resolver;
  
  
    public function __construct($session, $resolver)
    {
        $this->session = $session;
        $this->resolver = $resolver;
    }
  
    /**
     * This is used to check if the user that wants to access some hero game controller
     * chose a hero to play with
     */
    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();
      

        if (!is_array($controller)) {
            // not a object but a different kind of callable. Do nothing
            return;
        }
        $controller = $event->getController();
        $controllerObject = $controller[0];
      
     
        if ($controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\BattleController
        ||  $controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\HeroController
        ||  $controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\InventoryController
        ||  $controllerObject instanceOf \HungryCoders\HeroGameBundle\Controller\TownController
        )
        {
            if ($this->session->get('heroGameHeroId') === null) {
              
                $this->session->setFlash('heroGame.mustChooseAHero', 'You must choose a hero to play');
              
                //a way to create a new response without any redirect just create a response using a controller action
                $request = new \Symfony\Component\HttpFoundation\Request();
                $request->attributes->set('_controller', 'HungryCodersHeroGameBundle:HeroAccess:dashboard');
                $event->setController($this->resolver->getController($request));
            }
        }
    }
}


src/HungryCoders/HeroGameBundle/Resources/config/services.yml
parameters:
    heroGame.battle.maxRounds: 5
    heroGame.attack.rangeLevels: 5

services:
    beforeController.listener:
        class: HungryCoders\HeroGameBundle\EventListener\BeforeControllerListener
        arguments: [ @session, @controller_resolver]
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }