root@9
|
1 <?php
|
root@9
|
2 /**
|
root@9
|
3 * @file
|
root@9
|
4 * The mail handler class in smtp module, based on code of the phpmailer library,
|
root@9
|
5 * customized and relicensed to GPLv2.
|
root@9
|
6 *
|
root@9
|
7 */
|
root@9
|
8
|
root@9
|
9 /*~ class.phpmailer.php
|
root@9
|
10 Orginal release information:
|
root@9
|
11 .---------------------------------------------------------------------------.
|
root@9
|
12 | Software: PHPMailer - PHP email class |
|
root@9
|
13 | Version: 5.1 |
|
root@9
|
14 | Contact: via sourceforge.net support pages (also www.worxware.com) |
|
root@9
|
15 | Info: http://phpmailer.sourceforge.net |
|
root@9
|
16 | Support: http://sourceforge.net/projects/phpmailer/ |
|
root@9
|
17 | ------------------------------------------------------------------------- |
|
root@9
|
18 | Admin: Andy Prevost (project admininistrator) |
|
root@9
|
19 | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
|
root@9
|
20 | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
|
root@9
|
21 | Founder: Brent R. Matzelle (original founder) |
|
root@9
|
22 | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
|
root@9
|
23 | Copyright (c) 2001-2003, Brent R. Matzelle |
|
root@9
|
24 | ------------------------------------------------------------------------- |
|
root@9
|
25 | License: Distributed under the Lesser General Public License (LGPL) |
|
root@9
|
26 | http://www.gnu.org/copyleft/lesser.html |
|
root@9
|
27 | This program is distributed in the hope that it will be useful - WITHOUT |
|
root@9
|
28 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
root@9
|
29 | FITNESS FOR A PARTICULAR PURPOSE. |
|
root@9
|
30 | ------------------------------------------------------------------------- |
|
root@9
|
31 | We offer a number of paid services (www.worxware.com): |
|
root@9
|
32 | - Web Hosting on highly optimized fast and secure servers |
|
root@9
|
33 | - Technology Consulting |
|
root@9
|
34 | - Oursourcing (highly qualified programmers and graphic designers) |
|
root@9
|
35 '---------------------------------------------------------------------------'
|
root@9
|
36 */
|
root@9
|
37
|
root@9
|
38 /**
|
root@9
|
39 * PHPMailer - PHP email transport class
|
root@9
|
40 * NOTE: Requires PHP version 5 or later
|
root@9
|
41 * @package PHPMailer
|
root@9
|
42 * @author Andy Prevost
|
root@9
|
43 * @author Marcus Bointon
|
root@9
|
44 * @copyright 2004 - 2009 Andy Prevost
|
root@9
|
45 */
|
root@9
|
46
|
root@9
|
47 class PHPMailer {
|
root@9
|
48
|
root@9
|
49 /////////////////////////////////////////////////
|
root@9
|
50 // PROPERTIES, PUBLIC
|
root@9
|
51 /////////////////////////////////////////////////
|
root@9
|
52
|
root@9
|
53 /**
|
root@9
|
54 * Email priority (1 = High, 3 = Normal, 5 = low).
|
root@9
|
55 * @var int
|
root@9
|
56 */
|
root@9
|
57 public $Priority = 3;
|
root@9
|
58
|
root@9
|
59 /**
|
root@9
|
60 * Sets the CharSet of the message.
|
root@9
|
61 * @var string
|
root@9
|
62 */
|
root@9
|
63 public $CharSet = 'iso-8859-1';
|
root@9
|
64
|
root@9
|
65 /**
|
root@9
|
66 * Sets the Content-type of the message.
|
root@9
|
67 * @var string
|
root@9
|
68 */
|
root@9
|
69 public $ContentType = 'text/plain';
|
root@9
|
70
|
root@9
|
71 /**
|
root@9
|
72 * Sets the Encoding of the message. Options for this are
|
root@9
|
73 * "8bit", "7bit", "binary", "base64", and "quoted-printable".
|
root@9
|
74 * @var string
|
root@9
|
75 */
|
root@9
|
76 public $Encoding = '8bit';
|
root@9
|
77
|
root@9
|
78 /**
|
root@9
|
79 * Holds the most recent mailer error message.
|
root@9
|
80 * @var string
|
root@9
|
81 */
|
root@9
|
82 public $ErrorInfo = '';
|
root@9
|
83
|
root@9
|
84 /**
|
root@9
|
85 * Sets the From email address for the message.
|
root@9
|
86 * @var string
|
root@9
|
87 */
|
root@9
|
88 public $From = 'root@localhost';
|
root@9
|
89
|
root@9
|
90 /**
|
root@9
|
91 * Sets the From name of the message.
|
root@9
|
92 * @var string
|
root@9
|
93 */
|
root@9
|
94 public $FromName = 'Root User';
|
root@9
|
95
|
root@9
|
96 /**
|
root@9
|
97 * Sets the Sender email (Return-Path) of the message. If not empty,
|
root@9
|
98 * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
|
root@9
|
99 * @var string
|
root@9
|
100 */
|
root@9
|
101 public $Sender = '';
|
root@9
|
102
|
root@9
|
103 /**
|
root@9
|
104 * Sets the Subject of the message.
|
root@9
|
105 * @var string
|
root@9
|
106 */
|
root@9
|
107 public $Subject = '';
|
root@9
|
108
|
root@9
|
109 /**
|
root@9
|
110 * Sets the Body of the message. This can be either an HTML or text body.
|
root@9
|
111 * If HTML then run IsHTML(TRUE).
|
root@9
|
112 * @var string
|
root@9
|
113 */
|
root@9
|
114 public $Body = '';
|
root@9
|
115
|
root@9
|
116 /**
|
root@9
|
117 * Sets the text-only body of the message. This automatically sets the
|
root@9
|
118 * email to multipart/alternative. This body can be read by mail
|
root@9
|
119 * clients that do not have HTML email capability such as mutt. Clients
|
root@9
|
120 * that can read HTML will view the normal Body.
|
root@9
|
121 * @var string
|
root@9
|
122 */
|
root@9
|
123 public $AltBody = '';
|
root@9
|
124
|
root@9
|
125 /**
|
root@9
|
126 * Sets word wrapping on the body of the message to a given number of
|
root@9
|
127 * characters.
|
root@9
|
128 * @var int
|
root@9
|
129 */
|
root@9
|
130 public $WordWrap = 0;
|
root@9
|
131
|
root@9
|
132 /**
|
root@9
|
133 * Method to send mail: ("mail", "sendmail", or "smtp").
|
root@9
|
134 * @var string
|
root@9
|
135 */
|
root@9
|
136 public $Mailer = 'mail';
|
root@9
|
137
|
root@9
|
138 /**
|
root@9
|
139 * Sets the path of the sendmail program.
|
root@9
|
140 * @var string
|
root@9
|
141 */
|
root@9
|
142 public $Sendmail = '/usr/sbin/sendmail';
|
root@9
|
143
|
root@9
|
144 /**
|
root@9
|
145 * Path to PHPMailer plugins. Useful if the SMTP class
|
root@9
|
146 * is in a different directory than the PHP include path.
|
root@9
|
147 * @var string
|
root@9
|
148 */
|
root@9
|
149 public $PluginDir = '';
|
root@9
|
150
|
root@9
|
151 /**
|
root@9
|
152 * Sets the email address that a reading confirmation will be sent.
|
root@9
|
153 * @var string
|
root@9
|
154 */
|
root@9
|
155 public $ConfirmReadingTo = '';
|
root@9
|
156
|
root@9
|
157 /**
|
root@9
|
158 * Sets the hostname to use in Message-Id and Received headers
|
root@9
|
159 * and as default HELO string. If empty, the value returned
|
root@9
|
160 * by SERVER_NAME is used or 'localhost.localdomain'.
|
root@9
|
161 * @var string
|
root@9
|
162 */
|
root@9
|
163 public $Hostname = '';
|
root@9
|
164
|
root@9
|
165 /**
|
root@9
|
166 * Sets the message ID to be used in the Message-Id header.
|
root@9
|
167 * If empty, a unique id will be generated.
|
root@9
|
168 * @var string
|
root@9
|
169 */
|
root@9
|
170 public $MessageID = '';
|
root@9
|
171
|
root@9
|
172 /////////////////////////////////////////////////
|
root@9
|
173 // PROPERTIES FOR SMTP
|
root@9
|
174 /////////////////////////////////////////////////
|
root@9
|
175
|
root@9
|
176 /**
|
root@9
|
177 * Sets the SMTP hosts. All hosts must be separated by a
|
root@9
|
178 * semicolon. You can also specify a different port
|
root@9
|
179 * for each host by using this format: [hostname:port]
|
root@9
|
180 * (e.g. "smtp1.example.com:25;smtp2.example.com").
|
root@9
|
181 * Hosts will be tried in order.
|
root@9
|
182 * @var string
|
root@9
|
183 */
|
root@9
|
184 public $Host = 'localhost';
|
root@9
|
185
|
root@9
|
186 /**
|
root@9
|
187 * Sets the default SMTP server port.
|
root@9
|
188 * @var int
|
root@9
|
189 */
|
root@9
|
190 public $Port = 25;
|
root@9
|
191
|
root@9
|
192 /**
|
root@9
|
193 * Sets the SMTP HELO of the message (Default is $Hostname).
|
root@9
|
194 * @var string
|
root@9
|
195 */
|
root@9
|
196 public $Helo = '';
|
root@9
|
197
|
root@9
|
198 /**
|
root@9
|
199 * Sets connection prefix.
|
root@9
|
200 * Options are "", "ssl" or "tls"
|
root@9
|
201 * @var string
|
root@9
|
202 */
|
root@9
|
203 public $SMTPSecure = '';
|
root@9
|
204
|
root@9
|
205 /**
|
root@9
|
206 * Sets SMTP authentication. Utilizes the Username and Password variables.
|
root@9
|
207 * @var bool
|
root@9
|
208 */
|
root@9
|
209 public $SMTPAuth = FALSE;
|
root@9
|
210
|
root@9
|
211 /**
|
root@9
|
212 * Sets SMTP username.
|
root@9
|
213 * @var string
|
root@9
|
214 */
|
root@9
|
215 public $Username = '';
|
root@9
|
216
|
root@9
|
217 /**
|
root@9
|
218 * Sets SMTP password.
|
root@9
|
219 * @var string
|
root@9
|
220 */
|
root@9
|
221 public $Password = '';
|
root@9
|
222
|
root@9
|
223 /**
|
root@9
|
224 * Sets the SMTP server timeout in seconds.
|
root@9
|
225 * This function will not work with the win32 version.
|
root@9
|
226 * @var int
|
root@9
|
227 */
|
root@9
|
228 public $Timeout = 10;
|
root@9
|
229
|
root@9
|
230 /**
|
root@9
|
231 * Sets SMTP class debugging on or off.
|
root@9
|
232 * @var bool
|
root@9
|
233 */
|
root@9
|
234 public $SMTPDebug = FALSE;
|
root@9
|
235
|
root@9
|
236 /**
|
root@9
|
237 * Prevents the SMTP connection from being closed after each mail
|
root@9
|
238 * sending. If this is set to TRUE then to close the connection
|
root@9
|
239 * requires an explicit call to SmtpClose().
|
root@9
|
240 * @var bool
|
root@9
|
241 */
|
root@9
|
242 public $SMTPKeepAlive = FALSE;
|
root@9
|
243
|
root@9
|
244 /**
|
root@9
|
245 * Provides the ability to have the TO field process individual
|
root@9
|
246 * emails, instead of sending to entire TO addresses
|
root@9
|
247 * @var bool
|
root@9
|
248 */
|
root@9
|
249 public $SingleTo = FALSE;
|
root@9
|
250
|
root@9
|
251 /**
|
root@9
|
252 * If SingleTo is TRUE, this provides the array to hold the email addresses
|
root@9
|
253 * @var bool
|
root@9
|
254 */
|
root@9
|
255 public $SingleToArray = array();
|
root@9
|
256
|
root@9
|
257 /**
|
root@9
|
258 * Provides the ability to change the line ending
|
root@9
|
259 * @var string
|
root@9
|
260 */
|
root@9
|
261 public $LE = "\n";
|
root@9
|
262
|
root@9
|
263 /**
|
root@9
|
264 * Used with DKIM DNS Resource Record
|
root@9
|
265 * @var string
|
root@9
|
266 */
|
root@9
|
267 public $DKIM_selector = 'phpmailer';
|
root@9
|
268
|
root@9
|
269 /**
|
root@9
|
270 * Used with DKIM DNS Resource Record
|
root@9
|
271 * optional, in format of email address 'you@yourdomain.com'
|
root@9
|
272 * @var string
|
root@9
|
273 */
|
root@9
|
274 public $DKIM_identity = '';
|
root@9
|
275
|
root@9
|
276 /**
|
root@9
|
277 * Used with DKIM DNS Resource Record
|
root@9
|
278 * optional, in format of email address 'you@yourdomain.com'
|
root@9
|
279 * @var string
|
root@9
|
280 */
|
root@9
|
281 public $DKIM_domain = '';
|
root@9
|
282
|
root@9
|
283 /**
|
root@9
|
284 * Used with DKIM DNS Resource Record
|
root@9
|
285 * optional, in format of email address 'you@yourdomain.com'
|
root@9
|
286 * @var string
|
root@9
|
287 */
|
root@9
|
288 public $DKIM_private = '';
|
root@9
|
289
|
root@9
|
290 /**
|
root@9
|
291 * Callback Action function name
|
root@9
|
292 * the function that handles the result of the send email action. Parameters:
|
root@9
|
293 * bool $result result of the send action
|
root@9
|
294 * string $to email address of the recipient
|
root@9
|
295 * string $cc cc email addresses
|
root@9
|
296 * string $bcc bcc email addresses
|
root@9
|
297 * string $subject the subject
|
root@9
|
298 * string $body the email body
|
root@9
|
299 * @var string
|
root@9
|
300 */
|
root@9
|
301 public $action_function = ''; //'callbackAction';
|
root@9
|
302
|
root@9
|
303 /**
|
root@9
|
304 * Sets the PHPMailer Version number
|
root@9
|
305 * @var string
|
root@9
|
306 */
|
root@9
|
307 public $Version = '5.1';
|
root@9
|
308
|
root@9
|
309 /////////////////////////////////////////////////
|
root@9
|
310 // PROPERTIES, PRIVATE AND PROTECTED
|
root@9
|
311 /////////////////////////////////////////////////
|
root@9
|
312
|
root@9
|
313 private $smtp = NULL;
|
root@9
|
314 private $to = array();
|
root@9
|
315 private $cc = array();
|
root@9
|
316 private $bcc = array();
|
root@9
|
317 private $ReplyTo = array();
|
root@9
|
318 private $all_recipients = array();
|
root@9
|
319 private $attachment = array();
|
root@9
|
320 private $CustomHeader = array();
|
root@9
|
321 private $message_type = '';
|
root@9
|
322 private $boundary = array();
|
root@9
|
323 private $error_count = 0;
|
root@9
|
324 private $sign_cert_file = "";
|
root@9
|
325 private $sign_key_file = "";
|
root@9
|
326 private $sign_key_pass = "";
|
root@9
|
327 private $exceptions = FALSE;
|
root@9
|
328
|
root@9
|
329 /////////////////////////////////////////////////
|
root@9
|
330 // CONSTANTS
|
root@9
|
331 /////////////////////////////////////////////////
|
root@9
|
332
|
root@9
|
333 const STOP_MESSAGE = 0; // message only, continue processing
|
root@9
|
334 const STOP_CONTINUE = 1; // message?, likely ok to continue processing
|
root@9
|
335 const STOP_CRITICAL = 2; // message, plus full stop, critical error reached
|
root@9
|
336
|
root@9
|
337 /////////////////////////////////////////////////
|
root@9
|
338 // METHODS, VARIABLES
|
root@9
|
339 /////////////////////////////////////////////////
|
root@9
|
340
|
root@9
|
341 /**
|
root@9
|
342 * Constructor
|
root@9
|
343 * @param boolean $exceptions Should we throw external exceptions?
|
root@9
|
344 */
|
root@9
|
345 public function __construct($exceptions = FALSE) {
|
root@9
|
346 $this->exceptions = ($exceptions == TRUE);
|
root@9
|
347 }
|
root@9
|
348
|
root@9
|
349 /**
|
root@9
|
350 * Sets message type to HTML.
|
root@9
|
351 * @param bool $ishtml
|
root@9
|
352 * @return void
|
root@9
|
353 */
|
root@9
|
354 public function IsHTML($ishtml = TRUE) {
|
root@9
|
355 if ($ishtml) {
|
root@9
|
356 $this->ContentType = $this->is_html = 'text/html';
|
root@9
|
357 }
|
root@9
|
358 else {
|
root@9
|
359 $this->ContentType = $this->is_html = 'text/plain';
|
root@9
|
360 }
|
root@9
|
361 }
|
root@9
|
362
|
root@9
|
363 /**
|
root@9
|
364 * Sets Mailer to send message using SMTP.
|
root@9
|
365 * @return void
|
root@9
|
366 */
|
root@9
|
367 public function IsSMTP() {
|
root@9
|
368 $this->Mailer = 'smtp';
|
root@9
|
369 }
|
root@9
|
370
|
root@9
|
371 /**
|
root@9
|
372 * Sets Mailer to send message using PHP mail() function.
|
root@9
|
373 * @return void
|
root@9
|
374 */
|
root@9
|
375 public function IsMail() {
|
root@9
|
376 $this->Mailer = 'mail';
|
root@9
|
377 }
|
root@9
|
378
|
root@9
|
379 /**
|
root@9
|
380 * Sets Mailer to send message using the $Sendmail program.
|
root@9
|
381 * @return void
|
root@9
|
382 */
|
root@9
|
383 public function IsSendmail() {
|
root@9
|
384 if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
|
root@9
|
385 $this->Sendmail = '/var/qmail/bin/sendmail';
|
root@9
|
386 }
|
root@9
|
387 $this->Mailer = 'sendmail';
|
root@9
|
388 }
|
root@9
|
389
|
root@9
|
390 /**
|
root@9
|
391 * Sets Mailer to send message using the qmail MTA.
|
root@9
|
392 * @return void
|
root@9
|
393 */
|
root@9
|
394 public function IsQmail() {
|
root@9
|
395 if (stristr(ini_get('sendmail_path'), 'qmail')) {
|
root@9
|
396 $this->Sendmail = '/var/qmail/bin/sendmail';
|
root@9
|
397 }
|
root@9
|
398 $this->Mailer = 'sendmail';
|
root@9
|
399 }
|
root@9
|
400
|
root@9
|
401 /////////////////////////////////////////////////
|
root@9
|
402 // METHODS, RECIPIENTS
|
root@9
|
403 /////////////////////////////////////////////////
|
root@9
|
404
|
root@9
|
405 /**
|
root@9
|
406 * Adds a "To" address.
|
root@9
|
407 * @param string $address
|
root@9
|
408 * @param string $name
|
root@9
|
409 * @return boolean TRUE on success, FALSE if address already used
|
root@9
|
410 */
|
root@9
|
411 public function AddAddress($address, $name = '') {
|
root@9
|
412 return $this->AddAnAddress('to', $address, $name);
|
root@9
|
413 }
|
root@9
|
414
|
root@9
|
415 /**
|
root@9
|
416 * Adds a "Cc" address.
|
root@9
|
417 * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
|
root@9
|
418 * @param string $address
|
root@9
|
419 * @param string $name
|
root@9
|
420 * @return boolean TRUE on success, FALSE if address already used
|
root@9
|
421 */
|
root@9
|
422 public function AddCC($address, $name = '') {
|
root@9
|
423 return $this->AddAnAddress('cc', $address, $name);
|
root@9
|
424 }
|
root@9
|
425
|
root@9
|
426 /**
|
root@9
|
427 * Adds a "Bcc" address.
|
root@9
|
428 * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
|
root@9
|
429 * @param string $address
|
root@9
|
430 * @param string $name
|
root@9
|
431 * @return boolean TRUE on success, FALSE if address already used
|
root@9
|
432 */
|
root@9
|
433 public function AddBCC($address, $name = '') {
|
root@9
|
434 return $this->AddAnAddress('bcc', $address, $name);
|
root@9
|
435 }
|
root@9
|
436
|
root@9
|
437 /**
|
root@9
|
438 * Adds a "Reply-to" address.
|
root@9
|
439 * @param string $address
|
root@9
|
440 * @param string $name
|
root@9
|
441 * @return boolean
|
root@9
|
442 */
|
root@9
|
443 public function AddReplyTo($address, $name = '') {
|
root@9
|
444 return $this->AddAnAddress('ReplyTo', $address, $name);
|
root@9
|
445 }
|
root@9
|
446
|
root@9
|
447 /**
|
root@9
|
448 * Adds an address to one of the recipient arrays
|
root@9
|
449 * Addresses that have been added already return FALSE, but do not throw exceptions
|
root@9
|
450 * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
|
root@9
|
451 * @param string $address The email address to send to
|
root@9
|
452 * @param string $name
|
root@9
|
453 * @return boolean TRUE on success, FALSE if address already used or invalid in some way
|
root@9
|
454 * @access private
|
root@9
|
455 */
|
root@9
|
456 private function AddAnAddress($kind, $address, $name = '') {
|
root@9
|
457 if (!preg_match('/^(to|cc|bcc|ReplyTo)$/', $kind)) {
|
root@9
|
458 echo 'Invalid recipient array: ' . kind;
|
root@9
|
459 return FALSE;
|
root@9
|
460 }
|
root@9
|
461 $address = trim($address);
|
root@9
|
462 $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
|
root@9
|
463 if (!self::ValidateAddress($address)) {
|
root@9
|
464 $this->SetError(t('Invalid address') . ': ' . $address);
|
root@9
|
465 if ($this->exceptions) {
|
root@9
|
466 throw new phpmailerException(t('Invalid address') . ': ' . $address);
|
root@9
|
467 }
|
root@9
|
468 echo t('Invalid address') . ': ' . $address;
|
root@9
|
469 return FALSE;
|
root@9
|
470 }
|
root@9
|
471 if ($kind != 'ReplyTo') {
|
root@9
|
472 if (!isset($this->all_recipients[strtolower($address)])) {
|
root@9
|
473 array_push($this->$kind, array($address, $name));
|
root@9
|
474 $this->all_recipients[strtolower($address)] = TRUE;
|
root@9
|
475 return TRUE;
|
root@9
|
476 }
|
root@9
|
477 }
|
root@9
|
478 else {
|
root@9
|
479 if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
|
root@9
|
480 $this->ReplyTo[strtolower($address)] = array($address, $name);
|
root@9
|
481 return TRUE;
|
root@9
|
482 }
|
root@9
|
483 }
|
root@9
|
484 return FALSE;
|
root@9
|
485 }
|
root@9
|
486
|
root@9
|
487 /**
|
root@9
|
488 * Set the From and FromName properties
|
root@9
|
489 * @param string $address
|
root@9
|
490 * @param string $name
|
root@9
|
491 * @return boolean
|
root@9
|
492 */
|
root@9
|
493 public function SetFrom($address, $name = '', $auto=1) {
|
root@9
|
494 $address = trim($address);
|
root@9
|
495 $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
|
root@9
|
496 if (!self::ValidateAddress($address)) {
|
root@9
|
497 $this->SetError(t('Invalid address') . ': ' . $address);
|
root@9
|
498 if ($this->exceptions) {
|
root@9
|
499 throw new phpmailerException(t('Invalid address') . ': ' . $address);
|
root@9
|
500 }
|
root@9
|
501 echo t('Invalid address') . ': ' . $address;
|
root@9
|
502 return FALSE;
|
root@9
|
503 }
|
root@9
|
504 $this->From = $address;
|
root@9
|
505 $this->FromName = $name;
|
root@9
|
506 if ($auto) {
|
root@9
|
507 if (empty($this->ReplyTo)) {
|
root@9
|
508 $this->AddAnAddress('ReplyTo', $address, $name);
|
root@9
|
509 }
|
root@9
|
510 if (empty($this->Sender)) {
|
root@9
|
511 $this->Sender = $address;
|
root@9
|
512 }
|
root@9
|
513 }
|
root@9
|
514 return TRUE;
|
root@9
|
515 }
|
root@9
|
516
|
root@9
|
517 /**
|
root@9
|
518 * Check that a string looks roughly like an email address should
|
root@9
|
519 * Static so it can be used without instantiation
|
root@9
|
520 * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator
|
root@9
|
521 * Conforms approximately to RFC2822
|
root@9
|
522 * @link http://www.hexillion.com/samples/#Regex Original pattern found here
|
root@9
|
523 * @param string $address The email address to check
|
root@9
|
524 * @return boolean
|
root@9
|
525 * @static
|
root@9
|
526 * @access public
|
root@9
|
527 */
|
root@9
|
528 public static function ValidateAddress($address) {
|
root@9
|
529 if (function_exists('filter_var')) { //Introduced in PHP 5.2
|
root@9
|
530 if (filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
|
root@9
|
531 return FALSE;
|
root@9
|
532 }
|
root@9
|
533 else {
|
root@9
|
534 return TRUE;
|
root@9
|
535 }
|
root@9
|
536 }
|
root@9
|
537 else {
|
root@9
|
538 return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
|
root@9
|
539 }
|
root@9
|
540 }
|
root@9
|
541
|
root@9
|
542 /////////////////////////////////////////////////
|
root@9
|
543 // METHODS, MAIL SENDING
|
root@9
|
544 /////////////////////////////////////////////////
|
root@9
|
545
|
root@9
|
546 /**
|
root@9
|
547 * Creates message and assigns Mailer. If the message is
|
root@9
|
548 * not sent successfully then it returns FALSE. Use the ErrorInfo
|
root@9
|
549 * variable to view description of the error.
|
root@9
|
550 * @return bool
|
root@9
|
551 */
|
root@9
|
552 public function Send() {
|
root@9
|
553 try {
|
root@9
|
554 if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
|
root@9
|
555 throw new phpmailerException(t('You must provide at least one recipient email address.'), self::STOP_CRITICAL);
|
root@9
|
556 }
|
root@9
|
557
|
root@9
|
558 // Set whether the message is multipart/alternative
|
root@9
|
559 if (!empty($this->AltBody)) {
|
root@9
|
560 $this->ContentType = 'multipart/alternative';
|
root@9
|
561 }
|
root@9
|
562
|
root@9
|
563 $this->error_count = 0; // reset errors
|
root@9
|
564 $this->SetMessageType();
|
root@9
|
565 $header = $this->CreateHeader();
|
root@9
|
566 $body = $this->CreateBody();
|
root@9
|
567
|
root@9
|
568 if (empty($this->Body)) {
|
root@9
|
569 throw new phpmailerException(t('Message body empty'), self::STOP_CRITICAL);
|
root@9
|
570 }
|
root@9
|
571
|
root@9
|
572 // digitally sign with DKIM if enabled
|
root@9
|
573 if ($this->DKIM_domain && $this->DKIM_private) {
|
root@9
|
574 $header_dkim = $this->DKIM_Add($header, $this->Subject, $body);
|
root@9
|
575 $header = str_replace("\r\n", "\n", $header_dkim) . $header;
|
root@9
|
576 }
|
root@9
|
577
|
root@9
|
578 // Choose the mailer and send through it
|
root@9
|
579 switch ($this->Mailer) {
|
root@9
|
580 case 'sendmail':
|
root@9
|
581 return $this->SendmailSend($header, $body);
|
root@9
|
582 case 'smtp':
|
root@9
|
583 return $this->SmtpSend($header, $body);
|
root@9
|
584 default:
|
root@9
|
585 return $this->MailSend($header, $body);
|
root@9
|
586 }
|
root@9
|
587
|
root@9
|
588 } catch (phpmailerException $e) {
|
root@9
|
589 $this->SetError($e->getMessage());
|
root@9
|
590 if ($this->exceptions) {
|
root@9
|
591 throw $e;
|
root@9
|
592 }
|
root@9
|
593 echo $e->getMessage() . "\n";
|
root@9
|
594 return FALSE;
|
root@9
|
595 }
|
root@9
|
596 }
|
root@9
|
597
|
root@9
|
598 /**
|
root@9
|
599 * Sends mail using the $Sendmail program.
|
root@9
|
600 * @param string $header The message headers
|
root@9
|
601 * @param string $body The message body
|
root@9
|
602 * @access protected
|
root@9
|
603 * @return bool
|
root@9
|
604 */
|
root@9
|
605 protected function SendmailSend($header, $body) {
|
root@9
|
606 if ($this->Sender != '') {
|
root@9
|
607 $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
|
root@9
|
608 }
|
root@9
|
609 else {
|
root@9
|
610 $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
|
root@9
|
611 }
|
root@9
|
612 if ($this->SingleTo === TRUE) {
|
root@9
|
613 foreach ($this->SingleToArray as $key => $val) {
|
root@9
|
614 if (!@$mail = popen($sendmail, 'w')) {
|
root@9
|
615 throw new phpmailerException(t('Could not execute: !smail', array('!smail' => $this->Sendmail)), self::STOP_CRITICAL);
|
root@9
|
616 }
|
root@9
|
617 fputs($mail, "To: " . $val . "\n");
|
root@9
|
618 fputs($mail, $header);
|
root@9
|
619 fputs($mail, $body);
|
root@9
|
620 $result = pclose($mail);
|
root@9
|
621 // implement call back function if it exists
|
root@9
|
622 $isSent = ($result == 0) ? 1 : 0;
|
root@9
|
623 $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
|
root@9
|
624 if ($result != 0) {
|
root@9
|
625 throw new phpmailerException(t('Could not execute: !smail', array('!smail' => $this->Sendmail)), self::STOP_CRITICAL);
|
root@9
|
626 }
|
root@9
|
627 }
|
root@9
|
628 }
|
root@9
|
629 else {
|
root@9
|
630 if (!@$mail = popen($sendmail, 'w')) {
|
root@9
|
631 throw new phpmailerException(t('Could not execute: !smail', array('!smail' => $this->Sendmail)), self::STOP_CRITICAL);
|
root@9
|
632 }
|
root@9
|
633 fputs($mail, $header);
|
root@9
|
634 fputs($mail, $body);
|
root@9
|
635 $result = pclose($mail);
|
root@9
|
636 // implement call back function if it exists
|
root@9
|
637 $isSent = ($result == 0) ? 1 : 0;
|
root@9
|
638 $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body);
|
root@9
|
639 if ($result != 0) {
|
root@9
|
640 throw new phpmailerException(t('Could not execute: !smail', array('!smail' => $this->Sendmail)), self::STOP_CRITICAL);
|
root@9
|
641 }
|
root@9
|
642 }
|
root@9
|
643 return TRUE;
|
root@9
|
644 }
|
root@9
|
645
|
root@9
|
646 /**
|
root@9
|
647 * Sends mail using the PHP mail() function.
|
root@9
|
648 * @param string $header The message headers
|
root@9
|
649 * @param string $body The message body
|
root@9
|
650 * @access protected
|
root@9
|
651 * @return bool
|
root@9
|
652 */
|
root@9
|
653 protected function MailSend($header, $body) {
|
root@9
|
654 $toArr = array();
|
root@9
|
655 foreach ($this->to as $t) {
|
root@9
|
656 $toArr[] = $this->AddrFormat($t);
|
root@9
|
657 }
|
root@9
|
658 $to = implode(', ', $toArr);
|
root@9
|
659
|
root@9
|
660 $params = sprintf("-oi -f %s", $this->Sender);
|
root@9
|
661 if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) {
|
root@9
|
662 $old_from = ini_get('sendmail_from');
|
root@9
|
663 ini_set('sendmail_from', $this->Sender);
|
root@9
|
664 if ($this->SingleTo === TRUE && count($toArr) > 1) {
|
root@9
|
665 foreach ($toArr as $key => $val) {
|
root@9
|
666 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
|
root@9
|
667 // implement call back function if it exists
|
root@9
|
668 $isSent = ($rt == 1) ? 1 : 0;
|
root@9
|
669 $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
|
root@9
|
670 }
|
root@9
|
671 }
|
root@9
|
672 else {
|
root@9
|
673 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
|
root@9
|
674 // implement call back function if it exists
|
root@9
|
675 $isSent = ($rt == 1) ? 1 : 0;
|
root@9
|
676 $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
|
root@9
|
677 }
|
root@9
|
678 }
|
root@9
|
679 else {
|
root@9
|
680 if ($this->SingleTo === TRUE && count($toArr) > 1) {
|
root@9
|
681 foreach ($toArr as $key => $val) {
|
root@9
|
682 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
|
root@9
|
683 // implement call back function if it exists
|
root@9
|
684 $isSent = ($rt == 1) ? 1 : 0;
|
root@9
|
685 $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
|
root@9
|
686 }
|
root@9
|
687 }
|
root@9
|
688 else {
|
root@9
|
689 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
|
root@9
|
690 // implement call back function if it exists
|
root@9
|
691 $isSent = ($rt == 1) ? 1 : 0;
|
root@9
|
692 $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
|
root@9
|
693 }
|
root@9
|
694 }
|
root@9
|
695 if (isset($old_from)) {
|
root@9
|
696 ini_set('sendmail_from', $old_from);
|
root@9
|
697 }
|
root@9
|
698 if (!$rt) {
|
root@9
|
699 throw new phpmailerException(t('Could not instantiate mail function.'), self::STOP_CRITICAL);
|
root@9
|
700 }
|
root@9
|
701 return TRUE;
|
root@9
|
702 }
|
root@9
|
703
|
root@9
|
704 /**
|
root@9
|
705 * Sends mail via SMTP using PhpSMTP
|
root@9
|
706 * Returns FALSE if there is a bad MAIL FROM, RCPT, or DATA input.
|
root@9
|
707 * @param string $header The message headers
|
root@9
|
708 * @param string $body The message body
|
root@9
|
709 * @uses SMTP
|
root@9
|
710 * @access protected
|
root@9
|
711 * @return bool
|
root@9
|
712 */
|
root@9
|
713 protected function SmtpSend($header, $body) {
|
root@9
|
714 $bad_rcpt = array();
|
root@9
|
715
|
root@9
|
716 if (!$this->SmtpConnect()) {
|
root@9
|
717 throw new phpmailerException(t('SMTP Error: Could not connect to SMTP host.'), self::STOP_CRITICAL);
|
root@9
|
718 }
|
root@9
|
719 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
|
root@9
|
720 if (!$this->smtp->Mail($smtp_from)) {
|
root@9
|
721 throw new phpmailerException(t('The following From address failed: !from', array('!from' => $smtp_from)), self::STOP_CRITICAL);
|
root@9
|
722 }
|
root@9
|
723
|
root@9
|
724 // Attempt to send attach all recipients
|
root@9
|
725 foreach ($this->to as $to) {
|
root@9
|
726 if (!$this->smtp->Recipient($to[0])) {
|
root@9
|
727 $bad_rcpt[] = $to[0];
|
root@9
|
728 // implement call back function if it exists
|
root@9
|
729 $isSent = 0;
|
root@9
|
730 $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);
|
root@9
|
731 }
|
root@9
|
732 else {
|
root@9
|
733 // implement call back function if it exists
|
root@9
|
734 $isSent = 1;
|
root@9
|
735 $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);
|
root@9
|
736 }
|
root@9
|
737 }
|
root@9
|
738 foreach ($this->cc as $cc) {
|
root@9
|
739 if (!$this->smtp->Recipient($cc[0])) {
|
root@9
|
740 $bad_rcpt[] = $cc[0];
|
root@9
|
741 // implement call back function if it exists
|
root@9
|
742 $isSent = 0;
|
root@9
|
743 $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);
|
root@9
|
744 }
|
root@9
|
745 else {
|
root@9
|
746 // implement call back function if it exists
|
root@9
|
747 $isSent = 1;
|
root@9
|
748 $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);
|
root@9
|
749 }
|
root@9
|
750 }
|
root@9
|
751 foreach ($this->bcc as $bcc) {
|
root@9
|
752 if (!$this->smtp->Recipient($bcc[0])) {
|
root@9
|
753 $bad_rcpt[] = $bcc[0];
|
root@9
|
754 // implement call back function if it exists
|
root@9
|
755 $isSent = 0;
|
root@9
|
756 $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);
|
root@9
|
757 }
|
root@9
|
758 else {
|
root@9
|
759 // implement call back function if it exists
|
root@9
|
760 $isSent = 1;
|
root@9
|
761 $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);
|
root@9
|
762 }
|
root@9
|
763 }
|
root@9
|
764
|
root@9
|
765
|
root@9
|
766 if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses
|
root@9
|
767 $badaddresses = implode(', ', $bad_rcpt);
|
root@9
|
768 throw new phpmailerException(t('SMTP Error: The following recipients failed: !bad', array('!bad' => $badaddresses)));
|
root@9
|
769 }
|
root@9
|
770 if (!$this->smtp->Data($header . $body)) {
|
root@9
|
771 throw new phpmailerException(t('SMTP Error: Data not accepted.'), self::STOP_CRITICAL);
|
root@9
|
772 }
|
root@9
|
773 if ($this->SMTPKeepAlive == TRUE) {
|
root@9
|
774 $this->smtp->Reset();
|
root@9
|
775 }
|
root@9
|
776 return TRUE;
|
root@9
|
777 }
|
root@9
|
778
|
root@9
|
779 /**
|
root@9
|
780 * Initiates a connection to an SMTP server.
|
root@9
|
781 * Returns FALSE if the operation failed.
|
root@9
|
782 * @uses SMTP
|
root@9
|
783 * @access public
|
root@9
|
784 * @return bool
|
root@9
|
785 */
|
root@9
|
786 public function SmtpConnect() {
|
root@9
|
787 if (is_null($this->smtp)) {
|
root@9
|
788 $this->smtp = new SMTP();
|
root@9
|
789 }
|
root@9
|
790
|
root@9
|
791 $this->smtp->do_debug = $this->SMTPDebug;
|
root@9
|
792 $hosts = explode(';', $this->Host);
|
root@9
|
793 $index = 0;
|
root@9
|
794 $connection = $this->smtp->Connected();
|
root@9
|
795
|
root@9
|
796 // Retry while there is no connection
|
root@9
|
797 try {
|
root@9
|
798 while ($index < count($hosts) && !$connection) {
|
root@9
|
799 $hostinfo = array();
|
root@9
|
800 if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
|
root@9
|
801 $host = $hostinfo[1];
|
root@9
|
802 $port = $hostinfo[2];
|
root@9
|
803 }
|
root@9
|
804 else {
|
root@9
|
805 $host = $hosts[$index];
|
root@9
|
806 $port = $this->Port;
|
root@9
|
807 }
|
root@9
|
808
|
root@9
|
809 $tls = ($this->SMTPSecure == 'tls');
|
root@9
|
810 $ssl = ($this->SMTPSecure == 'ssl');
|
root@9
|
811
|
root@9
|
812 if ($this->smtp->Connect(($ssl ? 'ssl://':'') . $host, $port, $this->Timeout)) {
|
root@9
|
813
|
root@9
|
814 $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname());
|
root@9
|
815 $this->smtp->Hello($hello);
|
root@9
|
816
|
root@9
|
817 if ($tls) {
|
root@9
|
818 if (!$this->smtp->StartTLS()) {
|
root@9
|
819 throw new phpmailerException(t('StartTLS not supported by server or could not initiate session.'));
|
root@9
|
820 }
|
root@9
|
821
|
root@9
|
822 //We must resend HELO after tls negotiation
|
root@9
|
823 $this->smtp->Hello($hello);
|
root@9
|
824 }
|
root@9
|
825
|
root@9
|
826 $connection = TRUE;
|
root@9
|
827 if ($this->SMTPAuth) {
|
root@9
|
828 if (!$this->smtp->Authenticate($this->Username, $this->Password)) {
|
root@9
|
829 throw new phpmailerException(t('SMTP Error: Could not authenticate.'));
|
root@9
|
830 }
|
root@9
|
831 }
|
root@9
|
832 }
|
root@9
|
833 $index++;
|
root@9
|
834 if (!$connection) {
|
root@9
|
835 throw new phpmailerException(t('SMTP Error: Could not connect to SMTP host.'));
|
root@9
|
836 }
|
root@9
|
837 }
|
root@9
|
838 } catch (phpmailerException $e) {
|
root@9
|
839 $this->smtp->Reset();
|
root@9
|
840 throw $e;
|
root@9
|
841 }
|
root@9
|
842 return TRUE;
|
root@9
|
843 }
|
root@9
|
844
|
root@9
|
845 /**
|
root@9
|
846 * Closes the active SMTP session if one exists.
|
root@9
|
847 * @return void
|
root@9
|
848 */
|
root@9
|
849 public function SmtpClose() {
|
root@9
|
850 if (!is_null($this->smtp)) {
|
root@9
|
851 if ($this->smtp->Connected()) {
|
root@9
|
852 $this->smtp->Quit();
|
root@9
|
853 $this->smtp->Close();
|
root@9
|
854 }
|
root@9
|
855 }
|
root@9
|
856 }
|
root@9
|
857
|
root@9
|
858 /////////////////////////////////////////////////
|
root@9
|
859 // METHODS, MESSAGE CREATION
|
root@9
|
860 /////////////////////////////////////////////////
|
root@9
|
861
|
root@9
|
862 /**
|
root@9
|
863 * Creates recipient headers.
|
root@9
|
864 * @access public
|
root@9
|
865 * @return string
|
root@9
|
866 */
|
root@9
|
867 public function AddrAppend($type, $addr) {
|
root@9
|
868 $addr_str = $type . ': ';
|
root@9
|
869 $addresses = array();
|
root@9
|
870 foreach ($addr as $a) {
|
root@9
|
871 $addresses[] = $this->AddrFormat($a);
|
root@9
|
872 }
|
root@9
|
873 $addr_str .= implode(', ', $addresses);
|
root@9
|
874 $addr_str .= $this->LE;
|
root@9
|
875
|
root@9
|
876 return $addr_str;
|
root@9
|
877 }
|
root@9
|
878
|
root@9
|
879 /**
|
root@9
|
880 * Formats an address correctly.
|
root@9
|
881 * @access public
|
root@9
|
882 * @return string
|
root@9
|
883 */
|
root@9
|
884 public function AddrFormat($addr) {
|
root@9
|
885 if (empty($addr[1])) {
|
root@9
|
886 return $this->SecureHeader($addr[0]);
|
root@9
|
887 }
|
root@9
|
888 else {
|
root@9
|
889 return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
|
root@9
|
890 }
|
root@9
|
891 }
|
root@9
|
892
|
root@9
|
893 /**
|
root@9
|
894 * Wraps message for use with mailers that do not
|
root@9
|
895 * automatically perform wrapping and for quoted-printable.
|
root@9
|
896 * Original written by philippe.
|
root@9
|
897 * @param string $message The message to wrap
|
root@9
|
898 * @param integer $length The line length to wrap to
|
root@9
|
899 * @param boolean $qp_mode Whether to run in Quoted-Printable mode
|
root@9
|
900 * @access public
|
root@9
|
901 * @return string
|
root@9
|
902 */
|
root@9
|
903 public function WrapText($message, $length, $qp_mode = FALSE) {
|
root@9
|
904 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
|
root@9
|
905 // If utf-8 encoding is used, we will need to make sure we don't
|
root@9
|
906 // split multibyte characters when we wrap
|
root@9
|
907 $is_utf8 = (strtolower($this->CharSet) == "utf-8");
|
root@9
|
908
|
root@9
|
909 $message = $this->FixEOL($message);
|
root@9
|
910 if (substr($message, -1) == $this->LE) {
|
root@9
|
911 $message = substr($message, 0, -1);
|
root@9
|
912 }
|
root@9
|
913
|
root@9
|
914 $line = explode($this->LE, $message);
|
root@9
|
915 $message = '';
|
root@9
|
916 for ($i=0 ;$i < count($line); $i++) {
|
root@9
|
917 $line_part = explode(' ', $line[$i]);
|
root@9
|
918 $buf = '';
|
root@9
|
919 for ($e = 0; $e<count($line_part); $e++) {
|
root@9
|
920 $word = $line_part[$e];
|
root@9
|
921 if ($qp_mode and (strlen($word) > $length)) {
|
root@9
|
922 $space_left = $length - strlen($buf) - 1;
|
root@9
|
923 if ($e != 0) {
|
root@9
|
924 if ($space_left > 20) {
|
root@9
|
925 $len = $space_left;
|
root@9
|
926 if ($is_utf8) {
|
root@9
|
927 $len = $this->UTF8CharBoundary($word, $len);
|
root@9
|
928 }
|
root@9
|
929 elseif (substr($word, $len - 1, 1) == "=") {
|
root@9
|
930 $len--;
|
root@9
|
931 }
|
root@9
|
932 elseif (substr($word, $len - 2, 1) == "=") {
|
root@9
|
933 $len -= 2;
|
root@9
|
934 }
|
root@9
|
935 $part = substr($word, 0, $len);
|
root@9
|
936 $word = substr($word, $len);
|
root@9
|
937 $buf .= ' ' . $part;
|
root@9
|
938 $message .= $buf . sprintf("=%s", $this->LE);
|
root@9
|
939 }
|
root@9
|
940 else {
|
root@9
|
941 $message .= $buf . $soft_break;
|
root@9
|
942 }
|
root@9
|
943 $buf = '';
|
root@9
|
944 }
|
root@9
|
945 while (strlen($word) > 0) {
|
root@9
|
946 $len = $length;
|
root@9
|
947 if ($is_utf8) {
|
root@9
|
948 $len = $this->UTF8CharBoundary($word, $len);
|
root@9
|
949 }
|
root@9
|
950 elseif (substr($word, $len - 1, 1) == "=") {
|
root@9
|
951 $len--;
|
root@9
|
952 }
|
root@9
|
953 elseif (substr($word, $len - 2, 1) == "=") {
|
root@9
|
954 $len -= 2;
|
root@9
|
955 }
|
root@9
|
956 $part = substr($word, 0, $len);
|
root@9
|
957 $word = substr($word, $len);
|
root@9
|
958
|
root@9
|
959 if (strlen($word) > 0) {
|
root@9
|
960 $message .= $part . sprintf("=%s", $this->LE);
|
root@9
|
961 }
|
root@9
|
962 else {
|
root@9
|
963 $buf = $part;
|
root@9
|
964 }
|
root@9
|
965 }
|
root@9
|
966 }
|
root@9
|
967 else {
|
root@9
|
968 $buf_o = $buf;
|
root@9
|
969 $buf .= ($e == 0) ? $word : (' ' . $word);
|
root@9
|
970
|
root@9
|
971 if (strlen($buf) > $length and $buf_o != '') {
|
root@9
|
972 $message .= $buf_o . $soft_break;
|
root@9
|
973 $buf = $word;
|
root@9
|
974 }
|
root@9
|
975 }
|
root@9
|
976 }
|
root@9
|
977 $message .= $buf . $this->LE;
|
root@9
|
978 }
|
root@9
|
979
|
root@9
|
980 return $message;
|
root@9
|
981 }
|
root@9
|
982
|
root@9
|
983 /**
|
root@9
|
984 * Finds last character boundary prior to maxLength in a utf-8
|
root@9
|
985 * quoted (printable) encoded string.
|
root@9
|
986 * Original written by Colin Brown.
|
root@9
|
987 * @access public
|
root@9
|
988 * @param string $encodedText utf-8 QP text
|
root@9
|
989 * @param int $maxLength find last character boundary prior to this length
|
root@9
|
990 * @return int
|
root@9
|
991 */
|
root@9
|
992 public function UTF8CharBoundary($encodedText, $maxLength) {
|
root@9
|
993 $foundSplitPos = FALSE;
|
root@9
|
994 $lookBack = 3;
|
root@9
|
995 while (!$foundSplitPos) {
|
root@9
|
996 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
|
root@9
|
997 $encodedCharPos = strpos($lastChunk, "=");
|
root@9
|
998 if ($encodedCharPos !== FALSE) {
|
root@9
|
999 // Found start of encoded character byte within $lookBack block.
|
root@9
|
1000 // Check the encoded byte value (the 2 chars after the '=')
|
root@9
|
1001 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
|
root@9
|
1002 $dec = hexdec($hex);
|
root@9
|
1003 if ($dec < 128) { // Single byte character.
|
root@9
|
1004 // If the encoded char was found at pos 0, it will fit
|
root@9
|
1005 // otherwise reduce maxLength to start of the encoded char
|
root@9
|
1006 $maxLength = ($encodedCharPos == 0) ? $maxLength :
|
root@9
|
1007 $maxLength - ($lookBack - $encodedCharPos);
|
root@9
|
1008 $foundSplitPos = TRUE;
|
root@9
|
1009 }
|
root@9
|
1010 elseif ($dec >= 192) { // First byte of a multi byte character
|
root@9
|
1011 // Reduce maxLength to split at start of character
|
root@9
|
1012 $maxLength = $maxLength - ($lookBack - $encodedCharPos);
|
root@9
|
1013 $foundSplitPos = TRUE;
|
root@9
|
1014 }
|
root@9
|
1015 elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
|
root@9
|
1016 $lookBack += 3;
|
root@9
|
1017 }
|
root@9
|
1018 }
|
root@9
|
1019 else {
|
root@9
|
1020 // No encoded character found
|
root@9
|
1021 $foundSplitPos = TRUE;
|
root@9
|
1022 }
|
root@9
|
1023 }
|
root@9
|
1024 return $maxLength;
|
root@9
|
1025 }
|
root@9
|
1026
|
root@9
|
1027
|
root@9
|
1028 /**
|
root@9
|
1029 * Set the body wrapping.
|
root@9
|
1030 * @access public
|
root@9
|
1031 * @return void
|
root@9
|
1032 */
|
root@9
|
1033 public function SetWordWrap() {
|
root@9
|
1034 if ($this->WordWrap < 1) {
|
root@9
|
1035 return;
|
root@9
|
1036 }
|
root@9
|
1037
|
root@9
|
1038 switch ($this->message_type) {
|
root@9
|
1039 case 'alt':
|
root@9
|
1040 case 'alt_attachments':
|
root@9
|
1041 $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
|
root@9
|
1042 break;
|
root@9
|
1043 default:
|
root@9
|
1044 $this->Body = $this->WrapText($this->Body, $this->WordWrap);
|
root@9
|
1045 break;
|
root@9
|
1046 }
|
root@9
|
1047 }
|
root@9
|
1048
|
root@9
|
1049 /**
|
root@9
|
1050 * Assembles message header.
|
root@9
|
1051 * @access public
|
root@9
|
1052 * @return string The assembled header
|
root@9
|
1053 */
|
root@9
|
1054 public function CreateHeader() {
|
root@9
|
1055 $result = '';
|
root@9
|
1056
|
root@9
|
1057 // Set the boundaries
|
root@9
|
1058 $uniq_id = md5(uniqid(REQUEST_TIME));
|
root@9
|
1059 $this->boundary[1] = 'b1_' . $uniq_id;
|
root@9
|
1060 $this->boundary[2] = 'b2_' . $uniq_id;
|
root@9
|
1061
|
root@9
|
1062 $result .= $this->HeaderLine('Date', self::RFCDate());
|
root@9
|
1063 if ($this->Sender == '') {
|
root@9
|
1064 $result .= $this->HeaderLine('Return-Path', trim($this->From));
|
root@9
|
1065 }
|
root@9
|
1066 else {
|
root@9
|
1067 $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
|
root@9
|
1068 }
|
root@9
|
1069
|
root@9
|
1070 // To be created automatically by mail()
|
root@9
|
1071 if ($this->Mailer != 'mail') {
|
root@9
|
1072 if ($this->SingleTo === TRUE) {
|
root@9
|
1073 foreach ($this->to as $t) {
|
root@9
|
1074 $this->SingleToArray[] = $this->AddrFormat($t);
|
root@9
|
1075 }
|
root@9
|
1076 }
|
root@9
|
1077 else {
|
root@9
|
1078 if (count($this->to) > 0) {
|
root@9
|
1079 $result .= $this->AddrAppend('To', $this->to);
|
root@9
|
1080 }
|
root@9
|
1081 elseif (count($this->cc) == 0) {
|
root@9
|
1082 $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
|
root@9
|
1083 }
|
root@9
|
1084 }
|
root@9
|
1085 }
|
root@9
|
1086
|
root@9
|
1087 $from = array();
|
root@9
|
1088 $from[0][0] = trim($this->From);
|
root@9
|
1089 $from[0][1] = $this->FromName;
|
root@9
|
1090 $result .= $this->AddrAppend('From', $from);
|
root@9
|
1091
|
root@9
|
1092 // sendmail and mail() extract Cc from the header before sending
|
root@9
|
1093 if (count($this->cc) > 0) {
|
root@9
|
1094 $result .= $this->AddrAppend('Cc', $this->cc);
|
root@9
|
1095 }
|
root@9
|
1096
|
root@9
|
1097 // sendmail and mail() extract Bcc from the header before sending
|
root@9
|
1098 if ((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
|
root@9
|
1099 $result .= $this->AddrAppend('Bcc', $this->bcc);
|
root@9
|
1100 }
|
root@9
|
1101
|
root@9
|
1102 if (count($this->ReplyTo) > 0) {
|
root@9
|
1103 $result .= $this->AddrAppend('Reply-to', $this->ReplyTo);
|
root@9
|
1104 }
|
root@9
|
1105
|
root@9
|
1106 // mail() sets the subject itself
|
root@9
|
1107 if ($this->Mailer != 'mail') {
|
root@9
|
1108 $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
|
root@9
|
1109 }
|
root@9
|
1110
|
root@9
|
1111 if ($this->MessageID != '') {
|
root@9
|
1112 $result .= $this->HeaderLine('Message-ID', $this->MessageID);
|
root@9
|
1113 }
|
root@9
|
1114 else {
|
root@9
|
1115 $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
|
root@9
|
1116 }
|
root@9
|
1117 $result .= $this->HeaderLine('X-Priority', $this->Priority);
|
root@9
|
1118 $result .= $this->HeaderLine('X-Mailer', 'PHPMailer ' . $this->Version . ' (phpmailer.sourceforge.net)');
|
root@9
|
1119
|
root@9
|
1120 if ($this->ConfirmReadingTo != '') {
|
root@9
|
1121 $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
|
root@9
|
1122 }
|
root@9
|
1123
|
root@9
|
1124 // Add custom headers
|
root@9
|
1125 for ($index = 0; $index < count($this->CustomHeader); $index++) {
|
root@9
|
1126 $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
|
root@9
|
1127 }
|
root@9
|
1128 if (!$this->sign_key_file) {
|
root@9
|
1129 $result .= $this->HeaderLine('MIME-Version', '1.0');
|
root@9
|
1130 $result .= $this->GetMailMIME();
|
root@9
|
1131 }
|
root@9
|
1132
|
root@9
|
1133 return $result;
|
root@9
|
1134 }
|
root@9
|
1135
|
root@9
|
1136 /**
|
root@9
|
1137 * Returns the message MIME.
|
root@9
|
1138 * @access public
|
root@9
|
1139 * @return string
|
root@9
|
1140 */
|
root@9
|
1141 public function GetMailMIME() {
|
root@9
|
1142 $result = '';
|
root@9
|
1143 switch ($this->message_type) {
|
root@9
|
1144 case 'plain':
|
root@9
|
1145 $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
|
root@9
|
1146 $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
|
root@9
|
1147 break;
|
root@9
|
1148 case 'attachments':
|
root@9
|
1149 case 'alt_attachments':
|
root@9
|
1150 if ($this->InlineImageExists()) {
|
root@9
|
1151 $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
|
root@9
|
1152 }
|
root@9
|
1153 else {
|
root@9
|
1154 $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
|
root@9
|
1155 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
|
root@9
|
1156 }
|
root@9
|
1157 break;
|
root@9
|
1158 case 'alt':
|
root@9
|
1159 $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
|
root@9
|
1160 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
|
root@9
|
1161 break;
|
root@9
|
1162 }
|
root@9
|
1163
|
root@9
|
1164 if ($this->Mailer != 'mail') {
|
root@9
|
1165 $result .= $this->LE . $this->LE;
|
root@9
|
1166 }
|
root@9
|
1167
|
root@9
|
1168 return $result;
|
root@9
|
1169 }
|
root@9
|
1170
|
root@9
|
1171 /**
|
root@9
|
1172 * Assembles the message body. Returns an empty string on failure.
|
root@9
|
1173 * @access public
|
root@9
|
1174 * @return string The assembled message body
|
root@9
|
1175 */
|
root@9
|
1176 public function CreateBody() {
|
root@9
|
1177 $body = '';
|
root@9
|
1178
|
root@9
|
1179 if ($this->sign_key_file) {
|
root@9
|
1180 $body .= $this->GetMailMIME();
|
root@9
|
1181 }
|
root@9
|
1182
|
root@9
|
1183 $this->SetWordWrap();
|
root@9
|
1184
|
root@9
|
1185 switch ($this->message_type) {
|
root@9
|
1186 case 'alt':
|
root@9
|
1187 $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
|
root@9
|
1188 $body .= $this->EncodeString($this->AltBody, $this->Encoding);
|
root@9
|
1189 $body .= $this->LE . $this->LE;
|
root@9
|
1190 $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
|
root@9
|
1191 $body .= $this->EncodeString($this->Body, $this->Encoding);
|
root@9
|
1192 $body .= $this->LE . $this->LE;
|
root@9
|
1193 $body .= $this->EndBoundary($this->boundary[1]);
|
root@9
|
1194 break;
|
root@9
|
1195 case 'plain':
|
root@9
|
1196 $body .= $this->EncodeString($this->Body, $this->Encoding);
|
root@9
|
1197 break;
|
root@9
|
1198 case 'attachments':
|
root@9
|
1199 if ($this->is_html) {
|
root@9
|
1200 $body .= $this->GetBoundary($this->boundary[1], '', $this->is_html, '');
|
root@9
|
1201 }
|
root@9
|
1202 else {
|
root@9
|
1203 $body .= $this->GetBoundary($this->boundary[1], '', '', '');
|
root@9
|
1204 }
|
root@9
|
1205 $body .= $this->EncodeString($this->Body, $this->Encoding);
|
root@9
|
1206 $body .= $this->LE;
|
root@9
|
1207 $body .= $this->AttachAll();
|
root@9
|
1208 break;
|
root@9
|
1209 case 'alt_attachments':
|
root@9
|
1210 $body .= sprintf("--%s%s", $this->boundary[1], $this->LE);
|
root@9
|
1211 $body .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE . $this->LE);
|
root@9
|
1212 $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
|
root@9
|
1213 $body .= $this->EncodeString($this->AltBody, $this->Encoding);
|
root@9
|
1214 $body .= $this->LE . $this->LE;
|
root@9
|
1215 $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
|
root@9
|
1216 $body .= $this->EncodeString($this->Body, $this->Encoding);
|
root@9
|
1217 $body .= $this->LE . $this->LE;
|
root@9
|
1218 $body .= $this->EndBoundary($this->boundary[2]);
|
root@9
|
1219 $body .= $this->AttachAll();
|
root@9
|
1220 break;
|
root@9
|
1221 }
|
root@9
|
1222
|
root@9
|
1223 if ($this->IsError()) {
|
root@9
|
1224 $body = '';
|
root@9
|
1225 }
|
root@9
|
1226 elseif ($this->sign_key_file) {
|
root@9
|
1227 try {
|
root@9
|
1228 $file = tempnam('', 'mail');
|
root@9
|
1229 file_put_contents($file, $body); //TODO check this worked
|
root@9
|
1230 $signed = tempnam("", "signed");
|
root@9
|
1231 if (@openssl_pkcs7_sign($file, $signed, "file://" . $this->sign_cert_file, array("file://" . $this->sign_key_file, $this->sign_key_pass), NULL)) {
|
root@9
|
1232 @unlink($file);
|
root@9
|
1233 @unlink($signed);
|
root@9
|
1234 $body = file_get_contents($signed);
|
root@9
|
1235 }
|
root@9
|
1236 else {
|
root@9
|
1237 @unlink($file);
|
root@9
|
1238 @unlink($signed);
|
root@9
|
1239 throw new phpmailerException(t('Signing Error: !err', array('!err' => openssl_error_string())));
|
root@9
|
1240 }
|
root@9
|
1241 } catch (phpmailerException $e) {
|
root@9
|
1242 $body = '';
|
root@9
|
1243 if ($this->exceptions) {
|
root@9
|
1244 throw $e;
|
root@9
|
1245 }
|
root@9
|
1246 }
|
root@9
|
1247 }
|
root@9
|
1248
|
root@9
|
1249 return $body;
|
root@9
|
1250 }
|
root@9
|
1251
|
root@9
|
1252 /**
|
root@9
|
1253 * Returns the start of a message boundary.
|
root@9
|
1254 * @access private
|
root@9
|
1255 */
|
root@9
|
1256 private function GetBoundary($boundary, $charSet, $contentType, $encoding) {
|
root@9
|
1257 $result = '';
|
root@9
|
1258 if ($charSet == '') {
|
root@9
|
1259 $charSet = $this->CharSet;
|
root@9
|
1260 }
|
root@9
|
1261 if ($contentType == '') {
|
root@9
|
1262 $contentType = $this->ContentType;
|
root@9
|
1263 }
|
root@9
|
1264 if ($encoding == '') {
|
root@9
|
1265 $encoding = $this->Encoding;
|
root@9
|
1266 }
|
root@9
|
1267 $result .= $this->TextLine('--' . $boundary);
|
root@9
|
1268 $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
|
root@9
|
1269 $result .= $this->LE;
|
root@9
|
1270 $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
|
root@9
|
1271 $result .= $this->LE;
|
root@9
|
1272
|
root@9
|
1273 return $result;
|
root@9
|
1274 }
|
root@9
|
1275
|
root@9
|
1276 /**
|
root@9
|
1277 * Returns the end of a message boundary.
|
root@9
|
1278 * @access private
|
root@9
|
1279 */
|
root@9
|
1280 private function EndBoundary($boundary) {
|
root@9
|
1281 return $this->LE . '--' . $boundary . '--' . $this->LE;
|
root@9
|
1282 }
|
root@9
|
1283
|
root@9
|
1284 /**
|
root@9
|
1285 * Sets the message type.
|
root@9
|
1286 * @access private
|
root@9
|
1287 * @return void
|
root@9
|
1288 */
|
root@9
|
1289 private function SetMessageType() {
|
root@9
|
1290 if (count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
|
root@9
|
1291 $this->message_type = 'plain';
|
root@9
|
1292 }
|
root@9
|
1293 else {
|
root@9
|
1294 if (count($this->attachment) > 0) {
|
root@9
|
1295 $this->message_type = 'attachments';
|
root@9
|
1296 }
|
root@9
|
1297 if (strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
|
root@9
|
1298 $this->message_type = 'alt';
|
root@9
|
1299 }
|
root@9
|
1300 if (strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
|
root@9
|
1301 $this->message_type = 'alt_attachments';
|
root@9
|
1302 }
|
root@9
|
1303 }
|
root@9
|
1304 }
|
root@9
|
1305
|
root@9
|
1306 /**
|
root@9
|
1307 * Returns a formatted header line.
|
root@9
|
1308 * @access public
|
root@9
|
1309 * @return string
|
root@9
|
1310 */
|
root@9
|
1311 public function HeaderLine($name, $value) {
|
root@9
|
1312 return $name . ': ' . $value . $this->LE;
|
root@9
|
1313 }
|
root@9
|
1314
|
root@9
|
1315 /**
|
root@9
|
1316 * Returns a formatted mail line.
|
root@9
|
1317 * @access public
|
root@9
|
1318 * @return string
|
root@9
|
1319 */
|
root@9
|
1320 public function TextLine($value) {
|
root@9
|
1321 return $value . $this->LE;
|
root@9
|
1322 }
|
root@9
|
1323
|
root@9
|
1324 /////////////////////////////////////////////////
|
root@9
|
1325 // CLASS METHODS, ATTACHMENTS
|
root@9
|
1326 /////////////////////////////////////////////////
|
root@9
|
1327
|
root@9
|
1328 /**
|
root@9
|
1329 * Adds an attachment from a path on the filesystem.
|
root@9
|
1330 * Returns FALSE if the file could not be found
|
root@9
|
1331 * or accessed.
|
root@9
|
1332 * @param string $path Path to the attachment.
|
root@9
|
1333 * @param string $name Overrides the attachment name.
|
root@9
|
1334 * @param string $encoding File encoding (see $Encoding).
|
root@9
|
1335 * @param string $type File extension (MIME) type.
|
root@9
|
1336 * @return bool
|
root@9
|
1337 */
|
root@9
|
1338 public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
|
root@9
|
1339 try {
|
root@9
|
1340 if ( !@is_file($path) ) {
|
root@9
|
1341 throw new phpmailerException(t('Could not access file: !nofile', array('!nofile' => $path)), self::STOP_CONTINUE);
|
root@9
|
1342 }
|
root@9
|
1343 $filename = basename($path);
|
root@9
|
1344 if ( $name == '' ) {
|
root@9
|
1345 $name = $filename;
|
root@9
|
1346 }
|
root@9
|
1347
|
root@9
|
1348 $this->attachment[] = array(
|
root@9
|
1349 0 => $path,
|
root@9
|
1350 1 => $filename,
|
root@9
|
1351 2 => $name,
|
root@9
|
1352 3 => $encoding,
|
root@9
|
1353 4 => $type,
|
root@9
|
1354 5 => FALSE, // isStringAttachment
|
root@9
|
1355 6 => 'attachment',
|
root@9
|
1356 7 => 0
|
root@9
|
1357 );
|
root@9
|
1358
|
root@9
|
1359 } catch (phpmailerException $e) {
|
root@9
|
1360 $this->SetError($e->getMessage());
|
root@9
|
1361 if ($this->exceptions) {
|
root@9
|
1362 throw $e;
|
root@9
|
1363 }
|
root@9
|
1364 echo $e->getMessage() . "\n";
|
root@9
|
1365 if ( $e->getCode() == self::STOP_CRITICAL ) {
|
root@9
|
1366 return FALSE;
|
root@9
|
1367 }
|
root@9
|
1368 }
|
root@9
|
1369 return TRUE;
|
root@9
|
1370 }
|
root@9
|
1371
|
root@9
|
1372 /**
|
root@9
|
1373 * Return the current array of attachments
|
root@9
|
1374 * @return array
|
root@9
|
1375 */
|
root@9
|
1376 public function GetAttachments() {
|
root@9
|
1377 return $this->attachment;
|
root@9
|
1378 }
|
root@9
|
1379
|
root@9
|
1380 /**
|
root@9
|
1381 * Attaches all fs, string, and binary attachments to the message.
|
root@9
|
1382 * Returns an empty string on failure.
|
root@9
|
1383 * @access private
|
root@9
|
1384 * @return string
|
root@9
|
1385 */
|
root@9
|
1386 private function AttachAll() {
|
root@9
|
1387 // Return text of body
|
root@9
|
1388 $mime = array();
|
root@9
|
1389 $cidUniq = array();
|
root@9
|
1390 $incl = array();
|
root@9
|
1391
|
root@9
|
1392 // Add all attachments
|
root@9
|
1393 foreach ($this->attachment as $attachment) {
|
root@9
|
1394 // Check for string attachment
|
root@9
|
1395 $bString = $attachment[5];
|
root@9
|
1396 if ($bString) {
|
root@9
|
1397 $string = $attachment[0];
|
root@9
|
1398 }
|
root@9
|
1399 else {
|
root@9
|
1400 $path = $attachment[0];
|
root@9
|
1401 }
|
root@9
|
1402
|
root@9
|
1403 if (in_array($attachment[0], $incl)) {
|
root@9
|
1404 continue;
|
root@9
|
1405 }
|
root@9
|
1406
|
root@9
|
1407 $filename = $attachment[1];
|
root@9
|
1408 $name = $attachment[2];
|
root@9
|
1409 $encoding = $attachment[3];
|
root@9
|
1410 $type = $attachment[4];
|
root@9
|
1411 $disposition = $attachment[6];
|
root@9
|
1412 $cid = $attachment[7];
|
root@9
|
1413 $incl[] = $attachment[0];
|
root@9
|
1414
|
root@9
|
1415 if ($disposition == 'inline' && isset($cidUniq[$cid])) {
|
root@9
|
1416 continue;
|
root@9
|
1417 }
|
root@9
|
1418
|
root@9
|
1419 $cidUniq[$cid] = TRUE;
|
root@9
|
1420
|
root@9
|
1421 $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
|
root@9
|
1422 $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
|
root@9
|
1423 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
|
root@9
|
1424
|
root@9
|
1425 if ($disposition == 'inline') {
|
root@9
|
1426 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
|
root@9
|
1427 }
|
root@9
|
1428
|
root@9
|
1429 $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE . $this->LE);
|
root@9
|
1430
|
root@9
|
1431 // Encode as string attachment
|
root@9
|
1432 if ($bString) {
|
root@9
|
1433 $mime[] = $this->EncodeString($string, $encoding);
|
root@9
|
1434 if ($this->IsError()) {
|
root@9
|
1435 return '';
|
root@9
|
1436 }
|
root@9
|
1437 $mime[] = $this->LE . $this->LE;
|
root@9
|
1438 }
|
root@9
|
1439 else {
|
root@9
|
1440 $mime[] = $this->EncodeFile($path, $encoding);
|
root@9
|
1441 if ($this->IsError()) {
|
root@9
|
1442 return '';
|
root@9
|
1443 }
|
root@9
|
1444 $mime[] = $this->LE . $this->LE;
|
root@9
|
1445 }
|
root@9
|
1446 }
|
root@9
|
1447
|
root@9
|
1448 $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
|
root@9
|
1449
|
root@9
|
1450 return join('', $mime);
|
root@9
|
1451 }
|
root@9
|
1452
|
root@9
|
1453 /**
|
root@9
|
1454 * Encodes attachment in requested format.
|
root@9
|
1455 * Returns an empty string on failure.
|
root@9
|
1456 * @param string $path The full path to the file
|
root@9
|
1457 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
|
root@9
|
1458 * @see EncodeFile()
|
root@9
|
1459 * @access private
|
root@9
|
1460 * @return string
|
root@9
|
1461 */
|
root@9
|
1462 private function EncodeFile($path, $encoding = 'base64') {
|
root@9
|
1463 try {
|
root@9
|
1464 if (!is_readable($path)) {
|
root@9
|
1465 throw new phpmailerException(t('File Error: Could not open file: !nofile', array('!nofile' => $path)), self::STOP_CONTINUE);
|
root@9
|
1466 }
|
root@9
|
1467 if (function_exists('get_magic_quotes')) {
|
root@9
|
1468 function get_magic_quotes() {
|
root@9
|
1469 return FALSE;
|
root@9
|
1470 }
|
root@9
|
1471 }
|
root@9
|
1472 $magic_quotes = get_magic_quotes_runtime();
|
root@9
|
1473 if ($magic_quotes) {
|
root@9
|
1474 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
root@9
|
1475 set_magic_quotes_runtime(0);
|
root@9
|
1476 }
|
root@9
|
1477 else {
|
root@9
|
1478 ini_set('magic_quotes_runtime', 0);
|
root@9
|
1479 }
|
root@9
|
1480 }
|
root@9
|
1481 $file_buffer = file_get_contents($path);
|
root@9
|
1482 $file_buffer = $this->EncodeString($file_buffer, $encoding);
|
root@9
|
1483 if ($magic_quotes) {
|
root@9
|
1484 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
root@9
|
1485 set_magic_quotes_runtime($magic_quotes);
|
root@9
|
1486 }
|
root@9
|
1487 else {
|
root@9
|
1488 ini_set('magic_quotes_runtime', $magic_quotes);
|
root@9
|
1489 }
|
root@9
|
1490 }
|
root@9
|
1491 return $file_buffer;
|
root@9
|
1492 } catch (Exception $e) {
|
root@9
|
1493 $this->SetError($e->getMessage());
|
root@9
|
1494 return '';
|
root@9
|
1495 }
|
root@9
|
1496 }
|
root@9
|
1497
|
root@9
|
1498 /**
|
root@9
|
1499 * Encodes string to requested format.
|
root@9
|
1500 * Returns an empty string on failure.
|
root@9
|
1501 * @param string $str The text to encode
|
root@9
|
1502 * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
|
root@9
|
1503 * @access public
|
root@9
|
1504 * @return string
|
root@9
|
1505 */
|
root@9
|
1506 public function EncodeString($str, $encoding = 'base64') {
|
root@9
|
1507 $encoded = '';
|
root@9
|
1508 switch (strtolower($encoding)) {
|
root@9
|
1509 case 'base64':
|
root@9
|
1510 $encoded = chunk_split(base64_encode($str), 76, $this->LE);
|
root@9
|
1511 break;
|
root@9
|
1512 case '7bit':
|
root@9
|
1513 case '8bit':
|
root@9
|
1514 $encoded = $this->FixEOL($str);
|
root@9
|
1515 //Make sure it ends with a line break
|
root@9
|
1516 if (substr($encoded, -(strlen($this->LE))) != $this->LE)
|
root@9
|
1517 $encoded .= $this->LE;
|
root@9
|
1518 break;
|
root@9
|
1519 case 'binary':
|
root@9
|
1520 $encoded = $str;
|
root@9
|
1521 break;
|
root@9
|
1522 case 'quoted-printable':
|
root@9
|
1523 $encoded = $this->EncodeQP($str);
|
root@9
|
1524 break;
|
root@9
|
1525 default:
|
root@9
|
1526 $this->SetError(t('Unknown encoding: !enc', array('!enc' => $encoding)));
|
root@9
|
1527 break;
|
root@9
|
1528 }
|
root@9
|
1529 return $encoded;
|
root@9
|
1530 }
|
root@9
|
1531
|
root@9
|
1532 /**
|
root@9
|
1533 * Encode a header string to best (shortest) of Q, B, quoted or none.
|
root@9
|
1534 * @access public
|
root@9
|
1535 * @return string
|
root@9
|
1536 */
|
root@9
|
1537 public function EncodeHeader($str, $position = 'text') {
|
root@9
|
1538 $x = 0;
|
root@9
|
1539
|
root@9
|
1540 switch (strtolower($position)) {
|
root@9
|
1541 case 'phrase':
|
root@9
|
1542 if (!preg_match('/[\200-\377]/', $str)) {
|
root@9
|
1543 // Can't use addslashes as we don't know what value has magic_quotes_sybase
|
root@9
|
1544 $encoded = addcslashes($str, "\0..\37\177\\\"");
|
root@9
|
1545 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
|
root@9
|
1546 return ($encoded);
|
root@9
|
1547 }
|
root@9
|
1548 else {
|
root@9
|
1549 return ("\"$encoded\"");
|
root@9
|
1550 }
|
root@9
|
1551 }
|
root@9
|
1552 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
|
root@9
|
1553 break;
|
root@9
|
1554 case 'comment':
|
root@9
|
1555 $x = preg_match_all('/[()"]/', $str, $matches);
|
root@9
|
1556 // Fall-through
|
root@9
|
1557 case 'text':
|
root@9
|
1558 default:
|
root@9
|
1559 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
|
root@9
|
1560 break;
|
root@9
|
1561 }
|
root@9
|
1562
|
root@9
|
1563 if ($x == 0) {
|
root@9
|
1564 return ($str);
|
root@9
|
1565 }
|
root@9
|
1566
|
root@9
|
1567 $maxlen = 75 - 7 - strlen($this->CharSet);
|
root@9
|
1568 // Try to select the encoding which should produce the shortest output
|
root@9
|
1569 if (strlen($str)/3 < $x) {
|
root@9
|
1570 $encoding = 'B';
|
root@9
|
1571 if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
|
root@9
|
1572 // Use a custom function which correctly encodes and wraps long
|
root@9
|
1573 // multibyte strings without breaking lines within a character
|
root@9
|
1574 $encoded = $this->Base64EncodeWrapMB($str);
|
root@9
|
1575 }
|
root@9
|
1576 else {
|
root@9
|
1577 $encoded = base64_encode($str);
|
root@9
|
1578 $maxlen -= $maxlen % 4;
|
root@9
|
1579 $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
|
root@9
|
1580 }
|
root@9
|
1581 }
|
root@9
|
1582 else {
|
root@9
|
1583 $encoding = 'Q';
|
root@9
|
1584 $encoded = $this->EncodeQ($str, $position);
|
root@9
|
1585 $encoded = $this->WrapText($encoded, $maxlen, TRUE);
|
root@9
|
1586 $encoded = str_replace('=' . $this->LE, "\n", trim($encoded));
|
root@9
|
1587 }
|
root@9
|
1588
|
root@9
|
1589 $encoded = preg_replace('/^(.*)$/m', " =?" . $this->CharSet . "?$encoding?\\1?=", $encoded);
|
root@9
|
1590 $encoded = trim(str_replace("\n", $this->LE, $encoded));
|
root@9
|
1591
|
root@9
|
1592 return $encoded;
|
root@9
|
1593 }
|
root@9
|
1594
|
root@9
|
1595 /**
|
root@9
|
1596 * Checks if a string contains multibyte characters.
|
root@9
|
1597 * @access public
|
root@9
|
1598 * @param string $str multi-byte text to wrap encode
|
root@9
|
1599 * @return bool
|
root@9
|
1600 */
|
root@9
|
1601 public function HasMultiBytes($str) {
|
root@9
|
1602 if (function_exists('mb_strlen')) {
|
root@9
|
1603 return (strlen($str) > mb_strlen($str, $this->CharSet));
|
root@9
|
1604 }
|
root@9
|
1605 else { // Assume no multibytes (we can't handle without mbstring functions anyway)
|
root@9
|
1606 return FALSE;
|
root@9
|
1607 }
|
root@9
|
1608 }
|
root@9
|
1609
|
root@9
|
1610 /**
|
root@9
|
1611 * Correctly encodes and wraps long multibyte strings for mail headers
|
root@9
|
1612 * without breaking lines within a character.
|
root@9
|
1613 * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
|
root@9
|
1614 * @access public
|
root@9
|
1615 * @param string $str multi-byte text to wrap encode
|
root@9
|
1616 * @return string
|
root@9
|
1617 */
|
root@9
|
1618 public function Base64EncodeWrapMB($str) {
|
root@9
|
1619 $start = "=?" . $this->CharSet . "?B?";
|
root@9
|
1620 $end = "?=";
|
root@9
|
1621 $encoded = "";
|
root@9
|
1622
|
root@9
|
1623 $mb_length = mb_strlen($str, $this->CharSet);
|
root@9
|
1624 // Each line must have length <= 75, including $start and $end
|
root@9
|
1625 $length = 75 - strlen($start) - strlen($end);
|
root@9
|
1626 // Average multi-byte ratio
|
root@9
|
1627 $ratio = $mb_length / strlen($str);
|
root@9
|
1628 // Base64 has a 4:3 ratio
|
root@9
|
1629 $offset = $avgLength = floor($length * $ratio * .75);
|
root@9
|
1630
|
root@9
|
1631 for ($i = 0; $i < $mb_length; $i += $offset) {
|
root@9
|
1632 $lookBack = 0;
|
root@9
|
1633
|
root@9
|
1634 do {
|
root@9
|
1635 $offset = $avgLength - $lookBack;
|
root@9
|
1636 $chunk = mb_substr($str, $i, $offset, $this->CharSet);
|
root@9
|
1637 $chunk = base64_encode($chunk);
|
root@9
|
1638 $lookBack++;
|
root@9
|
1639 }
|
root@9
|
1640 while (strlen($chunk) > $length);
|
root@9
|
1641
|
root@9
|
1642 $encoded .= $chunk . $this->LE;
|
root@9
|
1643 }
|
root@9
|
1644
|
root@9
|
1645 // Chomp the last linefeed
|
root@9
|
1646 $encoded = substr($encoded, 0, -strlen($this->LE));
|
root@9
|
1647 return $encoded;
|
root@9
|
1648 }
|
root@9
|
1649
|
root@9
|
1650 /**
|
root@9
|
1651 * Encode string to quoted-printable.
|
root@9
|
1652 * Only uses standard PHP, slow, but will always work
|
root@9
|
1653 * @access public
|
root@9
|
1654 * @param string $string the text to encode
|
root@9
|
1655 * @param integer $line_max Number of chars allowed on a line before wrapping
|
root@9
|
1656 * @return string
|
root@9
|
1657 */
|
root@9
|
1658 public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = FALSE) {
|
root@9
|
1659 $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
|
root@9
|
1660 $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
|
root@9
|
1661 $eol = "\r\n";
|
root@9
|
1662 $escape = '=';
|
root@9
|
1663 $output = '';
|
root@9
|
1664 while ( list(, $line) = each($lines) ) {
|
root@9
|
1665 $linlen = strlen($line);
|
root@9
|
1666 $newline = '';
|
root@9
|
1667 for ($i = 0; $i < $linlen; $i++) {
|
root@9
|
1668 $c = substr( $line, $i, 1 );
|
root@9
|
1669 $dec = ord( $c );
|
root@9
|
1670 if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
|
root@9
|
1671 $c = '=2E';
|
root@9
|
1672 }
|
root@9
|
1673 if ( $dec == 32 ) {
|
root@9
|
1674 if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
|
root@9
|
1675 $c = '=20';
|
root@9
|
1676 }
|
root@9
|
1677 elseif ( $space_conv ) {
|
root@9
|
1678 $c = '=20';
|
root@9
|
1679 }
|
root@9
|
1680 }
|
root@9
|
1681 elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
|
root@9
|
1682 $h2 = floor($dec/16);
|
root@9
|
1683 $h1 = floor($dec%16);
|
root@9
|
1684 $c = $escape . $hex[$h2] . $hex[$h1];
|
root@9
|
1685 }
|
root@9
|
1686 if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
|
root@9
|
1687 $output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay
|
root@9
|
1688 $newline = '';
|
root@9
|
1689 // check if newline first character will be point or not
|
root@9
|
1690 if ( $dec == 46 ) {
|
root@9
|
1691 $c = '=2E';
|
root@9
|
1692 }
|
root@9
|
1693 }
|
root@9
|
1694 $newline .= $c;
|
root@9
|
1695 } // end of for
|
root@9
|
1696 $output .= $newline . $eol;
|
root@9
|
1697 } // end of while
|
root@9
|
1698 return $output;
|
root@9
|
1699 }
|
root@9
|
1700
|
root@9
|
1701 /**
|
root@9
|
1702 * Encode string to RFC2045 (6.7) quoted-printable format
|
root@9
|
1703 * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version
|
root@9
|
1704 * Also results in same content as you started with after decoding
|
root@9
|
1705 * @see EncodeQPphp()
|
root@9
|
1706 * @access public
|
root@9
|
1707 * @param string $string the text to encode
|
root@9
|
1708 * @param integer $line_max Number of chars allowed on a line before wrapping
|
root@9
|
1709 * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function
|
root@9
|
1710 * @return string
|
root@9
|
1711 * @author Marcus Bointon
|
root@9
|
1712 */
|
root@9
|
1713 public function EncodeQP($string, $line_max = 76, $space_conv = FALSE) {
|
root@9
|
1714 if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
|
root@9
|
1715 return quoted_printable_encode($string);
|
root@9
|
1716 }
|
root@9
|
1717 $filters = stream_get_filters();
|
root@9
|
1718 if (!in_array('convert.*', $filters)) { //Got convert stream filter?
|
root@9
|
1719 return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation
|
root@9
|
1720 }
|
root@9
|
1721 $fp = fopen('php://temp/', 'r+');
|
root@9
|
1722 $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks
|
root@9
|
1723 $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE);
|
root@9
|
1724 $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params);
|
root@9
|
1725 fputs($fp, $string);
|
root@9
|
1726 rewind($fp);
|
root@9
|
1727 $out = stream_get_contents($fp);
|
root@9
|
1728 stream_filter_remove($s);
|
root@9
|
1729 $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange
|
root@9
|
1730 fclose($fp);
|
root@9
|
1731 return $out;
|
root@9
|
1732 }
|
root@9
|
1733
|
root@9
|
1734 /**
|
root@9
|
1735 * Encode string to q encoding.
|
root@9
|
1736 * @link http://tools.ietf.org/html/rfc2047
|
root@9
|
1737 * @param string $str the text to encode
|
root@9
|
1738 * @param string $position Where the text is going to be used, see the RFC for what that means
|
root@9
|
1739 * @access public
|
root@9
|
1740 * @return string
|
root@9
|
1741 */
|
root@9
|
1742 public function EncodeQ($str, $position = 'text') {
|
root@9
|
1743 // There should not be any EOL in the string
|
root@9
|
1744 $encoded = preg_replace('/[\r\n]*/', '', $str);
|
root@9
|
1745
|
root@9
|
1746 switch (strtolower($position)) {
|
root@9
|
1747 case 'phrase':
|
root@9
|
1748 $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
|
root@9
|
1749 break;
|
root@9
|
1750 case 'comment':
|
root@9
|
1751 $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
|
root@9
|
1752 case 'text':
|
root@9
|
1753 default:
|
root@9
|
1754 // Replace every high ascii, control =, ? and _ characters
|
root@9
|
1755 //TODO using /e (equivalent to eval()) is probably not a good idea
|
root@9
|
1756 $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
|
root@9
|
1757 "'='.sprintf('%02X', ord('\\1'))", $encoded);
|
root@9
|
1758 break;
|
root@9
|
1759 }
|
root@9
|
1760
|
root@9
|
1761 // Replace every spaces to _ (more readable than =20)
|
root@9
|
1762 $encoded = str_replace(' ', '_', $encoded);
|
root@9
|
1763
|
root@9
|
1764 return $encoded;
|
root@9
|
1765 }
|
root@9
|
1766
|
root@9
|
1767 /**
|
root@9
|
1768 * Adds a string or binary attachment (non-filesystem) to the list.
|
root@9
|
1769 * This method can be used to attach ascii or binary data,
|
root@9
|
1770 * such as a BLOB record from a database.
|
root@9
|
1771 * @param string $string String attachment data.
|
root@9
|
1772 * @param string $filename Name of the attachment.
|
root@9
|
1773 * @param string $encoding File encoding (see $Encoding).
|
root@9
|
1774 * @param string $type File extension (MIME) type.
|
root@9
|
1775 * @return void
|
root@9
|
1776 */
|
root@9
|
1777 public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
|
root@9
|
1778 // Append to $attachment array
|
root@9
|
1779 $this->attachment[] = array(
|
root@9
|
1780 0 => $string,
|
root@9
|
1781 1 => $filename,
|
root@9
|
1782 2 => basename($filename),
|
root@9
|
1783 3 => $encoding,
|
root@9
|
1784 4 => $type,
|
root@9
|
1785 5 => TRUE, // isStringAttachment
|
root@9
|
1786 6 => 'attachment',
|
root@9
|
1787 7 => 0
|
root@9
|
1788 );
|
root@9
|
1789 }
|
root@9
|
1790
|
root@9
|
1791 /**
|
root@9
|
1792 * Adds an embedded attachment. This can include images, sounds, and
|
root@9
|
1793 * just about any other document. Make sure to set the $type to an
|
root@9
|
1794 * image type. For JPEG images use "image/jpeg" and for GIF images
|
root@9
|
1795 * use "image/gif".
|
root@9
|
1796 * @param string $path Path to the attachment.
|
root@9
|
1797 * @param string $cid Content ID of the attachment. Use this to identify
|
root@9
|
1798 * the Id for accessing the image in an HTML form.
|
root@9
|
1799 * @param string $name Overrides the attachment name.
|
root@9
|
1800 * @param string $encoding File encoding (see $Encoding).
|
root@9
|
1801 * @param string $type File extension (MIME) type.
|
root@9
|
1802 * @return bool
|
root@9
|
1803 */
|
root@9
|
1804 public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
|
root@9
|
1805
|
root@9
|
1806 if ( !@is_file($path) ) {
|
root@9
|
1807 $this->SetError(t('Could not access file: !nofile', array('!nofile' => $path)));
|
root@9
|
1808 return FALSE;
|
root@9
|
1809 }
|
root@9
|
1810
|
root@9
|
1811 $filename = basename($path);
|
root@9
|
1812 if ( $name == '' ) {
|
root@9
|
1813 $name = $filename;
|
root@9
|
1814 }
|
root@9
|
1815
|
root@9
|
1816 // Append to $attachment array
|
root@9
|
1817 $this->attachment[] = array(
|
root@9
|
1818 0 => $path,
|
root@9
|
1819 1 => $filename,
|
root@9
|
1820 2 => $name,
|
root@9
|
1821 3 => $encoding,
|
root@9
|
1822 4 => $type,
|
root@9
|
1823 5 => FALSE, // isStringAttachment
|
root@9
|
1824 6 => 'inline',
|
root@9
|
1825 7 => $cid
|
root@9
|
1826 );
|
root@9
|
1827
|
root@9
|
1828 return TRUE;
|
root@9
|
1829 }
|
root@9
|
1830
|
root@9
|
1831 /**
|
root@9
|
1832 * Returns TRUE if an inline attachment is present.
|
root@9
|
1833 * @access public
|
root@9
|
1834 * @return bool
|
root@9
|
1835 */
|
root@9
|
1836 public function InlineImageExists() {
|
root@9
|
1837 foreach ($this->attachment as $attachment) {
|
root@9
|
1838 if ($attachment[6] == 'inline') {
|
root@9
|
1839 return TRUE;
|
root@9
|
1840 }
|
root@9
|
1841 }
|
root@9
|
1842 return FALSE;
|
root@9
|
1843 }
|
root@9
|
1844
|
root@9
|
1845 /////////////////////////////////////////////////
|
root@9
|
1846 // CLASS METHODS, MESSAGE RESET
|
root@9
|
1847 /////////////////////////////////////////////////
|
root@9
|
1848
|
root@9
|
1849 /**
|
root@9
|
1850 * Clears all recipients assigned in the TO array. Returns void.
|
root@9
|
1851 * @return void
|
root@9
|
1852 */
|
root@9
|
1853 public function ClearAddresses() {
|
root@9
|
1854 foreach ($this->to as $to) {
|
root@9
|
1855 unset($this->all_recipients[strtolower($to[0])]);
|
root@9
|
1856 }
|
root@9
|
1857 $this->to = array();
|
root@9
|
1858 }
|
root@9
|
1859
|
root@9
|
1860 /**
|
root@9
|
1861 * Clears all recipients assigned in the CC array. Returns void.
|
root@9
|
1862 * @return void
|
root@9
|
1863 */
|
root@9
|
1864 public function ClearCCs() {
|
root@9
|
1865 foreach ($this->cc as $cc) {
|
root@9
|
1866 unset($this->all_recipients[strtolower($cc[0])]);
|
root@9
|
1867 }
|
root@9
|
1868 $this->cc = array();
|
root@9
|
1869 }
|
root@9
|
1870
|
root@9
|
1871 /**
|
root@9
|
1872 * Clears all recipients assigned in the BCC array. Returns void.
|
root@9
|
1873 * @return void
|
root@9
|
1874 */
|
root@9
|
1875 public function ClearBCCs() {
|
root@9
|
1876 foreach ($this->bcc as $bcc) {
|
root@9
|
1877 unset($this->all_recipients[strtolower($bcc[0])]);
|
root@9
|
1878 }
|
root@9
|
1879 $this->bcc = array();
|
root@9
|
1880 }
|
root@9
|
1881
|
root@9
|
1882 /**
|
root@9
|
1883 * Clears all recipients assigned in the ReplyTo array. Returns void.
|
root@9
|
1884 * @return void
|
root@9
|
1885 */
|
root@9
|
1886 public function ClearReplyTos() {
|
root@9
|
1887 $this->ReplyTo = array();
|
root@9
|
1888 }
|
root@9
|
1889
|
root@9
|
1890 /**
|
root@9
|
1891 * Clears all recipients assigned in the TO, CC and BCC
|
root@9
|
1892 * array. Returns void.
|
root@9
|
1893 * @return void
|
root@9
|
1894 */
|
root@9
|
1895 public function ClearAllRecipients() {
|
root@9
|
1896 $this->to = array();
|
root@9
|
1897 $this->cc = array();
|
root@9
|
1898 $this->bcc = array();
|
root@9
|
1899 $this->all_recipients = array();
|
root@9
|
1900 }
|
root@9
|
1901
|
root@9
|
1902 /**
|
root@9
|
1903 * Clears all previously set filesystem, string, and binary
|
root@9
|
1904 * attachments. Returns void.
|
root@9
|
1905 * @return void
|
root@9
|
1906 */
|
root@9
|
1907 public function ClearAttachments() {
|
root@9
|
1908 $this->attachment = array();
|
root@9
|
1909 }
|
root@9
|
1910
|
root@9
|
1911 /**
|
root@9
|
1912 * Clears all custom headers. Returns void.
|
root@9
|
1913 * @return void
|
root@9
|
1914 */
|
root@9
|
1915 public function ClearCustomHeaders() {
|
root@9
|
1916 $this->CustomHeader = array();
|
root@9
|
1917 }
|
root@9
|
1918
|
root@9
|
1919 /////////////////////////////////////////////////
|
root@9
|
1920 // CLASS METHODS, MISCELLANEOUS
|
root@9
|
1921 /////////////////////////////////////////////////
|
root@9
|
1922
|
root@9
|
1923 /**
|
root@9
|
1924 * Adds the error message to the error container.
|
root@9
|
1925 * @access protected
|
root@9
|
1926 * @return void
|
root@9
|
1927 */
|
root@9
|
1928 protected function SetError($msg) {
|
root@9
|
1929 $this->error_count++;
|
root@9
|
1930 if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
|
root@9
|
1931 $lasterror = $this->smtp->getError();
|
root@9
|
1932 if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
|
root@9
|
1933 $msg .= '<p>' . t('SMTP server error: !lasterror', array('!lasterror' => $lasterror['smtp_msg'])) . "</p>\n";
|
root@9
|
1934 }
|
root@9
|
1935 }
|
root@9
|
1936 $this->ErrorInfo = $msg;
|
root@9
|
1937 }
|
root@9
|
1938
|
root@9
|
1939 /**
|
root@9
|
1940 * Returns the proper RFC 822 formatted date.
|
root@9
|
1941 * @access public
|
root@9
|
1942 * @return string
|
root@9
|
1943 * @static
|
root@9
|
1944 */
|
root@9
|
1945 public static function RFCDate() {
|
root@9
|
1946 $tz = date('Z');
|
root@9
|
1947 $tzs = ($tz < 0) ? '-' : '+';
|
root@9
|
1948 $tz = abs($tz);
|
root@9
|
1949 $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
|
root@9
|
1950 $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
|
root@9
|
1951
|
root@9
|
1952 return $result;
|
root@9
|
1953 }
|
root@9
|
1954
|
root@9
|
1955 /**
|
root@9
|
1956 * Returns the server hostname or 'localhost.localdomain' if unknown.
|
root@9
|
1957 * @access private
|
root@9
|
1958 * @return string
|
root@9
|
1959 */
|
root@9
|
1960 private function ServerHostname() {
|
root@9
|
1961 if (!empty($this->Hostname)) {
|
root@9
|
1962 $result = $this->Hostname;
|
root@9
|
1963 }
|
root@9
|
1964 elseif (isset($_SERVER['SERVER_NAME'])) {
|
root@9
|
1965 $result = $_SERVER['SERVER_NAME'];
|
root@9
|
1966 }
|
root@9
|
1967 else {
|
root@9
|
1968 $result = 'localhost.localdomain';
|
root@9
|
1969 }
|
root@9
|
1970
|
root@9
|
1971 return $result;
|
root@9
|
1972 }
|
root@9
|
1973
|
root@9
|
1974 /**
|
root@9
|
1975 * Returns TRUE if an error occurred.
|
root@9
|
1976 * @access public
|
root@9
|
1977 * @return bool
|
root@9
|
1978 */
|
root@9
|
1979 public function IsError() {
|
root@9
|
1980 return ($this->error_count > 0);
|
root@9
|
1981 }
|
root@9
|
1982
|
root@9
|
1983 /**
|
root@9
|
1984 * Changes every end of line from CR or LF to CRLF.
|
root@9
|
1985 * @access private
|
root@9
|
1986 * @return string
|
root@9
|
1987 */
|
root@9
|
1988 private function FixEOL($str) {
|
root@9
|
1989 $str = str_replace("\r\n", "\n", $str);
|
root@9
|
1990 $str = str_replace("\r", "\n", $str);
|
root@9
|
1991 $str = str_replace("\n", $this->LE, $str);
|
root@9
|
1992 return $str;
|
root@9
|
1993 }
|
root@9
|
1994
|
root@9
|
1995 /**
|
root@9
|
1996 * Adds a custom header.
|
root@9
|
1997 * @access public
|
root@9
|
1998 * @return void
|
root@9
|
1999 */
|
root@9
|
2000 public function AddCustomHeader($custom_header) {
|
root@9
|
2001 $this->CustomHeader[] = explode(':', $custom_header, 2);
|
root@9
|
2002 }
|
root@9
|
2003
|
root@9
|
2004 /**
|
root@9
|
2005 * Evaluates the message and returns modifications for inline images and backgrounds
|
root@9
|
2006 * @access public
|
root@9
|
2007 * @return $message
|
root@9
|
2008 */
|
root@9
|
2009 public function MsgHTML($message, $basedir = '') {
|
root@9
|
2010 preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
|
root@9
|
2011 if (isset($images[2])) {
|
root@9
|
2012 foreach ($images[2] as $i => $url) {
|
root@9
|
2013 // do not change urls for absolute images (thanks to corvuscorax)
|
root@9
|
2014 if (!preg_match('#^[A-z]+://#', $url)) {
|
root@9
|
2015 $filename = basename($url);
|
root@9
|
2016 $directory = dirname($url);
|
root@9
|
2017 ($directory == '.')?$directory='':'';
|
root@9
|
2018 $cid = 'cid:' . md5($filename);
|
root@9
|
2019 $ext = pathinfo($filename, PATHINFO_EXTENSION);
|
root@9
|
2020 $mimeType = self::_mime_types($ext);
|
root@9
|
2021 if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') {
|
root@9
|
2022 $basedir .= '/';
|
root@9
|
2023 }
|
root@9
|
2024 if ( strlen($directory) > 1 && substr($directory, -1) != '/') {
|
root@9
|
2025 $directory .= '/';
|
root@9
|
2026 }
|
root@9
|
2027 if ( $this->AddEmbeddedImage($basedir . $directory . $filename, md5($filename), $filename, 'base64', $mimeType) ) {
|
root@9
|
2028 $message = preg_replace("/" . $images[1][$i] . "=\"" . preg_quote($url, '/') . "\"/Ui", $images[1][$i] . "=\"" . $cid . "\"", $message);
|
root@9
|
2029 }
|
root@9
|
2030 }
|
root@9
|
2031 }
|
root@9
|
2032 }
|
root@9
|
2033 $this->IsHTML(TRUE);
|
root@9
|
2034 $this->Body = $message;
|
root@9
|
2035 $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message)));
|
root@9
|
2036 if (!empty($textMsg) && empty($this->AltBody)) {
|
root@9
|
2037 $this->AltBody = html_entity_decode($textMsg);
|
root@9
|
2038 }
|
root@9
|
2039 if (empty($this->AltBody)) {
|
root@9
|
2040 $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
|
root@9
|
2041 }
|
root@9
|
2042 }
|
root@9
|
2043
|
root@9
|
2044 /**
|
root@9
|
2045 * Gets the MIME type of the embedded or inline image
|
root@9
|
2046 * @param string File extension
|
root@9
|
2047 * @access public
|
root@9
|
2048 * @return string MIME type of ext
|
root@9
|
2049 * @static
|
root@9
|
2050 */
|
root@9
|
2051 public static function _mime_types($ext = '') {
|
root@9
|
2052 $mimes = array(
|
root@9
|
2053 'hqx' => 'application/mac-binhex40',
|
root@9
|
2054 'cpt' => 'application/mac-compactpro',
|
root@9
|
2055 'doc' => 'application/msword',
|
root@9
|
2056 'bin' => 'application/macbinary',
|
root@9
|
2057 'dms' => 'application/octet-stream',
|
root@9
|
2058 'lha' => 'application/octet-stream',
|
root@9
|
2059 'lzh' => 'application/octet-stream',
|
root@9
|
2060 'exe' => 'application/octet-stream',
|
root@9
|
2061 'class' => 'application/octet-stream',
|
root@9
|
2062 'psd' => 'application/octet-stream',
|
root@9
|
2063 'so' => 'application/octet-stream',
|
root@9
|
2064 'sea' => 'application/octet-stream',
|
root@9
|
2065 'dll' => 'application/octet-stream',
|
root@9
|
2066 'oda' => 'application/oda',
|
root@9
|
2067 'pdf' => 'application/pdf',
|
root@9
|
2068 'ai' => 'application/postscript',
|
root@9
|
2069 'eps' => 'application/postscript',
|
root@9
|
2070 'ps' => 'application/postscript',
|
root@9
|
2071 'smi' => 'application/smil',
|
root@9
|
2072 'smil' => 'application/smil',
|
root@9
|
2073 'mif' => 'application/vnd.mif',
|
root@9
|
2074 'xls' => 'application/vnd.ms-excel',
|
root@9
|
2075 'ppt' => 'application/vnd.ms-powerpoint',
|
root@9
|
2076 'wbxml' => 'application/vnd.wap.wbxml',
|
root@9
|
2077 'wmlc' => 'application/vnd.wap.wmlc',
|
root@9
|
2078 'dcr' => 'application/x-director',
|
root@9
|
2079 'dir' => 'application/x-director',
|
root@9
|
2080 'dxr' => 'application/x-director',
|
root@9
|
2081 'dvi' => 'application/x-dvi',
|
root@9
|
2082 'gtar' => 'application/x-gtar',
|
root@9
|
2083 'php' => 'application/x-httpd-php',
|
root@9
|
2084 'php4' => 'application/x-httpd-php',
|
root@9
|
2085 'php3' => 'application/x-httpd-php',
|
root@9
|
2086 'phtml' => 'application/x-httpd-php',
|
root@9
|
2087 'phps' => 'application/x-httpd-php-source',
|
root@9
|
2088 'js' => 'application/x-javascript',
|
root@9
|
2089 'swf' => 'application/x-shockwave-flash',
|
root@9
|
2090 'sit' => 'application/x-stuffit',
|
root@9
|
2091 'tar' => 'application/x-tar',
|
root@9
|
2092 'tgz' => 'application/x-tar',
|
root@9
|
2093 'xhtml' => 'application/xhtml+xml',
|
root@9
|
2094 'xht' => 'application/xhtml+xml',
|
root@9
|
2095 'zip' => 'application/zip',
|
root@9
|
2096 'mid' => 'audio/midi',
|
root@9
|
2097 'midi' => 'audio/midi',
|
root@9
|
2098 'mpga' => 'audio/mpeg',
|
root@9
|
2099 'mp2' => 'audio/mpeg',
|
root@9
|
2100 'mp3' => 'audio/mpeg',
|
root@9
|
2101 'aif' => 'audio/x-aiff',
|
root@9
|
2102 'aiff' => 'audio/x-aiff',
|
root@9
|
2103 'aifc' => 'audio/x-aiff',
|
root@9
|
2104 'ram' => 'audio/x-pn-realaudio',
|
root@9
|
2105 'rm' => 'audio/x-pn-realaudio',
|
root@9
|
2106 'rpm' => 'audio/x-pn-realaudio-plugin',
|
root@9
|
2107 'ra' => 'audio/x-realaudio',
|
root@9
|
2108 'rv' => 'video/vnd.rn-realvideo',
|
root@9
|
2109 'wav' => 'audio/x-wav',
|
root@9
|
2110 'bmp' => 'image/bmp',
|
root@9
|
2111 'gif' => 'image/gif',
|
root@9
|
2112 'jpeg' => 'image/jpeg',
|
root@9
|
2113 'jpg' => 'image/jpeg',
|
root@9
|
2114 'jpe' => 'image/jpeg',
|
root@9
|
2115 'png' => 'image/png',
|
root@9
|
2116 'tiff' => 'image/tiff',
|
root@9
|
2117 'tif' => 'image/tiff',
|
root@9
|
2118 'css' => 'text/css',
|
root@9
|
2119 'html' => 'text/html',
|
root@9
|
2120 'htm' => 'text/html',
|
root@9
|
2121 'shtml' => 'text/html',
|
root@9
|
2122 'txt' => 'text/plain',
|
root@9
|
2123 'text' => 'text/plain',
|
root@9
|
2124 'log' => 'text/plain',
|
root@9
|
2125 'rtx' => 'text/richtext',
|
root@9
|
2126 'rtf' => 'text/rtf',
|
root@9
|
2127 'xml' => 'text/xml',
|
root@9
|
2128 'xsl' => 'text/xml',
|
root@9
|
2129 'mpeg' => 'video/mpeg',
|
root@9
|
2130 'mpg' => 'video/mpeg',
|
root@9
|
2131 'mpe' => 'video/mpeg',
|
root@9
|
2132 'qt' => 'video/quicktime',
|
root@9
|
2133 'mov' => 'video/quicktime',
|
root@9
|
2134 'avi' => 'video/x-msvideo',
|
root@9
|
2135 'movie' => 'video/x-sgi-movie',
|
root@9
|
2136 'doc' => 'application/msword',
|
root@9
|
2137 'word' => 'application/msword',
|
root@9
|
2138 'xl' => 'application/excel',
|
root@9
|
2139 'eml' => 'message/rfc822'
|
root@9
|
2140 );
|
root@9
|
2141 return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
|
root@9
|
2142 }
|
root@9
|
2143
|
root@9
|
2144 /**
|
root@9
|
2145 * Set (or reset) Class Objects (variables)
|
root@9
|
2146 *
|
root@9
|
2147 * Usage Example:
|
root@9
|
2148 * $page->set('X-Priority', '3');
|
root@9
|
2149 *
|
root@9
|
2150 * @access public
|
root@9
|
2151 * @param string $name Parameter Name
|
root@9
|
2152 * @param mixed $value Parameter Value
|
root@9
|
2153 * NOTE: will not work with arrays, there are no arrays to set/reset
|
root@9
|
2154 * @todo Should this not be using __set() magic function?
|
root@9
|
2155 */
|
root@9
|
2156 public function set($name, $value = '') {
|
root@9
|
2157 try {
|
root@9
|
2158 if (isset($this->$name) ) {
|
root@9
|
2159 $this->$name = $value;
|
root@9
|
2160 }
|
root@9
|
2161 else {
|
root@9
|
2162 throw new phpmailerException(t('Cannot set or reset variable: !name', array('!name' => $name)) , self::STOP_CRITICAL);
|
root@9
|
2163 }
|
root@9
|
2164 } catch (Exception $e) {
|
root@9
|
2165 $this->SetError($e->getMessage());
|
root@9
|
2166 if ($e->getCode() == self::STOP_CRITICAL) {
|
root@9
|
2167 return FALSE;
|
root@9
|
2168 }
|
root@9
|
2169 }
|
root@9
|
2170 return TRUE;
|
root@9
|
2171 }
|
root@9
|
2172
|
root@9
|
2173 /**
|
root@9
|
2174 * Strips newlines to prevent header injection.
|
root@9
|
2175 * @access public
|
root@9
|
2176 * @param string $str String
|
root@9
|
2177 * @return string
|
root@9
|
2178 */
|
root@9
|
2179 public function SecureHeader($str) {
|
root@9
|
2180 $str = str_replace("\r", '', $str);
|
root@9
|
2181 $str = str_replace("\n", '', $str);
|
root@9
|
2182 return trim($str);
|
root@9
|
2183 }
|
root@9
|
2184
|
root@9
|
2185 /**
|
root@9
|
2186 * Set the private key file and password to sign the message.
|
root@9
|
2187 *
|
root@9
|
2188 * @access public
|
root@9
|
2189 * @param string $key_filename Parameter File Name
|
root@9
|
2190 * @param string $key_pass Password for private key
|
root@9
|
2191 */
|
root@9
|
2192 public function Sign($cert_filename, $key_filename, $key_pass) {
|
root@9
|
2193 $this->sign_cert_file = $cert_filename;
|
root@9
|
2194 $this->sign_key_file = $key_filename;
|
root@9
|
2195 $this->sign_key_pass = $key_pass;
|
root@9
|
2196 }
|
root@9
|
2197
|
root@9
|
2198 /**
|
root@9
|
2199 * Set the private key file and password to sign the message.
|
root@9
|
2200 *
|
root@9
|
2201 * @access public
|
root@9
|
2202 * @param string $key_filename Parameter File Name
|
root@9
|
2203 * @param string $key_pass Password for private key
|
root@9
|
2204 */
|
root@9
|
2205 public function DKIM_QP($txt) {
|
root@9
|
2206 $tmp="";
|
root@9
|
2207 $line="";
|
root@9
|
2208 for ($i=0;$i<strlen($txt);$i++) {
|
root@9
|
2209 $ord=ord($txt[$i]);
|
root@9
|
2210 if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) {
|
root@9
|
2211 $line .=$txt[$i];
|
root@9
|
2212 }
|
root@9
|
2213 else {
|
root@9
|
2214 $line .="=" . sprintf("%02X", $ord);
|
root@9
|
2215 }
|
root@9
|
2216 }
|
root@9
|
2217 return $line;
|
root@9
|
2218 }
|
root@9
|
2219
|
root@9
|
2220 /**
|
root@9
|
2221 * Generate DKIM signature
|
root@9
|
2222 *
|
root@9
|
2223 * @access public
|
root@9
|
2224 * @param string $s Header
|
root@9
|
2225 */
|
root@9
|
2226 public function DKIM_Sign($s) {
|
root@9
|
2227 $privKeyStr = file_get_contents($this->DKIM_private);
|
root@9
|
2228 if ($this->DKIM_passphrase!='') {
|
root@9
|
2229 $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
|
root@9
|
2230 }
|
root@9
|
2231 else {
|
root@9
|
2232 $privKey = $privKeyStr;
|
root@9
|
2233 }
|
root@9
|
2234 if (openssl_sign($s, $signature, $privKey)) {
|
root@9
|
2235 return base64_encode($signature);
|
root@9
|
2236 }
|
root@9
|
2237 }
|
root@9
|
2238
|
root@9
|
2239 /**
|
root@9
|
2240 * Generate DKIM Canonicalization Header
|
root@9
|
2241 *
|
root@9
|
2242 * @access public
|
root@9
|
2243 * @param string $s Header
|
root@9
|
2244 */
|
root@9
|
2245 public function DKIM_HeaderC($s) {
|
root@9
|
2246 $s=preg_replace("/\r\n\s+/", " ", $s);
|
root@9
|
2247 $lines=explode("\r\n", $s);
|
root@9
|
2248 foreach ($lines as $key => $line) {
|
root@9
|
2249 list($heading, $value)=explode(":", $line, 2);
|
root@9
|
2250 $heading=strtolower($heading);
|
root@9
|
2251 $value=preg_replace("/\s+/", " ", $value); // Compress useless spaces
|
root@9
|
2252 $lines[$key]=$heading . ":" . trim($value); // Don't forget to remove WSP around the value
|
root@9
|
2253 }
|
root@9
|
2254 $s=implode("\r\n", $lines);
|
root@9
|
2255 return $s;
|
root@9
|
2256 }
|
root@9
|
2257
|
root@9
|
2258 /**
|
root@9
|
2259 * Generate DKIM Canonicalization Body
|
root@9
|
2260 *
|
root@9
|
2261 * @access public
|
root@9
|
2262 * @param string $body Message Body
|
root@9
|
2263 */
|
root@9
|
2264 public function DKIM_BodyC($body) {
|
root@9
|
2265 if ($body == '') return "\r\n";
|
root@9
|
2266 // stabilize line endings
|
root@9
|
2267 $body=str_replace("\r\n", "\n", $body);
|
root@9
|
2268 $body=str_replace("\n", "\r\n", $body);
|
root@9
|
2269 // END stabilize line endings
|
root@9
|
2270 while (substr($body, strlen($body)-4, 4) == "\r\n\r\n") {
|
root@9
|
2271 $body=substr($body, 0, strlen($body)-2);
|
root@9
|
2272 }
|
root@9
|
2273 return $body;
|
root@9
|
2274 }
|
root@9
|
2275
|
root@9
|
2276 /**
|
root@9
|
2277 * Create the DKIM header, body, as new header
|
root@9
|
2278 *
|
root@9
|
2279 * @access public
|
root@9
|
2280 * @param string $headers_line Header lines
|
root@9
|
2281 * @param string $subject Subject
|
root@9
|
2282 * @param string $body Body
|
root@9
|
2283 */
|
root@9
|
2284 public function DKIM_Add($headers_line, $subject, $body) {
|
root@9
|
2285 $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
|
root@9
|
2286 $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
|
root@9
|
2287 $DKIMquery = 'dns/txt'; // Query method
|
root@9
|
2288 $DKIMtime = REQUEST_TIME; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
|
root@9
|
2289 $subject_header = "Subject: $subject";
|
root@9
|
2290 $headers = explode("\r\n", $headers_line);
|
root@9
|
2291 foreach ($headers as $header) {
|
root@9
|
2292 if (strpos($header, 'From:') === 0) {
|
root@9
|
2293 $from_header=$header;
|
root@9
|
2294 }
|
root@9
|
2295 elseif (strpos($header, 'To:') === 0) {
|
root@9
|
2296 $to_header=$header;
|
root@9
|
2297 }
|
root@9
|
2298 }
|
root@9
|
2299 $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
|
root@9
|
2300 $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
|
root@9
|
2301 $subject = str_replace('|', '=7C', $this->DKIM_QP($subject_header)); // Copied header fields (dkim-quoted-printable
|
root@9
|
2302 $body = $this->DKIM_BodyC($body);
|
root@9
|
2303 $DKIMlen = strlen($body) ; // Length of body
|
root@9
|
2304 $DKIMb64 = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body
|
root@9
|
2305 $ident = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";";
|
root@9
|
2306 $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n" .
|
root@9
|
2307 "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n" .
|
root@9
|
2308 "\th=From:To:Subject;\r\n" .
|
root@9
|
2309 "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n" .
|
root@9
|
2310 "\tz=$from\r\n" .
|
root@9
|
2311 "\t|$to\r\n" .
|
root@9
|
2312 "\t|$subject;\r\n" .
|
root@9
|
2313 "\tbh=" . $DKIMb64 . ";\r\n" .
|
root@9
|
2314 "\tb=";
|
root@9
|
2315 $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
|
root@9
|
2316 $signed = $this->DKIM_Sign($toSign);
|
root@9
|
2317 return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n" . $dkimhdrs . $signed . "\r\n";
|
root@9
|
2318 }
|
root@9
|
2319
|
root@9
|
2320 protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body) {
|
root@9
|
2321 if (!empty($this->action_function) && function_exists($this->action_function)) {
|
root@9
|
2322 $params = array($isSent, $to, $cc, $bcc, $subject, $body);
|
root@9
|
2323 call_user_func_array($this->action_function, $params);
|
root@9
|
2324 }
|
root@9
|
2325 }
|
root@9
|
2326 }
|
root@9
|
2327
|
root@9
|
2328 class phpmailerException extends Exception {
|
root@9
|
2329 public function errorMessage() {
|
root@9
|
2330 $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
|
root@9
|
2331 return $errorMsg;
|
root@9
|
2332 }
|
root@9
|
2333 } |