PHPMailer::AddStringAttachment()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 4
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/*~ class.phpmailer.php
3
.---------------------------------------------------------------------------.
4
|  Software: PHPMailer - PHP email class                                    |
5
|   Version: 2.0.4                                                          |
6
|   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |
7
|      Info: http://phpmailer.sourceforge.net                               |
8
|   Support: http://sourceforge.net/projects/phpmailer/                     |
9
| ------------------------------------------------------------------------- |
10
|    Author: Andy Prevost (project admininistrator)                         |
11
|    Author: Brent R. Matzelle (original founder)                           |
12
| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |
13
| Copyright (c) 2001-2003, Brent R. Matzelle                                |
14
| ------------------------------------------------------------------------- |
15
|   License: Distributed under the Lesser General Public License (LGPL)     |
16
|            http://www.gnu.org/copyleft/lesser.html                        |
17
| This program is distributed in the hope that it will be useful - WITHOUT  |
18
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
19
| FITNESS FOR A PARTICULAR PURPOSE.                                         |
20
| ------------------------------------------------------------------------- |
21
| We offer a number of paid services (www.codeworxtech.com):                |
22
| - Web Hosting on highly optimized fast and secure servers                 |
23
| - Technology Consulting                                                   |
24
| - Oursourcing (highly qualified programmers and graphic designers)        |
25
'---------------------------------------------------------------------------'
26
27
/**
28
 * PHPMailer - PHP email transport class
29
 * @package PHPMailer
30
 * @author Andy Prevost
31
 * @copyright 2004 - 2009 Andy Prevost
32
 */
33
34
class PHPMailer {
35
36
  /////////////////////////////////////////////////
37
  // PROPERTIES, PUBLIC
38
  /////////////////////////////////////////////////
39
40
  /**
41
   * Email priority (1 = High, 3 = Normal, 5 = low).
42
   * @var int
43
   */
44
  var $Priority          = 3;
45
46
  /**
47
   * Sets the CharSet of the message.
48
   * @var string
49
   */
50
  var $CharSet           = 'iso-8859-1';
51
52
  /**
53
   * Sets the Content-type of the message.
54
   * @var string
55
   */
56
  var $ContentType        = 'text/plain';
57
58
  /**
59
   * Sets the Encoding of the message. Options for this are "8bit",
60
   * "7bit", "binary", "base64", and "quoted-printable".
61
   * @var string
62
   */
63
  var $Encoding          = '8bit';
64
65
  /**
66
   * Holds the most recent mailer error message.
67
   * @var string
68
   */
69
  var $ErrorInfo         = '';
70
71
  /**
72
   * Sets the From email address for the message.
73
   * @var string
74
   */
75
  var $From              = 'root@localhost';
76
77
  /**
78
   * Sets the From name of the message.
79
   * @var string
80
   */
81
  var $FromName          = 'Root User';
82
83
  /**
84
   * Sets the Sender email (Return-Path) of the message.  If not empty,
85
   * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
86
   * @var string
87
   */
88
  var $Sender            = '';
89
90
  /**
91
   * Sets the Subject of the message.
92
   * @var string
93
   */
94
  var $Subject           = '';
95
96
  /**
97
   * Sets the Body of the message.  This can be either an HTML or text body.
98
   * If HTML then run IsHTML(true).
99
   * @var string
100
   */
101
  var $Body              = '';
102
103
  /**
104
   * Sets the text-only body of the message.  This automatically sets the
105
   * email to multipart/alternative.  This body can be read by mail
106
   * clients that do not have HTML email capability such as mutt. Clients
107
   * that can read HTML will view the normal Body.
108
   * @var string
109
   */
110
  var $AltBody           = '';
111
112
  /**
113
   * Sets word wrapping on the body of the message to a given number of
114
   * characters.
115
   * @var int
116
   */
117
  var $WordWrap          = 0;
118
119
  /**
120
   * Method to send mail: ("mail", "sendmail", or "smtp").
121
   * @var string
122
   */
123
  var $Mailer            = 'mail';
124
125
  /**
126
   * Sets the path of the sendmail program.
127
   * @var string
128
   */
129
  var $Sendmail          = '/usr/sbin/sendmail';
130
131
  /**
132
   * Path to PHPMailer plugins.  This is now only useful if the SMTP class
133
   * is in a different directory than the PHP include path.
134
   * @var string
135
   */
136
  var $PluginDir         = '';
137
138
  /**
139
   * Holds PHPMailer version.
140
   * @var string
141
   */
142
  var $Version           = "2.0.4";
143
144
  /**
145
   * Sets the email address that a reading confirmation will be sent.
146
   * @var string
147
   */
148
  var $ConfirmReadingTo  = '';
149
150
  /**
151
   * Sets the hostname to use in Message-Id and Received headers
152
   * and as default HELO string. If empty, the value returned
153
   * by SERVER_NAME is used or 'localhost.localdomain'.
154
   * @var string
155
   */
156
  var $Hostname          = '';
157
158
  /**
159
   * Sets the message ID to be used in the Message-Id header.
160
   * If empty, a unique id will be generated.
161
   * @var string
162
   */
163
  var $MessageID         = '';
164
165
  /////////////////////////////////////////////////
166
  // PROPERTIES FOR SMTP
167
  /////////////////////////////////////////////////
168
169
  /**
170
   * Sets the SMTP hosts.  All hosts must be separated by a
171
   * semicolon.  You can also specify a different port
172
   * for each host by using this format: [hostname:port]
173
   * (e.g. "smtp1.example.com:25;smtp2.example.com").
174
   * Hosts will be tried in order.
175
   * @var string
176
   */
177
  var $Host        = 'localhost';
178
179
  /**
180
   * Sets the default SMTP server port.
181
   * @var int
182
   */
183
  var $Port        = 25;
184
185
  /**
186
   * Sets the SMTP HELO of the message (Default is $Hostname).
187
   * @var string
188
   */
189
  var $Helo        = '';
190
191
  /**
192
   * Sets connection prefix.
193
   * Options are "", "ssl" or "tls"
194
   * @var string
195
   */
196
  var $SMTPSecure = "";
197
198
  /**
199
   * Sets SMTP authentication. Utilizes the Username and Password variables.
200
   * @var bool
201
   */
202
  var $SMTPAuth     = false;
203
204
  /**
205
   * Sets SMTP username.
206
   * @var string
207
   */
208
  var $Username     = '';
209
210
  /**
211
   * Sets SMTP password.
212
   * @var string
213
   */
214
  var $Password     = '';
215
216
  /**
217
   * Sets the SMTP server timeout in seconds. This function will not
218
   * work with the win32 version.
219
   * @var int
220
   */
221
  var $Timeout      = 10;
222
223
  /**
224
   * Sets SMTP class debugging on or off.
225
   * @var bool
226
   */
227
  var $SMTPDebug    = false;
228
229
  /**
230
   * Prevents the SMTP connection from being closed after each mail
231
   * sending.  If this is set to true then to close the connection
232
   * requires an explicit call to SmtpClose().
233
   * @var bool
234
   */
235
  var $SMTPKeepAlive = false;
236
237
  /**
238
   * Provides the ability to have the TO field process individual
239
   * emails, instead of sending to entire TO addresses
240
   * @var bool
241
   */
242
  var $SingleTo = false;
243
244
  /////////////////////////////////////////////////
245
  // PROPERTIES, PRIVATE
246
  /////////////////////////////////////////////////
247
248
  var $smtp            = NULL;
249
  var $to              = array();
250
  var $cc              = array();
251
  var $bcc             = array();
252
  var $ReplyTo         = array();
253
  var $attachment      = array();
254
  var $CustomHeader    = array();
255
  var $message_type    = '';
256
  var $boundary        = array();
257
  var $language        = array();
258
  var $error_count     = 0;
259
  var $LE              = "\n";
260
  var $sign_cert_file  = "";
261
  var $sign_key_file   = "";
262
  var $sign_key_pass   = "";
263
264
  /////////////////////////////////////////////////
265
  // METHODS, VARIABLES
266
  /////////////////////////////////////////////////
267
268
  /**
269
   * Sets message type to HTML.
270
   * @param bool $bool
271
   * @return void
272
   */
273
  function IsHTML($bool) {
274
    if($bool == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
275
      $this->ContentType = 'text/html';
276
    } else {
277
      $this->ContentType = 'text/plain';
278
    }
279
  }
280
281
  /**
282
   * Sets Mailer to send message using SMTP.
283
   * @return void
284
   */
285
  function IsSMTP() {
286
    $this->Mailer = 'smtp';
287
  }
288
289
  /**
290
   * Sets Mailer to send message using PHP mail() function.
291
   * @return void
292
   */
293
  function IsMail() {
294
    $this->Mailer = 'mail';
295
  }
296
297
  /**
298
   * Sets Mailer to send message using the $Sendmail program.
299
   * @return void
300
   */
301
  function IsSendmail() {
302
    $this->Mailer = 'sendmail';
303
  }
304
305
  /**
306
   * Sets Mailer to send message using the qmail MTA.
307
   * @return void
308
   */
309
  function IsQmail() {
310
    $this->Sendmail = '/var/qmail/bin/sendmail';
311
    $this->Mailer = 'sendmail';
312
  }
313
314
  /////////////////////////////////////////////////
315
  // METHODS, RECIPIENTS
316
  /////////////////////////////////////////////////
317
318
  /**
319
   * Adds a "To" address.
320
   * @param string $address
321
   * @param string $name
322
   * @return void
323
   */
324
  function AddAddress($address, $name = '') {
325
    $cur = count($this->to);
326
    $this->to[$cur][0] = trim($address);
327
    $this->to[$cur][1] = $name;
328
  }
329
330
  /**
331
   * Adds a "Cc" address. Note: this function works
332
   * with the SMTP mailer on win32, not with the "mail"
333
   * mailer.
334
   * @param string $address
335
   * @param string $name
336
   * @return void
337
   */
338
  function AddCC($address, $name = '') {
339
    $cur = count($this->cc);
340
    $this->cc[$cur][0] = trim($address);
341
    $this->cc[$cur][1] = $name;
342
  }
343
344
  /**
345
   * Adds a "Bcc" address. Note: this function works
346
   * with the SMTP mailer on win32, not with the "mail"
347
   * mailer.
348
   * @param string $address
349
   * @param string $name
350
   * @return void
351
   */
352
  function AddBCC($address, $name = '') {
353
    $cur = count($this->bcc);
354
    $this->bcc[$cur][0] = trim($address);
355
    $this->bcc[$cur][1] = $name;
356
  }
357
358
  /**
359
   * Adds a "Reply-To" address.
360
   * @param string $address
361
   * @param string $name
362
   * @return void
363
   */
364
  function AddReplyTo($address, $name = '') {
365
    $cur = count($this->ReplyTo);
366
    $this->ReplyTo[$cur][0] = trim($address);
367
    $this->ReplyTo[$cur][1] = $name;
368
  }
369
370
  /////////////////////////////////////////////////
371
  // METHODS, MAIL SENDING
372
  /////////////////////////////////////////////////
373
374
  /**
375
   * Creates message and assigns Mailer. If the message is
376
   * not sent successfully then it returns false.  Use the ErrorInfo
377
   * variable to view description of the error.
378
   * @return bool
379
   */
380
  function Send() {
381
    $header = '';
382
    $body = '';
383
    $result = true;
384
385
    if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
386
      $this->SetError($this->Lang('provide_address'));
387
      return false;
388
    }
389
390
    /* Set whether the message is multipart/alternative */
391
    if(!empty($this->AltBody)) {
392
      $this->ContentType = 'multipart/alternative';
393
    }
394
395
    $this->error_count = 0; // reset errors
396
    $this->SetMessageType();
397
    $header .= $this->CreateHeader();
398
    $body = $this->CreateBody();
399
400
    if($body == '') {
401
      return false;
402
    }
403
404
    /* Choose the mailer */
405
    switch($this->Mailer) {
406
      case 'sendmail':
407
        $result = $this->SendmailSend($header, $body);
408
        break;
409
      case 'smtp':
410
        $result = $this->SmtpSend($header, $body);
411
        break;
412
      case 'mail':
413
        $result = $this->MailSend($header, $body);
414
        break;
415
      default:
416
        $result = $this->MailSend($header, $body);
417
        break;
418
        //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported'));
419
        //$result = false;
420
        //break;
421
    }
422
423
    return $result;
424
  }
