source: trunk/library/Zend/Mail/Transport/Abstract.php @ 5146

Revision 5146, 10.2 KB checked in by wmerlotto, 12 years ago (diff)

Ticket #2305 - Enviando alteracoes, desenvolvidas internamente na Prognus. Library: adicionando arquivos.

Line 
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}
Note: See TracBrowser for help on using the repository browser.