/tine20/Tinebase/Mail.php
PHP | 320 lines | 181 code | 52 blank | 87 comment | 28 complexity | f343e5a5f5fc60b7b45d5a8c68b7c7f8 MD5 | raw file
- <?php
- /**
- * Tine 2.0
- *
- * @package Tinebase
- * @subpackage Mail
- * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
- * @copyright Copyright (c) 2008-2013 Metaways Infosystems GmbH (http://www.metaways.de)
- * @author Lars Kneschke <l.kneschke@metaways.de>
- */
- /**
- * This class extends the Zend_Mail class
- *
- * @package Tinebase
- * @subpackage Mail
- */
- class Tinebase_Mail extends Zend_Mail
- {
- /**
- * email address regexp
- */
- const EMAIL_ADDRESS_REGEXP = '/([a-z0-9_\+-\.]+@[a-z0-9-\.]{1,})/i';
-
- /**
- * Sender: address
- * @var string
- */
- protected $_sender = null;
-
- /**
- * create Tinebase_Mail from Zend_Mail_Message
- *
- * @param Zend_Mail_Message $_zmm
- * @param string $_replyBody
- * @return Tinebase_Mail
- */
- public static function createFromZMM(Zend_Mail_Message $_zmm, $_replyBody = null)
- {
- $contentStream = fopen("php://temp", 'r+');
- fputs($contentStream, $_zmm->getContent());
- rewind($contentStream);
-
- $mp = new Zend_Mime_Part($contentStream);
-
- if ($_zmm->headerExists('content-transfer-encoding')) {
- $mp->encoding = $_zmm->getHeader('content-transfer-encoding');
- $mp->decodeContent();
- } else {
- $mp->encoding = Zend_Mime::ENCODING_7BIT;
- }
-
- // append old body when no multipart/mixed
- if ($_replyBody !== null && $_zmm->headerExists('content-transfer-encoding')) {
- $mp = self::_appendReplyBody($mp, $_replyBody);
- $mp->encoding = $_zmm->getHeader('content-transfer-encoding');
- }
-
- if ($_zmm->headerExists('content-type')) {
- $contentTypeHeader = Zend_Mime_Decode::splitHeaderField($_zmm->getHeader('content-type'));
-
- $mp->type = $contentTypeHeader[0];
-
- if (isset($contentTypeHeader['boundary'])) {
- $mp->boundary = $contentTypeHeader['boundary'];
- }
-
- if (isset($contentTypeHeader['charset'])) {
- $mp->charset = $contentTypeHeader['charset'];
- }
- } else {
- $mp->type = Zend_Mime::TYPE_TEXT;
- }
-
- $result = new Tinebase_Mail('utf-8');
-
- $result->setBodyText($mp);
-
- foreach ($_zmm->getHeaders() as $header => $values) {
- foreach ((array)$values as $value) {
- switch ($header) {
- case 'content-transfer-encoding':
- // these are implicitly set by Zend_Mail_Transport_Abstract::_getHeaders()
- case 'content-type':
- case 'mime-version':
- // do nothing
-
- break;
-
- case 'bcc':
- $addresses = Tinebase_EmailUser_Factory::callStatic('Message','parseAdresslist',array($value));
- foreach ($addresses as $address) {
- $result->addBcc($address['address'], $address['name']);
- }
-
- break;
-
- case 'cc':
- $addresses = Tinebase_EmailUser_Factory::callStatic('Message','parseAdresslist',array($value));
- foreach ($addresses as $address) {
- $result->addCc($address['address'], $address['name']);
- }
-
- break;
-
- case 'date':
- try {
- $result->setDate($value);
- } catch (Zend_Mail_Exception $zme) {
- if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE))
- Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " Could not set date: " . $value);
- if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE))
- Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " " . $zme);
- $result->setDate();
- }
-
- break;
-
- case 'from':
- $addresses = Tinebase_EmailUser_Factory::callStatic('Message','parseAdresslist',array($value));
- foreach ($addresses as $address) {
- $result->setFrom($address['address'], $address['name']);
- }
-
- break;
-
- case 'message-id':
- $result->setMessageId($value);
-
- break;
-
- case 'return-path':
- $result->setReturnPath($value);
-
- break;
-
- case 'subject':
- $result->setSubject($value);
-
- break;
-
- case 'to':
- $addresses = Tinebase_EmailUser_Factory::callStatic('Message','parseAdresslist',array($value));
- foreach ($addresses as $address) {
- $result->addTo($address['address'], $address['name']);
- }
-
- break;
-
- default:
- $result->addHeader($header, $value);
-
- break;
- }
- }
- }
-
- return $result;
- }
-
- /**
- * appends old body to mime part
- *
- * @param Zend_Mime_Part $mp
- * @param string $replyBody
- * @return Zend_Mime_Part
- */
- protected static function _appendReplyBody(Zend_Mime_Part $mp, $replyBody)
- {
- //if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
- // Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " reply body: " . $replyBody);
- // Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " mp content: " . $mp->getContent());
- // rewind($mp->getRawStream());
- //}
- $contentStream = fopen("php://temp", 'r+');
- stream_copy_to_stream($mp->getRawStream(), $contentStream);
-
- // check if html message, append before </body></html>
- // @todo might check content-type, too
- rewind($mp->getRawStream());
- if (preg_match('/(<\/body>[\s\r\n]*<\/html>)/i', $mp->getContent(), $matches)) {
- if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
- . ' Appending reply body to html body.');
-
- require_once 'StreamFilter/StringReplace.php';
- $filter = stream_filter_append($contentStream, 'str.replace', STREAM_FILTER_READ, array(
- 'search' => $matches[1],
- 'replace' => $replyBody . $matches[1]
- ));
- } else {
- if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
- . " Appending reply body to mime text part.");
-
- fputs($contentStream, $replyBody);
- }
-
- // create decoded stream
- rewind($contentStream);
- $mp = new Zend_Mime_Part($contentStream);
-
- return $mp;
- }
-
- /**
- * Sets the HTML body for the message
- *
- * @param string|Zend_Mime_Part $html
- * @param string $charset
- * @param string $encoding
- * @return Zend_Mail Provides fluent interface
- */
- public function setBodyHtml($html, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE)
- {
- if ($html instanceof Zend_Mime_Part) {
- $mp = $html;
- } else {
- if ($charset === null) {
- $charset = $this->_charset;
- }
-
- $mp = new Zend_Mime_Part($html);
- $mp->encoding = $encoding;
- $mp->type = Zend_Mime::TYPE_HTML;
- $mp->disposition = Zend_Mime::DISPOSITION_INLINE;
- $mp->charset = $charset;
- }
-
- $this->_bodyHtml = $mp;
-
- return $this;
- }
-
- /**
- * Sets the text body for the message.
- *
- * @param string|Zend_Mime_Part $txt
- * @param string $charset
- * @param string $encoding
- * @return Zend_Mail Provides fluent interface
- */
- public function setBodyText($txt, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE)
- {
- if ($txt instanceof Zend_Mime_Part) {
- $mp = $txt;
- } else {
- if ($charset === null) {
- $charset = $this->_charset;
- }
-
- $mp = new Zend_Mime_Part($txt);
- $mp->encoding = $encoding;
- $mp->type = Zend_Mime::TYPE_TEXT;
- $mp->disposition = Zend_Mime::DISPOSITION_INLINE;
- $mp->charset = $charset;
- }
-
- $this->_bodyText = $mp;
- return $this;
- }
-
- /**
- * Sets Sender-header and sender of the message
- *
- * @param string $email
- * @param string $name
- * @return Zend_Mail Provides fluent interface
- * @throws Zend_Mail_Exception if called subsequent times
- */
- public function setSender($email, $name = '')
- {
- if ($this->_sender === null) {
- $email = strtr($email,"\r\n\t",'???');
- $this->_from = $email;
- $this->_storeHeader('Sender', $this->_encodeHeader('"'.$name.'"').' <'.$email.'>', true);
- } else {
- throw new Zend_Mail_Exception('Sender Header set twice');
- }
- return $this;
- }
-
- /**
- * Formats e-mail address
- *
- * NOTE: we always add quotes to the name as this caused problems when name is encoded
- * @see Zend_Mail::_formatAddress
- *
- * @param string $email
- * @param string $name
- * @return string
- */
- protected function _formatAddress($email, $name)
- {
- if ($name === '' || $name === null || $name === $email) {
- return $email;
- } else {
- $encodedName = $this->_encodeHeader($name);
- $format = '"%s" <%s>';
- return sprintf($format, $encodedName, $email);
- }
- }
- /**
- * check if Zend_Mail_Message is/contains calendar iMIP message
- *
- * @param Zend_Mail_Message $zmm
- * @return boolean
- */
- public static function isiMIPMail(Zend_Mail_Message $zmm)
- {
- foreach ($zmm as $part) {
- if (preg_match('/text\/calendar/', $part->contentType)) {
- return TRUE;
- }
- }
-
- return FALSE;
- }
- }