425
426
  /**
427
   * Sends mail using the $Sendmail program.
428
   * @access private
429
   * @return bool
430
   */
431
  function SendmailSend($header, $body) {
432
    if ($this->Sender != '') {
433
      $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
434
    } else {
435
      $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
436
    }
437
438
    if(!@$mail = popen($sendmail, 'w')) {
439
      $this->SetError($this->Lang('execute') . $this->Sendmail);
440
      return false;
441
    }
442
443
    fputs($mail, $header);
444
    fputs($mail, $body);
445
446
    $result = pclose($mail);
447
    if (version_compare(phpversion(), '4.2.3') == -1) {
448
      $result = $result >> 8 & 0xFF;
449
    }
450
    if($result != 0) {
451
      $this->SetError($this->Lang('execute') . $this->Sendmail);
452
      return false;
453
    }
454
    return true;
455
  }
456
457
  /**
458
   * Sends mail using the PHP mail() function.
459
   * @access private
460
   * @return bool
461
   */
462
  function MailSend($header, $body) {
463
464
    $to = '';
465
    for($i = 0; $i < count($this->to); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
466
      if($i != 0) { $to .= ', '; }
467
      $to .= $this->AddrFormat($this->to[$i]);
468
    }
469
470
    $toArr = split(',', $to);
471
472
    $params = sprintf("-oi -f %s", $this->Sender);
473
    if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) {
474
      $old_from = ini_get('sendmail_from');
475
      ini_set('sendmail_from', $this->Sender);
476 View Code Duplication
      if ($this->SingleTo === true && count($toArr) > 1) {
477
        foreach ($toArr as $key => $val) {
478
          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
479
        }
480
      } else {
481
        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
482
      }
483 View Code Duplication
    } else {
484
      if ($this->SingleTo === true && count($toArr) > 1) {
485
        foreach ($toArr as $key => $val) {
486
          $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
487
        }
488
      } else {
489
        $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
490
      }
491
    }
492
493
    if (isset($old_from)) {
494
      ini_set('sendmail_from', $old_from);
495
    }
496
497
    if(!$rt) {
0 ignored issues
show
Bug introduced by
The variable $rt does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
498
      $this->SetError($this->Lang('instantiate'));
499
      return false;
500
    }
501
502
    return true;
503
  }
504
505
  /**
506
   * Sends mail via SMTP using PhpSMTP (Author:
507
   * Chris Ryan).  Returns bool.  Returns false if there is a
508
   * bad MAIL FROM, RCPT, or DATA input.
509
   * @access private
510
   * @return bool
511
   */
