MDL-60194 lib: Internal changes by Moodle to phpmailer.
[moodle.git] / lib / phpmailer / moodle_phpmailer.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Customised version of phpmailer for Moodle
19  *
20  * @package    core
21  * @author     Dan Poltawski <talktodan@gmail.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 defined('MOODLE_INTERNAL') || die();
27 // PLEASE NOTE: we use the phpmailer class _unmodified_
28 // through the joys of OO. Distros are free to use their stock
29 // version of this file.
31 /**
32  * Moodle Customised version of the PHPMailer class
33  *
34  * This class extends the stock PHPMailer class
35  * in order to make sensible configuration choices,
36  * and behave in a way which is friendly to moodle.
37  *
38  * @copyright 2009 Dan Poltawski <talktodan@gmail.com>
39  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40  * @since     Moodle 2.0
41  */
42 class moodle_phpmailer extends \PHPMailer\PHPMailer\PHPMailer {
44     /**
45      * Constructor - creates an instance of the PHPMailer class
46      * with Moodle defaults.
47      */
48     public function __construct(){
49         global $CFG;
50         $this->Version   = 'Moodle '.$CFG->version;         // mailer version
51         $this->CharSet   = 'UTF-8';
52         // MDL-52637: Disable the automatic TLS encryption added in v5.2.10 (9da56fc1328a72aa124b35b738966315c41ef5c6).
53         $this->SMTPAutoTLS = false;
55         if (!empty($CFG->smtpauthtype)) {
56             $this->AuthType = $CFG->smtpauthtype;
57         }
59         // Some MTAs may do double conversion of LF if CRLF used, CRLF is required line ending in RFC 822bis.
60         if (isset($CFG->mailnewline) and $CFG->mailnewline == 'CRLF') {
61             parent::setLE("\r\n");
62         } else {
63             parent::setLE("\n");
64         }
65     }
67     /**
68      * Extended AddCustomHeader function in order to stop duplicate 
69      * message-ids
70      * http://tracker.moodle.org/browse/MDL-3681
71      */
72     public function addCustomHeader($custom_header, $value = null) {
73         if ($value === null and preg_match('/message-id:(.*)/i', $custom_header, $matches)) {
74             $this->MessageID = trim($matches[1]);
75             return true;
76         } else if ($value !== null and strcasecmp($custom_header, 'message-id') === 0) {
77             $this->MessageID = trim($value);
78             return true;
79         } else {
80             return parent::addCustomHeader($custom_header, $value);
81         }
82     }
84     /**
85      * Use internal moodles own core_text to encode mimeheaders.
86      * Fall back to phpmailers inbuilt functions if not 
87      */
88     public function encodeHeader($str, $position = 'text') {
89         $encoded = core_text::encode_mimeheader($str, $this->CharSet);
90         if ($encoded !== false) {
91             if ($position === 'phrase') {
92                 // Escape special symbols in each line in the encoded string, join back together and enclose in quotes.
93                 $chunks = preg_split("/\\n/", $encoded);
94                 $chunks = array_map(function($chunk) {
95                     return addcslashes($chunk, "\0..\37\177\\\"");
96                 }, $chunks);
97                 return '"' . join(parent::getLE(), $chunks) . '"';
98             }
99             return str_replace("\n", parent::getLE(), $encoded);
100         }
102         return parent::encodeHeader($str, $position);
103     }
105     /**
106      * Replaced function to fix tz bug:
107      * http://tracker.moodle.org/browse/MDL-12596
108      */
109     public static function rfcDate() {
110         $tz = date('Z');
111         $tzs = ($tz < 0) ? '-' : '+';
112         $tz = abs($tz);
113         $tz = (($tz - ($tz%3600) )/3600)*100 + ($tz%3600)/60; // fixed tz bug
114         $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
116         return $result;
117     }
119     /**
120      * Sends this mail.
121      *
122      * This function has been overridden to facilitate unit testing.
123      *
124      * @return bool
125      */
126     public function postSend() {
127         // Now ask phpunit if it wants to catch this message.
128         if (PHPUNIT_TEST) {
129             if (!phpunit_util::is_redirecting_phpmailer()) {
130                 debugging('Unit tests must not send real emails! Use $this->redirectEmails()');
131                 return true;
132             }
133             $mail = new stdClass();
134             $mail->header = $this->MIMEHeader;
135             $mail->body = $this->MIMEBody;
136             $mail->subject = $this->Subject;
137             $mail->from = $this->From;
138             $mail->to = $this->to[0][0];
139             phpunit_util::phpmailer_sent($mail);
140             return true;
141         } else {
142             return parent::postSend();
143         }
144     }