Changeset 8762 for trunk/wp-includes/class-phpmailer.php
- Timestamp:
- 08/28/2008 08:26:36 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-includes/class-phpmailer.php
r8082 r8762 1 1 <?php 2 /** 3 * PHPMailer - PHP email class 4 * 5 * Class for sending email using either sendmail, PHP mail(), or SMTP. Methods 6 * are based upon the standard AspEmail(tm) classes. 7 * 8 * @copyright 2001 - 2003 Brent R. Matzelle 9 * @license LGPL 10 * @package PHPMailer 11 */ 2 /*~ class.phpmailer.php 3 .---------------------------------------------------------------------------. 4 | Software: PHPMailer - PHP email class | 5 | Version: 2.0.2 | 6 | Contact: via sourceforge.net support pages (also www.codeworxtech.com) | 7 | Info: http://phpmailer.sourceforge.net | 8 | Support: http://sourceforge.net/projects/phpmailer/ | 9 | ------------------------------------------------------------------------- | 10 | Author: Andy Prevost (project admininistrator) | 11 | Author: Brent R. Matzelle (original founder) | 12 | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. | 13 | Copyright (c) 2001-2003, Brent R. Matzelle | 14 | ------------------------------------------------------------------------- | 15 | License: Distributed under the Lesser General Public License (LGPL) | 16 | http://www.gnu.org/copyleft/lesser.html | 17 | This program is distributed in the hope that it will be useful - WITHOUT | 18 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 19 | FITNESS FOR A PARTICULAR PURPOSE. | 20 | ------------------------------------------------------------------------- | 21 | We offer a number of paid services (www.codeworxtech.com): | 22 | - Web Hosting on highly optimized fast and secure servers | 23 | - Technology Consulting | 24 | - Oursourcing (highly qualified programmers and graphic designers) | 25 '---------------------------------------------------------------------------' 12 26 13 27 /** 14 28 * PHPMailer - PHP email transport class 15 29 * @package PHPMailer 16 * @author Brent R. Matzelle17 * @copyright 200 1 - 2003 Brent R. Matzelle30 * @author Andy Prevost 31 * @copyright 2004 - 2008 Andy Prevost 18 32 */ 19 class PHPMailer 20 { 21 ///////////////////////////////////////////////// 22 // PUBLIC VARIABLES 23 ///////////////////////////////////////////////// 24 25 /** 26 * Email priority (1 = High, 3 = Normal, 5 = low). 27 * @var int 28 */ 29 var $Priority = 3; 30 31 /** 32 * Sets the CharSet of the message. 33 * @var string 34 */ 35 var $CharSet = "UTF-8"; 36 37 /** 38 * Sets the Content-type of the message. 39 * @var string 40 */ 41 var $ContentType = "text/plain"; 42 43 /** 44 * Sets the Encoding of the message. Options for this are "8bit", 45 * "7bit", "binary", "base64", and "quoted-printable". 46 * @var string 47 */ 48 var $Encoding = "8bit"; 49 50 /** 51 * Holds the most recent mailer error message. 52 * @var string 53 */ 54 var $ErrorInfo = ""; 55 56 /** 57 * Sets the From email address for the message. 58 * @var string 59 */ 60 var $From = "localhost.localdomain"; 61 62 /** 63 * Sets the From name of the message. 64 * @var string 65 */ 66 var $FromName = "Support"; 67 68 /** 69 * Sets the Sender email (Return-Path) of the message. If not empty, 70 * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. 71 * @var string 72 */ 73 var $Sender = ""; 74 75 /** 76 * Sets the Subject of the message. 77 * @var string 78 */ 79 var $Subject = ""; 80 81 /** 82 * Sets the Body of the message. This can be either an HTML or text body. 83 * If HTML then run IsHTML(true). 84 * @var string 85 */ 86 var $Body = ""; 87 88 /** 89 * Sets the text-only body of the message. This automatically sets the 90 * email to multipart/alternative. This body can be read by mail 91 * clients that do not have HTML email capability such as mutt. Clients 92 * that can read HTML will view the normal Body. 93 * @var string 94 */ 95 var $AltBody = ""; 96 97 /** 98 * Sets word wrapping on the body of the message to a given number of 99 * characters. 100 * @var int 101 */ 102 var $WordWrap = 0; 103 104 /** 105 * Method to send mail: ("mail", "sendmail", or "smtp"). 106 * @var string 107 */ 108 var $Mailer = "mail"; 109 110 /** 111 * Sets the path of the sendmail program. 112 * @var string 113 */ 114 var $Sendmail = "/usr/sbin/sendmail"; 115 116 /** 117 * Path to PHPMailer plugins. This is now only useful if the SMTP class 118 * is in a different directory than the PHP include path. 119 * @var string 120 */ 121 var $PluginDir = ""; 122 123 /** 124 * Holds PHPMailer version. 125 * @var string 126 */ 127 var $Version = "1.73"; 128 129 /** 130 * Sets the email address that a reading confirmation will be sent. 131 * @var string 132 */ 133 var $ConfirmReadingTo = ""; 134 135 /** 136 * Sets the hostname to use in Message-Id and Received headers 137 * and as default HELO string. If empty, the value returned 138 * by SERVER_NAME is used or 'localhost.localdomain'. 139 * @var string 140 */ 141 var $Hostname = ""; 142 143 ///////////////////////////////////////////////// 144 // SMTP VARIABLES 145 ///////////////////////////////////////////////// 146 147 /** 148 * Sets the SMTP hosts. All hosts must be separated by a 149 * semicolon. You can also specify a different port 150 * for each host by using this format: [hostname:port] 151 * (e.g. "smtp1.example.com:25;smtp2.example.com"). 152 * Hosts will be tried in order. 153 * @var string 154 */ 155 var $Host = "localhost"; 156 157 /** 158 * Sets the default SMTP server port. 159 * @var int 160 */ 161 var $Port = 25; 162 163 /** 164 * Sets the SMTP HELO of the message (Default is $Hostname). 165 * @var string 166 */ 167 var $Helo = ""; 168 169 /** 170 * Sets SMTP authentication. Utilizes the Username and Password variables. 171 * @var bool 172 */ 173 var $SMTPAuth = false; 174 175 /** 176 * Sets SMTP username. 177 * @var string 178 */ 179 var $Username = ""; 180 181 /** 182 * Sets SMTP password. 183 * @var string 184 */ 185 var $Password = ""; 186 187 /** 188 * Sets the SMTP server timeout in seconds. This function will not 189 * work with the win32 version. 190 * @var int 191 */ 192 var $Timeout = 10; 193 194 /** 195 * Sets SMTP class debugging on or off. 196 * @var bool 197 */ 198 var $SMTPDebug = false; 199 200 /** 201 * Prevents the SMTP connection from being closed after each mail 202 * sending. If this is set to true then to close the connection 203 * requires an explicit call to SmtpClose(). 204 * @var bool 205 */ 206 var $SMTPKeepAlive = false; 207 208 /**#@+ 209 * @access private 210 */ 211 var $smtp = NULL; 212 var $to = array(); 213 var $cc = array(); 214 var $bcc = array(); 215 var $ReplyTo = array(); 216 var $attachment = array(); 217 var $CustomHeader = array(); 218 var $message_type = ""; 219 var $boundary = array(); 220 var $language = array(); 221 var $error_count = 0; 222 var $LE = "\n"; 223 /**#@-*/ 224 225 ///////////////////////////////////////////////// 226 // VARIABLE METHODS 227 ///////////////////////////////////////////////// 228 229 /** 230 * Sets message type to HTML. 231 * @param bool $bool 232 * @return void 233 */ 234 function IsHTML($bool) { 235 if($bool == true) 236 $this->ContentType = "text/html"; 237 else 238 $this->ContentType = "text/plain"; 239 } 240 241 /** 242 * Sets Mailer to send message using SMTP. 243 * @return void 244 */ 245 function IsSMTP() { 246 $this->Mailer = "smtp"; 247 } 248 249 /** 250 * Sets Mailer to send message using PHP mail() function. 251 * @return void 252 */ 253 function IsMail() { 254 $this->Mailer = "mail"; 255 } 256 257 /** 258 * Sets Mailer to send message using the $Sendmail program. 259 * @return void 260 */ 261 function IsSendmail() { 262 $this->Mailer = "sendmail"; 263 } 264 265 /** 266 * Sets Mailer to send message using the qmail MTA. 267 * @return void 268 */ 269 function IsQmail() { 270 $this->Sendmail = "/var/qmail/bin/sendmail"; 271 $this->Mailer = "sendmail"; 272 } 273 274 275 ///////////////////////////////////////////////// 276 // RECIPIENT METHODS 277 ///////////////////////////////////////////////// 278 279 /** 280 * Adds a "To" address. 281 * @param string $address 282 * @param string $name 283 * @return void 284 */ 285 function AddAddress($address, $name = "") { 286 $cur = count($this->to); 287 $this->to[$cur][0] = trim($address); 288 $this->to[$cur][1] = $name; 289 } 290 291 /** 292 * Adds a "Cc" address. Note: this function works 293 * with the SMTP mailer on win32, not with the "mail" 294 * mailer. 295 * @param string $address 296 * @param string $name 297 * @return void 298 */ 299 function AddCC($address, $name = "") { 300 $cur = count($this->cc); 301 $this->cc[$cur][0] = trim($address); 302 $this->cc[$cur][1] = $name; 303 } 304 305 /** 306 * Adds a "Bcc" address. Note: this function works 307 * with the SMTP mailer on win32, not with the "mail" 308 * mailer. 309 * @param string $address 310 * @param string $name 311 * @return void 312 */ 313 function AddBCC($address, $name = "") { 314 $cur = count($this->bcc); 315 $this->bcc[$cur][0] = trim($address); 316 $this->bcc[$cur][1] = $name; 317 } 318 319 /** 320 * Adds a "Reply-to" address. 321 * @param string $address 322 * @param string $name 323 * @return void 324 */ 325 function AddReplyTo($address, $name = "") { 326 $cur = count($this->ReplyTo); 327 $this->ReplyTo[$cur][0] = trim($address); 328 $this->ReplyTo[$cur][1] = $name; 329 } 330 331 332 ///////////////////////////////////////////////// 333 // MAIL SENDING METHODS 334 ///////////////////////////////////////////////// 335 336 /** 337 * Creates message and assigns Mailer. If the message is 338 * not sent successfully then it returns false. Use the ErrorInfo 339 * variable to view description of the error. 340 * @return bool 341 */ 342 function Send() { 343 $header = ""; 344 $body = ""; 345 $result = true; 346 347 if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) 348 { 349 $this->SetError($this->Lang("provide_address")); 350 return false; 33 34 class PHPMailer { 35 36 ///////////////////////////////////////////////// 37 // PROPERTIES, PUBLIC 38 ///////////////////////////////////////////////// 39 40 /** 41 * Email priority (1 = High, 3 = Normal, 5 = low). 42 * @var int 43 */ 44 var $Priority = 3; 45 46 /** 47 * Sets the CharSet of the message. 48 * @var string 49 */ 50 var $CharSet = 'iso-8859-1'; 51 52 /** 53 * Sets the Content-type of the message. 54 * @var string 55 */ 56 var $ContentType = 'text/plain'; 57 58 /** 59 * Sets the Encoding of the message. Options for this are "8bit", 60 * "7bit", "binary", "base64", and "quoted-printable". 61 * @var string 62 */ 63 var $Encoding = '8bit'; 64 65 /** 66 * Holds the most recent mailer error message. 67 * @var string 68 */ 69 var $ErrorInfo = ''; 70 71 /** 72 * Sets the From email address for the message. 73 * @var string 74 */ 75 var $From = 'root@localhost'; 76 77 /** 78 * Sets the From name of the message. 79 * @var string 80 */ 81 var $FromName = 'Root User'; 82 83 /** 84 * Sets the Sender email (Return-Path) of the message. If not empty, 85 * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. 86 * @var string 87 */ 88 var $Sender = ''; 89 90 /** 91 * Sets the Subject of the message. 92 * @var string 93 */ 94 var $Subject = ''; 95 96 /** 97 * Sets the Body of the message. This can be either an HTML or text body. 98 * If HTML then run IsHTML(true). 99 * @var string 100 */ 101 var $Body = ''; 102 103 /** 104 * Sets the text-only body of the message. This automatically sets the 105 * email to multipart/alternative. This body can be read by mail 106 * clients that do not have HTML email capability such as mutt. Clients 107 * that can read HTML will view the normal Body. 108 * @var string 109 */ 110 var $AltBody = ''; 111 112 /** 113 * Sets word wrapping on the body of the message to a given number of 114 * characters. 115 * @var int 116 */ 117 var $WordWrap = 0; 118 119 /** 120 * Method to send mail: ("mail", "sendmail", or "smtp"). 121 * @var string 122 */ 123 var $Mailer = 'mail'; 124 125 /** 126 * Sets the path of the sendmail program. 127 * @var string 128 */ 129 var $Sendmail = '/usr/sbin/sendmail'; 130 131 /** 132 * Path to PHPMailer plugins. This is now only useful if the SMTP class 133 * is in a different directory than the PHP include path. 134 * @var string 135 */ 136 var $PluginDir = ''; 137 138 /** 139 * Holds PHPMailer version. 140 * @var string 141 */ 142 var $Version = "2.0.2"; 143 144 /** 145 * Sets the email address that a reading confirmation will be sent. 146 * @var string 147 */ 148 var $ConfirmReadingTo = ''; 149 150 /** 151 * Sets the hostname to use in Message-Id and Received headers 152 * and as default HELO string. If empty, the value returned 153 * by SERVER_NAME is used or 'localhost.localdomain'. 154 * @var string 155 */ 156 var $Hostname = ''; 157 158 /** 159 * Sets the message ID to be used in the Message-Id header. 160 * If empty, a unique id will be generated. 161 * @var string 162 */ 163 var $MessageID = ''; 164 165 ///////////////////////////////////////////////// 166 // PROPERTIES FOR SMTP 167 ///////////////////////////////////////////////// 168 169 /** 170 * Sets the SMTP hosts. All hosts must be separated by a 171 * semicolon. You can also specify a different port 172 * for each host by using this format: [hostname:port] 173 * (e.g. "smtp1.example.com:25;smtp2.example.com"). 174 * Hosts will be tried in order. 175 * @var string 176 */ 177 var $Host = 'localhost'; 178 179 /** 180 * Sets the default SMTP server port. 181 * @var int 182 */ 183 var $Port = 25; 184 185 /** 186 * Sets the SMTP HELO of the message (Default is $Hostname). 187 * @var string 188 */ 189 var $Helo = ''; 190 191 /** 192 * Sets connection prefix. 193 * Options are "", "ssl" or "tls" 194 * @var string 195 */ 196 var $SMTPSecure = ""; 197 198 /** 199 * Sets SMTP authentication. Utilizes the Username and Password variables. 200 * @var bool 201 */ 202 var $SMTPAuth = false; 203 204 /** 205 * Sets SMTP username. 206 * @var string 207 */ 208 var $Username = ''; 209 210 /** 211 * Sets SMTP password. 212 * @var string 213 */ 214 var $Password = ''; 215 216 /** 217 * Sets the SMTP server timeout in seconds. This function will not 218 * work with the win32 version. 219 * @var int 220 */ 221 var $Timeout = 10; 222 223 /** 224 * Sets SMTP class debugging on or off. 225 * @var bool 226 */ 227 var $SMTPDebug = false; 228 229 /** 230 * Prevents the SMTP connection from being closed after each mail 231 * sending. If this is set to true then to close the connection 232 * requires an explicit call to SmtpClose(). 233 * @var bool 234 */ 235 var $SMTPKeepAlive = false; 236 237 /** 238 * Provides the ability to have the TO field process individual 239 * emails, instead of sending to entire TO addresses 240 * @var bool 241 */ 242 var $SingleTo = false; 243 244 ///////////////////////////////////////////////// 245 // PROPERTIES, PRIVATE 246 ///////////////////////////////////////////////// 247 248 var $smtp = NULL; 249 var $to = array(); 250 var $cc = array(); 251 var $bcc = array(); 252 var $ReplyTo = array(); 253 var $attachment = array(); 254 var $CustomHeader = array(); 255 var $message_type = ''; 256 var $boundary = array(); 257 var $language = array(); 258 var $error_count = 0; 259 var $LE = "\n"; 260 var $sign_key_file = ""; 261 var $sign_key_pass = ""; 262 263 ///////////////////////////////////////////////// 264 // METHODS, VARIABLES 265 ///////////////////////////////////////////////// 266 267 /** 268 * Sets message type to HTML. 269 * @param bool $bool 270 * @return void 271 */ 272 function IsHTML($bool) { 273 if($bool == true) { 274 $this->ContentType = 'text/html'; 275 } else { 276 $this->ContentType = 'text/plain'; 277 } 278 } 279 280 /** 281 * Sets Mailer to send message using SMTP. 282 * @return void 283 */ 284 function IsSMTP() { 285 $this->Mailer = 'smtp'; 286 } 287 288 /** 289 * Sets Mailer to send message using PHP mail() function. 290 * @return void 291 */ 292 function IsMail() { 293 $this->Mailer = 'mail'; 294 } 295 296 /** 297 * Sets Mailer to send message using the $Sendmail program. 298 * @return void 299 */ 300 function IsSendmail() { 301 $this->Mailer = 'sendmail'; 302 } 303 304 /** 305 * Sets Mailer to send message using the qmail MTA. 306 * @return void 307 */ 308 function IsQmail() { 309 $this->Sendmail = '/var/qmail/bin/sendmail'; 310 $this->Mailer = 'sendmail'; 311 } 312 313 ///////////////////////////////////////////////// 314 // METHODS, RECIPIENTS 315 ///////////////////////////////////////////////// 316 317 /** 318 * Adds a "To" address. 319 * @param string $address 320 * @param string $name 321 * @return void 322 */ 323 function AddAddress($address, $name = '') { 324 $cur = count($this->to); 325 $this->to[$cur][0] = trim($address); 326 $this->to[$cur][1] = $name; 327 } 328 329 /** 330 * Adds a "Cc" address. Note: this function works 331 * with the SMTP mailer on win32, not with the "mail" 332 * mailer. 333 * @param string $address 334 * @param string $name 335 * @return void 336 */ 337 function AddCC($address, $name = '') { 338 $cur = count($this->cc); 339 $this->cc[$cur][0] = trim($address); 340 $this->cc[$cur][1] = $name; 341 } 342 343 /** 344 * Adds a "Bcc" address. Note: this function works 345 * with the SMTP mailer on win32, not with the "mail" 346 * mailer. 347 * @param string $address 348 * @param string $name 349 * @return void 350 */ 351 function AddBCC($address, $name = '') { 352 $cur = count($this->bcc); 353 $this->bcc[$cur][0] = trim($address); 354 $this->bcc[$cur][1] = $name; 355 } 356 357 /** 358 * Adds a "Reply-To" address. 359 * @param string $address 360 * @param string $name 361 * @return void 362 */ 363 function AddReplyTo($address, $name = '') { 364 $cur = count($this->ReplyTo); 365 $this->ReplyTo[$cur][0] = trim($address); 366 $this->ReplyTo[$cur][1] = $name; 367 } 368 369 ///////////////////////////////////////////////// 370 // METHODS, MAIL SENDING 371 ///////////////////////////////////////////////// 372 373 /** 374 * Creates message and assigns Mailer. If the message is 375 * not sent successfully then it returns false. Use the ErrorInfo 376 * variable to view description of the error. 377 * @return bool 378 */ 379 function Send() { 380 $header = ''; 381 $body = ''; 382 $result = true; 383 384 if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { 385 $this->SetError($this->Lang('provide_address')); 386 return false; 387 } 388 389 /* Set whether the message is multipart/alternative */ 390 if(!empty($this->AltBody)) { 391 $this->ContentType = 'multipart/alternative'; 392 } 393 394 $this->error_count = 0; // reset errors 395 $this->SetMessageType(); 396 $header .= $this->CreateHeader(); 397 $body = $this->CreateBody(); 398 399 if($body == '') { 400 return false; 401 } 402 403 /* Choose the mailer */ 404 switch($this->Mailer) { 405 case 'sendmail': 406 $result = $this->SendmailSend($header, $body); 407 break; 408 case 'smtp': 409 $result = $this->SmtpSend($header, $body); 410 break; 411 case 'mail': 412 $result = $this->MailSend($header, $body); 413 break; 414 default: 415 $result = $this->MailSend($header, $body); 416 break; 417 //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported')); 418 //$result = false; 419 //break; 420 } 421 422 return $result; 423 } 424 425 /** 426 * Sends mail using the $Sendmail program. 427 * @access private 428 * @return bool 429 */ 430 function SendmailSend($header, $body) { 431 if ($this->Sender != '') { 432 $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); 433 } else { 434 $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail)); 435 } 436 437 if(!@$mail = popen($sendmail, 'w')) { 438 $this->SetError($this->Lang('execute') . $this->Sendmail); 439 return false; 440 } 441 442 fputs($mail, $header); 443 fputs($mail, $body); 444 445 $result = pclose($mail); 446 if (version_compare(phpversion(), '4.2.3') == -1) { 447 $result = $result >> 8 & 0xFF; 448 } 449 if($result != 0) { 450 $this->SetError($this->Lang('execute') . $this->Sendmail); 451 return false; 452 } 453 return true; 454 } 455 456 /** 457 * Sends mail using the PHP mail() function. 458 * @access private 459 * @return bool 460 */ 461 function MailSend($header, $body) { 462 463 $to = ''; 464 for($i = 0; $i < count($this->to); $i++) { 465 if($i != 0) { $to .= ', '; } 466 $to .= $this->AddrFormat($this->to[$i]); 467 } 468 469 $toArr = split(',', $to); 470 471 $params = sprintf("-oi -f %s", $this->Sender); 472 if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) { 473 $old_from = ini_get('sendmail_from'); 474 ini_set('sendmail_from', $this->Sender); 475 if ($this->SingleTo === true && count($toArr) > 1) { 476 foreach ($toArr as $key => $val) { 477 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 351 478 } 352 353 // Set whether the message is multipart/alternative 354 if(!empty($this->AltBody)) 355 $this->ContentType = "multipart/alternative"; 356 357 $this->error_count = 0; // reset errors 358 $this->SetMessageType(); 359 $header .= $this->CreateHeader(); 360 $body = $this->CreateBody(); 361 362 if($body == "") { return false; } 363 364 // Choose the mailer 365 switch($this->Mailer) 366 { 367 case "sendmail": 368 $result = $this->SendmailSend($header, $body); 369 break; 370 case "mail": 371 $result = $this->MailSend($header, $body); 372 break; 373 case "smtp": 374 $result = $this->SmtpSend($header, $body); 375 break; 376 default: 377 $this->SetError($this->Mailer . $this->Lang("mailer_not_supported")); 378 $result = false; 379 break; 479 } else { 480 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 481 } 482 } else { 483 if ($this->SingleTo === true && count($toArr) > 1) { 484 foreach ($toArr as $key => $val) { 485 $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); 380 486 } 381 382 return $result; 383 } 384 385 /** 386 * Sends mail using the $Sendmail program. 387 * @access private 388 * @return bool 389 */ 390 function SendmailSend($header, $body) { 391 if ($this->Sender != "") 392 $sendmail = sprintf("%s -oi -f %s -t", $this->Sendmail, escapeshellarg($this->Sender)); 393 else 394 $sendmail = sprintf("%s -oi -t", $this->Sendmail); 395 396 if(!@$mail = popen($sendmail, "w")) 397 { 398 $this->SetError($this->Lang("execute") . $this->Sendmail); 399 return false; 487 } else { 488 $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); 489 } 490 } 491 492 if (isset($old_from)) { 493 ini_set('sendmail_from', $old_from); 494 } 495 496 if(!$rt) { 497 $this->SetError($this->Lang('instantiate')); 498 return false; 499 } 500 501 return true; 502 } 503 504 /** 505 * Sends mail via SMTP using PhpSMTP (Author: 506 * Chris Ryan). Returns bool. Returns false if there is a 507 * bad MAIL FROM, RCPT, or DATA input. 508 * @access private 509 * @return bool 510 */ 511 function SmtpSend($header, $body) { 512 include_once($this->PluginDir . 'class-smtp.php'); 513 $error = ''; 514 $bad_rcpt = array(); 515 516 if(!$this->SmtpConnect()) { 517 return false; 518 } 519 520 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; 521 if(!$this->smtp->Mail($smtp_from)) { 522 $error = $this->Lang('from_failed') . $smtp_from; 523 $this->SetError($error); 524 $this->smtp->Reset(); 525 return false; 526 } 527 528 /* Attempt to send attach all recipients */ 529 for($i = 0; $i < count($this->to); $i++) { 530 if(!$this->smtp->Recipient($this->to[$i][0])) { 531 $bad_rcpt[] = $this->to[$i][0]; 532 } 533 } 534 for($i = 0; $i < count($this->cc); $i++) { 535 if(!$this->smtp->Recipient($this->cc[$i][0])) { 536 $bad_rcpt[] = $this->cc[$i][0]; 537 } 538 } 539 for($i = 0; $i < count($this->bcc); $i++) { 540 if(!$this->smtp->Recipient($this->bcc[$i][0])) { 541 $bad_rcpt[] = $this->bcc[$i][0]; 542 } 543 } 544 545 if(count($bad_rcpt) > 0) { // Create error message 546 for($i = 0; $i < count($bad_rcpt); $i++) { 547 if($i != 0) { 548 $error .= ', '; 400 549 } 401 402 fputs($mail, $header); 403 fputs($mail, $body); 404 405 $result = pclose($mail) >> 8 & 0xFF; 406 if($result != 0) 407 { 408 $this->SetError($this->Lang("execute") . $this->Sendmail); 409 return false; 550 $error .= $bad_rcpt[$i]; 551 } 552 $error = $this->Lang('recipients_failed') . $error; 553 $this->SetError($error); 554 $this->smtp->Reset(); 555 return false; 556 } 557 558 if(!$this->smtp->Data($header . $body)) { 559 $this->SetError($this->Lang('data_not_accepted')); 560 $this->smtp->Reset(); 561 return false; 562 } 563 if($this->SMTPKeepAlive == true) { 564 $this->smtp->Reset(); 565 } else { 566 $this->SmtpClose(); 567 } 568 569 return true; 570 } 571 572 /** 573 * Initiates a connection to an SMTP server. Returns false if the 574 * operation failed. 575 * @access private 576 * @return bool 577 */ 578 function SmtpConnect() { 579 if($this->smtp == NULL) { 580 $this->smtp = new SMTP(); 581 } 582 583 $this->smtp->do_debug = $this->SMTPDebug; 584 $hosts = explode(';', $this->Host); 585 $index = 0; 586 $connection = ($this->smtp->Connected()); 587 588 /* Retry while there is no connection */ 589 while($index < count($hosts) && $connection == false) { 590 $hostinfo = array(); 591 if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) { 592 $host = $hostinfo[1]; 593 $port = $hostinfo[2]; 594 } else { 595 $host = $hosts[$index]; 596 $port = $this->Port; 597 } 598 599 if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) { 600 if ($this->Helo != '') { 601 $this->smtp->Hello($this->Helo); 602 } else { 603 $this->smtp->Hello($this->ServerHostname()); 410 604 } 411 605 412 return true; 413 } 414 415 /** 416 * Sends mail using the PHP mail() function. 417 * @access private 418 * @return bool 419 */ 420 function MailSend($header, $body) { 421 $to = ""; 422 for($i = 0; $i < count($this->to); $i++) 423 { 424 if($i != 0) { $to .= ", "; } 425 $to .= $this->to[$i][0]; 606 $connection = true; 607 if($this->SMTPAuth) { 608 if(!$this->smtp->Authenticate($this->Username, $this->Password)) { 609 $this->SetError($this->Lang('authenticate')); 610 $this->smtp->Reset(); 611 $connection = false; 612 } 426 613 } 427 428 if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1) 429 { 430 $old_from = ini_get("sendmail_from"); 431 ini_set("sendmail_from", $this->Sender); 432 $params = sprintf("-oi -f %s", $this->Sender); 433 $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, 434 $header, $params); 614 } 615 $index++; 616 } 617 if(!$connection) { 618 $this->SetError($this->Lang('connect_host')); 619 } 620 621 return $connection; 622 } 623 624 /** 625 * Closes the active SMTP session if one exists. 626 * @return void 627 */ 628 function SmtpClose() { 629 if($this->smtp != NULL) { 630 if($this->smtp->Connected()) { 631 $this->smtp->Quit(); 632 $this->smtp->Close(); 633 } 634 } 635 } 636 637 /** 638 * Sets the language for all class error messages. Returns false 639 * if it cannot load the language file. The default language type 640 * is English. 641 * @param string $lang_type Type of language (e.g. Portuguese: "br") 642 * @param string $lang_path Path to the language file directory 643 * @access public 644 * @return bool 645 */ 646 function SetLanguage($lang_type, $lang_path = 'language/') { 647 if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) { 648 include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); 649 } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) { 650 include($lang_path.'phpmailer.lang-en.php'); 651 } else { 652 $this->SetError('Could not load language file'); 653 return false; 654 } 655 $this->language = $PHPMAILER_LANG; 656 657 return true; 658 } 659 660 ///////////////////////////////////////////////// 661 // METHODS, MESSAGE CREATION 662 ///////////////////////////////////////////////// 663 664 /** 665 * Creates recipient headers. 666 * @access private 667 * @return string 668 */ 669 function AddrAppend($type, $addr) { 670 $addr_str = $type . ': '; 671 $addr_str .= $this->AddrFormat($addr[0]); 672 if(count($addr) > 1) { 673 for($i = 1; $i < count($addr); $i++) { 674 $addr_str .= ', ' . $this->AddrFormat($addr[$i]); 675 } 676 } 677 $addr_str .= $this->LE; 678 679 return $addr_str; 680 } 681 682 /** 683 * Formats an address correctly. 684 * @access private 685 * @return string 686 */ 687 function AddrFormat($addr) { 688 if(empty($addr[1])) { 689 $formatted = $this->SecureHeader($addr[0]); 690 } else { 691 $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">"; 692 } 693 694 return $formatted; 695 } 696 697 /** 698 * Wraps message for use with mailers that do not 699 * automatically perform wrapping and for quoted-printable. 700 * Original written by philippe. 701 * @access private 702 * @return string 703 */ 704 function WrapText($message, $length, $qp_mode = false) { 705 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 706 // If utf-8 encoding is used, we will need to make sure we don't 707 // split multibyte characters when we wrap 708 $is_utf8 = (strtolower($this->CharSet) == "utf-8"); 709 710 $message = $this->FixEOL($message); 711 if (substr($message, -1) == $this->LE) { 712 $message = substr($message, 0, -1); 713 } 714 715 $line = explode($this->LE, $message); 716 $message = ''; 717 for ($i=0 ;$i < count($line); $i++) { 718 $line_part = explode(' ', $line[$i]); 719 $buf = ''; 720 for ($e = 0; $e<count($line_part); $e++) { 721 $word = $line_part[$e]; 722 if ($qp_mode and (strlen($word) > $length)) { 723 $space_left = $length - strlen($buf) - 1; 724 if ($e != 0) { 725 if ($space_left > 20) { 726 $len = $space_left; 727 if ($is_utf8) { 728 $len = $this->UTF8CharBoundary($word, $len); 729 } elseif (substr($word, $len - 1, 1) == "=") { 730 $len--; 731 } elseif (substr($word, $len - 2, 1) == "=") { 732 $len -= 2; 733 } 734 $part = substr($word, 0, $len); 735 $word = substr($word, $len); 736 $buf .= ' ' . $part; 737 $message .= $buf . sprintf("=%s", $this->LE); 738 } else { 739 $message .= $buf . $soft_break; 740 } 741 $buf = ''; 742 } 743 while (strlen($word) > 0) { 744 $len = $length; 745 if ($is_utf8) { 746 $len = $this->UTF8CharBoundary($word, $len); 747 } elseif (substr($word, $len - 1, 1) == "=") { 748 $len--; 749 } elseif (substr($word, $len - 2, 1) == "=") { 750 $len -= 2; 751 } 752 $part = substr($word, 0, $len); 753 $word = substr($word, $len); 754 755 if (strlen($word) > 0) { 756 $message .= $part . sprintf("=%s", $this->LE); 757 } else { 758 $buf = $part; 759 } 760 } 761 } else { 762 $buf_o = $buf; 763 $buf .= ($e == 0) ? $word : (' ' . $word); 764 765 if (strlen($buf) > $length and $buf_o != '') { 766 $message .= $buf_o . $soft_break; 767 $buf = $word; 768 } 435 769 } 436 else 437 $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header); 438 439 if (isset($old_from)) 440 ini_set("sendmail_from", $old_from); 441 442 if(!$rt) 443 { 444 $this->SetError($this->Lang("instantiate")); 445 return false; 770 } 771 $message .= $buf . $this->LE; 772 } 773 774 return $message; 775 } 776 777 /** 778 * Finds last character boundary prior to maxLength in a utf-8 779 * quoted (printable) encoded string. 780 * Original written by Colin Brown. 781 * @access private 782 * @param string $encodedText utf-8 QP text 783 * @param int $maxLength find last character boundary prior to this length 784 * @return int 785 */ 786 function UTF8CharBoundary($encodedText, $maxLength) { 787 $foundSplitPos = false; 788 $lookBack = 3; 789 while (!$foundSplitPos) { 790 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); 791 $encodedCharPos = strpos($lastChunk, "="); 792 if ($encodedCharPos !== false) { 793 // Found start of encoded character byte within $lookBack block. 794 // Check the encoded byte value (the 2 chars after the '=') 795 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); 796 $dec = hexdec($hex); 797 if ($dec < 128) { // Single byte character. 798 // If the encoded char was found at pos 0, it will fit 799 // otherwise reduce maxLength to start of the encoded char 800 $maxLength = ($encodedCharPos == 0) ? $maxLength : 801 $maxLength - ($lookBack - $encodedCharPos); 802 $foundSplitPos = true; 803 } elseif ($dec >= 192) { // First byte of a multi byte character 804 // Reduce maxLength to split at start of character 805 $maxLength = $maxLength - ($lookBack - $encodedCharPos); 806 $foundSplitPos = true; 807 } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back 808 $lookBack += 3; 446 809 } 447 448 return true; 449 } 450 451 /** 452 * Sends mail via SMTP using PhpSMTP (Author: 453 * Chris Ryan). Returns bool. Returns false if there is a 454 * bad MAIL FROM, RCPT, or DATA input. 455 * @access private 456 * @return bool 457 */ 458 function SmtpSend($header, $body) { 459 include_once($this->PluginDir . "class-smtp.php"); 460 $error = ""; 461 $bad_rcpt = array(); 462 463 if(!$this->SmtpConnect()) 464 return false; 465 466 $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender; 467 if(!$this->smtp->Mail($smtp_from)) 468 { 469 $error = $this->Lang("from_failed") . $smtp_from; 470 $this->SetError($error); 471 $this->smtp->Reset(); 472 return false; 810 } else { 811 // No encoded character found 812 $foundSplitPos = true; 813 } 814 } 815 return $maxLength; 816 } 817 818 /** 819 * Set the body wrapping. 820 * @access private 821 * @return void 822 */ 823 function SetWordWrap() { 824 if($this->WordWrap < 1) { 825 return; 826 } 827 828 switch($this->message_type) { 829 case 'alt': 830 /* fall through */ 831 case 'alt_attachments': 832 $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 833 break; 834 default: 835 $this->Body = $this->WrapText($this->Body, $this->WordWrap); 836 break; 837 } 838 } 839 840 /** 841 * Assembles message header. 842 * @access private 843 * @return string 844 */ 845 function CreateHeader() { 846 $result = ''; 847 848 /* Set the boundaries */ 849 $uniq_id = md5(uniqid(time())); 850 $this->boundary[1] = 'b1_' . $uniq_id; 851 $this->boundary[2] = 'b2_' . $uniq_id; 852 853 $result .= $this->HeaderLine('Date', $this->RFCDate()); 854 if($this->Sender == '') { 855 $result .= $this->HeaderLine('Return-Path', trim($this->From)); 856 } else { 857 $result .= $this->HeaderLine('Return-Path', trim($this->Sender)); 858 } 859 860 /* To be created automatically by mail() */ 861 if($this->Mailer != 'mail') { 862 if(count($this->to) > 0) { 863 $result .= $this->AddrAppend('To', $this->to); 864 } elseif (count($this->cc) == 0) { 865 $result .= $this->HeaderLine('To', 'undisclosed-recipients:;'); 866 } 867 if(count($this->cc) > 0) { 868 $result .= $this->AddrAppend('Cc', $this->cc); 869 } 870 } 871 872 $from = array(); 873 $from[0][0] = trim($this->From); 874 $from[0][1] = $this->FromName; 875 $result .= $this->AddrAppend('From', $from); 876 877 /* sendmail and mail() extract Cc from the header before sending */ 878 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) { 879 $result .= $this->AddrAppend('Cc', $this->cc); 880 } 881 882 /* sendmail and mail() extract Bcc from the header before sending */ 883 if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) { 884 $result .= $this->AddrAppend('Bcc', $this->bcc); 885 } 886 887 if(count($this->ReplyTo) > 0) { 888 $result .= $this->AddrAppend('Reply-To', $this->ReplyTo); 889 } 890 891 /* mail() sets the subject itself */ 892 if($this->Mailer != 'mail') { 893 $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject))); 894 } 895 896 if($this->MessageID != '') { 897 $result .= $this->HeaderLine('Message-ID',$this->MessageID); 898 } else { 899 $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 900 } 901 $result .= $this->HeaderLine('X-Priority', $this->Priority); 902 $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']'); 903 904 if($this->ConfirmReadingTo != '') { 905 $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); 906 } 907 908 // Add custom headers 909 for($index = 0; $index < count($this->CustomHeader); $index++) { 910 $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); 911 } 912 if (!$this->sign_key_file) { 913 $result .= $this->HeaderLine('MIME-Version', '1.0'); 914 $result .= $this->GetMailMIME(); 915 } 916 917 return $result; 918 } 919 920 /** 921 * Returns the message MIME. 922 * @access private 923 * @return string 924 */ 925 function GetMailMIME() { 926 $result = ''; 927 switch($this->message_type) { 928 case 'plain': 929 $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding); 930 $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet); 931 break; 932 case 'attachments': 933 /* fall through */ 934 case 'alt_attachments': 935 if($this->InlineImageExists()){ 936 $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE); 937 } else { 938 $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;'); 939 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 473 940 } 474 475 // Attempt to send attach all recipients 476 for($i = 0; $i < count($this->to); $i++) 477 { 478 if(!$this->smtp->Recipient($this->to[$i][0])) 479 $bad_rcpt[] = $this->to[$i][0]; 941 break; 942 case 'alt': 943 $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;'); 944 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 945 break; 946 } 947 948 if($this->Mailer != 'mail') { 949 $result .= $this->LE.$this->LE; 950 } 951 952 return $result; 953 } 954 955 /** 956 * Assembles the message body. Returns an empty string on failure. 957 * @access private 958 * @return string 959 */ 960 function CreateBody() { 961 $result = ''; 962 if ($this->sign_key_file) { 963 $result .= $this->GetMailMIME(); 964 } 965 966 $this->SetWordWrap(); 967 968 switch($this->message_type) { 969 case 'alt': 970 $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', ''); 971 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 972 $result .= $this->LE.$this->LE; 973 $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', ''); 974 $result .= $this->EncodeString($this->Body, $this->Encoding); 975 $result .= $this->LE.$this->LE; 976 $result .= $this->EndBoundary($this->boundary[1]); 977 break; 978 case 'plain': 979 $result .= $this->EncodeString($this->Body, $this->Encoding); 980 break; 981 case 'attachments': 982 $result .= $this->GetBoundary($this->boundary[1], '', '', ''); 983 $result .= $this->EncodeString($this->Body, $this->Encoding); 984 $result .= $this->LE; 985 $result .= $this->AttachAll(); 986 break; 987 case 'alt_attachments': 988 $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); 989 $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE); 990 $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body 991 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 992 $result .= $this->LE.$this->LE; 993 $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body 994 $result .= $this->EncodeString($this->Body, $this->Encoding); 995 $result .= $this->LE.$this->LE; 996 $result .= $this->EndBoundary($this->boundary[2]); 997 $result .= $this->AttachAll(); 998 break; 999 } 1000 1001 if($this->IsError()) { 1002 $result = ''; 1003 } else if ($this->sign_key_file) { 1004 $file = tempnam("", "mail"); 1005 $fp = fopen($file, "w"); 1006 fwrite($fp, $result); 1007 fclose($fp); 1008 $signed = tempnam("", "signed"); 1009 1010 if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_key_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) { 1011 $fp = fopen($signed, "r"); 1012 $result = fread($fp, filesize($this->sign_key_file)); 1013 fclose($fp); 1014 } else { 1015 $this->SetError($this->Lang("signing").openssl_error_string()); 1016 $result = ''; 1017 } 1018 1019 unlink($file); 1020 unlink($signed); 1021 } 1022 1023 return $result; 1024 } 1025 1026 /** 1027 * Returns the start of a message boundary. 1028 * @access private 1029 */ 1030 function GetBoundary($boundary, $charSet, $contentType, $encoding) { 1031 $result = ''; 1032 if($charSet == '') { 1033 $charSet = $this->CharSet; 1034 } 1035 if($contentType == '') { 1036 $contentType = $this->ContentType; 1037 } 1038 if($encoding == '') { 1039 $encoding = $this->Encoding; 1040 } 1041 $result .= $this->TextLine('--' . $boundary); 1042 $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet); 1043 $result .= $this->LE; 1044 $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding); 1045 $result .= $this->LE; 1046 1047 return $result; 1048 } 1049 1050 /** 1051 * Returns the end of a message boundary. 1052 * @access private 1053 */ 1054 function EndBoundary($boundary) { 1055 return $this->LE . '--' . $boundary . '--' . $this->LE; 1056 } 1057 1058 /** 1059 * Sets the message type. 1060 * @access private 1061 * @return void 1062 */ 1063 function SetMessageType() { 1064 if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { 1065 $this->message_type = 'plain'; 1066 } else { 1067 if(count($this->attachment) > 0) { 1068 $this->message_type = 'attachments'; 1069 } 1070 if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) { 1071 $this->message_type = 'alt'; 1072 } 1073 if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) { 1074 $this->message_type = 'alt_attachments'; 1075 } 1076 } 1077 } 1078 1079 /* Returns a formatted header line. 1080 * @access private 1081 * @return string 1082 */ 1083 function HeaderLine($name, $value) { 1084 return $name . ': ' . $value . $this->LE; 1085 } 1086 1087 /** 1088 * Returns a formatted mail line. 1089 * @access private 1090 * @return string 1091 */ 1092 function TextLine($value) { 1093 return $value . $this->LE; 1094 } 1095 1096 ///////////////////////////////////////////////// 1097 // CLASS METHODS, ATTACHMENTS 1098 ///////////////////////////////////////////////// 1099 1100 /** 1101 * Adds an attachment from a path on the filesystem. 1102 * Returns false if the file could not be found 1103 * or accessed. 1104 * @param string $path Path to the attachment. 1105 * @param string $name Overrides the attachment name. 1106 * @param string $encoding File encoding (see $Encoding). 1107 * @param string $type File extension (MIME) type. 1108 * @return bool 1109 */ 1110 function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 1111 if(!@is_file($path)) { 1112 $this->SetError($this->Lang('file_access') . $path); 1113 return false; 1114 } 1115 1116 $filename = basename($path); 1117 if($name == '') { 1118 $name = $filename; 1119 } 1120 1121 $cur = count($this->attachment); 1122 $this->attachment[$cur][0] = $path; 1123 $this->attachment[$cur][1] = $filename; 1124 $this->attachment[$cur][2] = $name; 1125 $this->attachment[$cur][3] = $encoding; 1126 $this->attachment[$cur][4] = $type; 1127 $this->attachment[$cur][5] = false; // isStringAttachment 1128 $this->attachment[$cur][6] = 'attachment'; 1129 $this->attachment[$cur][7] = 0; 1130 1131 return true; 1132 } 1133 1134 /** 1135 * Attaches all fs, string, and binary attachments to the message. 1136 * Returns an empty string on failure. 1137 * @access private 1138 * @return string 1139 */ 1140 function AttachAll() { 1141 /* Return text of body */ 1142 $mime = array(); 1143 1144 /* Add all attachments */ 1145 for($i = 0; $i < count($this->attachment); $i++) { 1146 /* Check for string attachment */ 1147 $bString = $this->attachment[$i][5]; 1148 if ($bString) { 1149 $string = $this->attachment[$i][0]; 1150 } else { 1151 $path = $this->attachment[$i][0]; 1152 } 1153 1154 $filename = $this->attachment[$i][1]; 1155 $name = $this->attachment[$i][2]; 1156 $encoding = $this->attachment[$i][3]; 1157 $type = $this->attachment[$i][4]; 1158 $disposition = $this->attachment[$i][6]; 1159 $cid = $this->attachment[$i][7]; 1160 1161 $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); 1162 $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); 1163 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); 1164 1165 if($disposition == 'inline') { 1166 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); 1167 } 1168 1169 $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE); 1170 1171 /* Encode as string attachment */ 1172 if($bString) { 1173 $mime[] = $this->EncodeString($string, $encoding); 1174 if($this->IsError()) { 1175 return ''; 480 1176 } 481 for($i = 0; $i < count($this->cc); $i++) 482 { 483 if(!$this->smtp->Recipient($this->cc[$i][0])) 484 $bad_rcpt[] = $this->cc[$i][0]; 1177 $mime[] = $this->LE.$this->LE; 1178 } else { 1179 $mime[] = $this->EncodeFile($path, $encoding); 1180 if($this->IsError()) { 1181 return ''; 485 1182 } 486 for($i = 0; $i < count($this->bcc); $i++) 487 { 488 if(!$this->smtp->Recipient($this->bcc[$i][0])) 489 $bad_rcpt[] = $this->bcc[$i][0]; 1183 $mime[] = $this->LE.$this->LE; 1184 } 1185 } 1186 1187 $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); 1188 1189 return join('', $mime); 1190 } 1191 1192 /** 1193 * Encodes attachment in requested format. Returns an 1194 * empty string on failure. 1195 * @access private 1196 * @return string 1197 */ 1198 function EncodeFile ($path, $encoding = 'base64') { 1199 if(!@$fd = fopen($path, 'rb')) { 1200 $this->SetError($this->Lang('file_open') . $path); 1201 return ''; 1202 } 1203 $magic_quotes = get_magic_quotes_runtime(); 1204 set_magic_quotes_runtime(0); 1205 $file_buffer = fread($fd, filesize($path)); 1206 $file_buffer = $this->EncodeString($file_buffer, $encoding); 1207 fclose($fd); 1208 set_magic_quotes_runtime($magic_quotes); 1209 1210 return $file_buffer; 1211 } 1212 1213 /** 1214 * Encodes string to requested format. Returns an 1215 * empty string on failure. 1216 * @access private 1217 * @return string 1218 */ 1219 function EncodeString ($str, $encoding = 'base64') { 1220 $encoded = ''; 1221 switch(strtolower($encoding)) { 1222 case 'base64': 1223 /* chunk_split is found in PHP >= 3.0.6 */ 1224 $encoded = chunk_split(base64_encode($str), 76, $this->LE); 1225 break; 1226 case '7bit': 1227 case '8bit': 1228 $encoded = $this->FixEOL($str); 1229 if (substr($encoded, -(strlen($this->LE))) != $this->LE) 1230 $encoded .= $this->LE; 1231 break; 1232 case 'binary': 1233 $encoded = $str; 1234 break; 1235 case 'quoted-printable': 1236 $encoded = $this->EncodeQP($str); 1237 break; 1238 default: 1239 $this->SetError($this->Lang('encoding') . $encoding); 1240 break; 1241 } 1242 return $encoded; 1243 } 1244 1245 /** 1246 * Encode a header string to best of Q, B, quoted or none. 1247 * @access private 1248 * @return string 1249 */ 1250 function EncodeHeader ($str, $position = 'text') { 1251 $x = 0; 1252 1253 switch (strtolower($position)) { 1254 case 'phrase': 1255 if (!preg_match('/[\200-\377]/', $str)) { 1256 /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */ 1257 $encoded = addcslashes($str, "\0..\37\177\\\""); 1258 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { 1259 return ($encoded); 1260 } else { 1261 return ("\"$encoded\""); 1262 } 490 1263 } 491 492 if(count($bad_rcpt) > 0) // Create error message 493 { 494 for($i = 0; $i < count($bad_rcpt); $i++) 495 { 496 if($i != 0) { $error .= ", "; } 497 $error .= $bad_rcpt[$i]; 498 } 499 $error = $this->Lang("recipients_failed") . $error; 500 $this->SetError($error); 501 $this->smtp->Reset(); 502 return false; 503 } 504 505 if(!$this->smtp->Data($header . $body)) 506 { 507 $this->SetError($this->Lang("data_not_accepted")); 508 $this->smtp->Reset(); 509 return false; 510 } 511 if($this->SMTPKeepAlive == true) 512 $this->smtp->Reset(); 513 else 514 $this->SmtpClose(); 515 516 return true; 517 } 518 519 /** 520 * Initiates a connection to an SMTP server. Returns false if the 521 * operation failed. 522 * @access private 523 * @return bool 524 */ 525 function SmtpConnect() { 526 if($this->smtp == NULL) { $this->smtp = new SMTP(); } 527 528 $this->smtp->do_debug = $this->SMTPDebug; 529 $hosts = explode(";", $this->Host); 530 $index = 0; 531 $connection = ($this->smtp->Connected()); 532 533 // Retry while there is no connection 534 while($index < count($hosts) && $connection == false) 535 { 536 if(strstr($hosts[$index], ":")) 537 list($host, $port) = explode(":", $hosts[$index]); 538 else 539 { 540 $host = $hosts[$index]; 541 $port = $this->Port; 542 } 543 544 if($this->smtp->Connect($host, $port, $this->Timeout)) 545 { 546 if ($this->Helo != '') 547 $this->smtp->Hello($this->Helo); 548 else 549 $this->smtp->Hello($this->ServerHostname()); 550 551 if($this->SMTPAuth) 552 { 553 if(!$this->smtp->Authenticate($this->Username, 554 $this->Password)) 555 { 556 $this->SetError($this->Lang("authenticate")); 557 $this->smtp->Reset(); 558 $connection = false; 559 } 560 } 561 $connection = true; 562 } 563 $index++; 564 } 565 if(!$connection) 566 $this->SetError($this->Lang("connect_host")); 567 568 return $connection; 569 } 570 571 /** 572 * Closes the active SMTP session if one exists. 573 * @return void 574 */ 575 function SmtpClose() { 576 if($this->smtp != NULL) 577 { 578 if($this->smtp->Connected()) 579 { 580 $this->smtp->Quit(); 581 $this->smtp->Close(); 582 } 583 } 584 } 585 586 /** 587 * Sets the language for all class error messages. Returns false 588 * if it cannot load the language file. The default language type 589 * is English. 590 * @param string $lang_type Type of language (e.g. Portuguese: "br") 591 * @param string $lang_path Path to the language file directory 592 * @access public 593 * @return bool 594 */ 595 function SetLanguage($lang_type, $lang_path = "language/") { 596 if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) 597 include($lang_path.'phpmailer.lang-'.$lang_type.'.php'); 598 else if(file_exists($lang_path.'phpmailer.lang-en.php')) 599 include($lang_path.'phpmailer.lang-en.php'); 600 else 601 { 602 $this->SetError("Could not load language file"); 603 return false; 604 } 605 $this->language = $PHPMAILER_LANG; 606 607 return true; 608 } 609 610 ///////////////////////////////////////////////// 611 // MESSAGE CREATION METHODS 612 ///////////////////////////////////////////////// 613 614 /** 615 * Creates recipient headers. 616 * @access private 617 * @return string 618 */ 619 function AddrAppend($type, $addr) { 620 $addr_str = $type . ": "; 621 $addr_str .= $this->AddrFormat($addr[0]); 622 if(count($addr) > 1) 623 { 624 for($i = 1; $i < count($addr); $i++) 625 $addr_str .= ", " . $this->AddrFormat($addr[$i]); 626 } 627 $addr_str .= $this->LE; 628 629 return $addr_str; 630 } 631 632 /** 633 * Formats an address correctly. 634 * @access private 635 * @return string 636 */ 637 function AddrFormat($addr) { 638 if(empty($addr[1])) 639 $formatted = $addr[0]; 640 else 641 { 642 $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" . 643 $addr[0] . ">"; 644 } 645 646 return $formatted; 647 } 648 649 /** 650 * Wraps message for use with mailers that do not 651 * automatically perform wrapping and for quoted-printable. 652 * Original written by philippe. 653 * @access private 654 * @return string 655 */ 656 function WrapText($message, $length, $qp_mode = false) { 657 $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE; 658 659 $message = $this->FixEOL($message); 660 if (substr($message, -1) == $this->LE) 661 $message = substr($message, 0, -1); 662 663 $line = explode($this->LE, $message); 664 $message = ""; 665 for ($i=0 ;$i < count($line); $i++) 666 { 667 $line_part = explode(" ", $line[$i]); 668 $buf = ""; 669 for ($e = 0; $e<count($line_part); $e++) 670 { 671 $word = $line_part[$e]; 672 if ($qp_mode and (strlen($word) > $length)) 673 { 674 $space_left = $length - strlen($buf) - 1; 675 if ($e != 0) 676 { 677 if ($space_left > 20) 678 { 679 $len = $space_left; 680 if (substr($word, $len - 1, 1) == "=") 681 $len--; 682 elseif (substr($word, $len - 2, 1) == "=") 683 $len -= 2; 684 $part = substr($word, 0, $len); 685 $word = substr($word, $len); 686 $buf .= " " . $part; 687 $message .= $buf . sprintf("=%s", $this->LE); 688 } 689 else 690 { 691 $message .= $buf . $soft_break; 692 } 693 $buf = ""; 694 } 695 while (strlen($word) > 0) 696 { 697 $len = $length; 698 if (substr($word, $len - 1, 1) == "=") 699 $len--; 700 elseif (substr($word, $len - 2, 1) == "=") 701 $len -= 2; 702 $part = substr($word, 0, $len); 703 $word = substr($word, $len); 704 705 if (strlen($word) > 0) 706 $message .= $part . sprintf("=%s", $this->LE); 707 else 708 $buf = $part; 709 } 710 } 711 else 712 { 713 $buf_o = $buf; 714 $buf .= ($e == 0) ? $word : (" " . $word); 715 716 if (strlen($buf) > $length and $buf_o != "") 717 { 718 $message .= $buf_o . $soft_break; 719 $buf = $word; 720 } 721 } 722 } 723 $message .= $buf . $this->LE; 724 } 725 726 return $message; 727 } 728 729 /** 730 * Set the body wrapping. 731 * @access private 732 * @return void 733 */ 734 function SetWordWrap() { 735 if($this->WordWrap < 1) 736 return; 737 738 switch($this->message_type) 739 { 740 case "alt": 741 // fall through 742 case "alt_attachments": 743 $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap); 744 break; 745 default: 746 $this->Body = $this->WrapText($this->Body, $this->WordWrap); 747 break; 748 } 749 } 750 751 /** 752 * Assembles message header. 753 * @access private 754 * @return string 755 */ 756 function CreateHeader() { 757 $result = ""; 758 759 // Set the boundaries 760 $uniq_id = md5(uniqid(time())); 761 $this->boundary[1] = "b1_" . $uniq_id; 762 $this->boundary[2] = "b2_" . $uniq_id; 763 764 $result .= $this->HeaderLine("Date", $this->RFCDate()); 765 if($this->Sender == "") 766 $result .= $this->HeaderLine("Return-Path", trim($this->From)); 767 else 768 $result .= $this->HeaderLine("Return-Path", trim($this->Sender)); 769 770 // To be created automatically by mail() 771 if($this->Mailer != "mail") 772 { 773 if(count($this->to) > 0) 774 $result .= $this->AddrAppend("To", $this->to); 775 else if (count($this->cc) == 0) 776 $result .= $this->HeaderLine("To", "undisclosed-recipients:;"); 777 if(count($this->cc) > 0) 778 $result .= $this->AddrAppend("Cc", $this->cc); 779 } 780 781 $from = array(); 782 $from[0][0] = trim($this->From); 783 $from[0][1] = $this->FromName; 784 $result .= $this->AddrAppend("From", $from); 785 786 // sendmail and mail() extract Bcc from the header before sending 787 if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0)) 788 $result .= $this->AddrAppend("Bcc", $this->bcc); 789 790 if(count($this->ReplyTo) > 0) 791 $result .= $this->AddrAppend("Reply-to", $this->ReplyTo); 792 793 // mail() sets the subject itself 794 if($this->Mailer != "mail") 795 $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject))); 796 797 $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE); 798 $result .= $this->HeaderLine("X-Priority", $this->Priority); 799 800 if($this->ConfirmReadingTo != "") 801 { 802 $result .= $this->HeaderLine("Disposition-Notification-To", 803 "<" . trim($this->ConfirmReadingTo) . ">"); 804 } 805 806 // Add custom headers 807 for($index = 0; $index < count($this->CustomHeader); $index++) 808 { 809 $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), 810 $this->EncodeHeader(trim($this->CustomHeader[$index][1]))); 811 } 812 $result .= $this->HeaderLine("MIME-Version", "1.0"); 813 814 switch($this->message_type) 815 { 816 case "plain": 817 $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding); 818 $result .= sprintf("Content-Type: %s; charset=\"%s\"", 819 $this->ContentType, $this->CharSet); 820 break; 821 case "attachments": 822 // fall through 823 case "alt_attachments": 824 if($this->InlineImageExists()) 825 { 826 $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 827 "multipart/related", $this->LE, $this->LE, 828 $this->boundary[1], $this->LE); 829 } 830 else 831 { 832 $result .= $this->HeaderLine("Content-Type", "multipart/mixed;"); 833 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 834 } 835 break; 836 case "alt": 837 $result .= $this->HeaderLine("Content-Type", "multipart/alternative;"); 838 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"'); 839 break; 840 } 841 842 if($this->Mailer != "mail") 843 $result .= $this->LE.$this->LE; 844 845 return $result; 846 } 847 848 /** 849 * Assembles the message body. Returns an empty string on failure. 850 * @access private 851 * @return string 852 */ 853 function CreateBody() { 854 $result = ""; 855 856 $this->SetWordWrap(); 857 858 switch($this->message_type) 859 { 860 case "alt": 861 $result .= $this->GetBoundary($this->boundary[1], "", 862 "text/plain", ""); 863 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 864 $result .= $this->LE.$this->LE; 865 $result .= $this->GetBoundary($this->boundary[1], "", 866 "text/html", ""); 867 868 $result .= $this->EncodeString($this->Body, $this->Encoding); 869 $result .= $this->LE.$this->LE; 870 871 $result .= $this->EndBoundary($this->boundary[1]); 872 break; 873 case "plain": 874 $result .= $this->EncodeString($this->Body, $this->Encoding); 875 break; 876 case "attachments": 877 $result .= $this->GetBoundary($this->boundary[1], "", "", ""); 878 $result .= $this->EncodeString($this->Body, $this->Encoding); 879 $result .= $this->LE; 880 881 $result .= $this->AttachAll(); 882 break; 883 case "alt_attachments": 884 $result .= sprintf("--%s%s", $this->boundary[1], $this->LE); 885 $result .= sprintf("Content-Type: %s;%s" . 886 "\tboundary=\"%s\"%s", 887 "multipart/alternative", $this->LE, 888 $this->boundary[2], $this->LE.$this->LE); 889 890 // Create text body 891 $result .= $this->GetBoundary($this->boundary[2], "", 892 "text/plain", "") . $this->LE; 893 894 $result .= $this->EncodeString($this->AltBody, $this->Encoding); 895 $result .= $this->LE.$this->LE; 896 897 // Create the HTML body 898 $result .= $this->GetBoundary($this->boundary[2], "", 899 "text/html", "") . $this->LE; 900 901 $result .= $this->EncodeString($this->Body, $this->Encoding); 902 $result .= $this->LE.$this->LE; 903 904 $result .= $this->EndBoundary($this->boundary[2]); 905 906 $result .= $this->AttachAll(); 907 break; 908 } 909 if($this->IsError()) 910 $result = ""; 911 912 return $result; 913 } 914 915 /** 916 * Returns the start of a message boundary. 917 * @access private 918 */ 919 function GetBoundary($boundary, $charSet, $contentType, $encoding) { 920 $result = ""; 921 if($charSet == "") { $charSet = $this->CharSet; } 922 if($contentType == "") { $contentType = $this->ContentType; } 923 if($encoding == "") { $encoding = $this->Encoding; } 924 925 $result .= $this->TextLine("--" . $boundary); 926 $result .= sprintf("Content-Type: %s; charset = \"%s\"", 927 $contentType, $charSet); 928 $result .= $this->LE; 929 $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding); 930 $result .= $this->LE; 931 932 return $result; 933 } 934 935 /** 936 * Returns the end of a message boundary. 937 * @access private 938 */ 939 function EndBoundary($boundary) { 940 return $this->LE . "--" . $boundary . "--" . $this->LE; 941 } 942 943 /** 944 * Sets the message type. 945 * @access private 946 * @return void 947 */ 948 function SetMessageType() { 949 if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) 950 $this->message_type = "plain"; 951 else 952 { 953 if(count($this->attachment) > 0) 954 $this->message_type = "attachments"; 955 if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) 956 $this->message_type = "alt"; 957 if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) 958 $this->message_type = "alt_attachments"; 959 } 960 } 961 962 /** 963 * Returns a formatted header line. 964 * @access private 965 * @return string 966 */ 967 function HeaderLine($name, $value) { 968 return $name . ": " . $value . $this->LE; 969 } 970 971 /** 972 * Returns a formatted mail line. 973 * @access private 974 * @return string 975 */ 976 function TextLine($value) { 977 return $value . $this->LE; 978 } 979 980 ///////////////////////////////////////////////// 981 // ATTACHMENT METHODS 982 ///////////////////////////////////////////////// 983 984 /** 985 * Adds an attachment from a path on the filesystem. 986 * Returns false if the file could not be found 987 * or accessed. 988 * @param string $path Path to the attachment. 989 * @param string $name Overrides the attachment name. 990 * @param string $encoding File encoding (see $Encoding). 991 * @param string $type File extension (MIME) type. 992 * @return bool 993 */ 994 function AddAttachment($path, $name = "", $encoding = "base64", 995 $type = "application/octet-stream") { 996 if(!@is_file($path)) 997 { 998 $this->SetError($this->Lang("file_access") . $path); 999 return false; 1000 } 1001 1002 $filename = basename($path); 1003 if($name == "") 1004 $name = $filename; 1005 1006 $cur = count($this->attachment); 1007 $this->attachment[$cur][0] = $path; 1008 $this->attachment[$cur][1] = $filename; 1009 $this->attachment[$cur][2] = $name; 1010 $this->attachment[$cur][3] = $encoding; 1011 $this->attachment[$cur][4] = $type; 1012 $this->attachment[$cur][5] = false; // isStringAttachment 1013 $this->attachment[$cur][6] = "attachment"; 1014 $this->attachment[$cur][7] = 0; 1015 1016 return true; 1017 } 1018 1019 /** 1020 * Attaches all fs, string, and binary attachments to the message. 1021 * Returns an empty string on failure. 1022 * @access private 1023 * @return string 1024 */ 1025 function AttachAll() { 1026 // Return text of body 1027 $mime = array(); 1028 1029 // Add all attachments 1030 for($i = 0; $i < count($this->attachment); $i++) 1031 { 1032 // Check for string attachment 1033 $bString = $this->attachment[$i][5]; 1034 if ($bString) 1035 $string = $this->attachment[$i][0]; 1036 else 1037 $path = $this->attachment[$i][0]; 1038 1039 $filename = $this->attachment[$i][1]; 1040 $name = $this->attachment[$i][2]; 1041 $encoding = $this->attachment[$i][3]; 1042 $type = $this->attachment[$i][4]; 1043 $disposition = $this->attachment[$i][6]; 1044 $cid = $this->attachment[$i][7]; 1045 1046 $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); 1047 $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); 1048 $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); 1049 1050 if($disposition == "inline") 1051 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); 1052 1053 $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", 1054 $disposition, $name, $this->LE.$this->LE); 1055 1056 // Encode as string attachment 1057 if($bString) 1058 { 1059 $mime[] = $this->EncodeString($string, $encoding); 1060 if($this->IsError()) { return ""; } 1061 $mime[] = $this->LE.$this->LE; 1062 } 1063 else 1064 { 1065 $mime[] = $this->EncodeFile($path, $encoding); 1066 if($this->IsError()) { return ""; } 1067 $mime[] = $this->LE.$this->LE; 1068 } 1069 } 1070 1071 $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); 1072 1073 return join("", $mime); 1074 } 1075 1076 /** 1077 * Encodes attachment in requested format. Returns an 1078 * empty string on failure. 1079 * @access private 1080 * @return string 1081 */ 1082 function EncodeFile ($path, $encoding = "base64") { 1083 if(!@$fd = fopen($path, "rb")) 1084 { 1085 $this->SetError($this->Lang("file_open") . $path); 1086 return ""; 1087 } 1088 $magic_quotes = get_magic_quotes_runtime(); 1089 set_magic_quotes_runtime(0); 1090 $file_buffer = fread($fd, filesize($path)); 1091 $file_buffer = $this->EncodeString($file_buffer, $encoding); 1092 fclose($fd); 1093 set_magic_quotes_runtime($magic_quotes); 1094 1095 return $file_buffer; 1096 } 1097 1098 /** 1099 * Encodes string to requested format. Returns an 1100 * empty string on failure. 1101 * @access private 1102 * @return string 1103 */ 1104 function EncodeString ($str, $encoding = "base64") { 1105 $encoded = ""; 1106 switch(strtolower($encoding)) { 1107 case "base64": 1108 // chunk_split is found in PHP >= 3.0.6 1109 $encoded = chunk_split(base64_encode($str), 76, $this->LE); 1110 break; 1111 case "7bit": 1112 case "8bit": 1113 $encoded = $this->FixEOL($str); 1114 if (substr($encoded, -(strlen($this->LE))) != $this->LE) 1115 $encoded .= $this->LE; 1116 break; 1117 case "binary": 1118 $encoded = $str; 1119 break; 1120 case "quoted-printable": 1121 $encoded = $this->EncodeQP($str); 1122 break; 1123 default: 1124 $this->SetError($this->Lang("encoding") . $encoding); 1125 break; 1126 } 1127 return $encoded; 1128 } 1129 1130 /** 1131 * Encode a header string to best of Q, B, quoted or none. 1132 * @access private 1133 * @return string 1134 */ 1135 function EncodeHeader ($str, $position = 'text') { 1136 $x = 0; 1137 1138 switch (strtolower($position)) { 1139 case 'phrase': 1140 if (!preg_match('/[\200-\377]/', $str)) { 1141 // Can't use addslashes as we don't know what value has magic_quotes_sybase. 1142 $encoded = addcslashes($str, "\0..\37\177\\\""); 1143 1144 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) 1145 return ($encoded); 1146 else 1147 return ("\"$encoded\""); 1148 } 1149 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); 1150 break; 1151 case 'comment': 1152 $x = preg_match_all('/[()"]/', $str, $matches); 1153 // Fall-through 1154 case 'text': 1155 default: 1156 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 1157 break; 1158 } 1159 1160 if ($x == 0) 1161 return ($str); 1162 1163 $maxlen = 75 - 7 - strlen($this->CharSet); 1164 // Try to select the encoding which should produce the shortest output 1165 if (strlen($str)/3 < $x) { 1166 $encoding = 'B'; 1264 $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); 1265 break; 1266 case 'comment': 1267 $x = preg_match_all('/[()"]/', $str, $matches); 1268 /* Fall-through */ 1269 case 'text': 1270 default: 1271 $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); 1272 break; 1273 } 1274 1275 if ($x == 0) { 1276 return ($str); 1277 } 1278 1279 $maxlen = 75 - 7 - strlen($this->CharSet); 1280 /* Try to select the encoding which should produce the shortest output */ 1281 if (strlen($str)/3 < $x) { 1282 $encoding = 'B'; 1283 if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) { 1284 // Use a custom function which correctly encodes and wraps long 1285 // multibyte strings without breaking lines within a character 1286 $encoded = $this->Base64EncodeWrapMB($str); 1287 } else { 1167 1288 $encoded = base64_encode($str); 1168 1289 $maxlen -= $maxlen % 4; 1169 1290 $encoded = trim(chunk_split($encoded, $maxlen, "\n")); 1170 } else { 1171 $encoding = 'Q'; 1172 $encoded = $this->EncodeQ($str, $position); 1173 $encoded = $this->WrapText($encoded, $maxlen, true); 1174 $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); 1175 } 1176 1177 $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); 1178 $encoded = trim(str_replace("\n", $this->LE, $encoded)); 1179 1180 return $encoded; 1181 } 1182 1183 /** 1184 * Encode string to quoted-printable. 1185 * @access private 1186 * @return string 1187 */ 1188 function EncodeQP ($str) { 1189 $encoded = $this->FixEOL($str); 1190 if (substr($encoded, -(strlen($this->LE))) != $this->LE) 1191 $encoded .= $this->LE; 1192 1193 // Replace every high ascii, control and = characters 1194 $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e', 1195 "'='.sprintf('%02X', ord('\\1'))", $encoded); 1196 // Replace every spaces and tabs when it's the last character on a line 1197 $encoded = preg_replace("/([\011\040])".$this->LE."/e", 1198 "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded); 1199 1200 // Maximum line length of 76 characters before CRLF (74 + space + '=') 1201 $encoded = $this->WrapText($encoded, 74, true); 1202 1203 return $encoded; 1204 } 1205 1206 /** 1207 * Encode string to q encoding. 1208 * @access private 1209 * @return string 1210 */ 1211 function EncodeQ ($str, $position = "text") { 1212 // There should not be any EOL in the string 1213 $encoded = preg_replace("[\r\n]", "", $str); 1214 1215 switch (strtolower($position)) { 1216 case "phrase": 1217 $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 1218 break; 1219 case "comment": 1220 $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 1221 case "text": 1222 default: 1223 // Replace every high ascii, control =, ? and _ characters 1224 $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', 1225 "'='.sprintf('%02X', ord('\\1'))", $encoded); 1226 break; 1291 } 1292 } else { 1293 $encoding = 'Q'; 1294 $encoded = $this->EncodeQ($str, $position); 1295 $encoded = $this->WrapText($encoded, $maxlen, true); 1296 $encoded = str_replace('='.$this->LE, "\n", trim($encoded)); 1297 } 1298 1299 $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded); 1300 $encoded = trim(str_replace("\n", $this->LE, $encoded)); 1301 1302 return $encoded; 1303 } 1304 1305 /** 1306 * Checks if a string contains multibyte characters. 1307 * @access private 1308 * @param string $str multi-byte text to wrap encode 1309 * @return bool 1310 */ 1311 function HasMultiBytes($str) { 1312 if (function_exists('mb_strlen')) { 1313 return (strlen($str) > mb_strlen($str, $this->CharSet)); 1314 } else { // Assume no multibytes (we can't handle without mbstring functions anyway) 1315 return False; 1316 } 1317 } 1318 1319 /** 1320 * Correctly encodes and wraps long multibyte strings for mail headers 1321 * without breaking lines within a character. 1322 * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php 1323 * @access private 1324 * @param string $str multi-byte text to wrap encode 1325 * @return string 1326 */ 1327 function Base64EncodeWrapMB($str) { 1328 $start = "=?".$this->CharSet."?B?"; 1329 $end = "?="; 1330 $encoded = ""; 1331 1332 $mb_length = mb_strlen($str, $this->CharSet); 1333 // Each line must have length <= 75, including $start and $end 1334 $length = 75 - strlen($start) - strlen($end); 1335 // Average multi-byte ratio 1336 $ratio = $mb_length / strlen($str); 1337 // Base64 has a 4:3 ratio 1338 $offset = $avgLength = floor($length * $ratio * .75); 1339 1340 for ($i = 0; $i < $mb_length; $i += $offset) { 1341 $lookBack = 0; 1342 1343 do { 1344 $offset = $avgLength - $lookBack; 1345 $chunk = mb_substr($str, $i, $offset, $this->CharSet); 1346 $chunk = base64_encode($chunk); 1347 $lookBack++; 1348 } 1349 while (strlen($chunk) > $length); 1350 1351 $encoded .= $chunk . $this->LE; 1352 } 1353 1354 // Chomp the last linefeed 1355 $encoded = substr($encoded, 0, -strlen($this->LE)); 1356 return $encoded; 1357 } 1358 1359 /** 1360 * Encode string to quoted-printable. 1361 * @access private 1362 * @return string 1363 */ 1364 function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) { 1365 $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); 1366 $lines = preg_split('/(?:\r\n|\r|\n)/', $input); 1367 $eol = "\r\n"; 1368 $escape = '='; 1369 $output = ''; 1370 while( list(, $line) = each($lines) ) { 1371 $linlen = strlen($line); 1372 $newline = ''; 1373 for($i = 0; $i < $linlen; $i++) { 1374 $c = substr( $line, $i, 1 ); 1375 $dec = ord( $c ); 1376 if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E 1377 $c = '=2E'; 1227 1378 } 1228 1229 // Replace every spaces to _ (more readable than =20) 1230 $encoded = str_replace(" ", "_", $encoded); 1231 1232 return $encoded; 1233 } 1234 1235 /** 1236 * Adds a string or binary attachment (non-filesystem) to the list. 1237 * This method can be used to attach ascii or binary data, 1238 * such as a BLOB record from a database. 1239 * @param string $string String attachment data. 1240 * @param string $filename Name of the attachment. 1241 * @param string $encoding File encoding (see $Encoding). 1242 * @param string $type File extension (MIME) type. 1243 * @return void 1244 */ 1245 function AddStringAttachment($string, $filename, $encoding = "base64", 1246 $type = "application/octet-stream") { 1247 // Append to $attachment array 1248 $cur = count($this->attachment); 1249 $this->attachment[$cur][0] = $string; 1250 $this->attachment[$cur][1] = $filename; 1251 $this->attachment[$cur][2] = $filename; 1252 $this->attachment[$cur][3] = $encoding; 1253 $this->attachment[$cur][4] = $type; 1254 $this->attachment[$cur][5] = true; // isString 1255 $this->attachment[$cur][6] = "attachment"; 1256 $this->attachment[$cur][7] = 0; 1257 } 1258 1259 /** 1260 * Adds an embedded attachment. This can include images, sounds, and 1261 * just about any other document. Make sure to set the $type to an 1262 * image type. For JPEG images use "image/jpeg" and for GIF images 1263 * use "image/gif". 1264 * @param string $path Path to the attachment. 1265 * @param string $cid Content ID of the attachment. Use this to identify 1266 * the Id for accessing the image in an HTML form. 1267 * @param string $name Overrides the attachment name. 1268 * @param string $encoding File encoding (see $Encoding). 1269 * @param string $type File extension (MIME) type. 1270 * @return bool 1271 */ 1272 function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", 1273 $type = "application/octet-stream") { 1274 1275 if(!@is_file($path)) 1276 { 1277 $this->SetError($this->Lang("file_access") . $path); 1278 return false; 1379 if ( $dec == 32 ) { 1380 if ( $i == ( $linlen - 1 ) ) { // convert space at eol only 1381 $c = '=20'; 1382 } else if ( $space_conv ) { 1383 $c = '=20'; 1384 } 1385 } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required 1386 $h2 = floor($dec/16); 1387 $h1 = floor($dec%16); 1388 $c = $escape.$hex[$h2].$hex[$h1]; 1279 1389 } 1280 1281 $filename = basename($path); 1282 if($name == "") 1283 $name = $filename; 1284 1285 // Append to $attachment array 1286 $cur = count($this->attachment); 1287 $this->attachment[$cur][0] = $path; 1288 $this->attachment[$cur][1] = $filename; 1289 $this->attachment[$cur][2] = $name; 1290 $this->attachment[$cur][3] = $encoding; 1291 $this->attachment[$cur][4] = $type; 1292 $this->attachment[$cur][5] = false; // isStringAttachment 1293 $this->attachment[$cur][6] = "inline"; 1294 $this->attachment[$cur][7] = $cid; 1295 1296 return true; 1297 } 1298 1299 /** 1300 * Returns true if an inline attachment is present. 1301 * @access private 1302 * @return bool 1303 */ 1304 function InlineImageExists() { 1305 $result = false; 1306 for($i = 0; $i < count($this->attachment); $i++) 1307 { 1308 if($this->attachment[$i][6] == "inline") 1309 { 1310 $result = true; 1311 break; 1312 } 1390 if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted 1391 $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay 1392 $newline = ''; 1393 // check if newline first character will be point or not 1394 if ( $dec == 46 ) { 1395 $c = '=2E'; 1396 } 1313 1397 } 1314 1315 return $result; 1316 } 1317 1318 ///////////////////////////////////////////////// 1319 // MESSAGE RESET METHODS 1320 ///////////////////////////////////////////////// 1321 1322 /** 1323 * Clears all recipients assigned in the TO array. Returns void. 1324 * @return void 1325 */ 1326 function ClearAddresses() { 1327 $this->to = array(); 1328 } 1329 1330 /** 1331 * Clears all recipients assigned in the CC array. Returns void. 1332 * @return void 1333 */ 1334 function ClearCCs() { 1335 $this->cc = array(); 1336 } 1337 1338 /** 1339 * Clears all recipients assigned in the BCC array. Returns void. 1340 * @return void 1341 */ 1342 function ClearBCCs() { 1343 $this->bcc = array(); 1344 } 1345 1346 /** 1347 * Clears all recipients assigned in the ReplyTo array. Returns void. 1348 * @return void 1349 */ 1350 function ClearReplyTos() { 1351 $this->ReplyTo = array(); 1352 } 1353 1354 /** 1355 * Clears all recipients assigned in the TO, CC and BCC 1356 * array. Returns void. 1357 * @return void 1358 */ 1359 function ClearAllRecipients() { 1360 $this->to = array(); 1361 $this->cc = array(); 1362 $this->bcc = array(); 1363 } 1364 1365 /** 1366 * Clears all previously set filesystem, string, and binary 1367 * attachments. Returns void. 1368 * @return void 1369 */ 1370 function ClearAttachments() { 1371 $this->attachment = array(); 1372 } 1373 1374 /** 1375 * Clears all custom headers. Returns void. 1376 * @return void 1377 */ 1378 function ClearCustomHeaders() { 1379 $this->CustomHeader = array(); 1380 } 1381 1382 1383 ///////////////////////////////////////////////// 1384 // MISCELLANEOUS METHODS 1385 ///////////////////////////////////////////////// 1386 1387 /** 1388 * Adds the error message to the error container. 1389 * Returns void. 1390 * @access private 1391 * @return void 1392 */ 1393 function SetError($msg) { 1394 $this->error_count++; 1395 $this->ErrorInfo = $msg; 1396 } 1397 1398 /** 1399 * Returns the proper RFC 822 formatted date. 1400 * @access private 1401 * @return string 1402 */ 1403 function RFCDate() { 1404 $tz = date("Z"); 1405 $tzs = ($tz < 0) ? "-" : "+"; 1406 $tz = abs($tz); 1407 $tz = ($tz/3600)*100 + ($tz%3600)/60; 1408 $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz); 1409 1410 return $result; 1411 } 1412 1413 /** 1414 * Returns the appropriate server variable. Should work with both 1415 * PHP 4.1.0+ as well as older versions. Returns an empty string 1416 * if nothing is found. 1417 * @access private 1418 * @return mixed 1419 */ 1420 function ServerVar($varName) { 1421 global $HTTP_SERVER_VARS; 1422 global $HTTP_ENV_VARS; 1423 1424 if(!isset($_SERVER)) 1425 { 1426 $_SERVER = $HTTP_SERVER_VARS; 1427 if(!isset($_SERVER["REMOTE_ADDR"])) 1428 $_SERVER = $HTTP_ENV_VARS; // must be Apache 1398 $newline .= $c; 1399 } // end of for 1400 $output .= $newline.$eol; 1401 } // end of while 1402 return trim($output); 1403 } 1404 1405 /** 1406 * Encode string to q encoding. 1407 * @access private 1408 * @return string 1409 */ 1410 function EncodeQ ($str, $position = 'text') { 1411 /* There should not be any EOL in the string */ 1412 $encoded = preg_replace("[\r\n]", '', $str); 1413 1414 switch (strtolower($position)) { 1415 case 'phrase': 1416 $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 1417 break; 1418 case 'comment': 1419 $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); 1420 case 'text': 1421 default: 1422 /* Replace every high ascii, control =, ? and _ characters */ 1423 $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', 1424 "'='.sprintf('%02X', ord('\\1'))", $encoded); 1425 break; 1426 } 1427 1428 /* Replace every spaces to _ (more readable than =20) */ 1429 $encoded = str_replace(' ', '_', $encoded); 1430 1431 return $encoded; 1432 } 1433 1434 /** 1435 * Adds a string or binary attachment (non-filesystem) to the list. 1436 * This method can be used to attach ascii or binary data, 1437 * such as a BLOB record from a database. 1438 * @param string $string String attachment data. 1439 * @param string $filename Name of the attachment. 1440 * @param string $encoding File encoding (see $Encoding). 1441 * @param string $type File extension (MIME) type. 1442 * @return void 1443 */ 1444 function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') { 1445 /* Append to $attachment array */ 1446 $cur = count($this->attachment); 1447 $this->attachment[$cur][0] = $string; 1448 $this->attachment[$cur][1] = $filename; 1449 $this->attachment[$cur][2] = $filename; 1450 $this->attachment[$cur][3] = $encoding; 1451 $this->attachment[$cur][4] = $type; 1452 $this->attachment[$cur][5] = true; // isString 1453 $this->attachment[$cur][6] = 'attachment'; 1454 $this->attachment[$cur][7] = 0; 1455 } 1456 1457 /** 1458 * Adds an embedded attachment. This can include images, sounds, and 1459 * just about any other document. Make sure to set the $type to an 1460 * image type. For JPEG images use "image/jpeg" and for GIF images 1461 * use "image/gif". 1462 * @param string $path Path to the attachment. 1463 * @param string $cid Content ID of the attachment. Use this to identify 1464 * the Id for accessing the image in an HTML form. 1465 * @param string $name Overrides the attachment name. 1466 * @param string $encoding File encoding (see $Encoding). 1467 * @param string $type File extension (MIME) type. 1468 * @return bool 1469 */ 1470 function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { 1471 1472 if(!@is_file($path)) { 1473 $this->SetError($this->Lang('file_access') . $path); 1474 return false; 1475 } 1476 1477 $filename = basename($path); 1478 if($name == '') { 1479 $name = $filename; 1480 } 1481 1482 /* Append to $attachment array */ 1483 $cur = count($this->attachment); 1484 $this->attachment[$cur][0] = $path; 1485 $this->attachment[$cur][1] = $filename; 1486 $this->attachment[$cur][2] = $name; 1487 $this->attachment[$cur][3] = $encoding; 1488 $this->attachment[$cur][4] = $type; 1489 $this->attachment[$cur][5] = false; 1490 $this->attachment[$cur][6] = 'inline'; 1491 $this->attachment[$cur][7] = $cid; 1492 1493 return true; 1494 } 1495 1496 /** 1497 * Returns true if an inline attachment is present. 1498 * @access private 1499 * @return bool 1500 */ 1501 function InlineImageExists() { 1502 $result = false; 1503 for($i = 0; $i < count($this->attachment); $i++) { 1504 if($this->attachment[$i][6] == 'inline') { 1505 $result = true; 1506 break; 1507 } 1508 } 1509 1510 return $result; 1511 } 1512 1513 ///////////////////////////////////////////////// 1514 // CLASS METHODS, MESSAGE RESET 1515 ///////////////////////////////////////////////// 1516 1517 /** 1518 * Clears all recipients assigned in the TO array. Returns void. 1519 * @return void 1520 */ 1521 function ClearAddresses() { 1522 $this->to = array(); 1523 } 1524 1525 /** 1526 * Clears all recipients assigned in the CC array. Returns void. 1527 * @return void 1528 */ 1529 function ClearCCs() { 1530 $this->cc = array(); 1531 } 1532 1533 /** 1534 * Clears all recipients assigned in the BCC array. Returns void. 1535 * @return void 1536 */ 1537 function ClearBCCs() { 1538 $this->bcc = array(); 1539 } 1540 1541 /** 1542 * Clears all recipients assigned in the ReplyTo array. Returns void. 1543 * @return void 1544 */ 1545 function ClearReplyTos() { 1546 $this->ReplyTo = array(); 1547 } 1548 1549 /** 1550 * Clears all recipients assigned in the TO, CC and BCC 1551 * array. Returns void. 1552 * @return void 1553 */ 1554 function ClearAllRecipients() { 1555 $this->to = array(); 1556 $this->cc = array(); 1557 $this->bcc = array(); 1558 } 1559 1560 /** 1561 * Clears all previously set filesystem, string, and binary 1562 * attachments. Returns void. 1563 * @return void 1564 */ 1565 function ClearAttachments() { 1566 $this->attachment = array(); 1567 } 1568 1569 /** 1570 * Clears all custom headers. Returns void. 1571 * @return void 1572 */ 1573 function ClearCustomHeaders() { 1574 $this->CustomHeader = array(); 1575 } 1576 1577 ///////////////////////////////////////////////// 1578 // CLASS METHODS, MISCELLANEOUS 1579 ///////////////////////////////////////////////// 1580 1581 /** 1582 * Adds the error message to the error container. 1583 * Returns void. 1584 * @access private 1585 * @return void 1586 */ 1587 function SetError($msg) { 1588 $this->error_count++; 1589 $this->ErrorInfo = $msg; 1590 } 1591 1592 /** 1593 * Returns the proper RFC 822 formatted date. 1594 * @access private 1595 * @return string 1596 */ 1597 function RFCDate() { 1598 $tz = date('Z'); 1599 $tzs = ($tz < 0) ? '-' : '+'; 1600 $tz = abs($tz); 1601 $tz = (int)($tz/3600)*100 + ($tz%3600)/60; 1602 $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz); 1603 1604 return $result; 1605 } 1606 1607 /** 1608 * Returns the appropriate server variable. Should work with both 1609 * PHP 4.1.0+ as well as older versions. Returns an empty string 1610 * if nothing is found. 1611 * @access private 1612 * @return mixed 1613 */ 1614 function ServerVar($varName) { 1615 global $HTTP_SERVER_VARS; 1616 global $HTTP_ENV_VARS; 1617 1618 if(!isset($_SERVER)) { 1619 $_SERVER = $HTTP_SERVER_VARS; 1620 if(!isset($_SERVER['REMOTE_ADDR'])) { 1621 $_SERVER = $HTTP_ENV_VARS; // must be Apache 1622 } 1623 } 1624 1625 if(isset($_SERVER[$varName])) { 1626 return $_SERVER[$varName]; 1627 } else { 1628 return ''; 1629 } 1630 } 1631 1632 /** 1633 * Returns the server hostname or 'localhost.localdomain' if unknown. 1634 * @access private 1635 * @return string 1636 */ 1637 function ServerHostname() { 1638 if ($this->Hostname != '') { 1639 $result = $this->Hostname; 1640 } elseif ($this->ServerVar('SERVER_NAME') != '') { 1641 $result = $this->ServerVar('SERVER_NAME'); 1642 } else { 1643 $result = 'localhost.localdomain'; 1644 } 1645 1646 return $result; 1647 } 1648 1649 /** 1650 * Returns a message in the appropriate language. 1651 * @access private 1652 * @return string 1653 */ 1654 function Lang($key) { 1655 if(count($this->language) < 1) { 1656 $this->SetLanguage('en'); // set the default language 1657 } 1658 1659 if(isset($this->language[$key])) { 1660 return $this->language[$key]; 1661 } else { 1662 return 'Language string failed to load: ' . $key; 1663 } 1664 } 1665 1666 /** 1667 * Returns true if an error occurred. 1668 * @return bool 1669 */ 1670 function IsError() { 1671 return ($this->error_count > 0); 1672 } 1673 1674 /** 1675 * Changes every end of line from CR or LF to CRLF. 1676 * @access private 1677 * @return string 1678 */ 1679 function FixEOL($str) { 1680 $str = str_replace("\r\n", "\n", $str); 1681 $str = str_replace("\r", "\n", $str); 1682 $str = str_replace("\n", $this->LE, $str); 1683 return $str; 1684 } 1685 1686 /** 1687 * Adds a custom header. 1688 * @return void 1689 */ 1690 function AddCustomHeader($custom_header) { 1691 $this->CustomHeader[] = explode(':', $custom_header, 2); 1692 } 1693 1694 /** 1695 * Evaluates the message and returns modifications for inline images and backgrounds 1696 * @access public 1697 * @return $message 1698 */ 1699 function MsgHTML($message,$basedir='') { 1700 preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images); 1701 if(isset($images[2])) { 1702 foreach($images[2] as $i => $url) { 1703 // do not change urls for absolute images (thanks to corvuscorax) 1704 if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) { 1705 $filename = basename($url); 1706 $directory = dirname($url); 1707 ($directory == '.')?$directory='':''; 1708 $cid = 'cid:' . md5($filename); 1709 $fileParts = split("\.", $filename); 1710 $ext = $fileParts[1]; 1711 $mimeType = $this->_mime_types($ext); 1712 if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; } 1713 if ( strlen($directory) > 1 && substr($basedir,-1) != '/') { $directory .= '/'; } 1714 $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType); 1715 if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) { 1716 $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message); 1717 } 1429 1718 } 1430 1431 if(isset($_SERVER[$varName])) 1432 return $_SERVER[$varName]; 1433 else 1434 return ""; 1435 } 1436 1437 /** 1438 * Returns the server hostname or 'localhost.localdomain' if unknown. 1439 * @access private 1440 * @return string 1441 */ 1442 function ServerHostname() { 1443 if ($this->Hostname != "") 1444 $result = $this->Hostname; 1445 elseif ($this->ServerVar('SERVER_NAME') != "") 1446 $result = $this->ServerVar('SERVER_NAME'); 1447 else 1448 $result = "localhost.localdomain"; 1449 1450 return $result; 1451 } 1452 1453 /** 1454 * Returns a message in the appropriate language. 1455 * @access private 1456 * @return string 1457 */ 1458 function Lang($key) { 1459 if(count($this->language) < 1) 1460 $this->SetLanguage("en"); // set the default language 1461 1462 if(isset($this->language[$key])) 1463 return $this->language[$key]; 1464 else 1465 return "Language string failed to load: " . $key; 1466 } 1467 1468 /** 1469 * Returns true if an error occurred. 1470 * @return bool 1471 */ 1472 function IsError() { 1473 return ($this->error_count > 0); 1474 } 1475 1476 /** 1477 * Changes every end of line from CR or LF to CRLF. 1478 * @access private 1479 * @return string 1480 */ 1481 function FixEOL($str) { 1482 $str = str_replace("\r\n", "\n", $str); 1483 $str = str_replace("\r", "\n", $str); 1484 $str = str_replace("\n", $this->LE, $str); 1485 return $str; 1486 } 1487 1488 /** 1489 * Adds a custom header. 1490 * @return void 1491 */ 1492 function AddCustomHeader($custom_header) { 1493 $this->CustomHeader[] = explode(":", $custom_header, 2); 1494 } 1719 } 1720 } 1721 $this->IsHTML(true); 1722 $this->Body = $message; 1723 $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message))); 1724 if ( !empty($textMsg) && empty($this->AltBody) ) { 1725 $this->AltBody = $textMsg; 1726 } 1727 if ( empty($this->AltBody) ) { 1728 $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n"; 1729 } 1730 } 1731 1732 /** 1733 * Gets the mime type of the embedded or inline image 1734 * @access private 1735 * @return mime type of ext 1736 */ 1737 function _mime_types($ext = '') { 1738 $mimes = array( 1739 'hqx' => 'application/mac-binhex40', 1740 'cpt' => 'application/mac-compactpro', 1741 'doc' => 'application/msword', 1742 'bin' => 'application/macbinary', 1743 'dms' => 'application/octet-stream', 1744 'lha' => 'application/octet-stream', 1745 'lzh' => 'application/octet-stream', 1746 'exe' => 'application/octet-stream', 1747 'class' => 'application/octet-stream', 1748 'psd' => 'application/octet-stream', 1749 'so' => 'application/octet-stream', 1750 'sea' => 'application/octet-stream', 1751 'dll' => 'application/octet-stream', 1752 'oda' => 'application/oda', 1753 'pdf' => 'application/pdf', 1754 'ai' => 'application/postscript', 1755 'eps' => 'application/postscript', 1756 'ps' => 'application/postscript', 1757 'smi' => 'application/smil', 1758 'smil' => 'application/smil', 1759 'mif' => 'application/vnd.mif', 1760 'xls' => 'application/vnd.ms-excel', 1761 'ppt' => 'application/vnd.ms-powerpoint', 1762 'wbxml' => 'application/vnd.wap.wbxml', 1763 'wmlc' => 'application/vnd.wap.wmlc', 1764 'dcr' => 'application/x-director', 1765 'dir' => 'application/x-director', 1766 'dxr' => 'application/x-director', 1767 'dvi' => 'application/x-dvi', 1768 'gtar' => 'application/x-gtar', 1769 'php' => 'application/x-httpd-php', 1770 'php4' => 'application/x-httpd-php', 1771 'php3' => 'application/x-httpd-php', 1772 'phtml' => 'application/x-httpd-php', 1773 'phps' => 'application/x-httpd-php-source', 1774 'js' => 'application/x-javascript', 1775 'swf' => 'application/x-shockwave-flash', 1776 'sit' => 'application/x-stuffit', 1777 'tar' => 'application/x-tar', 1778 'tgz' => 'application/x-tar', 1779 'xhtml' => 'application/xhtml+xml', 1780 'xht' => 'application/xhtml+xml', 1781 'zip' => 'application/zip', 1782 'mid' => 'audio/midi', 1783 'midi' => 'audio/midi', 1784 'mpga' => 'audio/mpeg', 1785 'mp2' => 'audio/mpeg', 1786 'mp3' => 'audio/mpeg', 1787 'aif' => 'audio/x-aiff', 1788 'aiff' => 'audio/x-aiff', 1789 'aifc' => 'audio/x-aiff', 1790 'ram' => 'audio/x-pn-realaudio', 1791 'rm' => 'audio/x-pn-realaudio', 1792 'rpm' => 'audio/x-pn-realaudio-plugin', 1793 'ra' => 'audio/x-realaudio', 1794 'rv' => 'video/vnd.rn-realvideo', 1795 'wav' => 'audio/x-wav', 1796 'bmp' => 'image/bmp', 1797 'gif' => 'image/gif', 1798 'jpeg' => 'image/jpeg', 1799 'jpg' => 'image/jpeg', 1800 'jpe' => 'image/jpeg', 1801 'png' => 'image/png', 1802 'tiff' => 'image/tiff', 1803 'tif' => 'image/tiff', 1804 'css' => 'text/css', 1805 'html' => 'text/html', 1806 'htm' => 'text/html', 1807 'shtml' => 'text/html', 1808 'txt' => 'text/plain', 1809 'text' => 'text/plain', 1810 'log' => 'text/plain', 1811 'rtx' => 'text/richtext', 1812 'rtf' => 'text/rtf', 1813 'xml' => 'text/xml', 1814 'xsl' => 'text/xml', 1815 'mpeg' => 'video/mpeg', 1816 'mpg' => 'video/mpeg', 1817 'mpe' => 'video/mpeg', 1818 'qt' => 'video/quicktime', 1819 'mov' => 'video/quicktime', 1820 'avi' => 'video/x-msvideo', 1821 'movie' => 'video/x-sgi-movie', 1822 'doc' => 'application/msword', 1823 'word' => 'application/msword', 1824 'xl' => 'application/excel', 1825 'eml' => 'message/rfc822' 1826 ); 1827 return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)]; 1828 } 1829 1830 /** 1831 * Set (or reset) Class Objects (variables) 1832 * 1833 * Usage Example: 1834 * $page->set('X-Priority', '3'); 1835 * 1836 * @access public 1837 * @param string $name Parameter Name 1838 * @param mixed $value Parameter Value 1839 * NOTE: will not work with arrays, there are no arrays to set/reset 1840 */ 1841 function set ( $name, $value = '' ) { 1842 if ( isset($this->$name) ) { 1843 $this->$name = $value; 1844 } else { 1845 $this->SetError('Cannot set or reset variable ' . $name); 1846 return false; 1847 } 1848 } 1849 1850 /** 1851 * Read a file from a supplied filename and return it. 1852 * 1853 * @access public 1854 * @param string $filename Parameter File Name 1855 */ 1856 function getFile($filename) { 1857 $return = ''; 1858 if ($fp = fopen($filename, 'rb')) { 1859 while (!feof($fp)) { 1860 $return .= fread($fp, 1024); 1861 } 1862 fclose($fp); 1863 return $return; 1864 } else { 1865 return false; 1866 } 1867 } 1868 1869 /** 1870 * Strips newlines to prevent header injection. 1871 * @access private 1872 * @param string $str String 1873 * @return string 1874 */ 1875 function SecureHeader($str) { 1876 $str = trim($str); 1877 $str = str_replace("\r", "", $str); 1878 $str = str_replace("\n", "", $str); 1879 return $str; 1880 } 1881 1882 /** 1883 * Set the private key file and password to sign the message. 1884 * 1885 * @access public 1886 * @param string $key_filename Parameter File Name 1887 * @param string $key_pass Password for private key 1888 */ 1889 function Sign($key_filename, $key_pass) { 1890 $this->sign_key_file = $key_filename; 1891 $this->sign_key_pass = $key_pass; 1892 } 1893 1495 1894 } 1496 1895
Note: See TracChangeset
for help on using the changeset viewer.