512
  function SmtpSend($header, $body) {
513
    include_once($this->PluginDir . 'class.smtp.php');
514
    $error = '';
515
    $bad_rcpt = array();
516
517
    if(!$this->SmtpConnect()) {
518
      return false;
519
    }
520
521
    $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
522
    if(!$this->smtp->Mail($smtp_from)) {
523
      $error = $this->Lang('from_failed') . $smtp_from;
524
      $this->SetError($error);
525
      $this->smtp->Reset();
526
      return false;
527
    }
528
529
    /* Attempt to send attach all recipients */
530 View Code Duplication
    for($i = 0; $i < count($this->to); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
531
      if(!$this->smtp->Recipient($this->to[$i][0])) {
532
        $bad_rcpt[] = $this->to[$i][0];
533
      }
534
    }
535 View Code Duplication
    for($i = 0; $i < count($this->cc); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
536
      if(!$this->smtp->Recipient($this->cc[$i][0])) {
537
        $bad_rcpt[] = $this->cc[$i][0];
538
      }
539
    }
540 View Code Duplication
    for($i = 0; $i < count($this->bcc); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
541
      if(!$this->smtp->Recipient($this->bcc[$i][0])) {
542
        $bad_rcpt[] = $this->bcc[$i][0];
543
      }
544
    }
545
546
    if(count($bad_rcpt) > 0) { // Create error message
547
      for($i = 0; $i < count($bad_rcpt); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
548
        if($i != 0) {
549
          $error .= ', ';
550
        }
551
        $error .= $bad_rcpt[$i];
552
      }
553
      $error = $this->Lang('recipients_failed') . $error;
554
      $this->SetError($error);
555
      $this->smtp->Reset();
556
      return false;
557
    }
558
559
    if(!$this->smtp->Data($header . $body)) {
560
      $this->SetError($this->Lang('data_not_accepted'));
561
      $this->smtp->Reset();
562
      return false;
563
    }
564
    if($this->SMTPKeepAlive == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
565
      $this->smtp->Reset();
566
    } else {
567
      $this->SmtpClose();
568
    }
569
570
    return true;
571
  }
572
573
  /**
574
   * Initiates a connection to an SMTP server.  Returns false if the
575
   * operation failed.
576
   * @access private
577
   * @return bool
578
   */
579
  function SmtpConnect() {
580
    if($this->smtp == NULL) {
581
      $this->smtp = new SMTP();
582
    }
583
584
    $this->smtp->do_debug = $this->SMTPDebug;
585
    $hosts = explode(';', $this->Host);
586
    $index = 0;
587
    $connection = ($this->smtp->Connected());
588
589
    /* Retry while there is no connection */
590
    while($index < count($hosts) && $connection == false) {
591
      $hostinfo = array();
592
      if(preg_match('/^(.+):([0-9]+)$/i', $hosts[$index], $hostinfo)) {
593
        $host = $hostinfo[1];
594
        $port = $hostinfo[2];
595
      } else {
596
        $host = $hosts[$index];
597
        $port = $this->Port;
598
      }
599
600
      if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) {
601
        if ($this->Helo != '') {
602
          $this->smtp->Hello($this->Helo);
603
        } else {
604
          $this->smtp->Hello($this->ServerHostname());
605
        }
606
607
        $connection = true;
608
        if($this->SMTPAuth) {
609
          if(!$this->smtp->Authenticate($this->Username, $this->Password)) {
610
            $this->SetError($this->Lang('authenticate'));
611
            $this->smtp->Reset();
612
            $connection = false;
613
          }
614
        }
615
      }
616
      $index++;
617
    }
618
    if(!$connection) {
619
      $this->SetError($this->Lang('connect_host'));
620
    }
621
622
    return $connection;
623
  }
624
625
  /**
626
   * Closes the active SMTP session if one exists.
627
   * @return void
628
   */
629
  function SmtpClose() {
630
    if($this->smtp != NULL) {
631
      if($this->smtp->Connected()) {
632
        $this->smtp->Quit();
633
        $this->smtp->Close();
634
      }
635
    }
636
  }
637
638
  /**
639
   * Sets the language for all class error messages.  Returns false
640
   * if it cannot load the language file.  The default language type
641
   * is English.
642
   * @param string $lang_type Type of language (e.g. Portuguese: "br")
643
   * @param string $lang_path Path to the language file directory
644
   * @access public
645
   * @return bool
646
   */
647
  function SetLanguage($lang_type, $lang_path = 'language/') {
648
    if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) {
649
      include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
650
    } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) {
651
      include($lang_path.'phpmailer.lang-en.php');
652
    } else {
653
      $PHPMAILER_LANG = array();
654
      $PHPMAILER_LANG["provide_address"]      = 'You must provide at least one ' .
655
      $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
656
      $PHPMAILER_LANG["execute"]              = 'Could not execute: ';
657
      $PHPMAILER_LANG["instantiate"]          = 'Could not instantiate mail function.';
658
      $PHPMAILER_LANG["authenticate"]         = 'SMTP Error: Could not authenticate.';
659
      $PHPMAILER_LANG["from_failed"]          = 'The following From address failed: ';
660
      $PHPMAILER_LANG["recipients_failed"]    = 'SMTP Error: The following ' .
661
      $PHPMAILER_LANG["data_not_accepted"]    = 'SMTP Error: Data not accepted.';
662
      $PHPMAILER_LANG["connect_host"]         = 'SMTP Error: Could not connect to SMTP host.';
663
      $PHPMAILER_LANG["file_access"]          = 'Could not access file: ';
664
      $PHPMAILER_LANG["file_open"]            = 'File Error: Could not open file: ';
665
      $PHPMAILER_LANG["encoding"]             = 'Unknown encoding: ';
666
      $PHPMAILER_LANG["signing"]              = 'Signing Error: ';
667
    }
668
    $this->language = $PHPMAILER_LANG;
0 ignored issues
show
Bug introduced by
The variable $PHPMAILER_LANG does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
669
670
    return true;
671
  }
672
673
  /////////////////////////////////////////////////
674
  // METHODS, MESSAGE CREATION
675
  /////////////////////////////////////////////////
676
677
  /**
678
   * Creates recipient headers.
679
   * @access private
680
   * @return string
681
   */
682
  function AddrAppend($type, $addr) {
683
    $addr_str = $type . ': ';
684
    $addr_str .= $this->AddrFormat($addr[0]);
685
    if(count($addr) > 1) {
686
      for($i = 1; $i < count($addr); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
687
        $addr_str .= ', ' . $this->AddrFormat($addr[$i]);
688
      }
689
    }
690
    $addr_str .= $this->LE;
691
692
    return $addr_str;
693
  }
694
695
  /**
696
   * Formats an address correctly.
697
   * @access private
698
   * @return string
699
   */
700
  function AddrFormat($addr) {
701
    if(empty($addr[1])) {
702
      $formatted = $this->SecureHeader($addr[0]);
703
    } else {
704
      $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
705
    }
706
707
    return $formatted;
708
  }
709
710
  /**
711
   * Wraps message for use with mailers that do not
712
   * automatically perform wrapping and for quoted-printable.
713
   * Original written by philippe.
714
   * @access private
715
   * @return string
716
   */
717
  function WrapText($message, $length, $qp_mode = false) {
718
    $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
719
    // If utf-8 encoding is used, we will need to make sure we don't
720
    // split multibyte characters when we wrap
721
    $is_utf8 = (strtolower($this->CharSet) == "utf-8");
722
723
    $message = $this->FixEOL($message);
724
    if (substr($message, -1) == $this->LE) {
725
      $message = substr($message, 0, -1);
726
    }
727
728
    $line = explode($this->LE, $message);
729
    $message = '';
730
    for ($i=0 ;$i < count($line); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
731
      $line_part = explode(' ', $line[$i]);
732
      $buf = '';
733
      for ($e = 0; $e<count($line_part); $e++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
734
        $word = $line_part[$e];
735
        if ($qp_mode and (strlen($word) > $length)) {
736
          $space_left = $length - strlen($buf) - 1;
737
          if ($e != 0) {
738
            if ($space_left > 20) {
739
              $len = $space_left;
740 View Code Duplication
              if ($is_utf8) {
741
                $len = $this->UTF8CharBoundary($word, $len);
742
              } elseif (substr($word, $len - 1, 1) == "=") {
743
                $len--;
744
              } elseif (substr($word, $len - 2, 1) == "=") {
745
                $len -= 2;
746
              }
747
              $part = substr($word, 0, $len);
748
              $word = substr($word, $len);
749
              $buf .= ' ' . $part;
750
              $message .= $buf . sprintf("=%s", $this->LE);
751
            } else {
752
              $message .= $buf . $soft_break;
753
            }
754
            $buf = '';
755
          }
756
          while (strlen($word) > 0) {
757
            $len = $length;
758 View Code Duplication
            if ($is_utf8) {
759
              $len = $this->UTF8CharBoundary($word, $len);
760
            } elseif (substr($word, $len - 1, 1) == "=") {
761
              $len--;
762
            } elseif (substr($word, $len - 2, 1) == "=") {
763
              $len -= 2;
764
            }
765
            $part = substr($word, 0, $len);
766
            $word = substr($word, $len);
767
768
            if (strlen($word) > 0) {
769
              $message .= $part . sprintf("=%s", $this->LE);
770
            } else {
771
              $buf = $part;
772
            }
773
          }
774
        } else {
775
          $buf_o = $buf;
776
          $buf .= ($e == 0) ? $word : (' ' . $word);
777
778
          if (strlen($buf) > $length and $buf_o != '') {
779
            $message .= $buf_o . $soft_break;
780
            $buf = $word;
781
          }
782
        }
783
      }
784
      $message .= $buf . $this->LE;
785
    }
786
787
    return $message;
788
  }
