]> git.donarmstrong.com Git - roundcube.git/blob - program/include/rcube_mail_mime.php
c86be499b5cefcfb0c333f79b53b7f05a112bc7b
[roundcube.git] / program / include / rcube_mail_mime.php
1 <?php
2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/rcube_mail_mime.php                                   |
6  |                                                                       |
7  | This file is part of the RoundCube Webmail client                     |
8  | Copyright (C) 2007-2008, RoundCube Dev. - Switzerland                 |
9  | Licensed under the GNU GPL                                            |
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
23 /**
24  * Replacement PEAR:Mail_mime with some additional or overloaded methods
25  *
26  * @package Mail
27  */
28 class rcube_mail_mime extends Mail_mime
29 {
30
31   protected $mime_content;
32
33   /**
34    * Set build parameters
35    */
36   function setParam($param)
37   {
38     if (is_array($param)) {
39       $this->_build_params = array_merge($this->_build_params, $param);
40     }
41   }
42   
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;
60     if ($isfilename === true) {
61       $filename = ($name == '' ? $file : $name);
62     }
63     else {
64       $filename = $name;
65     }
66
67     if (PEAR::isError($filedata)) {
68         return $filedata;
69     }
70
71     if ($contentid == '') {
72        $contentid = md5(uniqid(time()));
73     }
74
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   }
84   
85   
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;
94   }
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;
110   }
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
130       if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) {
131         $chunks = $this->_explode_quoted_string(',', $hdr_value);
132       }
133       else {
134         $chunks = array($hdr_value);
135       }
136
137       $hdr_value = '';
138       $line_len = 0;
139
140       foreach ($chunks as $i => $value) {
141         $value = trim($value);
142
143         //This header contains non ASCII chars and should be encoded.
144         if (preg_match('/[\x80-\xFF]{1}/', $value)) {
145           $suffix = '';
146           // Don't encode e-mail address
147           if (preg_match('/(.+)\s(<.+@[a-z0-9\-\.]+>)$/Ui', $value, $matches)) {
148             $value = $matches[1];
149             $suffix = ' '.$matches[2];
150           }
151
152           switch ($params['head_encoding']) {
153             case 'base64':
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';
163             // replace ?, =, _ and spaces
164             $encoded = str_replace(array('=','_','?',' '), array('=3D','=5F','=3F','_'), $value);
165             $encoded = preg_replace('/([\x80-\xFF])/e', "'='.sprintf('%02X', ord('\\1'))", $encoded);
166           }
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);
173         if ($i == 0 || $line_len + $len < $maxlen) {
174           $hdr_value .= ($i>0?', ':'') . $value;
175           $line_len += $len + ($i>0?2:0);
176         }
177         else {
178           $hdr_value .= ($i>0?', ':'') . "\n " . $value;
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);
194     for ($q=$p=$i=0; $i < $strlen; $i++) {
195       if ($string{$i} == "\"" && $string{$i-1} != "\\") {
196         $q = $q ? false : true;
197       }
198       else if (!$q && $string{$i} == $delimiter) {
199         $result[] = substr($string, $p, $i - $p);
200         $p = $i + 1;
201       }
202     }
203     
204     $result[] = substr($string, $p);
205     return $result;
206   }
207   
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   }
222
223 }
224