/framework/vendor/zend/Zend/Mail/Transport/Abstract.php
PHP | 350 lines | 142 code | 39 blank | 169 comment | 16 complexity | 130ca6f412111dd9feba8780dbeeb990 MD5 | raw file
1<?php 2/** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to license@zend.com so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Mail 17 * @subpackage Transport 18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 19 * @license http://framework.zend.com/license/new-bsd New BSD License 20 * @version $Id: Abstract.php 20096 2010-01-06 02:05:09Z bkarwin $ 21 */ 22 23 24/** 25 * @see Zend_Mime 26 */ 27require_once 'Zend/Mime.php'; 28 29 30/** 31 * Abstract for sending eMails through different 32 * ways of transport 33 * 34 * @category Zend 35 * @package Zend_Mail 36 * @subpackage Transport 37 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 38 * @license http://framework.zend.com/license/new-bsd New BSD License 39 */ 40abstract class Zend_Mail_Transport_Abstract 41{ 42 /** 43 * Mail body 44 * @var string 45 * @access public 46 */ 47 public $body = ''; 48 49 /** 50 * MIME boundary 51 * @var string 52 * @access public 53 */ 54 public $boundary = ''; 55 56 /** 57 * Mail header string 58 * @var string 59 * @access public 60 */ 61 public $header = ''; 62 63 /** 64 * Array of message headers 65 * @var array 66 * @access protected 67 */ 68 protected $_headers = array(); 69 70 /** 71 * Message is a multipart message 72 * @var boolean 73 * @access protected 74 */ 75 protected $_isMultipart = false; 76 77 /** 78 * Zend_Mail object 79 * @var false|Zend_Mail 80 * @access protected 81 */ 82 protected $_mail = false; 83 84 /** 85 * Array of message parts 86 * @var array 87 * @access protected 88 */ 89 protected $_parts = array(); 90 91 /** 92 * Recipients string 93 * @var string 94 * @access public 95 */ 96 public $recipients = ''; 97 98 /** 99 * EOL character string used by transport 100 * @var string 101 * @access public 102 */ 103 public $EOL = "\r\n"; 104 105 /** 106 * Send an email independent from the used transport 107 * 108 * The requisite information for the email will be found in the following 109 * properties: 110 * 111 * - {@link $recipients} - list of recipients (string) 112 * - {@link $header} - message header 113 * - {@link $body} - message body 114 */ 115 abstract protected function _sendMail(); 116 117 /** 118 * Return all mail headers as an array 119 * 120 * If a boundary is given, a multipart header is generated with a 121 * Content-Type of either multipart/alternative or multipart/mixed depending 122 * on the mail parts present in the {@link $_mail Zend_Mail object} present. 123 * 124 * @param string $boundary 125 * @return array 126 */ 127 protected function _getHeaders($boundary) 128 { 129 if (null !== $boundary) { 130 // Build multipart mail 131 $type = $this->_mail->getType(); 132 if (!$type) { 133 if ($this->_mail->hasAttachments) { 134 $type = Zend_Mime::MULTIPART_MIXED; 135 } elseif ($this->_mail->getBodyText() && $this->_mail->getBodyHtml()) { 136 $type = Zend_Mime::MULTIPART_ALTERNATIVE; 137 } else { 138 $type = Zend_Mime::MULTIPART_MIXED; 139 } 140 } 141 142 $this->_headers['Content-Type'] = array( 143 $type . ';' 144 . $this->EOL 145 . " " . 'boundary="' . $boundary . '"' 146 ); 147 $this->boundary = $boundary; 148 } 149 150 $this->_headers['MIME-Version'] = array('1.0'); 151 152 return $this->_headers; 153 } 154 155 /** 156 * Prepend header name to header value 157 * 158 * @param string $item 159 * @param string $key 160 * @param string $prefix 161 * @static 162 * @access protected 163 * @return void 164 */ 165 protected static function _formatHeader(&$item, $key, $prefix) 166 { 167 $item = $prefix . ': ' . $item; 168 } 169 170 /** 171 * Prepare header string for use in transport 172 * 173 * Prepares and generates {@link $header} based on the headers provided. 174 * 175 * @param mixed $headers 176 * @access protected 177 * @return void 178 * @throws Zend_Mail_Transport_Exception if any header lines exceed 998 179 * characters 180 */ 181 protected function _prepareHeaders($headers) 182 { 183 if (!$this->_mail) { 184 /** 185 * @see Zend_Mail_Transport_Exception 186 */ 187 require_once 'Zend/Mail/Transport/Exception.php'; 188 throw new Zend_Mail_Transport_Exception('Missing Zend_Mail object in _mail property'); 189 } 190 191 $this->header = ''; 192 193 foreach ($headers as $header => $content) { 194 if (isset($content['append'])) { 195 unset($content['append']); 196 $value = implode(',' . $this->EOL . ' ', $content); 197 $this->header .= $header . ': ' . $value . $this->EOL; 198 } else { 199 array_walk($content, array(get_class($this), '_formatHeader'), $header); 200 $this->header .= implode($this->EOL, $content) . $this->EOL; 201 } 202 } 203 204 // Sanity check on headers -- should not be > 998 characters 205 $sane = true; 206 foreach (explode($this->EOL, $this->header) as $line) { 207 if (strlen(trim($line)) > 998) { 208 $sane = false; 209 break; 210 } 211 } 212 if (!$sane) { 213 /** 214 * @see Zend_Mail_Transport_Exception 215 */ 216 require_once 'Zend/Mail/Transport/Exception.php'; 217 throw new Zend_Mail_Exception('At least one mail header line is too long'); 218 } 219 } 220 221 /** 222 * Generate MIME compliant message from the current configuration 223 * 224 * If both a text and HTML body are present, generates a 225 * multipart/alternative Zend_Mime_Part containing the headers and contents 226 * of each. Otherwise, uses whichever of the text or HTML parts present. 227 * 228 * The content part is then prepended to the list of Zend_Mime_Parts for 229 * this message. 230 * 231 * @return void 232 */ 233 protected function _buildBody() 234 { 235 if (($text = $this->_mail->getBodyText()) 236 && ($html = $this->_mail->getBodyHtml())) 237 { 238 // Generate unique boundary for multipart/alternative 239 $mime = new Zend_Mime(null); 240 $boundaryLine = $mime->boundaryLine($this->EOL); 241 $boundaryEnd = $mime->mimeEnd($this->EOL); 242 243 $text->disposition = false; 244 $html->disposition = false; 245 246 $body = $boundaryLine 247 . $text->getHeaders($this->EOL) 248 . $this->EOL 249 . $text->getContent($this->EOL) 250 . $this->EOL 251 . $boundaryLine 252 . $html->getHeaders($this->EOL) 253 . $this->EOL 254 . $html->getContent($this->EOL) 255 . $this->EOL 256 . $boundaryEnd; 257 258 $mp = new Zend_Mime_Part($body); 259 $mp->type = Zend_Mime::MULTIPART_ALTERNATIVE; 260 $mp->boundary = $mime->boundary(); 261 262 $this->_isMultipart = true; 263 264 // Ensure first part contains text alternatives 265 array_unshift($this->_parts, $mp); 266 267 // Get headers 268 $this->_headers = $this->_mail->getHeaders(); 269 return; 270 } 271 272 // If not multipart, then get the body 273 if (false !== ($body = $this->_mail->getBodyHtml())) { 274 array_unshift($this->_parts, $body); 275 } elseif (false !== ($body = $this->_mail->getBodyText())) { 276 array_unshift($this->_parts, $body); 277 } 278 279 if (!$body) { 280 /** 281 * @see Zend_Mail_Transport_Exception 282 */ 283 require_once 'Zend/Mail/Transport/Exception.php'; 284 throw new Zend_Mail_Transport_Exception('No body specified'); 285 } 286 287 // Get headers 288 $this->_headers = $this->_mail->getHeaders(); 289 $headers = $body->getHeadersArray($this->EOL); 290 foreach ($headers as $header) { 291 // Headers in Zend_Mime_Part are kept as arrays with two elements, a 292 // key and a value 293 $this->_headers[$header[0]] = array($header[1]); 294 } 295 } 296 297 /** 298 * Send a mail using this transport 299 * 300 * @param Zend_Mail $mail 301 * @access public 302 * @return void 303 * @throws Zend_Mail_Transport_Exception if mail is empty 304 */ 305 public function send(Zend_Mail $mail) 306 { 307 $this->_isMultipart = false; 308 $this->_mail = $mail; 309 $this->_parts = $mail->getParts(); 310 $mime = $mail->getMime(); 311 312 // Build body content 313 $this->_buildBody(); 314 315 // Determine number of parts and boundary 316 $count = count($this->_parts); 317 $boundary = null; 318 if ($count < 1) { 319 /** 320 * @see Zend_Mail_Transport_Exception 321 */ 322 require_once 'Zend/Mail/Transport/Exception.php'; 323 throw new Zend_Mail_Transport_Exception('Empty mail cannot be sent'); 324 } 325 326 if ($count > 1) { 327 // Multipart message; create new MIME object and boundary 328 $mime = new Zend_Mime($this->_mail->getMimeBoundary()); 329 $boundary = $mime->boundary(); 330 } elseif ($this->_isMultipart) { 331 // multipart/alternative -- grab boundary 332 $boundary = $this->_parts[0]->boundary; 333 } 334 335 // Determine recipients, and prepare headers 336 $this->recipients = implode(',', $mail->getRecipients()); 337 $this->_prepareHeaders($this->_getHeaders($boundary)); 338 339 // Create message body 340 // This is done so that the same Zend_Mail object can be used in 341 // multiple transports 342 $message = new Zend_Mime_Message(); 343 $message->setParts($this->_parts); 344 $message->setMime($mime); 345 $this->body = $message->generateMessage($this->EOL); 346 347 // Send to transport! 348 $this->_sendMail(); 349 } 350}