789
790
  /**
791
   * Finds last character boundary prior to maxLength in a utf-8
792
   * quoted (printable) encoded string.
793
   * Original written by Colin Brown.
794
   * @access private
795
   * @param string $encodedText utf-8 QP text
796
   * @param int    $maxLength   find last character boundary prior to this length
797
   * @return int
798
   */
799
  function UTF8CharBoundary($encodedText, $maxLength) {
800
    $foundSplitPos = false;
801
    $lookBack = 3;
802
    while (!$foundSplitPos) {
803
      $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
804
      $encodedCharPos = strpos($lastChunk, "=");
805
      if ($encodedCharPos !== false) {
806
        // Found start of encoded character byte within $lookBack block.
807
        // Check the encoded byte value (the 2 chars after the '=')
808
        $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
809
        $dec = hexdec($hex);
810
        if ($dec < 128) { // Single byte character.
811
          // If the encoded char was found at pos 0, it will fit
812
          // otherwise reduce maxLength to start of the encoded char
813
          $maxLength = ($encodedCharPos == 0) ? $maxLength :
814
          $maxLength - ($lookBack - $encodedCharPos);
815
          $foundSplitPos = true;
816
        } elseif ($dec >= 192) { // First byte of a multi byte character
817
          // Reduce maxLength to split at start of character
818
          $maxLength = $maxLength - ($lookBack - $encodedCharPos);
819
          $foundSplitPos = true;
820
        } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
821
          $lookBack += 3;
822
        }
823
      } else {
824
        // No encoded character found
825
        $foundSplitPos = true;
826
      }
827
    }
828
    return $maxLength;
829
  }
830
831
  /**
832
   * Set the body wrapping.
833
   * @access private
834
   * @return void
835
   */
836
  function SetWordWrap() {
837
    if($this->WordWrap < 1) {
838
      return;
839
    }
840
841
    switch($this->message_type) {
842
      case 'alt':
843
        /* fall through */
844
      case 'alt_attachments':
845
        $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
846
        break;
847
      default:
848
        $this->Body = $this->WrapText($this->Body, $this->WordWrap);
849
        break;
850
    }
851
  }
852
853
  /**
854
   * Assembles message header.
855
   * @access private
856
   * @return string
857
   */
858
  function CreateHeader() {
859
    $result = '';
860
861
    /* Set the boundaries */
862
    $uniq_id = md5(uniqid(time()));
863
    $this->boundary[1] = 'b1_' . $uniq_id;
864
    $this->boundary[2] = 'b2_' . $uniq_id;
865
866
    $result .= $this->HeaderLine('Date', $this->RFCDate());
867
    if($this->Sender == '') {
868
      $result .= $this->HeaderLine('Return-Path', trim($this->From));
869
    } else {
870
      $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
871
    }
872
873
    /* To be created automatically by mail() */
874
    if($this->Mailer != 'mail') {
875
      if(count($this->to) > 0) {
876
        $result .= $this->AddrAppend('To', $this->to);
877
      } elseif (count($this->cc) == 0) {
878
        $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
879
      }
880
    }
881
882
    $from = array();
883
    $from[0][0] = trim($this->From);
884
    $from[0][1] = $this->FromName;
885
    $result .= $this->AddrAppend('From', $from);
886
887
    /* sendmail and mail() extract Cc from the header before sending */
888 View Code Duplication
    if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {
889
      $result .= $this->AddrAppend('Cc', $this->cc);
890
    }
891
892
    /* sendmail and mail() extract Bcc from the header before sending */
893 View Code Duplication
    if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
894
      $result .= $this->AddrAppend('Bcc', $this->bcc);
895
    }
896
897
    if(count($this->ReplyTo) > 0) {
898
      $result .= $this->AddrAppend('Reply-To', $this->ReplyTo);
899
    }
900
901
    /* mail() sets the subject itself */
902
    if($this->Mailer != 'mail') {
903
      $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
904
    }
905
906
    if($this->MessageID != '') {
907
      $result .= $this->HeaderLine('Message-ID',$this->MessageID);
908
    } else {
909
      $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
910
    }
911
    $result .= $this->HeaderLine('X-Priority', $this->Priority);
912
    $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']');
913
914
    if($this->ConfirmReadingTo != '') {
915
    //  $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
916
    }
917
918
    // Add custom headers
919
    for($index = 0; $index < count($this->CustomHeader); $index++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
920
      $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
921
    }
922
    if (!$this->sign_key_file) {
923
      $result .= $this->HeaderLine('MIME-Version', '1.0');
924
      $result .= $this->GetMailMIME();
925
    }
926
927
    return $result;
928
  }
929
930
  /**
931
   * Returns the message MIME.
932
   * @access private
933
   * @return string
934
   */
935
  function GetMailMIME() {
936
    $result = '';
937
    switch($this->message_type) {
938
      case 'plain':
939
        $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
940
        $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
941
        break;
942
      case 'attachments':
943
        /* fall through */
944
      case 'alt_attachments':
945
        if($this->InlineImageExists()){
946
          $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
947
        } else {
948
          $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
949
          $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
950
        }
951
        break;
952
      case 'alt':
953
        $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
954
        $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
955
        break;
956
    }
957
958
    if($this->Mailer != 'mail') {
959
      $result .= $this->LE.$this->LE;
960
    }
961
962
    return $result;
963
  }
964
965
  /**
966
   * Assembles the message body.  Returns an empty string on failure.
967
   * @access private
968
   * @return string
969
   */
