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