File: Message.php

package info (click to toggle)
horde3 3.1.3-4etch7
  • links: PTS
  • area: main
  • in suites: etch
  • size: 22,876 kB
  • ctags: 18,071
  • sloc: php: 75,151; xml: 2,979; sql: 1,069; makefile: 79; sh: 64
file content (344 lines) | stat: -rw-r--r-- 10,401 bytes parent folder | download | duplicates (2)
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
<?php

require_once dirname(__FILE__) . '/Part.php';

/**
 * The MIME_Message:: class provides methods for creating and manipulating
 * MIME email messages.
 *
 * $Horde: framework/MIME/MIME/Message.php,v 1.76.10.12 2006/01/01 21:28:24 jan Exp $
 *
 * Copyright 1999-2006 Chuck Hagenbuch <chuck@horde.org>
 * Copyright 2002-2006 Michael Slusarz <slusarz@bigworm.colorado.edu>
 *
 * See the enclosed file COPYING for license information (LGPL). If you
 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
 *
 * @author  Chuck Hagenbuch <chuck@horde.org>
 * @author  Michael Slusarz <slusarz@bigworm.colorado.edu>
 * @since   Horde 1.3
 * @package Horde_MIME
 */
class MIME_Message extends MIME_Part {

    /**
     * Has the message been parsed via buildMessage()?
     *
     * @var boolean
     */
    var $_build = false;

    /**
     * The server to default unqualified addresses to.
     *
     * @var string
     */
    var $_defaultServer = null;

    /**
     * Constructor - creates a new MIME email message.
     *
     * @param string $defaultServer  The server to default unqualified
     *                               addresses to.
     */
    function MIME_Message($defaultServer = null)
    {
        if (is_null($defaultServer)) {
            $this->_defaultServer = $_SERVER['SERVER_NAME'];
        } else {
            $this->_defaultServer = $defaultServer;
        }
    }

    /**
     * Create a MIME_Message object from a MIME_Part object.
     * This function can be called statically via:
     *    MIME_Message::convertMIMEPart();
     *
     * @param MIME_Part &$mime_part  The MIME_Part object.
     * @param string $server         The server to default unqualified
     *                               addresses to.
     *
     * @return MIME_Message  The new MIME_Message object.
     */
    function &convertMIMEPart(&$mime_part, $server = null)
    {
        if (!$mime_part->getMIMEId()) {
            $mime_part->setMIMEId(1);
        }

        $mime_message = &new MIME_Message($server);
        $mime_message->addPart($mime_part);
        $mime_message->buildMessage();

        return $mime_message;
    }

    /**
     * Sends this message.
     *
     * @param string $email    The address list to send to.
     * @param mixed &$headers  The MIME_Headers object holding this message's
     *                         headers, or a hash with header->value mappings.
     * @param string $driver   The Mail driver to use (since Horde 3.0.4).
     * @param array $params    Any parameters necessary for the Mail driver
     *                         (since Horde 3.0.4).
     *
     * @return mixed  True on success, PEAR_Error on error.
     */
    function send($email, &$headers, $driver = null, $params = array())
    {
        global $conf;
        static $mailer;

        if (!isset($mailer)) {
            require_once 'Mail.php';
            if (!isset($driver)) {
                $driver = $conf['mailer']['type'];
                $params = $conf['mailer']['params'];
            }
            $mailer = Mail::factory($driver, $params);
        }

        $msg = $this->toString();
        if (is_object($headers)) {
            $headerArray = $this->encode($headers->toArray(), $this->getCharset());
        } else {
            $headerArray = $this->encode($headers, $this->getCharset());
        }

        /* Make sure the message has a trailing newline. */
        if (substr($msg, -1) != "\n") {
            $msg .= "\n";
        }

        $result = $mailer->send(MIME::encodeAddress($email), $headerArray, $msg);

        if (is_a($result, 'PEAR_Error') &&
            $conf['mailer']['type'] == 'sendmail') {
            // Interpret return values as defined in /usr/include/sysexits.h
            switch ($result->getCode()) {
            case 64: // EX_USAGE
                $error = 'sendmail: ' . _("command line usage error") . ' (64)';
                break;

            case 65: // EX_DATAERR
                $error = 'sendmail: ' . _("data format error") . ' (65)';
                break;

            case 66: // EX_NOINPUT
                $error = 'sendmail: ' . _("cannot open input") . ' (66)';
                break;

            case 67: // EX_NOUSER
                $error = 'sendmail: ' . _("addressee unknown") . ' (67)';
                break;

            case 68: // EX_NOHOST
                $error = 'sendmail: ' . _("host name unknown") . ' (68)';
                break;

            case 69: // EX_UNAVAILABLE
                $error = 'sendmail: ' . _("service unavailable") . ' (69)';
                break;

            case 70: // EX_SOFTWARE
                $error = 'sendmail: ' . _("internal software error") . ' (70)';
                break;

            case 71: // EX_OSERR
                $error = 'sendmail: ' . _("system error") . ' (71)';
                break;

            case 72: // EX_OSFILE
                $error = 'sendmail: ' . _("critical system file missing") . ' (72)';
                break;

            case 73: // EX_CANTCREAT
                $error = 'sendmail: ' . _("cannot create output file") . ' (73)';
                break;

            case 74: // EX_IOERR
                $error = 'sendmail: ' . _("input/output error") . ' (74)';
                break;

            case 75: // EX_TEMPFAIL
                $error = 'sendmail: ' . _("temporary failure") . ' (75)';
                break;

            case 76: // EX_PROTOCOL
                $error = 'sendmail: ' . _("remote error in protocol") . ' (76)';
                break;

            case 77: // EX_NOPERM
                $error = 'sendmail: ' . _("permission denied") . ' (77)';
                break;

            case 78: // EX_CONFIG
                $error = 'sendmail: ' . _("configuration error") . ' (78)';
                break;

            case 79: // EX_NOTFOUND
                $error = 'sendmail: ' . _("entry not found") . ' (79)';
                break;

            default:
                $error = $result;
            }
            return PEAR::raiseError($error);
        }

        return $result;
    }