970
  function CreateBody() {
971
    $result = '';
972
    if ($this->sign_key_file) {
973
      $result .= $this->GetMailMIME();
974
    }
975
976
    $this->SetWordWrap();
977
978
    switch($this->message_type) {
979
      case 'alt':
980
        $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
981
        $result .= $this->EncodeString($this->AltBody, $this->Encoding);
982
        $result .= $this->LE.$this->LE;
983
        $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
984
        $result .= $this->EncodeString($this->Body, $this->Encoding);
985
        $result .= $this->LE.$this->LE;
986
        $result .= $this->EndBoundary($this->boundary[1]);
987
        break;
988
      case 'plain':
989
        $result .= $this->EncodeString($this->Body, $this->Encoding);
990
        break;
991
      case 'attachments':
992
        $result .= $this->GetBoundary($this->boundary[1], '', '', '');
993
        $result .= $this->EncodeString($this->Body, $this->Encoding);
994
        $result .= $this->LE;
995
        $result .= $this->AttachAll();
996
        break;
997
      case 'alt_attachments':
998
        $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
999
        $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
1000
        $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
1001
        $result .= $this->EncodeString($this->AltBody, $this->Encoding);
1002
        $result .= $this->LE.$this->LE;
1003
        $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
1004
        $result .= $this->EncodeString($this->Body, $this->Encoding);
1005
        $result .= $this->LE.$this->LE;
1006
        $result .= $this->EndBoundary($this->boundary[2]);
1007
        $result .= $this->AttachAll();
1008
        break;
1009
    }
1010
1011
    if($this->IsError()) {
1012
      $result = '';
1013
    } else if ($this->sign_key_file) {
1014
      $file = tempnam("", "mail");
1015
      $fp = fopen($file, "w");
1016
      fwrite($fp, $result);
1017
      fclose($fp);
1018
      $signed = tempnam("", "signed");
1019
1020
      if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) {
1021
        $fp = fopen($signed, "r");
1022
        $result = fread($fp, filesize($this->sign_key_file));
1023
        $result = '';
1024
        while(!feof($fp)){
1025
          $result = $result . fread($fp, 1024);
1026
        }
1027
        fclose($fp);
1028
      } else {
1029
        $this->SetError($this->Lang("signing").openssl_error_string());
1030
        $result = '';
1031
      }
1032
1033
      unlink($file);
1034
      unlink($signed);
1035
    }
1036
1037
    return $result;
1038
  }
1039
1040
  /**
1041
   * Returns the start of a message boundary.
1042
   * @access private
1043
   */
1044
  function GetBoundary($boundary, $charSet, $contentType, $encoding) {
1045
    $result = '';
1046
    if($charSet == '') {
1047
      $charSet = $this->CharSet;
1048
    }
1049
    if($contentType == '') {
1050
      $contentType = $this->ContentType;
1051
    }
1052
    if($encoding == '') {
1053
      $encoding = $this->Encoding;
1054
    }
1055
    $result .= $this->TextLine('--' . $boundary);
1056
    $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
1057
    $result .= $this->LE;
1058
    $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
1059
    $result .= $this->LE;
1060
1061
    return $result;
1062
  }
1063
1064
  /**
1065
   * Returns the end of a message boundary.
1066
   * @access private
1067
   */
1068
  function EndBoundary($boundary) {
1069
    return $this->LE . '--' . $boundary . '--' . $this->LE;
1070
  }
1071
1072
  /**
1073
   * Sets the message type.
1074
   * @access private
1075
   * @return void
1076
   */
1077
  function SetMessageType() {
1078
    if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
1079
      $this->message_type = 'plain';
1080
    } else {
1081
      if(count($this->attachment) > 0) {
1082
        $this->message_type = 'attachments';
1083
      }
1084 View Code Duplication
      if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
1085
        $this->message_type = 'alt';
1086
      }
1087 View Code Duplication
      if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
1088
        $this->message_type = 'alt_attachments';
1089
      }
1090
    }
1091
  }
1092
1093
  /* Returns a formatted header line.
1094
   * @access private
1095
   * @return string
1096
   */
1097
  function HeaderLine($name, $value) {
1098
    return $name . ': ' . $value . $this->LE;
1099
  }
1100
1101
  /**
1102
   * Returns a formatted mail line.
1103
   * @access private
1104
   * @return string
1105
   */
1106
  function TextLine($value) {
1107
    return $value . $this->LE;
1108
  }
1109
1110
  /////////////////////////////////////////////////
1111
  // CLASS METHODS, ATTACHMENTS
1112
  /////////////////////////////////////////////////
1113
1114
  /**
1115
   * Adds an attachment from a path on the filesystem.
1116
   * Returns false if the file could not be found
1117
   * or accessed.
1118
   * @param string $path Path to the attachment.
1119
   * @param string $name Overrides the attachment name.
1120
   * @param string $encoding File encoding (see $Encoding).
1121
   * @param string $type File extension (MIME) type.
1122
   * @return bool
1123
   */
1124 View Code Duplication
  function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1125
    if(!@is_file($path)) {
1126
      $this->SetError($this->Lang('file_access') . $path);
1127
      return false;
1128
    }
1129
1130
    $filename = basename($path);
1131
    if($name == '') {
1132
      $name = $filename;
1133
    }
1134
1135
    $cur = count($this->attachment);
1136
    $this->attachment[$cur][0] = $path;
1137
    $this->attachment[$cur][1] = $filename;
1138
    $this->attachment[$cur][2] = $name;
1139
    $this->attachment[$cur][3] = $encoding;
1140
    $this->attachment[$cur][4] = $type;
1141
    $this->attachment[$cur][5] = false; // isStringAttachment
1142
    $this->attachment[$cur][6] = 'attachment';
1143
    $this->attachment[$cur][7] = 0;
1144
1145
    return true;
1146
  }
1147
1148
  /**
1149
   * Attaches all fs, string, and binary attachments to the message.
1150
   * Returns an empty string on failure.
1151
   * @access private
1152
   * @return string
1153
   */
1154
  function AttachAll() {
1155
    /* Return text of body */
1156
    $mime = array();
1157
1158
    /* Add all attachments */
1159
    for($i = 0; $i < count($this->attachment); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1160
      /* Check for string attachment */
1161
      $bString = $this->attachment[$i][5];
1162
      if ($bString) {
1163
        $string = $this->attachment[$i][0];
1164
      } else {
1165
        $path = $this->attachment[$i][0];
1166
      }
1167
1168
      $filename    = $this->attachment[$i][1];
1169
      $name        = $this->attachment[$i][2];
1170
      $encoding    = $this->attachment[$i][3];
1171
      $type        = $this->attachment[$i][4];
1172
      $disposition = $this->attachment[$i][6];
1173
      $cid         = $this->attachment[$i][7];
1174
1175
      $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
1176
      $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
1177
      $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
1178
1179
      if($disposition == 'inline') {
1180
        $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
1181
      }
1182
1183
      $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);
1184
1185
      /* Encode as string attachment */
1186
      if($bString) {
1187
        $mime[] = $this->EncodeString($string, $encoding);
0 ignored issues
show
Bug introduced by
The variable $string does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1188
        if($this->IsError()) {
1189
          return '';
1190
        }
1191
        $mime[] = $this->LE.$this->LE;
1192
      } else {
1193
        $mime[] = $this->EncodeFile($path, $encoding);
0 ignored issues
show
Bug introduced by
The variable $path does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1194
        if($this->IsError()) {
1195
          return '';
1196
        }
1197
        $mime[] = $this->LE.$this->LE;
1198
      }
1199
    }
1200
1201
    $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
1202
1203
    return join('', $mime);
1204
  }
1205
1206
  /**
1207
   * Encodes attachment in requested format.  Returns an
1208
   * empty string on failure.
1209
   * @access private
1210
   * @return string
1211
   */
1212
  function EncodeFile ($path, $encoding = 'base64') {
1213
    if(!@$fd = fopen($path, 'rb')) {
1214
      $this->SetError($this->Lang('file_open') . $path);
1215
      return '';
1216
    }
1217
    $magic_quotes = get_magic_quotes_runtime();
1218
    set_magic_quotes_runtime(0);
1219
    $file_buffer = fread($fd, filesize($path));
1220
    $file_buffer = $this->EncodeString($file_buffer, $encoding);
1221
    fclose($fd);
1222
    set_magic_quotes_runtime($magic_quotes);
1223
1224
    return $file_buffer;
1225
  }
1226
1227
  /**
1228
   * Encodes string to requested format. Returns an
1229
   * empty string on failure.
1230
   * @access private
1231
   * @return string
1232
   */
