summaryrefslogtreecommitdiff
path: root/program/include/rcube_mail_mime.php
blob: ab93d3a708029cfecc2f8314b7eae451fb2fc7b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?php

/*
 +-----------------------------------------------------------------------+
 | program/include/rcube_mail_mime.php                                   |
 |                                                                       |
 | This file is part of the RoundCube Webmail client                     |
 | Copyright (C) 2007-2009, RoundCube Dev. - Switzerland                 |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 | PURPOSE:                                                              |
 |   Extend PEAR:Mail_mime class and override encodeHeaders method       |
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 +-----------------------------------------------------------------------+

 $Id: sendmail.inc 506 2007-03-14 00:39:51Z thomasb $

*/


/**
 * Replacement PEAR:Mail_mime with some additional or overloaded methods
 *
 * @package Mail
 */
class rcube_mail_mime extends Mail_mime
{

  protected $mime_content;

  /**
   * Set build parameters
   */
  function setParam($param)
  {
    if (is_array($param)) {
      $this->_build_params = array_merge($this->_build_params, $param);
    }
  }
  
  /**
   * Adds an image to the list of embedded images.
   *
   * @param  string  $file       The image file name OR image data itself
   * @param  string  $c_type     The content type
   * @param  string  $name       The filename of the image.
   *                             Only use if $file is the image data
   * @param  bool    $isfilename Whether $file is a filename or not
   *                             Defaults to true
   * @param  string  $contentid  Desired Content-ID of MIME part
   *                             Defaults to generated unique ID
   * @return mixed   true on success or PEAR_Error object
   * @access public
   */
  function addHTMLImage($file, $c_type='application/octet-stream', $name = '', $isfilename = true, $contentid = '')
  {
    $filedata = ($isfilename === true) ? $this->_file2str($file) : $file;
    if ($isfilename === true) {
      $filename = ($name == '' ? $file : $name);
    }
    else {
      $filename = $name;
    }

    if (PEAR::isError($filedata)) {
        return $filedata;
    }

    if ($contentid == '') {
       $contentid = md5(uniqid(time()));
    }

    $this->_html_images[] = array(
      'body'   => $filedata,
      'name'   => $filename,
      'c_type' => $c_type,
      'cid'    => $contentid
    );

    return true;
  }
  
  
  /**
  * returns the HTML body portion of the message
  * @return string HTML body of the message
  * @access public
  */
  function getHTMLBody()
  {
     return $this->_htmlbody;
  }
  
  
  /**
   * Creates a new mimePart object, using multipart/mixed as
   * the initial content-type and returns it during the
   * build process.
   *
   * @return object  The multipart/mixed mimePart object
   * @access private
   */
  function &_addMixedPart()
  {
    $params['content_type'] = $this->_headers['Content-Type'] ? $this->_headers['Content-Type'] : 'multipart/mixed';
    $ret = new Mail_mimePart('', $params);
    return $ret;
  }
  
  
  /**
   * Encodes a header as per RFC2047
   *
   * @param  array $input The header data to encode
   * @param  array $params Extra build parameters
   * @return array Encoded data
   * @access private
   * @override
   */
  function _encodeHeaders($input, $params = array())
  {
    $maxlen = 73;
    $params += $this->_build_params;
    
    foreach ($input as $hdr_name => $hdr_value)
    {
      // if header contains e-mail addresses
      if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) {
        $chunks = rcube_explode_quoted_string(',', $hdr_value);
      }
      else {
        $chunks = array($hdr_value);
      }

      $hdr_value = '';
      $line_len = 0;

      foreach ($chunks as $i => $value) {
        $value = trim($value);

        //This header contains non ASCII chars and should be encoded.
        if (preg_match('/[\x80-\xFF]{1}/', $value)) {
          $suffix = '';
          // Don't encode e-mail address
          if (preg_match('/(.+)\s(<.+@[a-z0-9\-\.]+>)$/Ui', $value, $matches)) {
            $value = $matches[1];
            $suffix = ' '.$matches[2];
          }

          switch ($params['head_encoding']) {
            case 'base64':
            // Base64 encoding has been selected.
            $mode = 'B';
            $encoded = base64_encode($value);
            break;

            case 'quoted-printable':
            default:
            // quoted-printable encoding has been selected
            $mode = 'Q';
            // replace ?, =, _ and spaces
            $encoded = str_replace(array('=','_','?',' '), array('=3D','=5F','=3F','_'), $value);
            $encoded = preg_replace('/([\x80-\xFF])/e', "'='.sprintf('%02X', ord('\\1'))", $encoded);
          }

          $value = '=?' . $params['head_charset'] . '?' . $mode . '?' . $encoded . '?=' . $suffix;
        }

        // add chunk to output string by regarding the header maxlen
        $len = strlen($value);
        if ($i == 0 || $line_len + $len < $maxlen) {
          $hdr_value .= ($i>0?', ':'') . $value;
          $line_len += $len + ($i>0?2:0);
        }
        else {
          $hdr_value .= ($i>0?', ':'') . "\n " . $value;
          $line_len = $len;
        }
      }

      $input[$hdr_name] = wordwrap($hdr_value, 990, "\n", true);  // hard limit header length
    }

    return $input;
  }


  /**
   * Provides caching of body of constructed MIME Message to avoid 
   * duplicate construction of message and damage of MIME headers
   *
   * @return string The mime content
   * @access public
   * @override
   */
  public function &get($build_params = null)
  {
    if(empty($this->mime_content))
      $this->mime_content = parent::get($build_params);
    return $this->mime_content;
  }

}