1. sfMailer.class.php
  2. /** * sfMailer is the main entry point for the mailer system. * * This class is instanciated by sfContext on demand. * * @package symfony * @subpackage mailer * @author Fabien Potencier * @version SVN: $Id: sfMailer.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $ */
  3. class sfMailer extends Swift_Mailer
  4. {
  5. const
  6. REALTIME = 'realtime',
  7. SPOOL = 'spool',
  8. SINGLE_ADDRESS = 'single_address',
  9. NONE = 'none';
  10. protected
  11. $spool = null,
  12. $logger = null,
  13. $strategy = 'realtime',
  14. $address = '',
  15. $realtimeTransport = null,
  16. $force = false;
  17. /**
  18. * Constructor.
  19. *
  20. * Available options:
  21. *
  22. * * charset: The default charset to use for messages
  23. * * logging: Whether to enable logging or not
  24. * * delivery_strategy: The delivery strategy to use
  25. * * spool_class: The spool class (for the spool strategy)
  26. * * spool_arguments: The arguments to pass to the spool constructor
  27. * * delivery_address: The email address to use for the single_address strategy
  28. * * transport: The main transport configuration
  29. * * * class: The main transport class
  30. * * * param: The main transport parameters
  31. *
  32. * @param sfEventDispatcher $dispatcher An event dispatcher instance
  33. * @param array $options An array of options
  34. */
  35. public function __construct(sfEventDispatcher $dispatcher, $options)
  36. {
  37. // options
  38. $options = array_merge(array(
  39. 'charset' => 'UTF-8',
  40. 'logging' => false,
  41. 'delivery_strategy' => 'realtime',
  42. 'transport' => array(
  43. 'class' => 'Swift_MailTransport',
  44. 'param' => array(),
  45. ),
  46. ), $options);
  47. $constantName = 'sfMailer::'.strtoupper($options['delivery_strategy']);
  48. $this->strategy = defined($constantName) ? constant($constantName) : false;
  49. if (!$this->strategy)
  50. {
  51. throw new InvalidArgumentException(sprintf('Unknown mail delivery strategy "%s" (should be one of realtime, spool, single_address, or none)', $options['delivery_strategy']));
  52. }
  53. // transport
  54. $class = $options['transport']['class'];
  55. $transport = new $class();
  56. if (isset($options['transport']['param']))
  57. {
  58. foreach ($options['transport']['param'] as $key => $value)
  59. {
  60. $method = 'set'.ucfirst($key);
  61. if (method_exists($transport, $method))
  62. {
  63. $transport->$method($value);
  64. }
  65. elseif (method_exists($transport, 'getExtensionHandlers'))
  66. {
  67. foreach ($transport->getExtensionHandlers() as $handler)
  68. {
  69. if (in_array(strtolower($method), array_map('strtolower', (array) $handler->exposeMixinMethods())))
  70. {
  71. $transport->$method($value);
  72. }
  73. }
  74. }
  75. }
  76. }
  77. $this->realtimeTransport = $transport;
  78. if (sfMailer::SPOOL == $this->strategy)
  79. {
  80. if (!isset($options['spool_class']))
  81. {
  82. throw new InvalidArgumentException('For the spool mail delivery strategy, you must also define a spool_class option');
  83. }
  84. $arguments = isset($options['spool_arguments']) ? $options['spool_arguments'] : array();
  85. if ($arguments)
  86. {
  87. $r = new ReflectionClass($options['spool_class']);
  88. $this->spool = $r->newInstanceArgs($arguments);
  89. }
  90. else
  91. {
  92. $this->spool = new $options['spool_class'];
  93. }
  94. $transport = new Swift_SpoolTransport($this->spool);
  95. }
  96. elseif (sfMailer::SINGLE_ADDRESS == $this->strategy)
  97. {
  98. if (!isset($options['delivery_address']))
  99. {
  100. throw new InvalidArgumentException('For the single_address mail delivery strategy, you must also define a delivery_address option');
  101. }
  102. $this->address = $options['delivery_address'];
  103. $transport->registerPlugin(new Swift_Plugins_RedirectingPlugin($this->address));
  104. }
  105. parent::__construct($transport);
  106. // logger
  107. if ($options['logging'])
  108. {
  109. $this->logger = new sfMailerMessageLoggerPlugin($dispatcher);
  110. $transport->registerPlugin($this->logger);
  111. }
  112. if (sfMailer::NONE == $this->strategy)
  113. {
  114. // must be registered after logging
  115. $transport->registerPlugin(new Swift_Plugins_BlackholePlugin());
  116. }
  117. // preferences
  118. Swift_Preferences::getInstance()->setCharset($options['charset']);
  119. $dispatcher->notify(new sfEvent($this, 'mailer.configure'));
  120. }
  121. /**
  122. * Gets the realtime transport instance.
  123. *
  124. * @return Swift_Transport The realtime transport instance.
  125. */
  126. public function getRealtimeTransport()
  127. {
  128. return $this->realtimeTransport;
  129. }
  130. /**
  131. * Sets the realtime transport instance.
  132. *
  133. * @param Swift_Transport $transport The realtime transport instance.
  134. */
  135. public function setRealtimeTransport(Swift_Transport $transport)
  136. {
  137. $this->realtimeTransport = $transport;
  138. }
  139. /**
  140. * Gets the logger instance.
  141. *
  142. * @return sfMailerMessageLoggerPlugin The logger instance.
  143. */
  144. public function getLogger()
  145. {
  146. return $this->logger;
  147. }
  148. /**
  149. * Sets the logger instance.
  150. *
  151. * @param sfMailerMessageLoggerPlugin $logger The logger instance.
  152. */
  153. public function setLogger($logger)
  154. {
  155. $this->logger = $logger;
  156. }
  157. /**
  158. * Gets the delivery strategy.
  159. *
  160. * @return string The delivery strategy
  161. */
  162. public function getDeliveryStrategy()
  163. {
  164. return $this->strategy;
  165. }
  166. /**
  167. * Gets the delivery address.
  168. *
  169. * @return string The delivery address
  170. */
  171. public function getDeliveryAddress()
  172. {
  173. return $this->address;
  174. }
  175. /**
  176. * Sets the delivery address.
  177. *
  178. * @param string $address The delivery address
  179. */
  180. public function setDeliveryAddress($address)
  181. {
  182. $this->address = $address;
  183. }
  184. /**
  185. * Creates a new message.
  186. *
  187. * @param string|array $from The from address
  188. * @param string|array $to The recipient(s)
  189. * @param string $subject The subject
  190. * @param string $body The body
  191. *
  192. * @return Swift_Message A Swift_Message instance
  193. */
  194. public function compose($from = null, $to = null, $subject = null, $body = null)
  195. {
  196. return Swift_Message::newInstance()
  197. ->setFrom($from)
  198. ->setTo($to)
  199. ->setSubject($subject)
  200. ->setBody($body)
  201. ;
  202. }
  203. /**
  204. * Sends a message.
  205. *
  206. * @param string|array $from The from address
  207. * @param string|array $to The recipient(s)
  208. * @param string $subject The subject
  209. * @param string $body The body
  210. *
  211. * @return int The number of sent emails
  212. */
  213. public function composeAndSend($from, $to, $subject, $body)
  214. {
  215. return $this->send($this->compose($from, $to, $subject, $body));
  216. }
  217. /**
  218. * Forces the next call to send() to use the realtime strategy.
  219. *
  220. * @return sfMailer The current sfMailer instance
  221. */
  222. public function sendNextImmediately()
  223. {
  224. $this->force = true;
  225. return $this;
  226. }
  227. /**
  228. * Sends the given message.
  229. *
  230. * @param Swift_Transport $transport A transport instance
  231. * @param string[] &$failedRecipients An array of failures by-reference
  232. *
  233. * @return int|false The number of sent emails
  234. */
  235. public function send(Swift_Mime_Message $message, &$failedRecipients = null)
  236. {
  237. if ($this->force)
  238. {
  239. $this->force = false;
  240. if (!$this->realtimeTransport->isStarted())
  241. {
  242. $this->realtimeTransport->start();
  243. }
  244. return $this->realtimeTransport->send($message, $failedRecipients);
  245. }
  246. return parent::send($message, $failedRecipients);
  247. }
  248. /**
  249. * Sends the current messages in the spool.
  250. *
  251. * The return value is the number of recipients who were accepted for delivery.
  252. *
  253. * @param string[] &$failedRecipients An array of failures by-reference
  254. *
  255. * @return int The number of sent emails
  256. */
  257. public function flushQueue(&$failedRecipients = null)
  258. {
  259. return $this->getSpool()->flushQueue($this->realtimeTransport, $failedRecipients);
  260. }
  261. public function getSpool()
  262. {
  263. if (self::SPOOL != $this->strategy)
  264. {
  265. throw new LogicException(sprintf('You can only send messages in the spool if the delivery strategy is "spool" (%s is the current strategy).', $this->strategy));
  266. }
  267. return $this->spool;
  268. }
  269. static public function initialize()
  270. {
  271. require_once sfConfig::get('sf_symfony_lib_dir').'/vendor/swiftmailer/swift_init.php';
  272. }
  273. }

Debug toolbar