Added feature #15998: Create a new API to send mails based on SwiftMailer to replace...
[Packages/TYPO3.CMS.git] / typo3 / contrib / swiftmailer / classes / Swift / Transport / MailTransport.php
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 //@require 'Swift/Transport.php';
12 //@require 'Swift/Transport/MailInvoker.php';
13 //@require 'Swift/Mime/Message.php';
14 //@require 'Swift/Events/EventListener.php';
15
16 /**
17 * Sends Messages using the mail() function.
18 *
19 * It is advised that users do not use this transport if at all possible
20 * since a number of plugin features cannot be used in conjunction with this
21 * transport due to the internal interface in PHP itself.
22 *
23 * The level of error reporting with this transport is incredibly weak, again
24 * due to limitations of PHP's internal mail() function. You'll get an
25 * all-or-nothing result from sending.
26 *
27 * @package Swift
28 * @subpackage Transport
29 * @author Chris Corbyn
30 */
31 class Swift_Transport_MailTransport implements Swift_Transport
32 {
33
34 /** Addtional parameters to pass to mail() */
35 private $_extraParams = '-f%s';
36
37 /** The event dispatcher from the plugin API */
38 private $_eventDispatcher;
39
40 /** An invoker that calls the mail() function */
41 private $_invoker;
42
43 /**
44 * Create a new MailTransport with the $log.
45 * @param Swift_Transport_Log $log
46 */
47 public function __construct(Swift_Transport_MailInvoker $invoker,
48 Swift_Events_EventDispatcher $eventDispatcher)
49 {
50 $this->_invoker = $invoker;
51 $this->_eventDispatcher = $eventDispatcher;
52 }
53
54 /**
55 * Not used.
56 */
57 public function isStarted()
58 {
59 return false;
60 }
61
62 /**
63 * Not used.
64 */
65 public function start()
66 {
67 }
68
69 /**
70 * Not used.
71 */
72 public function stop()
73 {
74 }
75
76 /**
77 * Set the additional parameters used on the mail() function.
78 *
79 * This string is formatted for sprintf() where %s is the sender address.
80 *
81 * @param string $params
82 */
83 public function setExtraParams($params)
84 {
85 $this->_extraParams = $params;
86 return $this;
87 }
88
89 /**
90 * Get the additional parameters used on the mail() function.
91 *
92 * This string is formatted for sprintf() where %s is the sender address.
93 *
94 * @return string
95 */
96 public function getExtraParams()
97 {
98 return $this->_extraParams;
99 }
100
101 /**
102 * Send the given Message.
103 *
104 * Recipient/sender data will be retreived from the Message API.
105 * The return value is the number of recipients who were accepted for delivery.
106 *
107 * @param Swift_Mime_Message $message
108 * @param string[] &$failedRecipients to collect failures by-reference
109 * @return int
110 */
111 public function send(Swift_Mime_Message $message, &$failedRecipients = null)
112 {
113 $failedRecipients = (array) $failedRecipients;
114
115 if ($evt = $this->_eventDispatcher->createSendEvent($this, $message))
116 {
117 $this->_eventDispatcher->dispatchEvent($evt, 'beforeSendPerformed');
118 if ($evt->bubbleCancelled())
119 {
120 return 0;
121 }
122 }
123
124 $count = (
125 count((array) $message->getTo())
126 + count((array) $message->getCc())
127 + count((array) $message->getBcc())
128 );
129
130 $toHeader = $message->getHeaders()->get('To');
131 $subjectHeader = $message->getHeaders()->get('Subject');
132
133 $to = $toHeader->getFieldBody();
134 $subject = $subjectHeader->getFieldBody();
135
136 $reversePath = $this->_getReversePath($message);
137
138 //Remove headers that would otherwise be duplicated
139 $message->getHeaders()->remove('To');
140 $message->getHeaders()->remove('Subject');
141
142 $messageStr = $message->toString();
143
144 $message->getHeaders()->set($toHeader);
145 $message->getHeaders()->set($subjectHeader);
146
147 //Separate headers from body
148 if (false !== $endHeaders = strpos($messageStr, "\r\n\r\n"))
149 {
150 $headers = substr($messageStr, 0, $endHeaders) . "\r\n"; //Keep last EOL
151 $body = substr($messageStr, $endHeaders + 4);
152 }
153 else
154 {
155 $headers = $messageStr . "\r\n";
156 $body = '';
157 }
158
159 unset($messageStr);
160
161 if ("\r\n" != PHP_EOL) //Non-windows (not using SMTP)
162 {
163 $headers = str_replace("\r\n", PHP_EOL, $headers);
164 $body = str_replace("\r\n", PHP_EOL, $body);
165 }
166 else //Windows, using SMTP
167 {
168 $headers = str_replace("\r\n.", "\r\n..", $headers);
169 $body = str_replace("\r\n.", "\r\n..", $body);
170 }
171
172 if ($this->_invoker->mail($to, $subject, $body, $headers,
173 sprintf($this->_extraParams, $reversePath)))
174 {
175 if ($evt)
176 {
177 $evt->setResult(Swift_Events_SendEvent::RESULT_SUCCESS);
178 $evt->setFailedRecipients($failedRecipients);
179 $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
180 }
181 }
182 else
183 {
184 $failedRecipients = array_merge(
185 $failedRecipients,
186 array_keys((array) $message->getTo()),
187 array_keys((array) $message->getCc()),
188 array_keys((array) $message->getBcc())
189 );
190
191 if ($evt)
192 {
193 $evt->setResult(Swift_Events_SendEvent::RESULT_FAILED);
194 $evt->setFailedRecipients($failedRecipients);
195 $this->_eventDispatcher->dispatchEvent($evt, 'sendPerformed');
196 }
197
198 $message->generateId();
199
200 $count = 0;
201 }
202
203 return $count;
204 }
205
206 /**
207 * Register a plugin.
208 *
209 * @param Swift_Events_EventListener $plugin
210 */
211 public function registerPlugin(Swift_Events_EventListener $plugin)
212 {
213 $this->_eventDispatcher->bindEventListener($plugin);
214 }
215
216 // -- Private methods
217
218 /** Determine the best-use reverse path for this message */
219 private function _getReversePath(Swift_Mime_Message $message)
220 {
221 $return = $message->getReturnPath();
222 $sender = $message->getSender();
223 $from = $message->getFrom();
224 $path = null;
225 if (!empty($return))
226 {
227 $path = $return;
228 }
229 elseif (!empty($sender))
230 {
231 $keys = array_keys($sender);
232 $path = array_shift($keys);
233 }
234 elseif (!empty($from))
235 {
236 $keys = array_keys($from);
237 $path = array_shift($keys);
238 }
239 return $path;
240 }
241
242 }