1233
  function EncodeString ($str, $encoding = 'base64') {
1234
    $encoded = '';
1235
    switch(strtolower($encoding)) {
1236
      case 'base64':
1237
        /* chunk_split is found in PHP >= 3.0.6 */
1238
        $encoded = chunk_split(base64_encode($str), 76, $this->LE);
1239
        break;
1240
      case '7bit':
1241
      case '8bit':
1242
        $encoded = $this->FixEOL($str);
1243
        if (substr($encoded, -(strlen($this->LE))) != $this->LE)
1244
          $encoded .= $this->LE;
1245
        break;
1246
      case 'binary':
1247
        $encoded = $str;
1248
        break;
1249
      case 'quoted-printable':
1250
        $encoded = $this->EncodeQP($str);
1251
        break;
1252
      default:
1253
        $this->SetError($this->Lang('encoding') . $encoding);
1254
        break;
1255
    }
1256
    return $encoded;
1257
  }
1258
1259
  /**
1260
   * Encode a header string to best of Q, B, quoted or none.
1261
   * @access private
1262
   * @return string
1263
   */
1264
  function EncodeHeader ($str, $position = 'text') {
1265
    $x = 0;
1266
1267
    switch (strtolower($position)) {
1268
      case 'phrase':
1269
        if (!preg_match('/[\200-\377]/', $str)) {
1270
          /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */
1271
          $encoded = addcslashes($str, "\0..\37\177\\\"");
1272
          if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
1273
            return ($encoded);
1274
          } else {
1275
            return ("\"$encoded\"");
1276
          }
1277
        }
1278
        $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
1279
        break;
1280
      case 'comment':
1281
        $x = preg_match_all('/[()"]/', $str, $matches);
1282
        /* Fall-through */
1283
      case 'text':
1284
      default:
1285
        $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
1286
        break;
1287
    }
1288
1289
    if ($x == 0) {
1290
      return ($str);
1291
    }
1292
1293
    $maxlen = 75 - 7 - strlen($this->CharSet);
1294
    /* Try to select the encoding which should produce the shortest output */
1295
    if (strlen($str)/3 < $x) {
1296
      $encoding = 'B';
1297
      if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
1298
     // Use a custom function which correctly encodes and wraps long
1299
     // multibyte strings without breaking lines within a character
1300
        $encoded = $this->Base64EncodeWrapMB($str);
1301
      } else {
1302
        $encoded = base64_encode($str);
1303
        $maxlen -= $maxlen % 4;
1304
        $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
1305
      }
1306
    } else {
1307
      $encoding = 'Q';
1308
      $encoded = $this->EncodeQ($str, $position);
1309
      $encoded = $this->WrapText($encoded, $maxlen, true);
1310
      $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
1311
    }
1312
1313
    $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
1314
    $encoded = trim(str_replace("\n", $this->LE, $encoded));
1315
1316
    return $encoded;
1317
  }
1318
1319
  /**
1320
   * Checks if a string contains multibyte characters.
1321
   * @access private
1322
   * @param string $str multi-byte text to wrap encode
1323
   * @return bool
1324
   */
1325
  function HasMultiBytes($str) {
1326
    if (function_exists('mb_strlen')) {
1327
      return (strlen($str) > mb_strlen($str, $this->CharSet));
1328
    } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
1329
      return False;
1330
    }
1331
  }
1332
1333
  /**
1334
   * Correctly encodes and wraps long multibyte strings for mail headers
1335
   * without breaking lines within a character.
1336
   * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
1337
   * @access private
1338
   * @param string $str multi-byte text to wrap encode
1339
   * @return string
1340
   */
1341
  function Base64EncodeWrapMB($str) {
1342
    $start = "=?".$this->CharSet."?B?";
1343
    $end = "?=";
1344
    $encoded = "";
1345
1346
    $mb_length = mb_strlen($str, $this->CharSet);
1347
    // Each line must have length <= 75, including $start and $end
1348
    $length = 75 - strlen($start) - strlen($end);
1349
    // Average multi-byte ratio
1350
    $ratio = $mb_length / strlen($str);
1351
    // Base64 has a 4:3 ratio
1352
    $offset = $avgLength = floor($length * $ratio * .75);
1353
1354
    for ($i = 0; $i < $mb_length; $i += $offset) {
1355
      $lookBack = 0;
1356
1357
      do {
1358
        $offset = $avgLength - $lookBack;
1359
        $chunk = mb_substr($str, $i, $offset, $this->CharSet);
1360
        $chunk = base64_encode($chunk);
1361
        $lookBack++;
1362
      }
1363
      while (strlen($chunk) > $length);
1364
1365
      $encoded .= $chunk . $this->LE;
1366
    }
1367
1368
    // Chomp the last linefeed
1369
    $encoded = substr($encoded, 0, -strlen($this->LE));
1370
    return $encoded;
1371
  }
1372
1373
  /**
1374
   * Encode string to quoted-printable.
1375
   * @access private
1376
   * @return string
1377
   */
1378
  function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {
1379
    $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
1380
    $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
1381
    $eol = "\r\n";
1382
    $escape = '=';
1383
    $output = '';
1384
    while( list(, $line) = each($lines) ) {
1385
      $linlen = strlen($line);
1386
      $newline = '';
1387
      for($i = 0; $i < $linlen; $i++) {
1388
        $c = substr( $line, $i, 1 );
1389
        $dec = ord( $c );
1390
        if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
1391
          $c = '=2E';
1392
        }
1393
        if ( $dec == 32 ) {
1394
          if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
1395
            $c = '=20';
1396
          } else if ( $space_conv ) {
1397
            $c = '=20';
1398
          }
1399
        } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
1400
          $h2 = floor($dec/16);
1401
          $h1 = floor($dec%16);
1402
          $c = $escape.$hex[$h2].$hex[$h1];
1403
        }
1404
        if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
1405
          $output .= $newline.$escape.$eol; //  soft line break; " =\r\n" is okay
1406
          $newline = '';
1407
          // check if newline first character will be point or not
1408
          if ( $dec == 46 ) {
1409
            $c = '=2E';
1410
          }
1411
        }
1412
        $newline .= $c;
1413
      } // end of for
1414
      $output .= $newline.$eol;
1415
    } // end of while
1416
    return $output;
1417
  }
1418
1419
  /**
1420
   * Encode string to q encoding.
1421
   * @access private
1422
   * @return string
1423
   */
1424
  function EncodeQ ($str, $position = 'text') {
1425
    /* There should not be any EOL in the string */
1426
    $encoded = preg_replace("[\r\n]", '', $str);
1427
1428
    switch (strtolower($position)) {
1429
      case 'phrase':
1430
        $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1431
        break;
1432
      case 'comment':
1433
        $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1434
      case 'text':
1435
      default:
1436
        /* Replace every high ascii, control =, ? and _ characters */
1437
        $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
1438
              "'='.sprintf('%02X', ord('\\1'))", $encoded);
1439
        break;
1440
    }
1441
1442
    /* Replace every spaces to _ (more readable than =20) */
1443
    $encoded = str_replace(' ', '_', $encoded);
1444
1445
    return $encoded;
1446
  }
1447
1448
  /**
1449
   * Adds a string or binary attachment (non-filesystem) to the list.
1450
   * This method can be used to attach ascii or binary data,
1451
   * such as a BLOB record from a database.
1452
   * @param string $string String attachment data.
1453
   * @param string $filename Name of the attachment.
1454
   * @param string $encoding File encoding (see $Encoding).
1455
   * @param string $type File extension (MIME) type.
1456
   * @return void
1457
   */
1458
  function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
1459
    /* Append to $attachment array */
1460
    $cur = count($this->attachment);
1461
    $this->attachment[$cur][0] = $string;
1462
    $this->attachment[$cur][1] = $filename;
1463
    $this->attachment[$cur][2] = $filename;
1464
    $this->attachment[$cur][3] = $encoding;
1465
    $this->attachment[$cur][4] = $type;
1466
    $this->attachment[$cur][5] = true; // isString
1467
    $this->attachment[$cur][6] = 'attachment';
1468
    $this->attachment[$cur][7] = 0;
1469
  }
