1<?php 2 3/* 4 * This file is part of SwiftMailer. 5 * (c) 2004-2009 Chris Corbyn 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11/** 12 * The EventDispatcher which handles the event dispatching layer. 13 * 14 * @author Chris Corbyn 15 */ 16class Swift_Events_SimpleEventDispatcher implements Swift_Events_EventDispatcher 17{ 18 /** A map of event types to their associated listener types */ 19 private $_eventMap = array(); 20 21 /** Event listeners bound to this dispatcher */ 22 private $_listeners = array(); 23 24 /** Listeners queued to have an Event bubbled up the stack to them */ 25 private $_bubbleQueue = array(); 26 27 /** 28 * Create a new EventDispatcher. 29 */ 30 public function __construct() 31 { 32 $this->_eventMap = array( 33 'Swift_Events_CommandEvent' => 'Swift_Events_CommandListener', 34 'Swift_Events_ResponseEvent' => 'Swift_Events_ResponseListener', 35 'Swift_Events_SendEvent' => 'Swift_Events_SendListener', 36 'Swift_Events_TransportChangeEvent' => 'Swift_Events_TransportChangeListener', 37 'Swift_Events_TransportExceptionEvent' => 'Swift_Events_TransportExceptionListener', 38 ); 39 } 40 41 /** 42 * Create a new SendEvent for $source and $message. 43 * 44 * @param Swift_Transport $source 45 * @param Swift_Mime_Message 46 * 47 * @return Swift_Events_SendEvent 48 */ 49 public function createSendEvent(Swift_Transport $source, Swift_Mime_Message $message) 50 { 51 return new Swift_Events_SendEvent($source, $message); 52 } 53 54 /** 55 * Create a new CommandEvent for $source and $command. 56 * 57 * @param Swift_Transport $source 58 * @param string $command That will be executed 59 * @param array $successCodes That are needed 60 * 61 * @return Swift_Events_CommandEvent 62 */ 63 public function createCommandEvent(Swift_Transport $source, $command, $successCodes = array()) 64 { 65 return new Swift_Events_CommandEvent($source, $command, $successCodes); 66 } 67 68 /** 69 * Create a new ResponseEvent for $source and $response. 70 * 71 * @param Swift_Transport $source 72 * @param string $response 73 * @param bool $valid If the response is valid 74 * 75 * @return Swift_Events_ResponseEvent 76 */ 77 public function createResponseEvent(Swift_Transport $source, $response, $valid) 78 { 79 return new Swift_Events_ResponseEvent($source, $response, $valid); 80 } 81 82 /** 83 * Create a new TransportChangeEvent for $source. 84 * 85 * @param Swift_Transport $source 86 * 87 * @return Swift_Events_TransportChangeEvent 88 */ 89 public function createTransportChangeEvent(Swift_Transport $source) 90 { 91 return new Swift_Events_TransportChangeEvent($source); 92 } 93 94 /** 95 * Create a new TransportExceptionEvent for $source. 96 * 97 * @param Swift_Transport $source 98 * @param Swift_TransportException $ex 99 * 100 * @return Swift_Events_TransportExceptionEvent 101 */ 102 public function createTransportExceptionEvent(Swift_Transport $source, Swift_TransportException $ex) 103 { 104 return new Swift_Events_TransportExceptionEvent($source, $ex); 105 } 106 107 /** 108 * Bind an event listener to this dispatcher. 109 * 110 * @param Swift_Events_EventListener $listener 111 */ 112 public function bindEventListener(Swift_Events_EventListener $listener) 113 { 114 foreach ($this->_listeners as $l) { 115 // Already loaded 116 if ($l === $listener) { 117 return; 118 } 119 } 120 $this->_listeners[] = $listener; 121 } 122 123 /** 124 * Dispatch the given Event to all suitable listeners. 125 * 126 * @param Swift_Events_EventObject $evt 127 * @param string $target method 128 */ 129 public function dispatchEvent(Swift_Events_EventObject $evt, $target) 130 { 131 $this->_prepareBubbleQueue($evt); 132 $this->_bubble($evt, $target); 133 } 134 135 /** Queue listeners on a stack ready for $evt to be bubbled up it */ 136 private function _prepareBubbleQueue(Swift_Events_EventObject $evt) 137 { 138 $this->_bubbleQueue = array(); 139 $evtClass = get_class($evt); 140 foreach ($this->_listeners as $listener) { 141 if (array_key_exists($evtClass, $this->_eventMap) 142 && ($listener instanceof $this->_eventMap[$evtClass])) { 143 $this->_bubbleQueue[] = $listener; 144 } 145 } 146 } 147 148 /** Bubble $evt up the stack calling $target() on each listener */ 149 private function _bubble(Swift_Events_EventObject $evt, $target) 150 { 151 if (!$evt->bubbleCancelled() && $listener = array_shift($this->_bubbleQueue)) { 152 $listener->$target($evt); 153 $this->_bubble($evt, $target); 154 } 155 } 156} 157