PageRenderTime 49ms CodeModel.GetById 14ms app.highlight 23ms RepoModel.GetById 2ms app.codeStats 0ms

/framework/vendor/zend/Zend/Mail/Transport/Abstract.php

http://zoop.googlecode.com/
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}