TYPO3 CMS  TYPO3_6-2
SwiftMailerAdapter.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Core\Mail;
3 
24 
28  protected $mailer;
29 
33  protected $message;
34 
38  protected $messageHeaders;
39 
43  protected $boundary = '';
44 
50  public function __construct() {
51  // create mailer object
52  $this->mailer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\Mailer');
53  // create message object
54  $this->message = \Swift_Message::newInstance();
55  }
56 
69  public function mail($to, $subject, $messageBody, $additionalHeaders = NULL, $additionalParameters = NULL, $fakeSending = FALSE) {
70  // report success for fake sending
71  if ($fakeSending === TRUE) {
72  return TRUE;
73  }
74  $this->message->setSubject($subject);
75  // handle recipients
76  $toAddresses = $this->parseAddresses($to);
77  $this->message->setTo($toAddresses);
78  // handle additional headers
79  $headers = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(LF, $additionalHeaders, TRUE);
80  $this->messageHeaders = $this->message->getHeaders();
81  foreach ($headers as $header) {
82  list($headerName, $headerValue) = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(':', $header, FALSE, 2);
83  $this->setHeader($headerName, $headerValue);
84  }
85  // handle additional parameters (force return path)
86  if (preg_match('/-f\\s*(\\S*?)/', $additionalParameters, $matches)) {
87  $this->message->setReturnPath($this->unescapeShellArguments($matches[1]));
88  }
89  // handle from:
90  $this->fixSender();
91  // handle message body
92  $this->setBody($messageBody);
93  // send mail
94  $result = $this->mailer->send($this->message);
95  // report success/failure
96  return (bool) $result;
97  }
98 
105  protected function unescapeShellArguments($escapedString) {
106  if (TYPO3_OS === 'WIN') {
107  // on Windows double quotes are used and % signs are replaced by spaces
108  if (preg_match('/^"([^"]*)"$/', trim($escapedString), $matches)) {
109  $result = str_replace('\\"', '"', $matches[1]);
110  }
111  } else {
112  // on Unix-like systems single quotes are escaped
113  if (preg_match('/^\'([^' . preg_quote('\'') . ']*)\'$/', trim($escapedString), $matches)) {
114  $result = str_replace('\\\'', '\'', $matches[1]);
115  }
116  }
117  return $result;
118  }
119 
127  protected function setHeader($headerName, $headerValue) {
128  // check for boundary in headers
129  if (preg_match('/^boundary="(.*)"$/', $headerName, $matches) > 0) {
130  $this->boundary = $matches[1];
131  return;
132  }
133 
134  // Ignore empty header-values (like from an 'Reply-To:' without an email-address)
135  $headerValue = trim($headerValue);
136  if (empty($headerValue)) {
137  return;
138  }
139 
140  // process other, real headers
141  if ($this->messageHeaders->has($headerName)) {
142  $header = $this->messageHeaders->get($headerName);
143  $headerType = $header->getFieldType();
144  switch ($headerType) {
145  case \Swift_Mime_Header::TYPE_TEXT:
146  $header->setValue($headerValue);
147  break;
148  case \Swift_Mime_Header::TYPE_PARAMETERIZED:
149  $header->setValue(rtrim($headerValue, ';'));
150  break;
151  case \Swift_Mime_Header::TYPE_MAILBOX:
152  $addressList = $this->parseAddresses($headerValue);
153  if (count($addressList) > 0) {
154  $header->setNameAddresses($addressList);
155  }
156  break;
157  case \Swift_Mime_Header::TYPE_DATE:
158  $header->setTimeStamp(strtotime($headerValue));
159  break;
160  case \Swift_Mime_Header::TYPE_ID:
161  // remove '<' and '>' from ID headers
162  $header->setId(trim($headerValue, '<>'));
163  break;
164  case \Swift_Mime_Header::TYPE_PATH:
165  $header->setAddress($headerValue);
166  break;
167  }
168  } else {
169  switch ($headerName) {
170  case 'From':
171  case 'To':
172  case 'Cc':
173  case 'Bcc':
174  case 'Reply-To':
175  case 'Sender':
176  $addressList = $this->parseAddresses($headerValue);
177  if (count($addressList) > 0) {
178  $this->messageHeaders->addMailboxHeader($headerName, $addressList);
179  }
180  break;
181  case 'Date':
182  $this->messageHeaders->addDateHeader($headerName, strtotime($headerValue));
183  break;
184  case 'Message-ID':
185  // remove '<' and '>' from ID headers
186  $this->messageHeaders->addIdHeader($headerName, trim($headerValue, '<>'));
187  case 'Return-Path':
188  $this->messageHeaders->addPathHeader($headerName, $headerValue);
189  break;
190  case 'Content-Type':
191  case 'Content-Disposition':
192  $this->messageHeaders->addParameterizedHeader($headerName, rtrim($headerValue, ';'));
193  break;
194  default:
195  $this->messageHeaders->addTextheader($headerName, $headerValue);
196  }
197  }
198  }
199 
207  protected function setBody($body) {
208  if ($this->boundary) {
209  // handle multi-part
210  $bodyParts = preg_split('/--' . preg_quote($this->boundary, '/') . '(--)?/m', $body, NULL, PREG_SPLIT_NO_EMPTY);
211  foreach ($bodyParts as $bodyPart) {
212  // skip empty parts
213  if (trim($bodyPart) == '') {
214  continue;
215  }
216  // keep leading white space when exploding the text
217  $lines = explode(LF, $bodyPart);
218  // set defaults for this part
219  $encoding = '';
220  $charset = 'utf-8';
221  $contentType = 'text/plain';
222  // skip intro messages
223  if (trim($lines[0]) == 'This is a multi-part message in MIME format.') {
224  continue;
225  }
226  // first line is empty leftover from splitting
227  array_shift($lines);
228  while (count($lines) > 0) {
229  $line = array_shift($lines);
230  if (preg_match('/^content-type:(.*);( charset=(.*))?$/i', $line, $matches)) {
231  $contentType = trim($matches[1]);
232  if ($matches[2]) {
233  $charset = trim($matches[3]);
234  }
235  } elseif (preg_match('/^content-transfer-encoding:(.*)$/i', $line, $matches)) {
236  $encoding = trim($matches[1]);
237  } elseif (strlen(trim($line)) == 0) {
238  // empty line before actual content of this part
239  break;
240  }
241  }
242  // use rest of part as body, but reverse encoding first
243  $bodyPart = $this->decode(implode(LF, $lines), $encoding);
244  $this->message->addPart($bodyPart, $contentType, $charset);
245  }
246  } else {
247  // Handle single body
248  // The headers have already been set, so use header information
249  $contentType = $this->message->getContentType();
250  $charset = $this->message->getCharset();
251  $encoding = $this->message->getEncoder()->getName();
252  // reverse encoding and set body
253  $rawBody = $this->decode($body, $encoding);
254  $this->message->setBody($rawBody, $contentType, $charset);
255  }
256  }
257 
265  protected function decode($text, $encoding) {
266  $result = $text;
267  switch ($encoding) {
268  case 'quoted-printable':
269  $result = quoted_printable_decode($text);
270  break;
271  case 'base64':
272  $result = base64_decode($text);
273  break;
274  }
275  return $result;
276  }
277 
289  protected function parseAddresses($rawAddresses = '') {
291  $addressParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\Rfc822AddressesParser', $rawAddresses);
292  $addresses = $addressParser->parseAddressList();
293  $addressList = array();
294  foreach ($addresses as $address) {
295  if ($address->personal) {
296  // item with name found ( name <email@example.org> )
297  $addressList[$address->mailbox . '@' . $address->host] = $address->personal;
298  } else {
299  // item without name found ( email@example.org )
300  $addressList[] = $address->mailbox . '@' . $address->host;
301  }
302  }
303  return $addressList;
304  }
305 
314  protected function fixSender() {
315  $from = $this->message->getFrom();
316  if (count($from) > 0) {
317  reset($from);
318  list($fromAddress, $fromName) = each($from);
319  } else {
320  $fromAddress = $this->message->getReturnPath();
321  $fromName = $fromAddress;
322  }
323  if (strlen($fromAddress) == 0) {
324  $fromAddress = 'no-reply@example.org';
325  $fromName = 'TYPO3 CMS';
326  }
327  $this->message->setFrom(array($fromAddress => $fromName));
328  }
329 
330 }
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren&#39;t numeric.
mail($to, $subject, $messageBody, $additionalHeaders=NULL, $additionalParameters=NULL, $fakeSending=FALSE)