source: branches/version-2_5-dev/data/module/Mail.php @ 20119

Revision 20119, 9.7 KB checked in by nanasess, 13 years ago (diff)

module 以下は svn:keywords を除外

  • Property svn:eol-style set to LF
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/**
3 *  PEAR's Mail:: interface.
4 *
5 * PHP versions 4 and 5
6 *
7 * LICENSE:
8 *
9 * Copyright (c) 2002-2007, Richard Heyes
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * o Redistributions of source code must retain the above copyright
17 *   notice, this list of conditions and the following disclaimer.
18 * o Redistributions in binary form must reproduce the above copyright
19 *   notice, this list of conditions and the following disclaimer in the
20 *   documentation and/or other materials provided with the distribution.
21 * o The names of the authors may not be used to endorse or promote
22 *   products derived from this software without specific prior written
23 *   permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * @category    Mail
38 * @package     Mail
39 * @author      Chuck Hagenbuch <chuck@horde.org>
40 * @copyright   1997-2010 Chuck Hagenbuch
41 * @license     http://opensource.org/licenses/bsd-license.php New BSD License
42 * @version     CVS: $Id: Mail.php 294747 2010-02-08 08:18:33Z clockwerx $
43 * @link        http://pear.php.net/package/Mail/
44 */
45
46require_once 'PEAR.php';
47
48/**
49 * PEAR's Mail:: interface. Defines the interface for implementing
50 * mailers under the PEAR hierarchy, and provides supporting functions
51 * useful in multiple mailer backends.
52 *
53 * @access public
54 * @version $Revision: 294747 $
55 * @package Mail
56 */
57class Mail
58{
59    /**
60     * Line terminator used for separating header lines.
61     * @var string
62     */
63    var $sep = "\r\n";
64
65    /**
66     * Provides an interface for generating Mail:: objects of various
67     * types
68     *
69     * @param string $driver The kind of Mail:: object to instantiate.
70     * @param array  $params The parameters to pass to the Mail:: object.
71     * @return object Mail a instance of the driver class or if fails a PEAR Error
72     * @access public
73     */
74    function &factory($driver, $params = array())
75    {
76        $driver = strtolower($driver);
77        @include_once 'Mail/' . $driver . '.php';
78        $class = 'Mail_' . $driver;
79        if (class_exists($class)) {
80            $mailer = new $class($params);
81            return $mailer;
82        } else {
83            return PEAR::raiseError('Unable to find class for driver ' . $driver);
84        }
85    }
86
87    /**
88     * Implements Mail::send() function using php's built-in mail()
89     * command.
90     *
91     * @param mixed $recipients Either a comma-seperated list of recipients
92     *              (RFC822 compliant), or an array of recipients,
93     *              each RFC822 valid. This may contain recipients not
94     *              specified in the headers, for Bcc:, resending
95     *              messages, etc.
96     *
97     * @param array $headers The array of headers to send with the mail, in an
98     *              associative array, where the array key is the
99     *              header name (ie, 'Subject'), and the array value
100     *              is the header value (ie, 'test'). The header
101     *              produced from those values would be 'Subject:
102     *              test'.
103     *
104     * @param string $body The full text of the message body, including any
105     *               Mime parts, etc.
106     *
107     * @return mixed Returns true on success, or a PEAR_Error
108     *               containing a descriptive error message on
109     *               failure.
110     *
111     * @access public
112     * @deprecated use Mail_mail::send instead
113     */
114    function send($recipients, $headers, $body)
115    {
116        if (!is_array($headers)) {
117            return PEAR::raiseError('$headers must be an array');
118        }
119
120        $result = $this->_sanitizeHeaders($headers);
121        if (is_a($result, 'PEAR_Error')) {
122            return $result;
123        }
124
125        // if we're passed an array of recipients, implode it.
126        if (is_array($recipients)) {
127            $recipients = implode(', ', $recipients);
128        }
129
130        // get the Subject out of the headers array so that we can
131        // pass it as a seperate argument to mail().
132        $subject = '';
133        if (isset($headers['Subject'])) {
134            $subject = $headers['Subject'];
135            unset($headers['Subject']);
136        }
137
138        // flatten the headers out.
139        list(, $text_headers) = Mail::prepareHeaders($headers);
140
141        return mail($recipients, $subject, $body, $text_headers);
142    }
143
144    /**
145     * Sanitize an array of mail headers by removing any additional header
146     * strings present in a legitimate header's value.  The goal of this
147     * filter is to prevent mail injection attacks.
148     *
149     * @param array $headers The associative array of headers to sanitize.
150     *
151     * @access private
152     */
153    function _sanitizeHeaders(&$headers)
154    {
155        foreach ($headers as $key => $value) {
156            $headers[$key] =
157                preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
158                             null, $value);
159        }
160    }
161
162    /**
163     * Take an array of mail headers and return a string containing
164     * text usable in sending a message.
165     *
166     * @param array $headers The array of headers to prepare, in an associative
167     *              array, where the array key is the header name (ie,
168     *              'Subject'), and the array value is the header
169     *              value (ie, 'test'). The header produced from those
170     *              values would be 'Subject: test'.
171     *
172     * @return mixed Returns false if it encounters a bad address,
173     *               otherwise returns an array containing two
174     *               elements: Any From: address found in the headers,
175     *               and the plain text version of the headers.
176     * @access private
177     */
178    function prepareHeaders($headers)
179    {
180        $lines = array();
181        $from = null;
182
183        foreach ($headers as $key => $value) {
184            if (strcasecmp($key, 'From') === 0) {
185                include_once 'Mail/RFC822.php';
186                $parser = new Mail_RFC822();
187                $addresses = $parser->parseAddressList($value, 'localhost', false);
188                if (is_a($addresses, 'PEAR_Error')) {
189                    return $addresses;
190                }
191
192                $from = $addresses[0]->mailbox . '@' . $addresses[0]->host;
193
194                // Reject envelope From: addresses with spaces.
195                if (strstr($from, ' ')) {
196                    return false;
197                }
198
199                $lines[] = $key . ': ' . $value;
200            } elseif (strcasecmp($key, 'Received') === 0) {
201                $received = array();
202                if (is_array($value)) {
203                    foreach ($value as $line) {
204                        $received[] = $key . ': ' . $line;
205                    }
206                }
207                else {
208                    $received[] = $key . ': ' . $value;
209                }
210                // Put Received: headers at the top.  Spam detectors often
211                // flag messages with Received: headers after the Subject:
212                // as spam.
213                $lines = array_merge($received, $lines);
214            } else {
215                // If $value is an array (i.e., a list of addresses), convert
216                // it to a comma-delimited string of its elements (addresses).
217                if (is_array($value)) {
218                    $value = implode(', ', $value);
219                }
220                $lines[] = $key . ': ' . $value;
221            }
222        }
223
224        return array($from, join($this->sep, $lines));
225    }
226
227    /**
228     * Take a set of recipients and parse them, returning an array of
229     * bare addresses (forward paths) that can be passed to sendmail
230     * or an smtp server with the rcpt to: command.
231     *
232     * @param mixed Either a comma-seperated list of recipients
233     *              (RFC822 compliant), or an array of recipients,
234     *              each RFC822 valid.
235     *
236     * @return mixed An array of forward paths (bare addresses) or a PEAR_Error
237     *               object if the address list could not be parsed.
238     * @access private
239     */
240    function parseRecipients($recipients)
241    {
242        include_once 'Mail/RFC822.php';
243
244        // if we're passed an array, assume addresses are valid and
245        // implode them before parsing.
246        if (is_array($recipients)) {
247            $recipients = implode(', ', $recipients);
248        }
249
250        // Parse recipients, leaving out all personal info. This is
251        // for smtp recipients, etc. All relevant personal information
252        // should already be in the headers.
253        $addresses = Mail_RFC822::parseAddressList($recipients, 'localhost', false);
254
255        // If parseAddressList() returned a PEAR_Error object, just return it.
256        if (is_a($addresses, 'PEAR_Error')) {
257            return $addresses;
258        }
259
260        $recipients = array();
261        if (is_array($addresses)) {
262            foreach ($addresses as $ob) {
263                $recipients[] = $ob->mailbox . '@' . $ob->host;
264            }
265        }
266
267        return $recipients;
268    }
269
270}
Note: See TracBrowser for help on using the repository browser.