Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Writing Extensible Code Using Event Dispatcher

John Kary
October 20, 2012

Writing Extensible Code Using Event Dispatcher

Demonstrate refactoring a typical Controller to using Symfony2 EventDispatcher component to make writing decoupled code easier.

John Kary

October 20, 2012
Tweet

More Decks by John Kary

Other Decks in Programming

Transcript

  1. ABOUT PHP since 2005 Contract PHP Developer in Lawrence Education

    & Trucking Industry Previously of University of Kansas - IT
  2. Overview 1. Procedural PHP 2. Refactor to Object-Oriented PHP 3.

    Extensibility 4. Controllers in Model View Controller 5. EventDispatcher concept 6. Refactor to using an EventDispatcher 7. EventDispatcher caveats
  3. Maybe you know about... JavaScript Events Basics of Object-Oriented Programming

    Inheritance Polymorphism Encapsulation Abstraction Delegation Dependency Injection Single Responsibility Principle Separation of Concerns MVC
  4. John, Customers are unhappy. Send them a “Welcome!” email after

    they register on the web site. Tell them we are glad to have them as a customer. That’ll teach ‘em. Do it now. The Boss The Boss
  5. Procedural PHP $_POST = array( 'name' => 'John Kary', 'email'

    => '[email protected]', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: [email protected]'; $headers[] = 'Reply-To: [email protected]'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n"));
  6. Object-Oriented PHP $_POST = array( 'name' => 'John Kary', 'email'

    => '[email protected]', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: [email protected]'; $headers[] = 'Reply-To: [email protected]'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n")); Customer
  7. Object-Oriented PHP class Customer { public function __construct(array $data) {

    $this->name = $data['name']; $this->email = $data['email']; } public function getName() { return $this->name; } public function getEmail() { return $this->email; } }
  8. Object-Oriented PHP $_POST = array( 'name' => 'John Kary', 'email'

    => '[email protected]', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: [email protected]'; $headers[] = 'Reply-To: [email protected]'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n")); Customer WelcomeEmail
  9. class WelcomeEmail { public function send($to, $name) { return mail($to,

    $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'New Account'; } protected function getMessage($name) { return "Welcome " . $name . "! Your new space has been created! Use this link to login: https://activate.demcrookidwigitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; } protected function getHeaders() { $headers = array(); $headers[] = 'From: [email protected]'; $headers[] = 'Reply-To: [email protected]'; $headers[] = 'X-Mailer: PHP/' . phpversion(); return implode($headers, "\r\n"); } }
  10. Object-Oriented PHP $_POST = array( 'name' => 'John Kary', 'email'

    => '[email protected]', ); $to = $_POST['email']; $subject = 'New Account'; $message = "Welcome " . $_POST['name'] . "! Your new space has been created! Use this link to login: https://activate.demcrookidwidgitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; $headers = array(); $headers[] = 'From: [email protected]'; $headers[] = 'Reply-To: [email protected]'; $headers[] = 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, implode($headers, "\r\n")); Customer WelcomeEmail Controller
  11. class Controller { // POST http://demcrookidwigitz.com/person public function newCustomer() {

    $customer = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail(), $customer->getName()); } } Object-Oriented PHP
  12. John, Advertising wants to know how many new customers we’re

    getting. Setup some logging. I don’t want their grubby hands on the database. That’ll teach ‘em. Do it now. The Boss The Boss
  13. Disk Logging class Controller { public function newCustomer() { $customer

    = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); } }
  14. John, Marketing wants to run statistics on orders. Keep them

    away from the database too. Just add to that other log file we setup for Advertising. That’ll teach ‘em. Do it now. The Boss The Boss
  15. More Disk Logging class Controller { public function newCustomer() {

    // ... $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); } }
  16. class Controller { public function newCustomer() { // ... $dLog

    = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  17. class Controller { public function newCustomer() { // ... $dLog

    = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(). ' at '.$customer->getEmail(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName().' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...');
  18. ?

  19. class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  20. class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  21. class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  22. class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  23. Extensibility [A] system design principle where the implementation takes into

    consideration future growth. Extensibility - Wikipedia http://en.wikipedia.org/wiki/Extensibility
  24. class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  25. class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } } NOT EXTENSIBLE!
  26. Event Dispatcher - Register Listeners CartListener:: onAddToCart() EventDispatcher cart.add CustomerListener::

    onRegister() customer.register CartListener:: grantDiscount() cart.checkout
  27. Event Dispatcher - Register Listeners use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new

    EventDispatcher(); $listener = new CustomerListener(); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); // Register more listeners class CustomerListener { public function onRegister(CustomerEvent $event) { // Do some work } } Any PHP Callable true === is_callable()
  28. Event Dispatcher - Register Listeners use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new

    EventDispatcher(); $dispatcher->addListener('customer.register', array('CustomerListener', 'onRegister')); // Register more listeners class CustomerListener { public static function onRegister(CustomerEvent $event) { // Do some work } }
  29. Event Dispatcher - Register Listeners use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new

    EventDispatcher(); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // Do some work });
  30. Request Response Event Dispatcher - Dispatch an Event EventDispatcher “customer.register”

    CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  31. Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  32. Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  33. Event Dispatcher - Dispatch an Event use Symfony\Component\EventDispatcher\EventDispatcher; class CustomerController

    { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer(array( 'first_name' => 'Bob', 'last_name' => 'Smith', 'email' => '[email protected]', )); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } } Customer Event Event Name
  34. Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  35. Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount() $this->dispatcher->dispatch('customer.register', $event);
  36. Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount()
  37. Request Response CustomerEvent “customer.register” Customer Event Dispatcher - Dispatch an

    Event EventDispatcher “customer.register” CustomerListener:: onRegister() “cart.add” CartListener:: onAddToCart() “cart.checkout” CartListener:: grantDiscount() “customer.register” CustomerListener:: onRegister()
  38. Event Dispatcher - Handle the Event class CustomerListener { public

    function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $name = $event->getName(); $dispatcher = $event->getDispatcher(); // Do something with Customer object } } CustomerEvent “customer.register” Customer
  39. Event Dispatcher - Handle the Event class CustomerListener { public

    function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $name = $event->getName(); $dispatcher = $event->getDispatcher(); // Do something with Customer object } }
  40. Event Dispatcher - Handle the Event use Symfony\Component\EventDispatcher\Event; class CustomerEvent

    extends Event { protected $customer; public function __construct(Customer $customer) { $this->customer = $customer; } public function getCustomer() { return $this->customer; } }
  41. Event Dispatcher - All together now! CartListener:: onAddToCart() CustomerListener:: onRegister()

    CartListener:: grantDiscount() EventDispatcher cart.checkout cart.add customer.register
  42. Event Dispatcher - All together now! CartListener:: onAddToCart() CustomerListener:: onRegister()

    CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister()
  43. CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister()
  44. CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister() $this->dispatcher->dispatch('customer.register', $event);
  45. CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister()
  46. CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister() “customer.register” CustomerListener:: onRegister()
  47. CustomerEvent “customer.register” Customer Event Dispatcher - All together now! CartListener::

    onAddToCart() CustomerListener:: onRegister() CartListener:: grantDiscount() EventDispatcher “cart.checkout” CartListener:: grantDiscount() “cart.add” CartListener:: onAddToCart() “customer.register” CustomerListener:: onRegister() “customer.register” CustomerListener:: onRegister() That’s Event Dispatcher!
  48. class Controller { public function newCustomer() { $customer = new

    Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } } START
  49. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.new', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.cancel', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } } FINISH
  50. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]');
  51. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $email = new WelcomeEmail(); $email->send($customer->getEmail()); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]');
  52. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]');
  53. use Symfony\Component\EventDispatcher\Event; class CustomerEvent extends Event { protected $customer; public

    function __construct(Customer $customer) { $this->customer = $customer; } public function getCustomer() { return $this->customer; } }
  54. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class WelcomeEmail { public function send($to, $name) { return mail($to, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'New Account'; } protected function getMessage($name) { return "Welcome " . $name . "! Your new space has been created! Use this link to login: https://activate.demcrookidwigitz.com/code/Sq9284tWBnWgpjw Thanks! DemCrookidWigitz"; } protected function getHeaders() { $headers = array(); $headers[] = 'From: [email protected]';
  55. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  56. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  57. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  58. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  59. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class WelcomeEmail { public function send($to, $name) { return mail($to, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } }
  60. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); // Wire listeners $listener

    = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class WelcomeEmail { public function send($to, $name) { return mail($to, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } }
  61. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]');
  62. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  63. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister'));
  64. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  65. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  66. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } }
  67. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); $this->logger->log('Sent welcome email to ' . $customer->getName()); } }
  68. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail(), $diskLogger); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); class CustomerEmailListener { public function __construct(WelcomeEmail $email) { $this->email = $email; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); } } class CustomerEmailListener { public function __construct(WelcomeEmail $email, DiskLogger $logger) { $this->email = $email; $this->logger = $logger; } public function onRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getEmail(), $customer->getName()); $this->logger->log('Sent welcome email to ' . $customer->getName()); } }
  69. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]');
  70. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  71. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $dLog = new DiskLogger('/logs/prod.log'); $msg = 'Sent welcome email to '.$customer->getName(); $dLog->log($msg); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  72. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  73. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  74. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  75. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); class BossNewCustomerEmail { public function __construct($bossEmail) { $this->bossEmail = $bossEmail; } public function send($name) { return mail($this->bossEmail, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'New Customer Registered!'; } protected function getMessage($name) { return "Boss! " . $name . " just registered! Sweet, huh?"; } // ... }
  76. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister'));
  77. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); class BossNewCustomerEmailListener { public function __construct(BossNewCustomerEmail $email) { $this->email = $email; } public function onCustomerRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getName()); } }
  78. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); class BossNewCustomerEmailListener { public function __construct(BossNewCustomerEmail $email) { $this->email = $email; } public function onCustomerRegister(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getName()); } }
  79. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  80. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' has registered!'); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } } class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  81. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  82. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $twitter->tweet($customer->getName() . ' just ordered from us!'); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } } class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  83. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $twitter = new Twitter('demcrookidwigitz',

    'b3@tb0Xpr0$'); // Wire listeners $listener = new TwitterListener($twitter); $dispatcher->addListener('order.new', array($listener, 'tweetAtOrderer'));
  84. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $twitter = new Twitter('demcrookidwigitz',

    'b3@tb0Xpr0$'); // Wire listeners $listener = new TwitterListener($twitter); $dispatcher->addListener('order.new', array($listener, 'tweetAtOrderer')); class TwitterListener { public function __construct(Twitter $twitter) { $this->twitter = $twitter; } public function tweetAtOrderer(CustomerEvent $event) { $customer = $event->getOrder(); $msg = $customer->getTwitterHandle().' Thanks for ordering from us!'; $this->twitter->tweet($msg); } }
  85. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $eLog = new EmailLogger('[email protected]'); $eLog->log($customer->getName() . ' cancelled their order...'); } }
  86. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossCancelOrderEmailListener(new BossCancelOrderEmail($bossEmail)); $dispatcher->addListener('customer.order.cancel', array($listener, 'onCancelOrder')); class BossCancelOrderEmail { public function __construct($bossEmail) { $this->bossEmail = $bossEmail; } public function send($name) { return mail($this->bossEmail, $this->getSubject(), $this->getMessage($name), $this->getHeaders()); } protected function getSubject() { return 'Customer Order Cancelled'; } protected function getMessage($name) { return "Boss! " . $name . " cancelled their order. Bummer!"; } // ... }
  87. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $bossEmail = '[email protected]'; //

    Wire listeners // ... $listener = new BossCancelOrderEmailListener(new BossCancelOrderEmail($bossEmail)); $dispatcher->addListener('customer.order.cancel', array($listener, 'onCancelOrder')); class BossCancelOrderEmailListener { public function __construct(BossCancelOrderEmail $email) { $this->email = $email; } public function onCancelOrder(CustomerEvent $event) { $customer = $event->getCustomer(); $this->email->send($customer->getName()); } }
  88. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } }
  89. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } }
  90. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Created order ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $dLog = new DiskLogger('/logs/prod.log'); $dLog->log('Cancelled order number ' . $number); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } } class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher = $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.new', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.cancel', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } }
  91. use Symfony\Component\EventDispatcher\Event; class OrderEvent extends Event { protected $order; public

    function __construct(Order $order) { $this->order = $order; } public function getOrder() { return $this->order; } }
  92. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new OrderLoggerListener($diskLogger); $dispatcher->addListener('order.new', array($listener, 'onNewOrder')); class OrderLoggerListener { public function __construct(DiskLogger $logger) { $this->logger = $logger; } public function onNewOrder(OrderEvent $event) { $order = $event->getOrder(); $this->logger->log('Created order number ' . $order->getNumber()); } }
  93. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    // Wire listeners $listener = new OrderLoggerListener($diskLogger); $dispatcher->addListener('order.new', array($listener, 'onNewOrder')); $dispatcher->addListener('order.cancel', array($listener, 'onCancelOrder')); class OrderLoggerListener { public function __construct(DiskLogger $logger) { $this->logger = $logger; } public function onNewOrder(OrderEvent $event) { $order = $event->getOrder(); $this->logger->log('Created order number ' . $order->getNumber()); } public function onCancelOrder(OrderEvent $event) { $order = $event->getOrder(); $this->logger->log('Cancelled order number ' . $order->getNumber()); } }
  94. class Controller { public function __construct(EventDispatcher $dispatcher) { $this->dispatcher =

    $dispatcher; } public function newCustomer() { $customer = new Customer($_POST); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.register', $event); } public function createOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.new', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.new', $event); } public function cancelOrder() { // ... $event = new OrderEvent($order); $this->dispatcher->dispatch('order.cancel', $event); $event = new CustomerEvent($customer); $this->dispatcher->dispatch('customer.order.cancel', $event); } } FINISH
  95. use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $diskLogger = new DiskLogger('/logs/prod.log');

    $twitter = new Twitter('demcrookidwigitz', 'b3@tb0Xpr0$'); $bossEmail = '[email protected]'; // Wire listeners $listener = new CustomerEmailListener(new WelcomeEmail()); $dispatcher->addListener('customer.register', array($listener, 'onRegister')); $listener = new BossNewCustomerEmailListener(new BossNewCustomerEmail($bossEmail)); $dispatcher->addListener('customer.register', array($listener, 'onCustomerRegister')); $listener = new BossCancelOrderEmailListener(new BossCancelOrderEmail($bossEmail)); $dispatcher->addListener('customer.order.cancel', array($listener, 'onCancelOrder')); $listener = new OrderLoggerListener($diskLogger); $dispatcher->addListener('order.new', array($listener, 'onNewOrder')); $dispatcher->addListener('order.cancel', array($listener, 'onCancelOrder')); $listener = new TwitterListener($twitter); $dispatcher->addListener('order.new', array($listener, 'tweetAtOrderer')); FINISH
  96. Caveat - Priority use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addListener('customer.register',

    function(CustomerEvent $event) { // First }); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // Second }); $customer = new Customer(); $customer->setEmail('[email protected]'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); First Second
  97. Caveat - Priority use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addListener('customer.register',

    function(CustomerEvent $event) { // Second }, 100); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // First }, 200); $customer = new Customer(); $customer->setEmail('[email protected]'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); First Second
  98. Caveat - Priority use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addListener('customer.register',

    function(CustomerEvent $event) { // Third }, 100); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // First }, 200); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { // Second }, 200); $customer = new Customer(); $customer->setEmail('[email protected]'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); First Third Second
  99. Caveat - Side Effects use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher();

    $dispatcher->addListener('customer.register', function(CustomerEvent $event) { echo $event->getCustomer()->getEmail(); // [email protected] $event->getCustomer()->setEmail('[email protected]'); }); $dispatcher->addListener('customer.register', function(CustomerEvent $event) { echo $event->getCustomer()->getEmail(); // [email protected] }); $customer = new Customer(); $customer->setEmail('[email protected]'); $event = new CustomerEvent($customer); $dispatcher->dispatch('customer.register', $event); 1. Set Email 2. Get Email 3. Update Email 4. Email not the same
  100. Ideas for Utilizing Events • Logging • Offloading expensive operations

    to a message queue • Email, PDF generation, file system access • Setting “created_at” or “updated_at” on an entity • Updating a search index when persisting an entity • Allowing users of your plug-ins to extend their functionality without modifying your code • What ideas have you come up with?
  101. Further Reading • Introduction to Symfony2 EventDispatcher http://bit.ly/sf2-event-dispatcher • An

    Introduction to Zend Framework 2 Event Manager http://bit.ly/zf2-event-manater • The S.O.L.I.D. Principles of OO and Agile Design http://bit.ly/uncle-bob-oo-insights
  102. Sources • http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf • http://stlab.adobe.com/wiki/index.php/File:2008_07_25_google.pdf Photo Credits • http://www.flickr.com/photos/pedromourapinheiro/2456410959/ •

    http://www.flickr.com/photos/seat850/3893504473/ • http://www.flickr.com/photos/slworking/5170065748/ • http://www.flickr.com/photos/33037982@N04/3727397261/ • http://www.flickr.com/photos/factoryjoe/26967479/
  103. John Kary johnkary@ gmail.com @ johnkary Slides @ http://johnkary.net/talks WRITING

    EXTENSIBLE CODE USING EVENT DISPATCHER https://joind.in/7551