MailTransport.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * Sends Messages using the mail() function.
  11. *
  12. * It is advised that users do not use this transport if at all possible
  13. * since a number of plugin features cannot be used in conjunction with this
  14. * transport due to the internal interface in PHP itself.
  15. *
  16. * The level of error reporting with this transport is incredibly weak, again
  17. * due to limitations of PHP's internal mail() function. You'll get an
  18. * all-or-nothing result from sending.
  19. *
  20. * @author Chris Corbyn
  21. */
  22. class Swift_Transport_MailTransport implements Swift_Transport
  23. {
  24. /** Additional parameters to pass to mail() */
  25. private $_extraParams = '-f%s';
  26. /** The event dispatcher from the plugin API */
  27. private $_eventDispatcher;
  28. /** An invoker that calls the mail() function */
  29. private $_invoker;
  30. /**
  31. * Create a new MailTransport with the $log.
  32. *
  33. * @param Swift_Transport_MailInvoker $invoker
  34. * @param Swift_Events_EventDispatcher $eventDispatcher
  35. */
  36. public function __construct(Swift_Transport_MailInvoker $invoker, Swift_Events_EventDispatcher $eventDispatcher)
  37. {
  38. $this->_invoker = $invoker;
  39. $this->_eventDispatcher = $eventDispatcher;
  40. }
  41. /**
  42. * Not used.
  43. */
  44. public function isStarted()
  45. {
  46. return false;
  47. }
  48. /**
  49. * Not used.
  50. */
  51. public function start()
  52. {
  53. }
  54. /**
  55. * Not used.
  56. */
  57. public function stop()
  58. {
  59. }
  60. /**
  61. * Set the additional parameters used on the mail() function.
  62. *
  63. * This string is formatted for sprintf() where %s is the sender address.
  64. *
  65. * @param string $params
  66. *
  67. * @return Swift_Transport_MailTransport
  68. */
  69. public function setExtraParams($params)
  70. {
  71. $this->_extraParams = $params;
  72. return $this;
  73. }
  74. /**
  75. * Get the additional parameters used on the mail() function.
  76. *
  77. * This string is formatted for sprintf() where %s is the sender address.
  78. *
  79. * @return string
  80. */
  81. public function getExtraParams()
  82. {
  83. return $this->_extraParams;
  84. }
  85. /**
  86. * Send the given Message.
  87. *
  88. * Recipient/sender data will be retrieved from the Message API.
  89. * The return value is the number of recipients who were accepted for delivery.
  90. *
  91. * @param Swift_Mime_Message $message
  92. * @param string[] $failedRecipients An array of failures by-reference
  93. *
  94. * @return int
  95. */
  96. public function send(Swift_Mime_Message $message, &$failedRecipients = null)
  97. {
  98. $failedRecipients = (array) $failedRecipients;
  99. if ($evt = $this->_eventDispatcher->createSendEvent($this, $message)) {
  100. $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed');
  101. if ($evt->bubbleCancelled()) {
  102. return 0;
  103. }
  104. }
  105. $count = (
  106. count((array) $message->getTo())
  107. + count((array) $message->getCc())
  108. + count((array) $message->getBcc())
  109. );
  110. $toHeader = $message->getHeaders()->get('To');
  111. $subjectHeader = $message->getHeaders()->get('Subject');
  112. if (!$toHeader) {
  113. throw new Swift_TransportException(
  114. 'Cannot send message without a recipient'
  115. );
  116. }
  117. $to = $toHeader->getFieldBody();
  118. $subject = $subjectHeader ? $subjectHeader->getFieldBody() : '';
  119. $reversePath = $this->_getReversePath($message);
  120. // Remove headers that would otherwise be duplicated
  121. $message->getHeaders()->remove('To');
  122. $message->getHeaders()->remove('Subject');
  123. $messageStr = $message->toString();
  124. $message->getHeaders()->set($toHeader);
  125. $message->getHeaders()->set($subjectHeader);
  126. // Separate headers from body
  127. if (false !== $endHeaders = strpos($messageStr, "\r\n\r\n")) {
  128. $headers = substr($messageStr, 0, $endHeaders) . "\r\n"; //Keep last EOL
  129. $body = substr($messageStr, $endHeaders + 4);
  130. } else {
  131. $headers = $messageStr . "\r\n";
  132. $body = '';
  133. }
  134. unset($messageStr);
  135. if ("\r\n" != PHP_EOL) {
  136. // Non-windows (not using SMTP)
  137. $headers = str_replace("\r\n", PHP_EOL, $headers);
  138. $body = str_replace("\r\n", PHP_EOL, $body);
  139. } else {
  140. // Windows, using SMTP
  141. $headers = str_replace("\r\n.", "\r\n..", $headers);
  142. $body = str_replace("\r\n.", "\r\n..", $body);
  143. }
  144. if ($this->_invoker->mail($to, $subject, $body, $headers,
  145. sprintf($this->_extraParams, $reversePath)))
  146. {
  147. if ($evt) {
  148. $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS);
  149. $evt->setFailedRecipients($failedRecipients);
  150. $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
  151. }
  152. } else {
  153. $failedRecipients = array_merge(
  154. $failedRecipients,
  155. array_keys((array) $message->getTo()),
  156. array_keys((array) $message->getCc()),
  157. array_keys((array) $message->getBcc())
  158. );
  159. if ($evt) {
  160. $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED);
  161. $evt->setFailedRecipients($failedRecipients);
  162. $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
  163. }
  164. $message->generateId();
  165. $count = 0;
  166. }
  167. return $count;
  168. }
  169. /**
  170. * Register a plugin.
  171. *
  172. * @param Swift_Events_EventListener $plugin
  173. */
  174. public function registerPlugin(Swift_Events_EventListener $plugin)
  175. {
  176. $this->_eventDispatcher->bindEventListener($plugin);
  177. }
  178. /** Determine the best-use reverse path for this message */
  179. private function _getReversePath(Swift_Mime_Message $message)
  180. {
  181. $return = $message->getReturnPath();
  182. $sender = $message->getSender();
  183. $from = $message->getFrom();
  184. $path = null;
  185. if (!empty($return)) {
  186. $path = $return;
  187. } elseif (!empty($sender)) {
  188. $keys = array_keys($sender);
  189. $path = array_shift($keys);
  190. } elseif (!empty($from)) {
  191. $keys = array_keys($from);
  192. $path = array_shift($keys);
  193. }
  194. return $path;
  195. }
  196. }