1470
1471
  /**
1472
   * Adds an embedded attachment.  This can include images, sounds, and
1473
   * just about any other document.  Make sure to set the $type to an
1474
   * image type.  For JPEG images use "image/jpeg" and for GIF images
1475
   * use "image/gif".
1476
   * @param string $path Path to the attachment.
1477
   * @param string $cid Content ID of the attachment.  Use this to identify
1478
   *        the Id for accessing the image in an HTML form.
1479
   * @param string $name Overrides the attachment name.
1480
   * @param string $encoding File encoding (see $Encoding).
1481
   * @param string $type File extension (MIME) type.
1482
   * @return bool
1483
   */
1484 View Code Duplication
  function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1485
1486
    if(!@is_file($path)) {
1487
      $this->SetError($this->Lang('file_access') . $path);
1488
      return false;
1489
    }
1490
1491
    $filename = basename($path);
1492
    if($name == '') {
1493
      $name = $filename;
1494
    }
1495
1496
    /* Append to $attachment array */
1497
    $cur = count($this->attachment);
1498
    $this->attachment[$cur][0] = $path;
1499
    $this->attachment[$cur][1] = $filename;
1500
    $this->attachment[$cur][2] = $name;
1501
    $this->attachment[$cur][3] = $encoding;
1502
    $this->attachment[$cur][4] = $type;
1503
    $this->attachment[$cur][5] = false;
1504
    $this->attachment[$cur][6] = 'inline';
1505
    $this->attachment[$cur][7] = $cid;
1506
1507
    return true;
1508
  }
1509
1510
  /**
1511
   * Returns true if an inline attachment is present.
1512
   * @access private
1513
   * @return bool
1514
   */
1515
  function InlineImageExists() {
1516
    $result = false;
1517
    for($i = 0; $i < count($this->attachment); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1518
      if($this->attachment[$i][6] == 'inline') {
1519
        $result = true;
1520
        break;
1521
      }
1522
    }
1523
1524
    return $result;
1525
  }
1526
1527
  /////////////////////////////////////////////////
1528
  // CLASS METHODS, MESSAGE RESET
1529
  /////////////////////////////////////////////////
1530
1531
  /**
1532
   * Clears all recipients assigned in the TO array.  Returns void.
1533
   * @return void
1534
   */
1535
  function ClearAddresses() {
1536
    $this->to = array();
1537
  }
1538
1539
  /**
1540
   * Clears all recipients assigned in the CC array.  Returns void.
1541
   * @return void
1542
   */
1543
  function ClearCCs() {
1544
    $this->cc = array();
1545
  }
1546
1547
  /**
1548
   * Clears all recipients assigned in the BCC array.  Returns void.
1549
   * @return void
1550
   */
1551
  function ClearBCCs() {
1552
    $this->bcc = array();
1553
  }
1554
1555
  /**
1556
   * Clears all recipients assigned in the ReplyTo array.  Returns void.
1557
   * @return void
1558
   */
1559
  function ClearReplyTos() {
1560
    $this->ReplyTo = array();
1561
  }
1562
1563
  /**
1564
   * Clears all recipients assigned in the TO, CC and BCC
1565
   * array.  Returns void.
1566
   * @return void
1567
   */
1568
  function ClearAllRecipients() {
1569
    $this->to = array();
1570
    $this->cc = array();
1571
    $this->bcc = array();
1572
  }
1573
1574
  /**
1575
   * Clears all previously set filesystem, string, and binary
1576
   * attachments.  Returns void.
1577
   * @return void
1578
   */
1579
  function ClearAttachments() {
1580
    $this->attachment = array();
1581
  }
1582
1583
  /**
1584
   * Clears all custom headers.  Returns void.
1585
   * @return void
1586
   */
1587
  function ClearCustomHeaders() {
1588
    $this->CustomHeader = array();
1589
  }
1590
1591
  /////////////////////////////////////////////////
1592
  // CLASS METHODS, MISCELLANEOUS
1593
  /////////////////////////////////////////////////
1594
1595
  /**
1596
   * Adds the error message to the error container.
1597
   * Returns void.
1598
   * @access private
1599
   * @return void
1600
   */
1601
  function SetError($msg) {
1602
    $this->error_count++;
1603
    $this->ErrorInfo = $msg;
1604
  }
1605
1606
  /**
1607
   * Returns the proper RFC 822 formatted date.
1608
   * @access private
1609
   * @return string
1610
   */
1611
  function RFCDate() {
1612
    $tz = date('Z');
1613
    $tzs = ($tz < 0) ? '-' : '+';
1614
    $tz = abs($tz);
1615
    $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
1616
    $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
1617
1618
    return $result;
1619
  }
1620
1621
  /**
1622
   * Returns the appropriate server variable.  Should work with both
1623
   * PHP 4.1.0+ as well as older versions.  Returns an empty string
1624
   * if nothing is found.
1625
   * @access private
1626
   * @return mixed
1627
   */
1628
  function ServerVar($varName) {
1629
    global $HTTP_SERVER_VARS;
1630
    global $HTTP_ENV_VARS;
1631
1632
    if(!isset($_SERVER)) {
1633
      $_SERVER = $HTTP_SERVER_VARS;
1634
      if(!isset($_SERVER['REMOTE_ADDR'])) {
1635
        $_SERVER = $HTTP_ENV_VARS; // must be Apache
1636
      }
1637
    }
1638
1639
    if(isset($_SERVER[$varName])) {
1640
      return $_SERVER[$varName];
1641
    } else {
1642
      return '';
1643
    }
1644
  }
1645
1646
  /**
1647
   * Returns the server hostname or 'localhost.localdomain' if unknown.
1648
   * @access private
1649
   * @return string
1650
   */
1651
  function ServerHostname() {
1652
    if ($this->Hostname != '') {
1653
      $result = $this->Hostname;
1654
    } elseif ($this->ServerVar('SERVER_NAME') != '') {
1655
      $result = $this->ServerVar('SERVER_NAME');
1656
    } else {
1657
      $result = 'localhost.localdomain';
1658
    }
1659
1660
    return $result;
1661
  }
1662
1663
  /**
1664
   * Returns a message in the appropriate language.
1665
   * @access private
1666
   * @return string
1667
   */
1668
  function Lang($key) {
1669
    if(count($this->language) < 1) {
1670
      $this->SetLanguage('en'); // set the default language
1671
    }
1672
1673
    if(isset($this->language[$key])) {
1674
      return $this->language[$key];
1675
    } else {
1676
      return 'Language string failed to load: ' . $key;
1677
    }
1678
  }
1679
1680
  /**
1681
   * Returns true if an error occurred.
1682
   * @return bool
1683
   */
1684
  function IsError() {
1685
    return ($this->error_count > 0);
1686
  }
1687
1688
  /**
1689
   * Changes every end of line from CR or LF to CRLF.
1690
   * @access private
1691
   * @return string
1692
   */
1693 View Code Duplication
  function FixEOL($str) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1694
    $str = str_replace("\r\n", "\n", $str);
1695
    $str = str_replace("\r", "\n", $str);
1696
    $str = str_replace("\n", $this->LE, $str);
1697
    return $str;
1698
  }
1699
1700
  /**
1701
   * Adds a custom header.
1702
   * @return void
1703
   */
1704
  function AddCustomHeader($custom_header) {
1705
    $this->CustomHeader[] = explode(':', $custom_header, 2);
1706
  }
1707
1708
  /**
1709
   * Evaluates the message and returns modifications for inline images and backgrounds
1710
   * @access public
1711
   * @return $message
0 ignored issues
show
Documentation introduced by
The doc-type $message could not be parsed: Unknown type name "$message" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1712
   */
