Project

General

Profile

Bug #24471 ยป 16911.patch

Administrator Admin, 2011-01-04 14:48

View differences:

t3lib/config_default.php (working copy)
$TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionalErrors'] = $TYPO3_CONF_VARS['SYS']['exceptionalErrors'];
// Mail sending via Swift Mailer
$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'][] = 'tx_t3lib_mail_hooks->sendMail';
$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'][] = 't3lib_mail_SwiftMailerAdapter';
// Turn error logging on/off.
if (($displayErrors = intval($TYPO3_CONF_VARS['SYS']['displayErrors'])) != '-1') {
t3lib/core_autoload.php (working copy)
't3lib_formprotection_backendformprotection' => PATH_t3lib . 'formprotection/class.t3lib_formprotection_backendformprotection.php',
't3lib_formprotection_installtoolformprotection' => PATH_t3lib . 'formprotection/class.t3lib_formprotection_installtoolformprotection.php',
't3lib_localrecordlistgettablehook' => PATH_t3lib . 'interfaces/interface.t3lib_localrecordlistgettablehook.php',
't3lib_mail_maileradapter' => PATH_t3lib . 'interfaces/interface.t3lib_mail_maileradapter.php',
't3lib_pageselect_getpagehook' => PATH_t3lib . 'interfaces/interface.t3lib_pageselect_getpagehook.php',
't3lib_pageselect_getrecordoverlayhook' => PATH_t3lib . 'interfaces/interface.t3lib_pageselect_getrecordoverlayhook.php',
't3lib_pageselect_getpageoverlayhook' => PATH_t3lib . 'interfaces/interface.t3lib_pageselect_getpageoverlayhook.php',
......
't3lib_mail_mboxtransport' => PATH_t3lib . 'mail/class.t3lib_mail_mboxtransport.php',
't3lib_mail_message' => PATH_t3lib . 'mail/class.t3lib_mail_message.php',
't3lib_mail_mailer' => PATH_t3lib . 'mail/class.t3lib_mail_mailer.php',
'tx_t3lib_mail_hooks' => PATH_t3lib . 'mail/class.tx_t3lib_mail_hooks.php',
't3lib_mail_swiftmaileradapter' => PATH_t3lib . 'mail/class.t3lib_mail_swiftmaileradapter.php',
't3lib_matchcondition_abstract' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_abstract.php',
't3lib_matchcondition_backend' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_backend.php',
't3lib_matchcondition_frontend' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_frontend.php',
t3lib/interfaces/interface.t3lib_mail_maileradapter.php (revision 0)
<?php
/***************************************************************
* Copyright notice
*
* (c) 2011 Ingo Renner <ingo@typo3.org>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Mailer Adapter interface
*
* @author Ingo Renner <ingo@typo3.org>
* @package TYPO3
* @subpackage t3lib
*/
interface t3lib_mail_MailerAdapter {
/**
* Mail sending function
*
* @param string $to Mail recipient.
* @param string $subject Mail subject.
* @param string $messageBody Mail body.
* @param array $additionalHeaders Additional mail headers.
* @param array $additionalParameters Additional mailer parameters.
* @param boolean $fakeSending Whether to fake sending or not, used in Unit Tests.
* @return boolean TRUE if the mail was successfully sent, FALSE otherwise.
*/
public function mail($to, $subject, $messageBody, $additionalHeaders = NULL, $additionalParameters = NULL, $fakeSending = FALSE);
}
?>
t3lib/mail/class.t3lib_mail_swiftmaileradapter.php (working copy)
<?php
/***************************************************************
* Copyright notice
*
* (c) 2010 Jigal van Hemert <jigal@xs4all.nl>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Hook subscriber for using Swift Mailer with the t3lib_utility_mail function
*
* $Id$
*
* @author Jigal van Hemert <jigal@xs4all.nl>
* @package TYPO3
* @subpackage t3lib
*/
class tx_t3lib_mail_hooks {
/** @var $mailerObject t3lib_mail_Mailer */
protected $mailerObject;
/** @var $messageObject Swift_Message */
protected $messageObject;
/** @var $messageHeaders Swift_Mime_HeaderSet */
protected $messageHeaders;
/**
* @param array $parameters Array with keys: 'to', 'subject', 'messageBody', 'additionalHeaders', 'additionalParameters'
* @param bool $fakeSending If set fake sending a mail
* @throws t3lib_exception
* @return bool
*/
public function sendMail(array $parameters = array(), $fakeSending = FALSE) {
// report success for fake sending
if ($fakeSending === TRUE) {
return TRUE;
}
// create mailer object
$this->mailerObject = t3lib_div::makeInstance('t3lib_mail_Mailer');
// create message object
$this->messageObject = Swift_Message::newInstance($parameters['subject'], $parameters['messageBody']);
$this->messageObject->setTo($parameters['to']);
// handle additional headers
$headers = t3lib_div::trimExplode(LF, $parameters['additionalHeaders'], TRUE);
$this->messageHeaders = $this->messageObject->getHeaders();
foreach ($headers as $header) {
list($headerName, $headerValue) = t3lib_div::trimExplode(':', $header, FALSE, 2);
$this->setHeader($headerName, $headerValue);
}
// handle additional parameters (force return path)
if (preg_match('/-f\s*(\S*?)/', $parameters['additionalParameters'], $matches)) {
$this->messageObject->setReturnPath($this->unEscapeShellArg($matches[1]));
}
// handle from:
$from = $this->messageObject->getFrom();
if (count($from) > 0) {
reset($from);
list($fromAddress, $fromName) = each($from);
} else {
$fromAddress = $this->messageObject->getReturnPath();
$fromName = $fromAddress;
}
if (strlen($fromAddress) == 0) {
$fromAddress = 'no-reply@example.org';
$fromName = 'TYPO3 Installation';
}
$this->messageObject->setFrom(array($fromAddress => $fromName));
// send mail
$result = $this->mailerObject->send($this->messageObject);
// report success/failure
return (bool) $result;
}
/**
* Tries to undo the action by escapeshellarg()
*
* @param $escapedString String escaped by escapeshellarg()
* @return string String with escapeshellarg() action undone as best as possible
*/
protected function unEscapeShellArg($escapedString) {
if (TYPO3_OS === 'WIN') {
// on Windows double quotes are used and % signs are replaced by spaces
if (preg_match('/^"([^"]*)"$/', trim($escapedString), $matches)) {
$result = str_replace('\"', '"', $matches[1]);
// % signs are replaced with spaces, so they can't be recovered
}
} else {
// on Unix-like systems single quotes are escaped
if (preg_match('/^\'([^' . preg_quote('\'') . ']*)\'$/', trim($escapedString), $matches)) {
$result = str_replace('\\\'', '\'', $matches[1]);
}
}
return $result;
}
/**
* Handles setting and replacing of mail headers
*
* @param $headerName Name of header
* @param $headerValue Value of header
* @return void
*/
protected function setHeader($headerName, $headerValue) {
if ($this->messageHeaders->has($headerName)) {
$header = $this->messageHeaders->get($headerName);
$headerType = $header->getFieldType();
switch ($headerType) {
case Swift_Mime_Header::TYPE_TEXT:
$header->setValue($headerValue);
break;
case Swift_Mime_Header::TYPE_PARAMETERIZED:
$header->setValue($headerValue);
break;
case Swift_Mime_Header::TYPE_MAILBOX:
// mailbox headers look like:
// name <email@example.org>, othermail@example.org, ...
// pattern matches cases with and without name
// comma is added to match each item in a comma separated list
preg_match_all('/,\s*([^<]+)(<([^>]*?)>)?/', ', ' . $headerValue, $addresses, PREG_SET_ORDER);
$addressList = array();
foreach ($addresses as $address) {
if (!$address[2]) {
// item with name found ( name <email@example.org> )
if (t3lib_div::validEmail($address[1])) {
$addressList[] = $address[1];
}
} else {
// item without name found ( email@example.org )
if (t3lib_div::validEmail($address[3])) {
$addressList[$address[3]] = $address[1];
}
}
}
if (count($addressList) > 0) {
$header->setNameAddresses($addressList);
}
break;
case Swift_Mime_Header::TYPE_DATE:
$header->setTimeStamp(strtotime($headerValue));
break;
case Swift_Mime_Header::TYPE_ID:
// remove '<' and '>' from ID headers
$header->setId(trim($headerValue, '<>'));
break;
case Swift_Mime_Header::TYPE_PATH:
$header->setAddress($headerValue);
break;
}
// change value
} else {
switch ($headerName) {
// mailbox headers
case 'From':
case 'To':
case 'Cc':
case 'Bcc':
case 'Reply-To':
case 'Sender':
// mailbox headers look like:
// name <email@example.org>, othermail@example.org, ...
// pattern matches cases with and without name
// comma is added to match each item in a comma separated list
preg_match_all('/,\s*(.*?)(<([^>]*?)>)?/', ', ' . $headerValue, $addresses, PREG_SET_ORDER);
$addressList = array();
foreach ($addresses as $address) {
if ($address[2]) {
// item with name found ( name <email@example.org> )
if (t3lib_div::validEmail($address[1])) {
$addressList[] = $address[1];
}
} else {
// item without name found ( email@example.org )
if (t3lib_div::validEmail($address[3])) {
$addressList[$address[3]] = $address[1];
}
}
}
if (count($addressList) > 0) {
$header->addMailboxHeader($headerName, $addressList);
}
break;
// date headers
case 'Date':
$this->messageHeaders->addDateHeader($headerName, strtotime($headerValue));
break;
// ID headers
case 'Message-ID':
// remove '<' and '>' from ID headers
$this->messageHeaders->addIdHeader($headerName, trim($headerValue, '<>'));
// path headers
case 'Return-Path':
$this->messageHeaders->addPathHeader($headerName, $headerValue);
break;
// parameterized headers
case 'Content-Type':
case 'Content-Disposition':
$this->messageHeaders->addParameterizedHeader($headerName, $headerValue);
break;
// text headers
default:
$this->messageHeaders->addTextheader($headerName, $headerValue);
break;
}
}
}
}
<?php
/***************************************************************
* Copyright notice
*
* (c) 2010 Jigal van Hemert <jigal@xs4all.nl>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Hook subscriber for using Swift Mailer with the t3lib_utility_mail function
*
* $Id$
*
* @author Jigal van Hemert <jigal@xs4all.nl>
* @package TYPO3
* @subpackage t3lib
*/
class t3lib_mail_SwiftMailerAdapter implements t3lib_mail_MailerAdapter {
/** @var $mailer t3lib_mail_Mailer */
protected $mailer;
/** @var $message Swift_Message */
protected $message;
/** @var $messageHeaders Swift_Mime_HeaderSet */
protected $messageHeaders;
/** @var string */
protected $boundary = '';
/**
* Constructor
*
* @return void
*/
public function __construct() {
// create mailer object
$this->mailer = t3lib_div::makeInstance('t3lib_mail_Mailer');
// create message object
$this->message = Swift_Message::newInstance();
}
/**
* Parses parts of the mail message and sends it with the Swift Mailer functions
*
* @param string $to Email address to send the message to
* @param string $subject Subject of mail message
* @param string $messageBody Raw body (may be multipart)
* @param array $additionalHeaders Additional mail headers
* @param array $additionalParameters Extra parameters for the mail() command
* @param bool $fakeSending If set fake sending a mail
* @throws t3lib_exception
* @return bool
*/
public function mail($to, $subject, $messageBody, $additionalHeaders = NULL, $additionalParameters = NULL, $fakeSending = FALSE) {
// report success for fake sending
if ($fakeSending === TRUE) {
return TRUE;
}
$this->message->setSubject($subject);
$this->message->setTo($to);
// handle additional headers
$headers = t3lib_div::trimExplode(LF, $additionalHeaders, TRUE);
$this->messageHeaders = $this->message->getHeaders();
foreach ($headers as $header) {
list($headerName, $headerValue) = t3lib_div::trimExplode(':', $header, FALSE, 2);
$this->setHeader($headerName, $headerValue);
}
// handle additional parameters (force return path)
if (preg_match('/-f\s*(\S*?)/', $additionalParameters, $matches)) {
$this->message->setReturnPath($this->unescapeShellArguments($matches[1]));
}
// handle from:
$this->fixSender();
// handle message body
$this->setBody($messageBody);
// send mail
$result = $this->mailer->send($this->message);
// report success/failure
return (bool) $result;
}
/**
* Tries to undo the action by escapeshellarg()
*
* @param $escapedString String escaped by escapeshellarg()
* @return string String with escapeshellarg() action undone as best as possible
*/
protected function unescapeShellArguments($escapedString) {
if (TYPO3_OS === 'WIN') {
// on Windows double quotes are used and % signs are replaced by spaces
if (preg_match('/^"([^"]*)"$/', trim($escapedString), $matches)) {
$result = str_replace('\"', '"', $matches[1]);
// % signs are replaced with spaces, so they can't be recovered
}
} else {
// on Unix-like systems single quotes are escaped
if (preg_match('/^\'([^' . preg_quote('\'') . ']*)\'$/', trim($escapedString), $matches)) {
$result = str_replace('\\\'', '\'', $matches[1]);
}
}
return $result;
}
/**
* Handles setting and replacing of mail headers
*
* @param $headerName Name of header
* @param $headerValue Value of header
* @return void
*/
protected function setHeader($headerName, $headerValue) {
// check for boundary in headers
if (preg_match('/^boundary="(.*)"$/', $headerName, $matches) > 0) {
$this->boundary = $matches[1];
return;
}
// process other, real headers
if ($this->messageHeaders->has($headerName)) {
$header = $this->messageHeaders->get($headerName);
$headerType = $header->getFieldType();
switch ($headerType) {
case Swift_Mime_Header::TYPE_TEXT:
$header->setValue($headerValue);
break;
case Swift_Mime_Header::TYPE_PARAMETERIZED:
$header->setValue(rtrim($headerValue, ';'));
break;
case Swift_Mime_Header::TYPE_MAILBOX:
$addressList = $this->parseAddresses($headerValue);
if (count($addressList) > 0) {
$header->setNameAddresses($addressList);
}
break;
case Swift_Mime_Header::TYPE_DATE:
$header->setTimeStamp(strtotime($headerValue));
break;
case Swift_Mime_Header::TYPE_ID:
// remove '<' and '>' from ID headers
$header->setId(trim($headerValue, '<>'));
break;
case Swift_Mime_Header::TYPE_PATH:
$header->setAddress($headerValue);
break;
}
// change value
} else {
switch ($headerName) {
// mailbox headers
case 'From':
case 'To':
case 'Cc':
case 'Bcc':
case 'Reply-To':
case 'Sender':
$addressList = $this->parseAddresses($headerValue);
if (count($addressList) > 0) {
$header->addMailboxHeader($headerName, $addressList);
}
break;
// date headers
case 'Date':
$this->messageHeaders->addDateHeader($headerName, strtotime($headerValue));
break;
// ID headers
case 'Message-ID':
// remove '<' and '>' from ID headers
$this->messageHeaders->addIdHeader($headerName, trim($headerValue, '<>'));
// path headers
case 'Return-Path':
$this->messageHeaders->addPathHeader($headerName, $headerValue);
break;
// parameterized headers
case 'Content-Type':
case 'Content-Disposition':
$this->messageHeaders->addParameterizedHeader($headerName, rtrim($headerValue, ';'));
break;
// text headers
default:
$this->messageHeaders->addTextheader($headerName, $headerValue);
break;
}
}
}
/**
* Sets body of mail message. Handles multi-part and single part messages. Encoded body parts are decoded prior to adding
* them to the message object.
*
* @param string $body Raw body, may be multi-part
* @return void
*/
protected function setBody($body) {
if ($this->boundary) {
// handle multi-part
$bodyParts = preg_split('/--' . preg_quote($this->boundary) . '(--)?/m', $body, NULL, PREG_SPLIT_NO_EMPTY);
foreach ($bodyParts as $bodyPart) {
// skip empty parts
if (trim($bodyPart) == '') {
continue;
}
// keep leading white space when exploding the text
$lines = explode(LF, $bodyPart);
// set defaults for this part
$encoding = '';
$charset = 'utf-8';
$contentType = 'text/plain';
// skip intro messages
if (trim($lines[0]) == 'This is a multi-part message in MIME format.') {
continue;
}
// first line is empty leftover from splitting
array_shift($lines);
while (count($lines) > 0) {
$line = array_shift($lines);
if (preg_match('/^content-type:(.*);( charset=(.*))?$/i', $line, $matches)) {
$contentType = trim($matches[1]);
if ($matches[2]) {
$charset = trim($matches[3]);
}
} else if (preg_match('/^content-transfer-encoding:(.*)$/i', $line, $matches)) {
$encoding = trim($matches[1]);
} else if (strlen(trim($line)) == 0) {
// empty line before actual content of this part
break;
}
}
// use rest of part as body, but reverse encoding first
$bodyPart = $this->decode(implode(LF, $lines), $encoding);
$this->message->addPart($bodyPart, $contentType, $charset);
}
} else {
// Handle single body
// The headers have already been set, so use header information
$contentType = $this->message->getContentType();
$charset = $this->message->getCharset();
$encoding = $this->message->getEncoder();
// reverse encoding and set body
$rawBody = $this->decode($body, $encoding);
$this->message->setBody($rawBody, $contentType, $charset);
}
}
/**
* Reverts encoding of body text
*
* @param string $text Body text to be decoded
* @param string $encoding Encoding type to be reverted
* @return string Decoded message body
*/
protected function decode($text, $encoding) {
$result = $text;
switch ($encoding) {
case 'quoted-printable':
$result = quoted_printable_decode($text);
break;
case 'base64':
$result = base64_decode($text);
break;
}
return $result;
}
/**
* Parses mailbox headers and turns them into an array.
*
* Mailbox headers are a comma separated list of 'name <email@example.org' combinations or plain email addresses (or a mix
* of these).
* The resulting array has key-value pairs where the key is either a number (no name in the mailbox header) or a display
* name and the value is the email address.
*
* @param string $rawAddresses Comma separated list of email addresses (optionally with display name)
* @return array Parsed list of addresses.
*/
protected function parseAddresses($rawAddresses = '') {
// comma is added to match each item in a comma separated list
preg_match_all('/,\s*([^<]+)(<([^>]*?)>)?/', ', ' . $rawAddresses, $addresses, PREG_SET_ORDER);
$addressList = array();
foreach ($addresses as $address) {
if ($address[2]) {
// item with name found ( name <email@example.org> )
if (t3lib_div::validEmail($address[1])) {
$addressList[] = $address[1];
}
} else {
// item without name found ( email@example.org )
if (t3lib_div::validEmail($address[3])) {
$addressList[$address[3]] = trim($address[1], "\n\r\t\0\x0B \"");
}
}
}
return $addressList;
}
/**
* Makes sure there is a correct sender set.
*
* If there is no from header the returnpath will be used. If that also fails a fake address will be used to make sure
* Swift Mailer will be able to send the message. Some SMTP server will not accept mail messages without a valid sender.
*
* @return void
*/
protected function fixSender() {
$from = $this->message->getFrom();
if (count($from) > 0) {
reset($from);
list($fromAddress, $fromName) = each($from);
} else {
$fromAddress = $this->message->getReturnPath();
$fromName = $fromAddress;
}
if (strlen($fromAddress) == 0) {
$fromAddress = 'no-reply@example.org';
$fromName = 'TYPO3 CMS';
}
$this->message->setFrom(array($fromAddress => $fromName));
}
}
t3lib/mail/class.tx_t3lib_mail_hooks.php (working copy)
<?php
/***************************************************************
* Copyright notice
*
* (c) 2010 Jigal van Hemert <jigal@xs4all.nl>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
* Hook subscriber for using Swift Mailer with the t3lib_utility_mail function
*
* $Id$
*
* @author Jigal van Hemert <jigal@xs4all.nl>
* @package TYPO3
* @subpackage t3lib
*/
class tx_t3lib_mail_hooks {
/** @var $mailerObject t3lib_mail_Mailer */
protected $mailerObject;
/** @var $messageObject Swift_Message */
protected $messageObject;
/** @var $messageHeaders Swift_Mime_HeaderSet */
protected $messageHeaders;
/**
* @param array $parameters Array with keys: 'to', 'subject', 'messageBody', 'additionalHeaders', 'additionalParameters'
* @param bool $fakeSending If set fake sending a mail
* @throws t3lib_exception
* @return bool
*/
public function sendMail(array $parameters = array(), $fakeSending = FALSE) {
// report success for fake sending
if ($fakeSending === TRUE) {
return TRUE;
}
// create mailer object
$this->mailerObject = t3lib_div::makeInstance('t3lib_mail_Mailer');
// create message object
$this->messageObject = Swift_Message::newInstance($parameters['subject'], $parameters['messageBody']);
$this->messageObject->setTo($parameters['to']);
// handle additional headers
$headers = t3lib_div::trimExplode(LF, $parameters['additionalHeaders'], TRUE);
$this->messageHeaders = $this->messageObject->getHeaders();
foreach ($headers as $header) {
list($headerName, $headerValue) = t3lib_div::trimExplode(':', $header, FALSE, 2);
$this->setHeader($headerName, $headerValue);
}
// handle additional parameters (force return path)
if (preg_match('/-f\s*(\S*?)/', $parameters['additionalParameters'], $matches)) {
$this->messageObject->setReturnPath($this->unEscapeShellArg($matches[1]));
}
// handle from:
$from = $this->messageObject->getFrom();
if (count($from) > 0) {
reset($from);
list($fromAddress, $fromName) = each($from);
} else {
$fromAddress = $this->messageObject->getReturnPath();
$fromName = $fromAddress;
}
if (strlen($fromAddress) == 0) {
$fromAddress = 'no-reply@example.org';
$fromName = 'TYPO3 Installation';
}
$this->messageObject->setFrom(array($fromAddress => $fromName));
// send mail
$result = $this->mailerObject->send($this->messageObject);
// report success/failure
return (bool) $result;
}
/**
* Tries to undo the action by escapeshellarg()
*
* @param $escapedString String escaped by escapeshellarg()
* @return string String with escapeshellarg() action undone as best as possible
*/
protected function unEscapeShellArg($escapedString) {
if (TYPO3_OS === 'WIN') {
// on Windows double quotes are used and % signs are replaced by spaces
if (preg_match('/^"([^"]*)"$/', trim($escapedString), $matches)) {
$result = str_replace('\"', '"', $matches[1]);
// % signs are replaced with spaces, so they can't be recovered
}
} else {
// on Unix-like systems single quotes are escaped
if (preg_match('/^\'([^' . preg_quote('\'') . ']*)\'$/', trim($escapedString), $matches)) {
$result = str_replace('\\\'', '\'', $matches[1]);
}
}
return $result;
}
/**
* Handles setting and replacing of mail headers
*
* @param $headerName Name of header
* @param $headerValue Value of header
* @return void
*/
protected function setHeader($headerName, $headerValue) {
if ($this->messageHeaders->has($headerName)) {
$header = $this->messageHeaders->get($headerName);
$headerType = $header->getFieldType();
switch ($headerType) {
case Swift_Mime_Header::TYPE_TEXT:
$header->setValue($headerValue);
break;
case Swift_Mime_Header::TYPE_PARAMETERIZED:
$header->setValue($headerValue);
break;
case Swift_Mime_Header::TYPE_MAILBOX:
// mailbox headers look like:
// name <email@example.org>, othermail@example.org, ...
// pattern matches cases with and without name
// comma is added to match each item in a comma separated list
preg_match_all('/,\s*([^<]+)(<([^>]*?)>)?/', ', ' . $headerValue, $addresses, PREG_SET_ORDER);
$addressList = array();
foreach ($addresses as $address) {
if (!$address[2]) {
// item with name found ( name <email@example.org> )
if (t3lib_div::validEmail($address[1])) {
$addressList[] = $address[1];
}
} else {
// item without name found ( email@example.org )
if (t3lib_div::validEmail($address[3])) {
$addressList[$address[3]] = $address[1];
}
}
}
if (count($addressList) > 0) {
$header->setNameAddresses($addressList);
}
break;
case Swift_Mime_Header::TYPE_DATE:
$header->setTimeStamp(strtotime($headerValue));
break;
case Swift_Mime_Header::TYPE_ID:
// remove '<' and '>' from ID headers
$header->setId(trim($headerValue, '<>'));
break;
case Swift_Mime_Header::TYPE_PATH:
$header->setAddress($headerValue);
break;
}
// change value
} else {
switch ($headerName) {
// mailbox headers
case 'From':
case 'To':
case 'Cc':
case 'Bcc':
case 'Reply-To':
case 'Sender':
// mailbox headers look like:
// name <email@example.org>, othermail@example.org, ...
// pattern matches cases with and without name
// comma is added to match each item in a comma separated list
preg_match_all('/,\s*(.*?)(<([^>]*?)>)?/', ', ' . $headerValue, $addresses, PREG_SET_ORDER);
$addressList = array();
foreach ($addresses as $address) {
if ($address[2]) {
// item with name found ( name <email@example.org> )
if (t3lib_div::validEmail($address[1])) {
$addressList[] = $address[1];
}
} else {
// item without name found ( email@example.org )
if (t3lib_div::validEmail($address[3])) {
$addressList[$address[3]] = $address[1];
}
}
}
if (count($addressList) > 0) {
$header->addMailboxHeader($headerName, $addressList);
}
break;
// date headers
case 'Date':
$this->messageHeaders->addDateHeader($headerName, strtotime($headerValue));
break;
// ID headers
case 'Message-ID':
// remove '<' and '>' from ID headers
$this->messageHeaders->addIdHeader($headerName, trim($headerValue, '<>'));
// path headers
case 'Return-Path':
$this->messageHeaders->addPathHeader($headerName, $headerValue);
break;
// parameterized headers
case 'Content-Type':
case 'Content-Disposition':
$this->messageHeaders->addParameterizedHeader($headerName, $headerValue);
break;
// text headers
default:
$this->messageHeaders->addTextheader($headerName, $headerValue);
break;
}
}
}
}
t3lib/utility/class.t3lib_utility_mail.php (working copy)
'additionalParameters' => $additionalParameters,
);
$fakeThis = FALSE;
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'] as $hookMethod) {
$success = $success && t3lib_div::callUserFunction($hookMethod, $parameters, $fakeThis);
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/utility/class.t3lib_utility_mail.php']['substituteMailDelivery'] as $hookSubscriber) {
$hookSubscriberContainsArrow = strpos($hookSubscriber, '->');
if ($hookSubscriberContainsArrow !== FALSE) {
// deprecated, remove in TYPO3 4.7
t3lib_div::deprecationLog(
'The usage of user function notation for the substituteMailDelivery hook is deprecated,
use the t3lib_mail_MailerAdapter interface instead.'
);
$success = $success && t3lib_div::callUserFunction($hookSubscriber, $parameters, $fakeThis);
} else {
$mailerAdapter = t3lib_div::makeInstance($hookSubscriber);
if ($mailerAdapter instanceof t3lib_mail_MailerAdapter) {
$success = $success && $mailerAdapter->mail($to, $subject, $messageBody, $additionalHeaders, $additionalParameters, $fakeThis);
} else {
throw new RuntimeException(
$hookSubscriber . ' is not an implementation of t3lib_mail_MailerAdapter,
but must implement that interface to be used in the substituteMailDelivery hook.',
1294062286
);
}
}
}
} else {
if (t3lib_utility_PhpOptions::isSafeModeEnabled() && !is_null($additionalParameters)) {
    (1-1/1)