thomascube
2008-09-13 14c5b8e1323c029a17abc4ead8999d508c86ac5b
commit | author | age
ab6f80 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
47124c 5  | program/include/rcube_mail_mime.php                                   |
ab6f80 6  |                                                                       |
T 7  | This file is part of the RoundCube Webmail client                     |
47124c 8  | Copyright (C) 2007-2008, RoundCube Dev. - Switzerland                 |
ab6f80 9  | Licensed under the GNU GPL                                            |
T 10  |                                                                       |
11  | PURPOSE:                                                              |
12  |   Extend PEAR:Mail_mime class and override encodeHeaders method       |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
18  $Id: sendmail.inc 506 2007-03-14 00:39:51Z thomasb $
19
20 */
21
22
47124c 23 /**
T 24  * Replacement PEAR:Mail_mime with some additional or overloaded methods
25  *
26  * @package Mail
27  */
28 class rcube_mail_mime extends Mail_mime
ab6f80 29 {
60881e 30
A 31   protected $mime_content;
32
fba1f5 33   /**
T 34    * Set build parameters
35    */
36   function setParam($param)
37   {
47124c 38     if (is_array($param)) {
fba1f5 39       $this->_build_params = array_merge($this->_build_params, $param);
47124c 40     }
fba1f5 41   }
ab6f80 42   
T 43   /**
44    * Adds an image to the list of embedded images.
45    *
46    * @param  string  $file       The image file name OR image data itself
47    * @param  string  $c_type     The content type
48    * @param  string  $name       The filename of the image.
49    *                             Only use if $file is the image data
50    * @param  bool    $isfilename Whether $file is a filename or not
51    *                             Defaults to true
52    * @param  string  $contentid  Desired Content-ID of MIME part
53    *                             Defaults to generated unique ID
54    * @return mixed   true on success or PEAR_Error object
55    * @access public
56    */
57   function addHTMLImage($file, $c_type='application/octet-stream', $name = '', $isfilename = true, $contentid = '')
58   {
59     $filedata = ($isfilename === true) ? $this->_file2str($file) : $file;
47124c 60     if ($isfilename === true) {
ab6f80 61       $filename = ($name == '' ? $file : $name);
47124c 62     }
T 63     else {
ab6f80 64       $filename = $name;
47124c 65     }
ab6f80 66
47124c 67     if (PEAR::isError($filedata)) {
ab6f80 68         return $filedata;
47124c 69     }
ab6f80 70
47124c 71     if ($contentid == '') {
ab6f80 72        $contentid = md5(uniqid(time()));
47124c 73     }
ab6f80 74
T 75     $this->_html_images[] = array(
76       'body'   => $filedata,
77       'name'   => $filename,
78       'c_type' => $c_type,
79       'cid'    => $contentid
80     );
81
82     return true;
83   }
fba1f5 84   
ab6f80 85   
T 86   /**
87   * returns the HTML body portion of the message
88   * @return string HTML body of the message
89   * @access public
90   */
91   function getHTMLBody()
92   {
93      return $this->_htmlbody;
fba1f5 94   }
T 95   
96   
97   /**
98    * Creates a new mimePart object, using multipart/mixed as
99    * the initial content-type and returns it during the
100    * build process.
101    *
102    * @return object  The multipart/mixed mimePart object
103    * @access private
104    */
105   function &_addMixedPart()
106   {
107     $params['content_type'] = $this->_headers['Content-Type'] ? $this->_headers['Content-Type'] : 'multipart/mixed';
108     $ret = new Mail_mimePart('', $params);
109     return $ret;
ab6f80 110   }
T 111   
112   
113   /**
114    * Encodes a header as per RFC2047
115    *
116    * @param  array $input The header data to encode
117    * @param  array $params Extra build parameters
118    * @return array Encoded data
119    * @access private
120    * @override
121    */
122   function _encodeHeaders($input, $params = array())
123   {
124     $maxlen = 73;
125     $params += $this->_build_params;
126     
127     foreach ($input as $hdr_name => $hdr_value)
128     {
129       // if header contains e-mail addresses
47124c 130       if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) {
ab6f80 131         $chunks = $this->_explode_quoted_string(',', $hdr_value);
47124c 132       }
T 133       else {
ab6f80 134         $chunks = array($hdr_value);
47124c 135       }
ab6f80 136
T 137       $hdr_value = '';
138       $line_len = 0;
139
47124c 140       foreach ($chunks as $i => $value) {
ab6f80 141         $value = trim($value);
T 142
143         //This header contains non ASCII chars and should be encoded.
14c5b8 144         if (preg_match('/[\x80-\xFF]{1}/', $value)) {
ab6f80 145           $suffix = '';
T 146           // Don't encode e-mail address
47124c 147           if (preg_match('/(.+)\s(<.+@[a-z0-9\-\.]+>)$/Ui', $value, $matches)) {
ab6f80 148             $value = $matches[1];
T 149             $suffix = ' '.$matches[2];
150           }
151
47124c 152           switch ($params['head_encoding']) {
ab6f80 153             case 'base64':
T 154             // Base64 encoding has been selected.
155             $mode = 'B';
156             $encoded = base64_encode($value);
157             break;
158
159             case 'quoted-printable':
160             default:
161             // quoted-printable encoding has been selected
162             $mode = 'Q';
14c5b8 163             // replace ?, =, _ and spaces
T 164             $encoded = str_replace(array('=','_','?',' '), array('=3D','=5F','=3F','_'), $value);
165             $encoded = preg_replace('/([\x80-\xFF])/e', "'='.sprintf('%02X', ord('\\1'))", $encoded);
ab6f80 166           }
T 167
168           $value = '=?' . $params['head_charset'] . '?' . $mode . '?' . $encoded . '?=' . $suffix;
169         }
170
171         // add chunk to output string by regarding the header maxlen
172         $len = strlen($value);
47124c 173         if ($i == 0 || $line_len + $len < $maxlen) {
ab6f80 174           $hdr_value .= ($i>0?', ':'') . $value;
T 175           $line_len += $len + ($i>0?2:0);
176         }
47124c 177         else {
ab6f80 178           $hdr_value .= ($i>0?', ':'') . "\n " . $value;
T 179           $line_len = $len;
180         }
181       }
182
183       $input[$hdr_name] = $hdr_value;
184     }
185
186     return $input;
187   }
188
189
190   function _explode_quoted_string($delimiter, $string)
191   {
192     $result = array();
193     $strlen = strlen($string);
47124c 194     for ($q=$p=$i=0; $i < $strlen; $i++) {
T 195       if ($string{$i} == "\"" && $string{$i-1} != "\\") {
ab6f80 196         $q = $q ? false : true;
47124c 197       }
T 198       else if (!$q && $string{$i} == $delimiter) {
ab6f80 199         $result[] = substr($string, $p, $i - $p);
T 200         $p = $i + 1;
201       }
202     }
203     
204     $result[] = substr($string, $p);
205     return $result;
206   }
60881e 207   
A 208   /**
209    * Provides caching of body of constructed MIME Message to avoid 
210    * duplicate construction of message and damage of MIME headers
211    *
212    * @return string The mime content
213    * @access public
214    * @override
215    */
216   public function &get($build_params = null)
217   {
218     if(empty($this->mime_content))
219       $this->mime_content = parent::get($build_params);
220     return $this->mime_content;
221   }
ab6f80 222
T 223 }
224