# | Code | Descriptions |
1 | <?php | |
2 | /*~ class.phpmailer.php | |
3 | .---------------------------------------------------------------------------. | |
4 | | Software: PHPMailer - PHP email class | | |
5 | | Version: 2.0.4 | | |
6 | | Contact: via sourceforge.net support pages (also www.codeworxtech.com) | | |
7 | | Info: http://phpmailer.sourceforge.net | | |
8 | | Support: http://sourceforge.net/projects/phpmailer/ | | |
9 | | ------------------------------------------------------------------------- | | |
10 | | Author: Andy Prevost (project admininistrator) | | |
11 | | Author: Brent R. Matzelle (original founder) | | |
12 | | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. | | |
13 | | Copyright (c) 2001-2003, Brent R. Matzelle | | |
14 | | ------------------------------------------------------------------------- | | |
15 | | License: Distributed under the Lesser General Public License (LGPL) | | |
16 | | http://www.gnu.org/copyleft/lesser.html | | |
17 | | This program is distributed in the hope that it will be useful - WITHOUT | | |
18 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | | |
19 | | FITNESS FOR A PARTICULAR PURPOSE. | | |
20 | | ------------------------------------------------------------------------- | | |
21 | | We offer a number of paid services (www.codeworxtech.com): | | |
22 | | - Web Hosting on highly optimized fast and secure servers | | |
23 | | - Technology Consulting | | |
24 | | - Oursourcing (highly qualified programmers and graphic designers) | | |
25 | '---------------------------------------------------------------------------' | |
26 | */ | |
27 | /** | |
28 | * PHPMailer - PHP email transport class | |
29 | * @package PHPMailer | |
30 | * @author Andy Prevost | |
31 | * @copyright 2004 - 2009 Andy Prevost | |
32 | */ | |
33 | ||
34 | class PHPMailer { | |
35 | ||
36 | ///////////////////////////////////////////////// | |
37 | // PROPERTIES, PUBLIC | |
38 | ///////////////////////////////////////////////// | |
39 | ||
40 | /** | |
41 | * Email priority (1 = High, 3 = Normal, 5 = low). | |
42 | * @var int | |
43 | */ | |
44 | var $Priority = 3; | |
45 | ||
46 | /** | |
47 | * Sets the CharSet of the message. | |
48 | * @var string | |
49 | */ | |
50 | var $CharSet = 'iso-8859-1'; | |
51 | ||
52 | /** | |
53 | * Sets the Content-type of the message. | |
54 | * @var string | |
55 | */ | |
56 | var $ContentType = 'text/plain'; | |
57 | ||
58 | /** | |
59 | * Sets the Encoding of the message. Options for this are "8bit", | |
60 | * "7bit", "binary", "base64", and "quoted-printable". | |
61 | * @var string | |
62 | */ | |
63 | var $Encoding = '8bit'; | |
64 | ||
65 | /** | |
66 | * Holds the most recent mailer error message. | |
67 | * @var string | |
68 | */ | |
69 | var $ErrorInfo = ''; | |
70 | ||
71 | /** | |
72 | * Sets the From email address for the message. | |
73 | * @var string | |
74 | */ | |
75 | var $From = 'root@localhost'; | |
76 | ||
77 | /** | |
78 | * Sets the From name of the message. | |
79 | * @var string | |
80 | */ | |
81 | var $FromName = 'Root User'; | |
82 | ||
83 | /** | |
84 | * Sets the Sender email (Return-Path) of the message. If not empty, | |
85 | * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. | |
86 | * @var string | |
87 | */ | |
88 | var $Sender = ''; | |
89 | ||
90 | /** | |
91 | * Sets the Subject of the message. | |
92 | * @var string | |
93 | */ | |
94 | var $Subject = ''; | |
95 | ||
96 | /** | |
97 | * Sets the Body of the message. This can be either an HTML or text body. | |
98 | * If HTML then run IsHTML(true). | |
99 | * @var string | |
100 | */ | |
101 | var $Body = ''; | |
102 | ||
103 | /** | |
104 | * Sets the text-only body of the message. This automatically sets the | |
105 | * email to multipart/alternative. This body can be read by mail | |
106 | * clients that do not have HTML email capability such as mutt. Clients | |
107 | * that can read HTML will view the normal Body. | |
108 | * @var string | |
109 | */ | |
110 | var $AltBody = ''; | |
111 | ||
112 | /** | |
113 | * Sets word wrapping on the body of the message to a given number of | |
114 | * characters. | |
115 | * @var int | |
116 | */ | |
117 | var $WordWrap = 0; | |
118 | ||
119 | /** | |
120 | * Method to send mail: ("mail", "sendmail", or "smtp"). | |
121 | * @var string | |
122 | */ | |
123 | var $Mailer = 'mail'; | |
124 | ||
125 | /** | |
126 | * Sets the path of the sendmail program. | |
127 | * @var string | |
128 | */ | |
129 | var $Sendmail = '/usr/sbin/sendmail'; | |
130 | ||
131 | /** | |
132 | * Path to PHPMailer plugins. This is now only useful if the SMTP class | |
133 | * is in a different directory than the PHP include path. | |
134 | * @var string | |
135 | */ | |
136 | var $PluginDir = ''; | |
137 | ||
138 | /** | |
139 | * Holds PHPMailer version. | |
140 | * @var string | |
141 | */ | |
142 | var $Version = "2.0.4"; | |
143 | ||
144 | /** | |
145 | * Sets the email address that a reading confirmation will be sent. | |
146 | * @var string | |
147 | */ | |
148 | var $ConfirmReadingTo = ''; | |
149 | ||
150 | /** | |
151 | * Sets the hostname to use in Message-Id and Received headers | |
152 | * and as default HELO string. If empty, the value returned | |
153 | * by SERVER_NAME is used or 'localhost.localdomain'. | |
154 | * @var string | |
155 | */ | |
156 | var $Hostname = ''; | |
157 | ||
158 | /** | |
159 | * Sets the message ID to be used in the Message-Id header. | |
160 | * If empty, a unique id will be generated. | |
161 | * @var string | |
162 | */ | |
163 | var $MessageID = ''; | |
164 | ||
165 | ///////////////////////////////////////////////// | |
166 | // PROPERTIES FOR SMTP | |
167 | ///////////////////////////////////////////////// | |
168 | ||
169 | /** | |
170 | * Sets the SMTP hosts. All hosts must be separated by a | |
171 | * semicolon. You can also specify a different port | |
172 | * for each host by using this format: [hostname:port] | |
173 | * (e.g. "smtp1.example.com:25;smtp2.example.com"). | |
174 | * Hosts will be tried in order. | |
175 | * @var string | |
176 | */ | |
177 | var $Host = 'localhost'; | |
178 | ||
179 | /** | |
180 | * Sets the default SMTP server port. | |
181 | * @var int | |
182 | */ | |
183 | var $Port = 25; | |
184 | ||
185 | /** | |
186 | * Sets the SMTP HELO of the message (Default is $Hostname). | |
187 | * @var string | |
188 | */ | |
189 | var $Helo = ''; | |
190 | ||
191 | /** | |
192 | * Sets connection prefix. | |
193 | * Options are "", "ssl" or "tls" | |
194 | * @var string | |
195 | */ | |
196 | var $SMTPSecure = ""; | |
197 | ||
198 | /** | |
199 | * Sets SMTP authentication. Utilizes the Username and Password variables. | |
200 | * @var bool | |
201 | */ | |
202 | var $SMTPAuth = false; | |
203 | ||
204 | /** | |
205 | * Sets SMTP username. | |
206 | * @var string | |
207 | */ | |
208 | var $Username = ''; | |
209 | ||
210 | /** | |
211 | * Sets SMTP password. | |
212 | * @var string | |
213 | */ | |
214 | var $Password = ''; | |
215 | ||
216 | /** | |
217 | * Sets the SMTP server timeout in seconds. This function will not | |
218 | * work with the win32 version. | |
219 | * @var int | |
220 | */ | |
221 | var $Timeout = 10; | |
222 | ||
223 | /** | |
224 | * Sets SMTP class debugging on or off. | |
225 | * @var bool | |
226 | */ | |
227 | var $SMTPDebug = false; | |
228 | ||
229 | /** | |
230 | * Prevents the SMTP connection from being closed after each mail | |
231 | * sending. If this is set to true then to close the connection | |
232 | * requires an explicit call to SmtpClose(). | |
233 | * @var bool | |
234 | */ | |
235 | var $SMTPKeepAlive = false; | |
236 | ||
237 | /** | |
238 | * Provides the ability to have the TO field process individual | |
239 | * emails, instead of sending to entire TO addresses | |
240 | * @var bool | |
241 | */ | |
242 | var $SingleTo = false; | |
243 | ||
244 | ///////////////////////////////////////////////// | |
245 | // PROPERTIES, PRIVATE | |
246 | ///////////////////////////////////////////////// | |
247 | ||
248 | var $smtp = NULL; | |
249 | var $to = array(); | |
250 | var $cc = array(); | |
251 | var $bcc = array(); | |
252 | var $ReplyTo = array(); | |
253 | var $attachment = array(); | |
254 | var $CustomHeader = array(); | |
255 | var $message_type = ''; | |
256 | var $boundary = array(); | |
257 | var $language = array(); | |
258 | var $error_count = 0; | |
259 | var $LE = "\n"; | |
260 | var $sign_cert_file = ""; | |
261 | var $sign_key_file = ""; | |
262 | var $sign_key_pass = ""; | |
263 | ||
264 | ///////////////////////////////////////////////// | |
265 | // METHODS, VARIABLES | |
266 | ///////////////////////////////////////////////// | |
267 | ||
268 | /** | |
269 | * Sets message type to HTML. | |
270 | * @param bool $bool | |
271 | * @return void | |
272 | */ | |
273 | function IsHTML($bool) { | |
274 | if($bool == true) { | |
275 | $this->ContentType = 'text/html'; | |
276 | } else { | |
277 | $this->ContentType = 'text/plain'; | |
278 | } | |
279 | } | |
280 | ||
281 | /** | |
282 | * Sets Mailer to send message using SMTP. | |
283 | * @return void | |
284 | */ | |
285 | function IsSMTP() { | |
286 | $this->Mailer = 'smtp'; | |
287 | } | |
288 | ||
289 | /** | |
290 | * Sets Mailer to send message using PHP mail() function. | |
291 | * @return void | |
292 | */ | |
293 | function IsMail() { | |
294 | $this->Mailer = 'mail'; | |
295 | } | |
296 | ||
297 | /** | |
298 | * Sets Mailer to send message using the $Sendmail program. | |
299 | * @return void | |
300 | */ | |
301 | function IsSendmail() { | |
302 | $this->Mailer = 'sendmail'; | |
303 | } | |
304 | ||
305 | /** | |
306 | * Sets Mailer to send message using the qmail MTA. | |
307 | * @return void | |
308 | */ | |
309 | function IsQmail() { | |
310 | $this->Sendmail = '/var/qmail/bin/sendmail'; | |
311 | $this->Mailer = 'sendmail'; | |
312 | } | |
313 | ||
314 | ///////////////////////////////////////////////// | |
315 | // METHODS, RECIPIENTS | |
316 | ///////////////////////////////////////////////// | |
317 | ||
318 | /** | |
319 | * Adds a "To" address. | |
320 | * @param string $address | |
321 | * @param string $name | |
322 | * @return void | |
323 | */ | |
324 | function AddAddress($address, $name = '') { | |
325 | $cur = count($this->to); | |
326 | $this->to[$cur][0] = trim($address); | |
327 | $this->to[$cur][1] = $name; | |
328 | } | |
329 | ||
330 | /** | |
331 | * Adds a "Cc" address. Note: this function works | |
332 | * with the SMTP mailer on win32, not with the "mail" | |
333 | * mailer. | |
334 | * @param string $address | |
335 | * @param string $name | |
336 | * @return void | |
337 | */ | |
338 | function AddCC($address, $name = '') { | |
339 | $cur = count($this->cc); | |
340 | $this->cc[$cur][0] = trim($address); | |
341 | $this->cc[$cur][1] = $name; | |
342 | } | |
343 | ||
344 | /** | |
345 | * Adds a "Bcc" address. Note: this function works | |
346 | * with the SMTP mailer on win32, not with the "mail" | |
347 | * mailer. | |
348 | * @param string $address | |
349 | * @param string $name | |
350 | * @return void | |
351 | */ | |
352 | function AddBCC($address, $name = '') { | |
353 | $cur = count($this->bcc); | |
354 | $this->bcc[$cur][0] = trim($address); | |
355 | $this->bcc[$cur][1] = $name; | |
356 | } | |
357 | ||
358 | /** | |
359 | * Adds a "Reply-To" address. | |
360 | * @param string $address | |
361 | * @param string $name | |
362 | * @return void | |
363 | */ | |
364 | function AddReplyTo($address, $name = '') { | |
365 | $cur = count($this->ReplyTo); | |
366 | $this->ReplyTo[$cur][0] = trim($address); | |
367 | $this->ReplyTo[$cur][1] = $name; | |
368 | } | |
369 | ||
370 | ///////////////////////////////////////////////// | |
371 | // METHODS, MAIL SENDING | |
372 | ///////////////////////////////////////////////// | |
373 | ||
374 | /** | |
375 | * Creates message and assigns Mailer. If the message is | |
376 | * not sent successfully then it returns false. Use the ErrorInfo | |
377 | * variable to view description of the error. | |
378 | * @return bool | |
379 | */ | |
380 | function Send() { | |
381 | $header = ''; | |
382 | $body = ''; | |
383 | $result = true; | |
384 | ||
385 | if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { | |
386 | $this->SetError($this->Lang('provide_address')); | |
387 | return false; | |
388 | } | |
389 | ||
390 | /* Set whether the message is multipart/alternative */ | |
391 | if(!empty($this->AltBody)) { | |
392 | $this->ContentType = 'multipart/alternative'; | |
393 | } | |
394 | ||
395 | $this->error_count = 0; // reset errors | |
396 | $this->SetMessageType(); | |
397 | $header .= $this->CreateHeader(); | //Cross Site Scripting |
398 | $body = $this->CreateBody(); | |
399 | ||
400 | if($body == '') { | |
401 | return false; | |
402 | } | |
403 | ||
404 | /* Choose the mailer */ | |
405 | switch($this->Mailer) { | |
406 | case 'sendmail': | |
407 | $result = $this->SendmailSend($header, $body); | //Cross Site Scripting |
408 | break; | |
409 | case 'smtp': | |
410 | $result = $this->SmtpSend($header, $body); | //Cross Site Scripting |
411 | break; | |
412 | case 'mail': | |
413 | $result = $this->MailSend($header, $body); | //Cross Site Scripting |
414 | break; | |
415 | default: | |
416 | $result = $this->MailSend($header, $body); | //Cross Site Scripting |
417 | break; | |
418 | //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported')); | |
419 | //$result = false; | |
420 | //break; | |
421 | } | |
422 | ||
423 | return $result; | |
424 | } | |
425 | ||
426 | /** | |
427 | * Sends mail using the $Sendmail program. | |
428 | * @access private | |
429 | * @return bool | |
430 | */ | |
431 | function SendmailSend($header, $body) { | |
432 | if ($this->Sender != '') { | |
433 | $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); | |
434 | } else { | |
435 | $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); | |
436 | } | |
437 | ||
438 | if(!@$mail = popen($sendmail, 'w')) { | |
439 | $this->SetError($this->Lang('execute') . $this->Sendmail); | |
440 | return false; | |
441 | } | |
442 | ||
443 | fputs($mail, $header); | //Arbitrary file manipulations //Connection Handling |
444 | fputs($mail, $body); | //Arbitrary file manipulations //Connection Handling |
445 | ||
446 | $result = pclose($mail); | |
447 | if (version_compare(phpversion(), '4.2.3') == -1) { | |
448 | $result = $result >> 8 & 0xFF; | |
449 | } | |
450 | if($result != 0) { | |
451 | $this->SetError($this->Lang('execute') . $this->Sendmail); | |
452 | return false; | |
453 | } | |
454 | return true; | |
455 | } | |
456 | ||
457 | /** | |
458 | * Sends mail using the PHP mail() function. | |
459 | * @access private | |
460 | * @return bool | |
461 | */ | |
462 | function MailSend($header, $body) { | |
463 | ||
464 | $to = ''; | |
465 | for($i = 0; $i < count($this->to); $i++) { | |
466 | if($i != 0) { $to .= ', '; } | |
467 | $to .= $this->AddrFormat($this->to[$i]); | |
468 | } | |
469 | ||
470 | $toArr = split(',', $to); | |
471 | ||
472 | $params = sprintf("-oi -f %s", $this->Sender); | |
473 | if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) { | |
474 | $old_from = ini_get('sendmail_from'); | |
475 | ini_set('sendmail_from', $this->Sender); | |
476 | if ($this->SingleTo === true && count($toArr) > 1) { | |
477 | foreach ($toArr as $key => $val) { | |
478 | $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); | //Cross Site Scripting //Connection Handling |
479 | } | |
480 | } else { | |
481 | $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); | //Cross Site Scripting //Connection Handling |
482 | } | |
483 | } else { | |
484 | if ($this->SingleTo === true && count($toArr) > 1) { | |
485 | foreach ($toArr as $key => $val) { | |
486 | $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); | //Cross Site Scripting //Connection Handling |
487 | } | |
488 | } else { | |
489 | $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); | //Connection Handling |
490 | } | |
491 | } | |
492 | ||
493 | if (isset($old_from)) { | |
494 | ini_set('sendmail_from', $old_from); | |
495 | } | |
496 | ||
497 | if(!$rt) { | |
498 | $this->SetError($this->Lang('instantiate')); | |
499 | return false; | |
500 | } | |
501 | ||
502 | return true; | |
503 | } | |
504 | ||
505 | /** | |
506 | * Sends mail via SMTP using PhpSMTP (Author: | |
507 | * Chris Ryan). Returns bool. Returns false if there is a | |
508 | * bad MAIL FROM, RCPT, or DATA input. | |
509 | * @access private | |
510 | * @return bool | |
511 | */ | |
512 | function SmtpSend($header, $body) { | |
513 | include_once($this->PluginDir . 'class-smtp.php'); | //Arbitrary code inclusion |
514 | $error = ''; | |
515 | $bad_rcpt = array(); | |
516 | ||
517 | if(!$this->SmtpConnect()) { | |
518 | return false; | |
519 | } | |
520 | ||
521 | $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; | |
522 | if(!$this->smtp->Mail($smtp_from)) { | |
523 | $error = $this->Lang('from_failed') . $smtp_from; | |
524 | $this->SetError($error); | |
525 | $this->smtp->Reset(); | |
526 | return false; | |
527 | } | |
528 | ||
529 | /* Attempt to send attach all recipients */ | |
530 | for($i = 0; $i < count($this->to); $i++) { | |
531 | if(!$this->smtp->Recipient($this->to[$i][0])) { | |
532 | $bad_rcpt[] = $this->to[$i][0]; | |
533 | } | |
534 | } | |
535 | for($i = 0; $i < count($this->cc); $i++) { | |
536 | if(!$this->smtp->Recipient($this->cc[$i][0])) { | |
537 | $bad_rcpt[] = $this->cc[$i][0]; | |
538 | } | |
539 | } | |
540 | for($i = 0; $i < count($this->bcc); $i++) { | |
541 | if(!$this->smtp->Recipient($this->bcc[$i][0])) { | |
542 | $bad_rcpt[] = $this->bcc[$i][0]; | |
543 | } | |
544 | } | |
545 | ||
546 | if(count($bad_rcpt) > 0) { // Create error message | |
547 | for($i = 0; $i < count($bad_rcpt); $i++) { | |
548 | if($i != 0) { | |
549 | $error .= ', '; | |
550 | } | |
551 | $error .= $bad_rcpt[$i]; | |
552 | } | |
553 | $error = $this->Lang('recipients_failed') . $error; | |
554 | $this->SetError($error); | |
555 | $this->smtp->Reset(); | |
556 | return false; | |
557 | } | |
558 | ||
559 | if(!$this->smtp->Data($header . $body)) { | |
560 | $this->SetError($this->Lang('data_not_accepted')); | |
561 | $this->smtp->Reset(); | |
562 | return false; | |
563 | } | |
564 | if($this->SMTPKeepAlive == true) { | |
565 | $this->smtp->Reset(); | |
566 | } else { | |
567 | $this->SmtpClose(); | |
568 | } | |
569 | ||
570 | return true; | |
571 | } | |
572 | ||
573 | /** | |
574 | * Initiates a connection to an SMTP server. Returns false if the | |
575 | * operation failed. | |
576 | * @access private | |
577 | * @return bool | |
578 | */ | |
579 | function SmtpConnect() { | |
580 | if($this->smtp == NULL) { | |
581 | $this->smtp = new SMTP(); | |
582 | } | |
583 | ||
584 | $this->smtp->do_debug = $this->SMTPDebug; | |
585 | $hosts = explode(';', $this->Host); | |
586 | $index = 0; | |
587 | $connection = ($this->smtp->Connected()); | |
588 | ||
589 | /* Retry while there is no connection */ | |
590 | while($index < count($hosts) && $connection == false) { | |
591 | $hostinfo = array(); | |
592 | if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) { | |
593 | $host = $hostinfo[1]; | |
594 | $port = $hostinfo[2]; | |
595 | } else { | |
596 | $host = $hosts[$index]; | |
597 | $port = $this->Port; | |
598 | } | |
599 | ||
600 | if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) { | |
601 | if ($this->Helo != '') { | |
602 | $this->smtp->Hello($this->Helo); | |
603 | } else { | |
604 | $this->smtp->Hello($this->ServerHostname()); | |
605 | } | |
606 | ||
607 | $connection = true; | |
608 | if($this->SMTPAuth) { | |
609 | if(!$this->smtp->Authenticate($this->Username, $this->Password)) { | |
610 | $this->SetError($this->Lang('authenticate')); | |
611 | $this->smtp->Reset(); | |
612 | $connection = false; | |
613 | } | |
614 | } | |
615 | } | |
616 | $index++; | |
617 | } | |
618 | if(!$connection) { | |
619 | $this->SetError($this->Lang('connect_host')); | |
620 | } | |
621 | ||
622 | return $connection; | |
623 | } | |
624 | ||
625 | /** | |
626 | * Closes the active SMTP session if one exists. | |
627 | * @return void | |
628 | */ | |
629 | function SmtpClose() { | |
630 | if($this->smtp != NULL) { | |
631 | if($this->smtp->Connected()) { | |
632 | $this->smtp->Quit(); | |
633 | $this->smtp->Close(); | |
634 | } | |
635 | } | |
636 | } | |
637 | ||
638 | /** | |
639 | * Sets the language for all class error messages. Returns false | |
640 | * if it cannot load the language file. The default language type | |
641 | * is English. | |
642 | * @param string $lang_type Type of language (e.g. Portuguese: "br") | |
643 | * @param string $lang_path Path to the language file directory | |
644 | * @access public | |
645 | * @return bool | |
646 | */ | |
647 | function SetLanguage($lang_type, $lang_path = 'language/') { | |
648 | if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) { | |
649 | include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); | //Arbitrary code inclusion |
650 | } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) { | |
651 | include($lang_path.'phpmailer.lang-en.php'); | //Arbitrary code inclusion |
652 | } else { | |
653 | $PHPMAILER_LANG = array(); | |
654 | $PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' . | |
655 | $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.'; | |
656 | $PHPMAILER_LANG["execute"] = 'Could not execute: '; | |
657 | $PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.'; | |
658 | $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.'; | |
659 | $PHPMAILER_LANG["from_failed"] = 'The following From address failed: '; | |
660 | $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' . | |
661 | $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.'; | |
662 | $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.'; | |
663 | $PHPMAILER_LANG["file_access"] = 'Could not access file: '; | |
664 | $PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: '; | |
665 | $PHPMAILER_LANG["encoding"] = 'Unknown encoding: '; | |
666 | $PHPMAILER_LANG["signing"] = 'Signing Error: '; | |
667 | } | |
668 | $this->language = $PHPMAILER_LANG; | |
669 | ||
670 | return true; | |
671 | } | |
672 | ||
673 | ///////////////////////////////////////////////// | |
674 | // METHODS, MESSAGE CREATION | |
675 | ///////////////////////////////////////////////// | |
676 | ||
677 | /** | |
678 | * Creates recipient headers. | |
679 | * @access private | |
680 | * @return string | |
681 | */ | |
682 | function AddrAppend($type, $addr) { | |
683 | $addr_str = $type . ': '; | |
684 | $addr_str .= $this->AddrFormat($addr[0]); | |
685 | if(count($addr) > 1) { | |
686 | for($i = 1; $i < count($addr); $i++) { | |
687 | $addr_str .= ', ' . $this->AddrFormat($addr[$i]); | |
688 | } | |
689 | } | |
690 | $addr_str .= $this->LE; | |
691 | ||
692 | return $addr_str; | |
693 | } | |
694 | ||
695 | /** | |
696 | * Formats an address correctly. | |
697 | * @access private | |
698 | * @return string | |
699 | */ | |
700 | function AddrFormat($addr) { | |
701 | if(empty($addr[1])) { | |
702 | $formatted = $this->SecureHeader($addr[0]); | |
703 | } else { | |
704 | $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; | |
705 | } | |
706 | ||
707 | return $formatted; | |
708 | } | |
709 | ||
710 | /** | |
711 | * Wraps message for use with mailers that do not | |
712 | * automatically perform wrapping and for quoted-printable. | |
713 | * Original written by philippe. | |
714 | * @access private | |
715 | * @return string | |
716 | */ | |
717 | function WrapText($message, $length, $qp_mode = false) { | |
718 | $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; | |
719 | // If utf-8 encoding is used, we will need to make sure we don't | |
720 | // split multibyte characters when we wrap | |
721 | $is_utf8 = (strtolower($this->CharSet) == "utf-8"); | |
722 | ||
723 | $message = $this->FixEOL($message); | |
724 | if (substr($message, -1) == $this->LE) { | |
725 | $message = substr($message, 0, -1); | |
726 | } | |
727 | ||
728 | $line = explode($this->LE, $message); | |
729 | $message = ''; | |
730 | for ($i=0 ;$i < count($line); $i++) { | |
731 | $line_part = explode(' ', $line[$i]); | |
732 | $buf = ''; | |
733 | for ($e = 0; $e<count($line_part); $e++) { | |
734 | $word = $line_part[$e]; | |
735 | if ($qp_mode and (strlen($word) > $length)) { | |
736 | $space_left = $length - strlen($buf) - 1; | |
737 | if ($e != 0) { | |
738 | if ($space_left > 20) { | |
739 | $len = $space_left; | |
740 | if ($is_utf8) { | |
741 | $len = $this->UTF8CharBoundary($word, $len); | |
742 | } elseif (substr($word, $len - 1, 1) == "=") { | |
743 | $len--; | |
744 | } elseif (substr($word, $len - 2, 1) == "=") { | |
745 | $len -= 2; | |
746 | } | |
747 | $part = substr($word, 0, $len); | |
748 | $word = substr($word, $len); | |
749 | $buf .= ' ' . $part; | |
750 | $message .= $buf . sprintf("=%s", $this->LE); | |
751 | } else { | |
752 | $message .= $buf . $soft_break; | |
753 | } | |
754 | $buf = ''; | |
755 | } | |
756 | while (strlen($word) > 0) { | |
757 | $len = $length; | |
758 | if ($is_utf8) { | |
759 | $len = $this->UTF8CharBoundary($word, $len); | |
760 | } elseif (substr($word, $len - 1, 1) == "=") { | |
761 | $len--; | |
762 | } elseif (substr($word, $len - 2, 1) == "=") { | |
763 | $len -= 2; | |
764 | } | |
765 | $part = substr($word, 0, $len); | |
766 | $word = substr($word, $len); | |
767 | ||
768 | if (strlen($word) > 0) { | |
769 | $message .= $part . sprintf("=%s", $this->LE); | |
770 | } else { | |
771 | $buf = $part; | |
772 | } | |
773 | } | |
774 | } else { | |
775 | $buf_o = $buf; | |
776 | $buf .= ($e == 0) ? $word : (' ' . $word); | |
777 | ||
778 | if (strlen($buf) > $length and $buf_o != '') { | |
779 | $message .= $buf_o . $soft_break; | |
780 | $buf = $word; | |
781 | } | |
782 | } | |
783 | } | |
784 | $message .= $buf . $this->LE; | |
785 | } | |
786 | ||
787 | return $message; | |
788 | } | |
789 | ||
790 | /** | |
791 | * Finds last character boundary prior to maxLength in a utf-8 | |
792 | * quoted (printable) encoded string. | |
793 | * Original written by Colin Brown. | |
794 | * @access private | |
795 | * @param string $encodedText utf-8 QP text | |
796 | * @param int $maxLength find last character boundary prior to this length | |
797 | * @return int | |
798 | */ | |
799 | function UTF8CharBoundary($encodedText, $maxLength) { | |
800 | $foundSplitPos = false; | |
801 | $lookBack = 3; | |
802 | while (!$foundSplitPos) { | |
803 | $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); | |
804 | $encodedCharPos = strpos($lastChunk, "="); | |
805 | if ($encodedCharPos !== false) { | |
806 | // Found start of encoded character byte within $lookBack block. | |
807 | // Check the encoded byte value (the 2 chars after the '=') | |
808 | $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); | |
809 | $dec = hexdec($hex); | |
810 | if ($dec < 128) { // Single byte character. | |
811 | // If the encoded char was found at pos 0, it will fit | |
812 | // otherwise reduce maxLength to start of the encoded char | |
813 | $maxLength = ($encodedCharPos == 0) ? $maxLength : | |
814 | $maxLength - ($lookBack - $encodedCharPos); | |
815 | $foundSplitPos = true; | |
816 | } elseif ($dec >= 192) { // First byte of a multi byte character | |
817 | // Reduce maxLength to split at start of character | |
818 | $maxLength = $maxLength - ($lookBack - $encodedCharPos); | |
819 | $foundSplitPos = true; | |
820 | } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back | |
821 | $lookBack += 3; | |
822 | } | |
823 | } else { | |
824 | // No encoded character found | |
825 | $foundSplitPos = true; | |
826 | } | |
827 | } | |
828 | return $maxLength; | |
829 | } | |
830 | ||
831 | /** | |
832 | * Set the body wrapping. | |
833 | * @access private | |
834 | * @return void | |
835 | */ | |
836 | function SetWordWrap() { | |
837 | if($this->WordWrap < 1) { | |
838 | return; | |
839 | } | |
840 | ||
841 | switch($this->message_type) { | |
842 | case 'alt': | |
843 | /* fall through */ | |
844 | case 'alt_attachments': | |
845 | $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); | |
846 | break; | |
847 | default: | |
848 | $this->Body = $this->WrapText($this->Body, $this->WordWrap); | |
849 | break; | |
850 | } | |
851 | } | |
852 | ||
853 | /** | |
854 | * Assembles message header. | |
855 | * @access private | |
856 | * @return string | |
857 | */ | |
858 | function CreateHeader() { | |
859 | $result = ''; | |
860 | ||
861 | /* Set the boundaries */ | |
862 | $uniq_id = md5(uniqid(time())); | |
863 | $this->boundary[1] = 'b1_' . $uniq_id; | |
864 | $this->boundary[2] = 'b2_' . $uniq_id; | |
865 | ||
866 | $result .= $this->HeaderLine('Date', $this->RFCDate()); | |
867 | if($this->Sender == '') { | |
868 | $result .= $this->HeaderLine('Return-Path', trim($this->From)); | |
869 | } else { | |
870 | $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); | |
871 | } | |
872 | ||
873 | /* To be created automatically by mail() */ | |
874 | if($this->Mailer != 'mail') { | |
875 | if(count($this->to) > 0) { | |
876 | $result .= $this->AddrAppend('To', $this->to); | |
877 | } elseif (count($this->cc) == 0) { | |
878 | $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); | |
879 | } | |
880 | } | |
881 | ||
882 | $from = array(); | |
883 | $from[0][0] = trim($this->From); | |
884 | $from[0][1] = $this->FromName; | |
885 | $result .= $this->AddrAppend('From', $from); | |
886 | ||
887 | /* sendmail and mail() extract Cc from the header before sending */ | |
888 | if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) { | |
889 | $result .= $this->AddrAppend('Cc', $this->cc); | |
890 | } | |
891 | ||
892 | /* sendmail and mail() extract Bcc from the header before sending */ | |
893 | if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { | |
894 | $result .= $this->AddrAppend('Bcc', $this->bcc); | |
895 | } | |
896 | ||
897 | if(count($this->ReplyTo) > 0) { | |
898 | $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); | |
899 | } | |
900 | ||
901 | /* mail() sets the subject itself */ | |
902 | if($this->Mailer != 'mail') { | |
903 | $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); | |
904 | } | |
905 | ||
906 | if($this->MessageID != '') { | |
907 | $result .= $this->HeaderLine('Message-ID',$this->MessageID); | |
908 | } else { | |
909 | $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); | |
910 | } | |
911 | $result .= $this->HeaderLine('X-Priority', $this->Priority); | |
912 | $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']'); | |
913 | ||
914 | if($this->ConfirmReadingTo != '') { | |
915 | $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); | |
916 | } | |
917 | ||
918 | // Add custom headers | |
919 | for($index = 0; $index < count($this->CustomHeader); $index++) { | |
920 | $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); | |
921 | } | |
922 | if (!$this->sign_key_file) { | |
923 | $result .= $this->HeaderLine('MIME-Version', '1.0'); | |
924 | $result .= $this->GetMailMIME(); | |
925 | } | |
926 | ||
927 | return $result; | |
928 | } | |
929 | ||
930 | /** | |
931 | * Returns the message MIME. | |
932 | * @access private | |
933 | * @return string | |
934 | */ | |
935 | function GetMailMIME() { | |
936 | $result = ''; | |
937 | switch($this->message_type) { | |
938 | case 'plain': | |
939 | $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); | |
940 | $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); | |
941 | break; | |
942 | case 'attachments': | |
943 | /* fall through */ | |
944 | case 'alt_attachments': | |
945 | if($this->InlineImageExists()){ | |
946 | $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE); | |
947 | } else { | |
948 | $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); | |
949 | $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); | |
950 | } | |
951 | break; | |
952 | case 'alt': | |
953 | $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); | |
954 | $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); | |
955 | break; | |
956 | } | |
957 | ||
958 | if($this->Mailer != 'mail') { | |
959 | $result .= $this->LE.$this->LE; | |
960 | } | |
961 | ||
962 | return $result; | |
963 | } | |
964 | ||
965 | /** | |
966 | * Assembles the message body. Returns an empty string on failure. | |
967 | * @access private | |
968 | * @return string | |
969 | */ | |
970 | function CreateBody() { | |
971 | $result = ''; | |
972 | if ($this->sign_key_file) { | |
973 | $result .= $this->GetMailMIME(); | |
974 | } | |
975 | ||
976 | $this->SetWordWrap(); | |
977 | ||
978 | switch($this->message_type) { | |
979 | case 'alt': | |
980 | $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); | |
981 | $result .= $this->EncodeString($this->AltBody, $this->Encoding); | |
982 | $result .= $this->LE.$this->LE; | |
983 | $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); | |
984 | $result .= $this->EncodeString($this->Body, $this->Encoding); | |
985 | $result .= $this->LE.$this->LE; | |
986 | $result .= $this->EndBoundary($this->boundary[1]); | |
987 | break; | |
988 | case 'plain': | |
989 | $result .= $this->EncodeString($this->Body, $this->Encoding); | |
990 | break; | |
991 | case 'attachments': | |
992 | $result .= $this->GetBoundary($this->boundary[1], '', '', ''); | |
993 | $result .= $this->EncodeString($this->Body, $this->Encoding); | |
994 | $result .= $this->LE; | |
995 | $result .= $this->AttachAll(); | |
996 | break; | |
997 | case 'alt_attachments': | |
998 | $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); | |
999 | $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); | |
1000 | $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body |