Fixed bug #16591 The new Swift Mailer should be used by TYPO3 for sending all kinds...
authorJigal van Hemert <jigal@xs4all.nl>
Wed, 1 Dec 2010 09:30:30 +0000 (09:30 +0000)
committerJigal van Hemert <jigal@xs4all.nl>
Wed, 1 Dec 2010 09:30:30 +0000 (09:30 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@9707 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/config_default.php
t3lib/core_autoload.php
t3lib/mail/class.t3lib_mail_mailer.php
t3lib/mail/class.tx_t3lib_mail_hooks.php [new file with mode: 0644]

index 9a5a90b..4a16314 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-12-01  Jigal van Hemert <jigal@xs4all.nl>
+
+       * Fixed bug #16591 The new Swift Mailer should be used by TYPO3 for sending all kinds of mail
+
 2010-12-01  Steffen Ritter  <typo3@steffen-ritter.net>
 
        * Fixed Bug #16613: CleanUp alt_db_navframe.php to work with new workspaces module
index f1b0f82..2c249a0 100644 (file)
@@ -590,6 +590,9 @@ $T3_SERVICES = array();
 $TYPO3_CONF_VARS['SC_OPTIONS']['errors']['exceptionHandler'] = $TYPO3_CONF_VARS['SYS']['productionExceptionHandler'];
 $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';
+
        // Turn error logging on/off.
 if (($displayErrors = intval($TYPO3_CONF_VARS['SYS']['displayErrors'])) != '-1')       {
        if ($displayErrors == 2)        {       // Special value "2" enables this feature only if $TYPO3_CONF_VARS[SYS][devIPmask] matches
index 865a5e5..d960a3d 100644 (file)
@@ -137,6 +137,7 @@ $t3libClasses = array(
        't3lib_tcemain_processuploadhook' => PATH_t3lib . 'interfaces/interface.t3lib_tcemain_processuploadhook.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_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',
index b5b7bac..e2c73f3 100644 (file)
@@ -89,7 +89,7 @@ class t3lib_mail_Mailer extends Swift_Mailer {
 
                        case 'smtp':
                                        // Get settings to be used when constructing the transport object
-                               list($host, $port) = split(':', $mailSettings['transport_smtp_server']);
+                               list($host, $port) = preg_split('/:/', $mailSettings['transport_smtp_server']);
                                if ($host === '') {
                                        throw new t3lib_exception(
                                                '$TYPO3_CONF_VARS[\'MAIL\'][\'transport_smtp_server\'] needs to be set when transport is set to "smtp"',
diff --git a/t3lib/mail/class.tx_t3lib_mail_hooks.php b/t3lib/mail/class.tx_t3lib_mail_hooks.php
new file mode 100644 (file)
index 0000000..1ec0c15
--- /dev/null
@@ -0,0 +1,230 @@
+<?php\r
+/***************************************************************\r
+ *  Copyright notice\r
+ *\r
+ *  (c) 2010 Jigal van Hemert <jigal@xs4all.nl>\r
+ *  All rights reserved\r
+ *\r
+ *  This script is part of the TYPO3 project. The TYPO3 project is\r
+ *  free software; you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License as published by\r
+ *  the Free Software Foundation; either version 2 of the License, or\r
+ *  (at your option) any later version.\r
+ *\r
+ *  The GNU General Public License can be found at\r
+ *  http://www.gnu.org/copyleft/gpl.html.\r
+ *  A copy is found in the textfile GPL.txt and important notices to the license\r
+ *  from the author is found in LICENSE.txt distributed with these scripts.\r
+ *\r
+ *\r
+ *  This script is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  This copyright notice MUST APPEAR in all copies of the script!\r
+ ***************************************************************/\r
+\r
+/**\r
+ * Hook subscriber for using Swift Mailer with the t3lib_utility_mail function\r
+ *\r
+ * $Id$\r
+ *\r
+ * @author     Jigal van Hemert <jigal@xs4all.nl>\r
+ * @package TYPO3\r
+ * @subpackage t3lib\r
+ */\r
+class tx_t3lib_mail_hooks {\r
+\r
+       /** @var $mailerObject t3lib_mail_Mailer */\r
+       protected $mailerObject;\r
+\r
+       /** @var $messageObject Swift_Message */\r
+       protected $messageObject;\r
+\r
+       /** @var $messageHeaders Swift_Mime_HeaderSet */\r
+       protected $messageHeaders;\r
+\r
+       /**\r
+        * @param array $parameters Array with keys: 'to', 'subject', 'messageBody', 'additionalHeaders', 'additionalParameters'\r
+        * @param bool $fakeSending If set fake sending a mail\r
+        * @throws t3lib_exception\r
+        * @return bool\r
+        */\r
+       public function sendMail(array $parameters = array(), $fakeSending = FALSE) {\r
+\r
+                       // report success for fake sending\r
+               if ($fakeSending === TRUE) {\r
+                       return TRUE;\r
+               }\r
+                       // create mailer object\r
+               $this->mailerObject = t3lib_div::makeInstance('t3lib_mail_Mailer');\r
+\r
+                       // create message object\r
+               $this->messageObject = Swift_Message::newInstance($parameters['subject'], $parameters['messageBody']);\r
+               $this->messageObject->setTo($parameters['to']);\r
+                       // handle additional headers\r
+               $headers = t3lib_div::trimExplode(LF, $parameters['additionalHeaders'], TRUE);\r
+               $this->messageHeaders = $this->messageObject->getHeaders();\r
+               foreach ($headers as $header) {\r
+                       list($headerName, $headerValue) = t3lib_div::trimExplode(':', $header, FALSE, 2);\r
+                       $this->setHeader($headerName, $headerValue);\r
+               }\r
+                       // handle additional parameters (force return path)\r
+               if (preg_match('/-f\s*(\S*?)/', $parameters['additionalParameters'], $matches)) {\r
+                       $this->messageObject->setReturnPath($this->unEscapeShellArg($matches[1]));\r
+               }\r
+                       // handle from:\r
+               $from = $this->messageObject->getFrom();\r
+               if (count($from) > 0) {\r
+                       reset($from);\r
+                       list($fromAddress, $fromName) = each($from);\r
+               } else {\r
+                       $fromAddress = $this->messageObject->getReturnPath();\r
+                       $fromName = $fromAddress;\r
+               }\r
+               if (strlen($fromAddress) == 0) {\r
+                       $fromAddress = 'no-reply@example.org';\r
+                       $fromName = 'TYPO3 Installation';\r
+               }\r
+               $this->messageObject->setFrom(array($fromAddress => $fromName));\r
+                       // send mail\r
+               $result = $this->mailerObject->send($this->messageObject);\r
+\r
+                       // report success/failure\r
+               return (bool) $result;\r
+       }\r
+\r
+       /**\r
+        * Tries to undo the action by escapeshellarg()\r
+        *\r
+        * @param  $escapedString String escaped by escapeshellarg()\r
+        * @return string       String with escapeshellarg() action undone as best as possible\r
+        */\r
+       protected function unEscapeShellArg($escapedString) {\r
+               if (TYPO3_OS === 'WIN') {\r
+                               // on Windows double quotes are used and % signs are replaced by spaces\r
+                       if (preg_match('/^"([^"]*)"$/', trim($escapedString), $matches)) {\r
+                               $result = str_replace('\"', '"', $matches[1]);\r
+                                       // % signs are replaced with spaces, so they can't be recovered\r
+                       }\r
+               } else {\r
+                               // on Unix-like systems single quotes are escaped\r
+                       if (preg_match('/^\'([^' . preg_quote('\'') . ']*)\'$/', trim($escapedString), $matches)) {\r
+                               $result = str_replace('\\\'', '\'', $matches[1]);\r
+                       }\r
+               }\r
+               return $result;\r
+       }\r
+\r
+       /**\r
+        * Handles setting and replacing of mail headers\r
+        *\r
+        * @param  $headerName Name of header\r
+        * @param  $headerValue Value of header\r
+        * @return void\r
+        */\r
+       protected function setHeader($headerName, $headerValue) {\r
+               if ($this->messageHeaders->has($headerName)) {\r
+                       $header = $this->messageHeaders->get($headerName);\r
+                       $headerType = $header->getFieldType();\r
+                       switch ($headerType) {\r
+                               case Swift_Mime_Header::TYPE_TEXT:\r
+                                       $header->setValue($headerValue);\r
+                                       break;\r
+                               case Swift_Mime_Header::TYPE_PARAMETERIZED:\r
+                                       $header->setValue($headerValue);\r
+                                       break;\r
+                               case Swift_Mime_Header::TYPE_MAILBOX:\r
+                                               // mailbox headers look like:\r
+                                               // name <email@example.org>, othermail@example.org, ...\r
+                                               // pattern matches cases with and without name\r
+                                               // comma is added to match each item in a comma separated list\r
+                                       preg_match_all('/,\s*([^<]+)(<([^>]*?)>)?/', ', ' . $headerValue, $addresses, PREG_SET_ORDER);\r
+                                       $addressList = array();\r
+                                       foreach ($addresses as $address) {\r
+                                               if (!$address[2]) {\r
+                                                               // item with name found ( name <email@example.org> )\r
+                                                       if (t3lib_div::validEmail($address[1])) {\r
+                                                               $addressList[] = $address[1];\r
+                                                       }\r
+                                               } else {\r
+                                                               // item without name found ( email@example.org )\r
+                                                       if (t3lib_div::validEmail($address[3])) {\r
+                                                               $addressList[$address[3]] = $address[1];\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       if (count($addressList) > 0) {\r
+                                               $header->setNameAddresses($addressList);\r
+                                       }\r
+                                       break;\r
+                               case Swift_Mime_Header::TYPE_DATE:\r
+                                       $header->setTimeStamp(strtotime($headerValue));\r
+                                       break;\r
+                               case Swift_Mime_Header::TYPE_ID:\r
+                                               // remove '<' and '>' from ID headers\r
+                                       $header->setId(trim($headerValue, '<>'));\r
+                                       break;\r
+                               case Swift_Mime_Header::TYPE_PATH:\r
+                                       $header->setAddress($headerValue);\r
+                                       break;\r
+                       }\r
+                               // change value\r
+               } else {\r
+                       switch ($headerName) {\r
+                                       // mailbox headers\r
+                               case 'From':\r
+                               case 'To':\r
+                               case 'Cc':\r
+                               case 'Bcc':\r
+                               case 'Reply-To':\r
+                               case 'Sender':\r
+                                               // mailbox headers look like:\r
+                                               // name <email@example.org>, othermail@example.org, ...\r
+                                               // pattern matches cases with and without name\r
+                                               // comma is added to match each item in a comma separated list\r
+                                       preg_match_all('/,\s*(.*?)(<([^>]*?)>)?/', ', ' . $headerValue, $addresses, PREG_SET_ORDER);\r
+                                       $addressList = array();\r
+                                       foreach ($addresses as $address) {\r
+                                               if ($address[2]) {\r
+                                                               // item with name found ( name <email@example.org> )\r
+                                                       if (t3lib_div::validEmail($address[1])) {\r
+                                                               $addressList[] = $address[1];\r
+                                                       }\r
+                                               } else {\r
+                                                               // item without name found ( email@example.org )\r
+                                                       if (t3lib_div::validEmail($address[3])) {\r
+                                                               $addressList[$address[3]] = $address[1];\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       if (count($addressList) > 0) {\r
+                                               $header->addMailboxHeader($headerName, $addressList);\r
+                                       }\r
+                                       break;\r
+                                       // date headers\r
+                               case 'Date':\r
+                                       $this->messageHeaders->addDateHeader($headerName, strtotime($headerValue));\r
+                                       break;\r
+                                       // ID headers\r
+                               case 'Message-ID':\r
+                                               // remove '<' and '>' from ID headers\r
+                                       $this->messageHeaders->addIdHeader($headerName, trim($headerValue, '<>'));\r
+                                       // path headers\r
+                               case 'Return-Path':\r
+                                       $this->messageHeaders->addPathHeader($headerName, $headerValue);\r
+                                       break;\r
+                                       // parameterized headers\r
+                               case 'Content-Type':\r
+                               case 'Content-Disposition':\r
+                                       $this->messageHeaders->addParameterizedHeader($headerName, $headerValue);\r
+                                       break;\r
+                                       // text headers\r
+                               default:\r
+                                       $this->messageHeaders->addTextheader($headerName, $headerValue);\r
+                                       break;\r
+                       }\r
+               }\r
+       }\r
+}\r