Custom Events And Event Listeners in Symfony2

January 28, 2016 | 1 Comment | Programming | event listener PHP Symfony2

All we know that fat controllers is evil in MVC but where we can place additional logic ? One of the solutions in Symfony2 – events and event listeners provided by EventDispatcher Component.

For example, you need to send emails in controller but you don’t want to store email code there. In this case we can delegate that functionality to event listeners which will be triggered in controller.

First step, you need to create class which extends base event class. This gives the listener special information about the event.

<?php
 
namespace AppBundle\Event;
 
use Symfony\Component\EventDispatcher\Event;
 
class BidEvent extends Event {
 
    protected $bid;
 
    public function __construct($bid)
    {
        $this->bid = $bid;
    }
 
    public function getBid()
    {
        return $this->bid;
    }
 
}

Next step is event listener creation. In this class we store all logic. In our case we send emails there. You can inject any components you want to using DependencyInjection Component.

<?php
 
namespace AppBundle\EventListener;
 
use CMS\RequestBundle\Event\BidEvent;
use Symfony\Bundle\TwigBundle\TwigEngine;
 
class BidListener {
 
    protected $mailer;
 
    protected $engine;
 
    public function __construct(\Swift_Mailer $mailer, TwigEngine $engine)
    {
        $this->mailer = $mailer;
        $this->engine = $engine;
    }
 
    public function onBidEvent(BidEvent $event)
    {
        $bid = $event->getBid();
 
        $message = \Swift_Message::newInstance()
            ->setSubject('New bid posted')
            ->setFrom('noreply@example.com','Example')
            ->setTo($bid->getOwner()->getEmail())
            ->setBody(
                $this->engine->render(
                    'App:Mail:newBid.html.twig',
                    array(
                        'bid' => $bid
                    )
                ),
                'text/html'
            )
        ;
 
        $this->mailer->send($message);
    }
}

Next, register listener as service in service configuration file. Don’t forget to inject all needed components and remember event name. Also method should match with method name in listener.

app.listener.bid:
       class: AppBundle\EventListener\BidListener
       arguments:
             ["@mailer","@templating"]
       tags:
           - { name: kernel.event_listener, event: app.bid, method: onBidEvent }

Last, call it from any place in our application, not necessary in controller, you have to inject only event dispatcher component.

$dispatcher = $this->container->get('event_dispatcher');
$dispatcher->dispatch('app.bid', new BidEvent($data));

About the Author / Artem Zhuravlev

Artem Zhuravlev. Web developer. Blog writer.

Need help with your website ? Contact with me by email infzanoza@gmail.com for services of experienced web developer.

Follow @infernosquad
1 COMMENT
anonyms

Very Well explianed!!!

LEAVE A COMMENT