~titan-phpdevshell/phpdevshell/main

« back to all changes in this revision

Viewing changes to includes/legacy/phpmailer/class.phpmailer.php

  • Committer: Jason Schoeman
  • Date: 2011-12-06 14:03:32 UTC
  • Revision ID: titan@phpdevshell.org-20111206140332-4ej6qy4b36d3q96s
Crud Added
ORM Added
Control Panel optimized

Show diffs side-by-side

added added

removed removed

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