1713
  function MsgHTML($message,$basedir='') {
1714
    preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
1715
    if(isset($images[2])) {
1716
      foreach($images[2] as $i => $url) {
1717
        // do not change urls for absolute images (thanks to corvuscorax)
1718
        if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) {
1719
          $filename = basename($url);
1720
          $directory = dirname($url);
1721
          ($directory == '.')?$directory='':'';
1722
          $cid = 'cid:' . md5($filename);
1723
          $fileParts = split("\.", $filename);
1724
          $ext = $fileParts[1];
1725
          $mimeType = $this->_mime_types($ext);
1726
          if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; }
1727 View Code Duplication
          if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; }
1728
          if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {
1729
            $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message);
1730
          }
1731
        }
1732
      }
1733
    }
1734
    $this->IsHTML(true);
1735
    $this->Body = $message;
1736
    $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message)));
1737
    if ( !empty($textMsg) && empty($this->AltBody) ) {
1738
      $this->AltBody = html_entity_decode($textMsg);
1739
    }
1740
    if ( empty($this->AltBody) ) {
1741
      $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n";
1742
    }
1743
  }
1744
1745
  /**
1746
   * Gets the mime type of the embedded or inline image
1747
   * @access private
1748
   * @return mime type of ext
1749
   */
1750
  function _mime_types($ext = '') {
1751
    $mimes = array(
1752
      'ai'    =>  'application/postscript',
1753
      'aif'   =>  'audio/x-aiff',
1754
      'aifc'  =>  'audio/x-aiff',
1755
      'aiff'  =>  'audio/x-aiff',
1756
      'avi'   =>  'video/x-msvideo',
1757
      'bin'   =>  'application/macbinary',
1758
      'bmp'   =>  'image/bmp',
1759
      'class' =>  'application/octet-stream',
1760
      'cpt'   =>  'application/mac-compactpro',
1761
      'css'   =>  'text/css',
1762
      'dcr'   =>  'application/x-director',
1763
      'dir'   =>  'application/x-director',
1764
      'dll'   =>  'application/octet-stream',
1765
      'dms'   =>  'application/octet-stream',
1766
      'doc'   =>  'application/msword',
1767
      'dvi'   =>  'application/x-dvi',
1768
      'dxr'   =>  'application/x-director',
1769
      'eml'   =>  'message/rfc822',
1770
      'eps'   =>  'application/postscript',
1771
      'exe'   =>  'application/octet-stream',
1772
      'gif'   =>  'image/gif',
1773
      'gtar'  =>  'application/x-gtar',
1774
      'htm'   =>  'text/html',
1775
      'html'  =>  'text/html',
1776
      'jpe'   =>  'image/jpeg',
1777
      'jpeg'  =>  'image/jpeg',
1778
      'jpg'   =>  'image/jpeg',
1779
      'hqx'   =>  'application/mac-binhex40',
1780
      'js'    =>  'application/x-javascript',
1781
      'lha'   =>  'application/octet-stream',
1782
      'log'   =>  'text/plain',
1783
      'lzh'   =>  'application/octet-stream',
1784
      'mid'   =>  'audio/midi',
1785
      'midi'  =>  'audio/midi',
1786
      'mif'   =>  'application/vnd.mif',
1787
      'mov'   =>  'video/quicktime',
1788
      'movie' =>  'video/x-sgi-movie',
1789
      'mp2'   =>  'audio/mpeg',
1790
      'mp3'   =>  'audio/mpeg',
1791
      'mpe'   =>  'video/mpeg',
1792
      'mpeg'  =>  'video/mpeg',
1793
      'mpg'   =>  'video/mpeg',
1794
      'mpga'  =>  'audio/mpeg',
1795
      'oda'   =>  'application/oda',
1796
      'pdf'   =>  'application/pdf',
1797
      'php'   =>  'application/x-httpd-php',
1798
      'php3'  =>  'application/x-httpd-php',
1799
      'php4'  =>  'application/x-httpd-php',
1800
      'phps'  =>  'application/x-httpd-php-source',
1801
      'phtml' =>  'application/x-httpd-php',
1802
      'png'   =>  'image/png',
1803
      'ppt'   =>  'application/vnd.ms-powerpoint',
1804
      'ps'    =>  'application/postscript',
1805
      'psd'   =>  'application/octet-stream',
1806
      'qt'    =>  'video/quicktime',
1807
      'ra'    =>  'audio/x-realaudio',
1808
      'ram'   =>  'audio/x-pn-realaudio',
1809
      'rm'    =>  'audio/x-pn-realaudio',
1810
      'rpm'   =>  'audio/x-pn-realaudio-plugin',
1811
      'rtf'   =>  'text/rtf',
1812
      'rtx'   =>  'text/richtext',
1813
      'rv'    =>  'video/vnd.rn-realvideo',
1814
      'sea'   =>  'application/octet-stream',
1815
      'shtml' =>  'text/html',
1816
      'sit'   =>  'application/x-stuffit',
1817
      'so'    =>  'application/octet-stream',
1818
      'smi'   =>  'application/smil',
1819
      'smil'  =>  'application/smil',
1820
      'swf'   =>  'application/x-shockwave-flash',
1821
      'tar'   =>  'application/x-tar',
1822
      'text'  =>  'text/plain',
1823
      'txt'   =>  'text/plain',
1824
      'tgz'   =>  'application/x-tar',
1825
      'tif'   =>  'image/tiff',
1826
      'tiff'  =>  'image/tiff',
1827
      'wav'   =>  'audio/x-wav',
1828
      'wbxml' =>  'application/vnd.wap.wbxml',
1829
      'wmlc'  =>  'application/vnd.wap.wmlc',
1830
      'word'  =>  'application/msword',
1831
      'xht'   =>  'application/xhtml+xml',
1832
      'xhtml' =>  'application/xhtml+xml',
1833
      'xl'    =>  'application/excel',
1834
      'xls'   =>  'application/vnd.ms-excel',
1835
      'xml'   =>  'text/xml',
1836
      'xsl'   =>  'text/xml',
1837
      'zip'   =>  'application/zip'
1838
    );
1839
    return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
1840
  }
1841
1842
  /**
1843
   * Set (or reset) Class Objects (variables)
1844
   *
1845
   * Usage Example:
1846
   * $page->set('X-Priority', '3');
1847
   *
1848
   * @access public
1849
   * @param string $name Parameter Name
1850
   * @param mixed $value Parameter Value
1851
   * NOTE: will not work with arrays, there are no arrays to set/reset
1852
   */
1853
  function set ( $name, $value = '' ) {
1854
    if ( isset($this->$name) ) {
1855
      $this->$name = $value;
1856
    } else {
1857
      $this->SetError('Cannot set or reset variable ' . $name);
1858
      return false;
1859
    }
1860
  }
1861
1862
  /**
1863
   * Read a file from a supplied filename and return it.
1864
   *
1865
   * @access public
1866
   * @param string $filename Parameter File Name
1867
   */
1868
  function getFile($filename) {
1869
    $return = '';
1870
    if ($fp = fopen($filename, 'rb')) {
1871
      while (!feof($fp)) {
1872
        $return .= fread($fp, 1024);
1873
      }
1874
      fclose($fp);
1875
      return $return;
1876
    } else {
1877
      return false;
1878
    }
1879
  }
1880
1881
  /**
1882
   * Strips newlines to prevent header injection.
1883
   * @access private
1884
   * @param string $str String
1885
   * @return string
1886
   */
1887 View Code Duplication
  function SecureHeader($str) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1888
    $str = trim($str);
1889
    $str = str_replace("\r", "", $str);
1890
    $str = str_replace("\n", "", $str);
1891
    return $str;
1892
  }
1893
1894
  /**
1895
   * Set the private key file and password to sign the message.
1896
   *
1897
   * @access public
1898
   * @param string $key_filename Parameter File Name
1899
   * @param string $key_pass Password for private key
1900
   */
1901
  function Sign($cert_filename, $key_filename, $key_pass) {
1902
    $this->sign_cert_file = $cert_filename;
1903
    $this->sign_key_file = $key_filename;
1904
    $this->sign_key_pass = $key_pass;
1905
  }
1906
1907
}
1908
1909
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...