    /**
     * Take a set of headers and make sure they are encoded properly.
     *
     * @param array $headers   The headers to encode.
     * @param string $charset  The character set to use.
     *
     * @return array  The array of encoded headers.
     */
    function encode($headers, $charset)
    {
        require_once 'Horde/MIME.php';

        $addressKeys = array('To', 'Cc', 'Bcc', 'From');
        foreach ($headers as $key => $val) {
            if (in_array($key, $addressKeys)) {
                $text = MIME::encodeAddress($val, $charset, $this->_defaultServer);
                if (is_a($text, 'PEAR_Error')) {
                    $text = $val;
                }
            } else {
                $text = MIME::encode($val, $charset);
            }
            $headers[$key] = MIME::wrapHeaders($key, $text, $this->getEOL());
        }

        return $headers;
    }

    /**
     * Add the proper set of MIME headers for this message to an array.
     *
     * @param array $headers  The headers to add the MIME headers to.
     *
     * @return array  The full set of headers including MIME headers.
     */
    function header($headers = array())
    {
        /* Per RFC 2045 [4], this MUST appear in the message headers. */
        $headers['MIME-Version'] = '1.0';

        if ($this->_build) {
            return parent::header($headers);
        } else {
            $this->buildMessage();
            return $this->encode($this->header($headers), $this->getCharset());
        }
    }

    /**
     * Return the entire message contents, including headers, as a string.
     *
     * @return string  The encoded, generated message.
     */
    function toString()
    {
        if ($this->_build) {
            return parent::toString(false);
        } else {
            $this->buildMessage();
            return $this->toString();
        }
    }

    /**
     * Build message from current contents.
     */
    function buildMessage()
    {
        if ($this->_build) {
            return;
        }

        if (empty($this->_flags['setType'])) {
            if (count($this->_parts) > 1) {
                $this->setType('multipart/mixed');
            } else {
                /* Copy the information from the single part to the current
                   base part. */
                if (($obVars = get_object_vars(reset($this->_parts)))) {
                    foreach ($obVars as $key => $val) {
                        $this->$key = $val;
                    }
                }
            }
        }

        /* Set the build flag now. */
        $this->_build = true;
    }

    /**
     * Get a list of all MIME subparts.
     *
     * @return array  An array of the MIME_Part subparts.
     */
    function getParts()
    {
        if ($this->_build) {
            return parent::getParts();
        } else {
            $this->buildMessage();
            return $this->getParts();
        }
    }

    /**
     * Return the base part of the message. This function does NOT
     * return a reference to make sure that the whole MIME_Message
     * object isn't accidentally modified.
     *
     * @return MIME_Message  The base MIME_Part of the message.
     */
    function getBasePart()
    {
        $this->buildMessage();
        return $this;
    }

    /**
     * Retrieve a specific MIME part.
     *
     * @param string $id  The MIME_Part ID string.
     *
     * @return MIME_Part  The MIME_Part requested, or false if the part
     *                    doesn't exist.
     */
    function &getPart($id)
    {
        if ($this->_build) {
            $part = parent::getPart($id);
        } else {
            $this->buildMessage();
            $part = $this->getPart($id);
        }
        if (is_a($part, 'MIME_Message')) {
            $newpart = &new MIME_Part();
            $skip = array('_build', '_defaultServer');
            foreach (array_keys(get_object_vars($part)) as $key) {
                /* Ignore local variables that aren't a part of the original
                 * class. */
                if (!in_array($key, $skip)) {
                    $newpart->$key = &$part->$key;
                }
            }
            return $newpart;
        } else {
            return $part;
       }
    }

}