PHPMailer   F
last analyzed

Complexity

Total Complexity 528

Size/Duplication

Total Lines 4017
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 528
eloc 1664
c 0
b 0
f 0
dl 0
loc 4017
rs 0.8

104 Methods

Rating   Name   Duplication   Size   Complexity  
A isShellSafe() 0 23 6
A isPermittedPath() 0 3 1
B addAttachment() 0 37 7
A __destruct() 0 4 1
B punyencodeAddress() 0 18 8
B addAnAddress() 0 33 8
B sendmailSend() 0 63 11
A headerLine() 0 3 1
A addrAppend() 0 7 2
A generateId() 0 2 1
D validateAddress() 0 88 19
A smtpClose() 0 6 3
A setWordWrap() 0 16 6
B setLanguage() 0 61 7
A addAddress() 0 3 1
A send() 0 14 4
C getMailMIME() 0 45 12
A addrFormat() 0 8 2
A endBoundary() 0 3 1
F preSend() 0 91 20
B parseAddresses() 0 43 11
A isHTML() 0 6 2
D wrapText() 0 88 21
B setFrom() 0 24 8
A __construct() 0 7 3
A isMail() 0 3 1
A getSMTPInstance() 0 6 2
A addBCC() 0 3 1
A textLine() 0 3 1
A setMessageType() 0 16 5
A isQmail() 0 10 2
B edebug() 0 33 7
A addCC() 0 3 1
B postSend() 0 28 8
B addOrEnqueueAnAddress() 0 32 8
A idnSupported() 0 4 2
A mailPassthru() 0 17 5
A addReplyTo() 0 3 1
F smtpConnect() 0 116 28
A getTranslations() 0 3 1
A getSentMIMEMessage() 0 3 1
A isSMTP() 0 3 1
C smtpSend() 0 52 13
C mailSend() 0 37 13
A getBoundary() 0 22 5
A getLastMessageID() 0 3 1
B utf8CharBoundary() 0 35 7
A isSendmail() 0 10 2
A getAttachments() 0 3 1
F createHeader() 0 88 23
F attachAll() 0 114 16
F createBody() 0 203 26
A getReplyToAddresses() 0 3 1
A clearAllRecipients() 0 7 1
A encodeQPphp() 0 6 1
A getCustomHeaders() 0 3 1
A filenameToType() 0 9 2
A addStringAttachment() 0 21 2
B encodeHeader() 0 56 11
A normalizeBreaks() 0 3 1
B setError() 0 19 7
A hasLineLongerThanMax() 0 4 1
A clearReplyTos() 0 4 1
A clearCustomHeaders() 0 3 1
B DKIM_Add() 0 70 8
A getCcAddresses() 0 3 1
A alternativeExists() 0 3 1
B serverHostname() 0 13 8
B encodeFile() 0 33 9
A addCustomHeader() 0 7 2
A attachmentExists() 0 8 3
A clearAttachments() 0 3 1
A DKIM_HeaderC() 0 12 2
A base64EncodeWrapMB() 0 31 4
A set() 0 8 2
A clearAddresses() 0 7 2
A rfcDate() 0 6 1
A hasMultiBytes() 0 6 2
A clearCCs() 0 7 2
C mb_pathinfo() 0 33 14
A getAllRecipientAddresses() 0 3 1
B encodeQ() 0 38 7
A getBccAddresses() 0 3 1
A clearBCCs() 0 7 2
A inlineImageExists() 0 8 3
C msgHTML() 0 72 17
A secureHeader() 0 3 1
A doCallback() 0 5 3
B encodeString() 0 26 7
A addStringEmbeddedImage() 0 25 3
A clearQueuedAddresses() 0 6 3
A addEmbeddedImage() 0 29 5
B DKIM_QP() 0 12 7
B _mime_types() 0 106 2
A isError() 0 3 1
A lang() 0 17 4
B DKIM_Sign() 0 38 9
A has8bitChars() 0 3 1
A DKIM_BodyC() 0 13 3
A sign() 0 6 1
A getToAddresses() 0 3 1
A fixEOL() 0 9 2
A encodeQP() 0 13 2
A html2text() 0 9 2

How to fix   Complexity   

Complex Class

Complex classes like PHPMailer often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use PHPMailer, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * PHPMailer - PHP email creation and transport class.
4
 * PHP Version 5
5
 * @package PHPMailer
6
 * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
7
 * @author Marcus Bointon (Synchro/coolbru) <[email protected]>
8
 * @author Jim Jagielski (jimjag) <[email protected]>
9
 * @author Andy Prevost (codeworxtech) <[email protected]>
10
 * @author Brent R. Matzelle (original founder)
11
 * @copyright 2012 - 2014 Marcus Bointon
12
 * @copyright 2010 - 2012 Jim Jagielski
13
 * @copyright 2004 - 2009 Andy Prevost
14
 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
15
 * @note This program is distributed in the hope that it will be useful - WITHOUT
16
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
 * FITNESS FOR A PARTICULAR PURPOSE.
18
 */
19
20
/**
21
 * PHPMailer - PHP email creation and transport class.
22
 * @package PHPMailer
23
 * @author Marcus Bointon (Synchro/coolbru) <[email protected]>
24
 * @author Jim Jagielski (jimjag) <[email protected]>
25
 * @author Andy Prevost (codeworxtech) <[email protected]>
26
 * @author Brent R. Matzelle (original founder)
27
 */
28
class PHPMailer
29
{
30
    /**
31
     * The PHPMailer Version number.
32
     * @var string
33
     */
34
    public $Version = '5.2.28';
35
36
    /**
37
     * Email priority.
38
     * Options: null (default), 1 = High, 3 = Normal, 5 = low.
39
     * When null, the header is not set at all.
40
     * @var integer
41
     */
42
    public $Priority = null;
43
44
    /**
45
     * The character set of the message.
46
     * @var string
47
     */
48
    public $CharSet = 'iso-8859-1';
49
50
    /**
51
     * The MIME Content-type of the message.
52
     * @var string
53
     */
54
    public $ContentType = 'text/plain';
55
56
    /**
57
     * The message encoding.
58
     * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable".
59
     * @var string
60
     */
61
    public $Encoding = '8bit';
62
63
    /**
64
     * Holds the most recent mailer error message.
65
     * @var string
66
     */
67
    public $ErrorInfo = '';
68
69
    /**
70
     * The From email address for the message.
71
     * @var string
72
     */
73
    public $From = '[email protected]';
74
75
    /**
76
     * The From name of the message.
77
     * @var string
78
     */
79
    public $FromName = 'Root User';
80
81
    /**
82
     * The Sender email (Return-Path) of the message.
83
     * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
84
     * @var string
85
     */
86
    public $Sender = '';
87
88
    /**
89
     * The Return-Path of the message.
90
     * If empty, it will be set to either From or Sender.
91
     * @var string
92
     * @deprecated Email senders should never set a return-path header;
93
     * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything.
94
     * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference
95
     */
96
    public $ReturnPath = '';
97
98
    /**
99
     * The Subject of the message.
100
     * @var string
101
     */
102
    public $Subject = '';
103
104
    /**
105
     * An HTML or plain text message body.
106
     * If HTML then call isHTML(true).
107
     * @var string
108
     */
109
    public $Body = '';
110
111
    /**
112
     * The plain-text message body.
113
     * This body can be read by mail clients that do not have HTML email
114
     * capability such as mutt & Eudora.
115
     * Clients that can read HTML will view the normal Body.
116
     * @var string
117
     */
118
    public $AltBody = '';
119
120
    /**
121
     * An iCal message part body.
122
     * Only supported in simple alt or alt_inline message types
123
     * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator
124
     * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/
125
     * @link http://kigkonsult.se/iCalcreator/
126
     * @var string
127
     */
128
    public $Ical = '';
129
130
    /**
131
     * The complete compiled MIME message body.
132
     * @access protected
133
     * @var string
134
     */
135
    protected $MIMEBody = '';
136
137
    /**
138
     * The complete compiled MIME message headers.
139
     * @var string
140
     * @access protected
141
     */
142
    protected $MIMEHeader = '';
143
144
    /**
145
     * Extra headers that createHeader() doesn't fold in.
146
     * @var string
147
     * @access protected
148
     */
149
    protected $mailHeader = '';
150
151
    /**
152
     * Word-wrap the message body to this number of chars.
153
     * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance.
154
     * @var integer
155
     */
156
    public $WordWrap = 0;
157
158
    /**
159
     * Which method to use to send mail.
160
     * Options: "mail", "sendmail", or "smtp".
161
     * @var string
162
     */
163
    public $Mailer = 'mail';
164
165
    /**
166
     * The path to the sendmail program.
167
     * @var string
168
     */
169
    public $Sendmail = '/usr/sbin/sendmail';
170
171
    /**
172
     * Whether mail() uses a fully sendmail-compatible MTA.
173
     * One which supports sendmail's "-oi -f" options.
174
     * @var boolean
175
     */
176
    public $UseSendmailOptions = true;
177
178
    /**
179
     * Path to PHPMailer plugins.
180
     * Useful if the SMTP class is not in the PHP include path.
181
     * @var string
182
     * @deprecated Should not be needed now there is an autoloader.
183
     */
184
    public $PluginDir = '';
185
186
    /**
187
     * The email address that a reading confirmation should be sent to, also known as read receipt.
188
     * @var string
189
     */
190
    public $ConfirmReadingTo = '';
191
192
    /**
193
     * The hostname to use in the Message-ID header and as default HELO string.
194
     * If empty, PHPMailer attempts to find one with, in order,
195
     * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value
196
     * 'localhost.localdomain'.
197
     * @var string
198
     */
199
    public $Hostname = '';
200
201
    /**
202
     * An ID to be used in the Message-ID header.
203
     * If empty, a unique id will be generated.
204
     * You can set your own, but it must be in the format "<[email protected]>",
205
     * as defined in RFC5322 section 3.6.4 or it will be ignored.
206
     * @see https://tools.ietf.org/html/rfc5322#section-3.6.4
207
     * @var string
208
     */
209
    public $MessageID = '';
210
211
    /**
212
     * The message Date to be used in the Date header.
213
     * If empty, the current date will be added.
214
     * @var string
215
     */
216
    public $MessageDate = '';
217
218
    /**
219
     * SMTP hosts.
220
     * Either a single hostname or multiple semicolon-delimited hostnames.
221
     * You can also specify a different port
222
     * for each host by using this format: [hostname:port]
223
     * (e.g. "smtp1.example.com:25;smtp2.example.com").
224
     * You can also specify encryption type, for example:
225
     * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465").
226
     * Hosts will be tried in order.
227
     * @var string
228
     */
229
    public $Host = 'localhost';
230
231
    /**
232
     * The default SMTP server port.
233
     * @var integer
234
     * @TODO Why is this needed when the SMTP class takes care of it?
235
     */
236
    public $Port = 25;
237
238
    /**
239
     * The SMTP HELO of the message.
240
     * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find
241
     * one with the same method described above for $Hostname.
242
     * @var string
243
     * @see PHPMailer::$Hostname
244
     */
245
    public $Helo = '';
246
247
    /**
248
     * What kind of encryption to use on the SMTP connection.
249
     * Options: '', 'ssl' or 'tls'
250
     * @var string
251
     */
252
    public $SMTPSecure = '';
253
254
    /**
255
     * Whether to enable TLS encryption automatically if a server supports it,
256
     * even if `SMTPSecure` is not set to 'tls'.
257
     * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid.
258
     * @var boolean
259
     */
260
    public $SMTPAutoTLS = true;
261
262
    /**
263
     * Whether to use SMTP authentication.
264
     * Uses the Username and Password properties.
265
     * @var boolean
266
     * @see PHPMailer::$Username
267
     * @see PHPMailer::$Password
268
     */
269
    public $SMTPAuth = false;
270
271
    /**
272
     * Options array passed to stream_context_create when connecting via SMTP.
273
     * @var array
274
     */
275
    public $SMTPOptions = array();
276
277
    /**
278
     * SMTP username.
279
     * @var string
280
     */
281
    public $Username = '';
282
283
    /**
284
     * SMTP password.
285
     * @var string
286
     */
287
    public $Password = '';
288
289
    /**
290
     * SMTP auth type.
291
     * Options are CRAM-MD5, LOGIN, PLAIN, NTLM, XOAUTH2, attempted in that order if not specified
292
     * @var string
293
     */
294
    public $AuthType = '';
295
296
    /**
297
     * SMTP realm.
298
     * Used for NTLM auth
299
     * @var string
300
     */
301
    public $Realm = '';
302
303
    /**
304
     * SMTP workstation.
305
     * Used for NTLM auth
306
     * @var string
307
     */
308
    public $Workstation = '';
309
310
    /**
311
     * The SMTP server timeout in seconds.
312
     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
313
     * @var integer
314
     */
315
    public $Timeout = 300;
316
317
    /**
318
     * SMTP class debug output mode.
319
     * Debug output level.
320
     * Options:
321
     * * `0` No output
322
     * * `1` Commands
323
     * * `2` Data and commands
324
     * * `3` As 2 plus connection status
325
     * * `4` Low-level data output
326
     * @var integer
327
     * @see SMTP::$do_debug
328
     */
329
    public $SMTPDebug = 0;
330
331
    /**
332
     * How to handle debug output.
333
     * Options:
334
     * * `echo` Output plain-text as-is, appropriate for CLI
335
     * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output
336
     * * `error_log` Output to error log as configured in php.ini
337
     *
338
     * Alternatively, you can provide a callable expecting two params: a message string and the debug level:
339
     * <code>
340
     * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
341
     * </code>
342
     * @var string|callable
343
     * @see SMTP::$Debugoutput
344
     */
345
    public $Debugoutput = 'echo';
346
347
    /**
348
     * Whether to keep SMTP connection open after each message.
349
     * If this is set to true then to close the connection
350
     * requires an explicit call to smtpClose().
351
     * @var boolean
352
     */
353
    public $SMTPKeepAlive = false;
354
355
    /**
356
     * Whether to split multiple to addresses into multiple messages
357
     * or send them all in one message.
358
     * Only supported in `mail` and `sendmail` transports, not in SMTP.
359
     * @var boolean
360
     */
361
    public $SingleTo = false;
362
363
    /**
364
     * Storage for addresses when SingleTo is enabled.
365
     * @var array
366
     * @TODO This should really not be public
367
     */
368
    public $SingleToArray = array();
369
370
    /**
371
     * Whether to generate VERP addresses on send.
372
     * Only applicable when sending via SMTP.
373
     * @link https://en.wikipedia.org/wiki/Variable_envelope_return_path
374
     * @link http://www.postfix.org/VERP_README.html Postfix VERP info
375
     * @var boolean
376
     */
377
    public $do_verp = false;
378
379
    /**
380
     * Whether to allow sending messages with an empty body.
381
     * @var boolean
382
     */
383
    public $AllowEmpty = false;
384
385
    /**
386
     * The default line ending.
387
     * @note The default remains "\n". We force CRLF where we know
388
     *        it must be used via self::CRLF.
389
     * @var string
390
     */
391
    public $LE = "\n";
392
393
    /**
394
     * DKIM selector.
395
     * @var string
396
     */
397
    public $DKIM_selector = '';
398
399
    /**
400
     * DKIM Identity.
401
     * Usually the email address used as the source of the email.
402
     * @var string
403
     */
404
    public $DKIM_identity = '';
405
406
    /**
407
     * DKIM passphrase.
408
     * Used if your key is encrypted.
409
     * @var string
410
     */
411
    public $DKIM_passphrase = '';
412
413
    /**
414
     * DKIM signing domain name.
415
     * @example 'example.com'
416
     * @var string
417
     */
418
    public $DKIM_domain = '';
419
420
    /**
421
     * DKIM private key file path.
422
     * @var string
423
     */
424
    public $DKIM_private = '';
425
426
    /**
427
     * DKIM private key string.
428
     * If set, takes precedence over `$DKIM_private`.
429
     * @var string
430
     */
431
    public $DKIM_private_string = '';
432
433
    /**
434
     * Callback Action function name.
435
     *
436
     * The function that handles the result of the send email action.
437
     * It is called out by send() for each email sent.
438
     *
439
     * Value can be any php callable: http://www.php.net/is_callable
440
     *
441
     * Parameters:
442
     *   boolean $result        result of the send action
443
     *   array   $to            email addresses of the recipients
444
     *   array   $cc            cc email addresses
445
     *   array   $bcc           bcc email addresses
446
     *   string  $subject       the subject
447
     *   string  $body          the email body
448
     *   string  $from          email address of sender
449
     * @var string
450
     */
451
    public $action_function = '';
452
453
    /**
454
     * What to put in the X-Mailer header.
455
     * Options: An empty string for PHPMailer default, whitespace for none, or a string to use
456
     * @var string
457
     */
458
    public $XMailer = '';
459
460
    /**
461
     * Which validator to use by default when validating email addresses.
462
     * May be a callable to inject your own validator, but there are several built-in validators.
463
     * @see PHPMailer::validateAddress()
464
     * @var string|callable
465
     * @static
466
     */
467
    public static $validator = 'auto';
468
469
    /**
470
     * An instance of the SMTP sender class.
471
     * @var SMTP
472
     * @access protected
473
     */
474
    protected $smtp = null;
475
476
    /**
477
     * The array of 'to' names and addresses.
478
     * @var array
479
     * @access protected
480
     */
481
    protected $to = array();
482
483
    /**
484
     * The array of 'cc' names and addresses.
485
     * @var array
486
     * @access protected
487
     */
488
    protected $cc = array();
489
490
    /**
491
     * The array of 'bcc' names and addresses.
492
     * @var array
493
     * @access protected
494
     */
495
    protected $bcc = array();
496
497
    /**
498
     * The array of reply-to names and addresses.
499
     * @var array
500
     * @access protected
501
     */
502
    protected $ReplyTo = array();
503
504
    /**
505
     * An array of all kinds of addresses.
506
     * Includes all of $to, $cc, $bcc
507
     * @var array
508
     * @access protected
509
     * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
510
     */
511
    protected $all_recipients = array();
512
513
    /**
514
     * An array of names and addresses queued for validation.
515
     * In send(), valid and non duplicate entries are moved to $all_recipients
516
     * and one of $to, $cc, or $bcc.
517
     * This array is used only for addresses with IDN.
518
     * @var array
519
     * @access protected
520
     * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc
521
     * @see PHPMailer::$all_recipients
522
     */
523
    protected $RecipientsQueue = array();
524
525
    /**
526
     * An array of reply-to names and addresses queued for validation.
527
     * In send(), valid and non duplicate entries are moved to $ReplyTo.
528
     * This array is used only for addresses with IDN.
529
     * @var array
530
     * @access protected
531
     * @see PHPMailer::$ReplyTo
532
     */
533
    protected $ReplyToQueue = array();
534
535
    /**
536
     * The array of attachments.
537
     * @var array
538
     * @access protected
539
     */
540
    protected $attachment = array();
541
542
    /**
543
     * The array of custom headers.
544
     * @var array
545
     * @access protected
546
     */
547
    protected $CustomHeader = array();
548
549
    /**
550
     * The most recent Message-ID (including angular brackets).
551
     * @var string
552
     * @access protected
553
     */
554
    protected $lastMessageID = '';
555
556
    /**
557
     * The message's MIME type.
558
     * @var string
559
     * @access protected
560
     */
561
    protected $message_type = '';
562
563
    /**
564
     * The array of MIME boundary strings.
565
     * @var array
566
     * @access protected
567
     */
568
    protected $boundary = array();
569
570
    /**
571
     * The array of available languages.
572
     * @var array
573
     * @access protected
574
     */
575
    protected $language = array();
576
577
    /**
578
     * The number of errors encountered.
579
     * @var integer
580
     * @access protected
581
     */
582
    protected $error_count = 0;
583
584
    /**
585
     * The S/MIME certificate file path.
586
     * @var string
587
     * @access protected
588
     */
589
    protected $sign_cert_file = '';
590
591
    /**
592
     * The S/MIME key file path.
593
     * @var string
594
     * @access protected
595
     */
596
    protected $sign_key_file = '';
597
598
    /**
599
     * The optional S/MIME extra certificates ("CA Chain") file path.
600
     * @var string
601
     * @access protected
602
     */
603
    protected $sign_extracerts_file = '';
604
605
    /**
606
     * The S/MIME password for the key.
607
     * Used only if the key is encrypted.
608
     * @var string
609
     * @access protected
610
     */
611
    protected $sign_key_pass = '';
612
613
    /**
614
     * Whether to throw exceptions for errors.
615
     * @var boolean
616
     * @access protected
617
     */
618
    protected $exceptions = false;
619
620
    /**
621
     * Unique ID used for message ID and boundaries.
622
     * @var string
623
     * @access protected
624
     */
625
    protected $uniqueid = '';
626
627
    /**
628
     * Error severity: message only, continue processing.
629
     */
630
    const STOP_MESSAGE = 0;
631
632
    /**
633
     * Error severity: message, likely ok to continue processing.
634
     */
635
    const STOP_CONTINUE = 1;
636
637
    /**
638
     * Error severity: message, plus full stop, critical error reached.
639
     */
640
    const STOP_CRITICAL = 2;
641
642
    /**
643
     * SMTP RFC standard line ending.
644
     */
645
    const CRLF = "\r\n";
646
647
    /**
648
     * The maximum line length allowed by RFC 2822 section 2.1.1
649
     * @var integer
650
     */
651
    const MAX_LINE_LENGTH = 998;
652
653
    /**
654
     * Constructor.
655
     * @param boolean $exceptions Should we throw external exceptions?
656
     */
657
    public function __construct($exceptions = null)
658
    {
659
        if ($exceptions !== null) {
660
            $this->exceptions = (boolean)$exceptions;
661
        }
662
        //Pick an appropriate debug output format automatically
663
        $this->Debugoutput = (strpos(PHP_SAPI, 'cli') !== false ? 'echo' : 'html');
664
    }
665
666
    /**
667
     * Destructor.
668
     */
669
    public function __destruct()
670
    {
671
        //Close any open SMTP connection nicely
672
        $this->smtpClose();
673
    }
674
675
    /**
676
     * Call mail() in a safe_mode-aware fashion.
677
     * Also, unless sendmail_path points to sendmail (or something that
678
     * claims to be sendmail), don't pass params (not a perfect fix,
679
     * but it will do)
680
     * @param string $to To
681
     * @param string $subject Subject
682
     * @param string $body Message Body
683
     * @param string $header Additional Header(s)
684
     * @param string $params Params
685
     * @access private
686
     * @return boolean
687
     */
688
    private function mailPassthru($to, $subject, $body, $header, $params)
689
    {
690
        //Check overloading of mail function to avoid double-encoding
691
        if (ini_get('mbstring.func_overload') & 1) {
692
            $subject = $this->secureHeader($subject);
693
        } else {
694
            $subject = $this->encodeHeader($this->secureHeader($subject));
695
        }
696
697
        //Can't use additional_parameters in safe_mode, calling mail() with null params breaks
698
        //@link http://php.net/manual/en/function.mail.php
699
        if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {
700
            $result = @mail($to, $subject, $body, $header);
701
        } else {
702
            $result = @mail($to, $subject, $body, $header, $params);
703
        }
704
        return $result;
705
    }
706
    /**
707
     * Output debugging info via user-defined method.
708
     * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).
709
     * @see PHPMailer::$Debugoutput
710
     * @see PHPMailer::$SMTPDebug
711
     * @param string $str
712
     */
713
    protected function edebug($str)
714
    {
715
        if ($this->SMTPDebug <= 0) {
716
            return;
717
        }
718
        //Avoid clash with built-in function names
719
        if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
720
            call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
721
            return;
722
        }
723
        switch ($this->Debugoutput) {
724
            case 'error_log':
725
                //Don't output, just log
726
                error_log($str);
727
                break;
728
            case 'html':
729
                //Cleans up output a bit for a better looking, HTML-safe output
730
                echo htmlentities(
731
                    preg_replace('/[\r\n]+/', '', $str),
732
                    ENT_QUOTES,
733
                    'UTF-8'
734
                )
735
                . "<br>\n";
736
                break;
737
            case 'echo':
738
            default:
739
                //Normalize line breaks
740
                $str = preg_replace('/\r\n?/ms', "\n", $str);
741
                echo gmdate('Y-m-d H:i:s') . "\t" . str_replace(
742
                    "\n",
743
                    "\n                   \t                  ",
744
                    trim($str)
745
                ) . "\n";
746
        }
747
    }
748
749
    /**
750
     * Sets message type to HTML or plain.
751
     * @param boolean $isHtml True for HTML mode.
752
     * @return void
753
     */
754
    public function isHTML($isHtml = true)
755
    {
756
        if ($isHtml) {
757
            $this->ContentType = 'text/html';
758
        } else {
759
            $this->ContentType = 'text/plain';
760
        }
761
    }
762
763
    /**
764
     * Send messages using SMTP.
765
     * @return void
766
     */
767
    public function isSMTP()
768
    {
769
        $this->Mailer = 'smtp';
770
    }
771
772
    /**
773
     * Send messages using PHP's mail() function.
774
     * @return void
775
     */
776
    public function isMail()
777
    {
778
        $this->Mailer = 'mail';
779
    }
780
781
    /**
782
     * Send messages using $Sendmail.
783
     * @return void
784
     */
785
    public function isSendmail()
786
    {
787
        $ini_sendmail_path = ini_get('sendmail_path');
788
789
        if (!stristr($ini_sendmail_path, 'sendmail')) {
790
            $this->Sendmail = '/usr/sbin/sendmail';
791
        } else {
792
            $this->Sendmail = $ini_sendmail_path;
793
        }
794
        $this->Mailer = 'sendmail';
795
    }
796
797
    /**
798
     * Send messages using qmail.
799
     * @return void
800
     */
801
    public function isQmail()
802
    {
803
        $ini_sendmail_path = ini_get('sendmail_path');
804
805
        if (!stristr($ini_sendmail_path, 'qmail')) {
806
            $this->Sendmail = '/var/qmail/bin/qmail-inject';
807
        } else {
808
            $this->Sendmail = $ini_sendmail_path;
809
        }
810
        $this->Mailer = 'qmail';
811
    }
812
813
    /**
814
     * Add a "To" address.
815
     * @param string $address The email address to send to
816
     * @param string $name
817
     * @return boolean true on success, false if address already used or invalid in some way
818
     */
819
    public function addAddress($address, $name = '')
820
    {
821
        return $this->addOrEnqueueAnAddress('to', $address, $name);
822
    }
823
824
    /**
825
     * Add a "CC" address.
826
     * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
827
     * @param string $address The email address to send to
828
     * @param string $name
829
     * @return boolean true on success, false if address already used or invalid in some way
830
     */
831
    public function addCC($address, $name = '')
832
    {
833
        return $this->addOrEnqueueAnAddress('cc', $address, $name);
834
    }
835
836
    /**
837
     * Add a "BCC" address.
838
     * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer.
839
     * @param string $address The email address to send to
840
     * @param string $name
841
     * @return boolean true on success, false if address already used or invalid in some way
842
     */
843
    public function addBCC($address, $name = '')
844
    {
845
        return $this->addOrEnqueueAnAddress('bcc', $address, $name);
846
    }
847
848
    /**
849
     * Add a "Reply-To" address.
850
     * @param string $address The email address to reply to
851
     * @param string $name
852
     * @return boolean true on success, false if address already used or invalid in some way
853
     */
854
    public function addReplyTo($address, $name = '')
855
    {
856
        return $this->addOrEnqueueAnAddress('Reply-To', $address, $name);
857
    }
858
859
    /**
860
     * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer
861
     * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still
862
     * be modified after calling this function), addition of such addresses is delayed until send().
863
     * Addresses that have been added already return false, but do not throw exceptions.
864
     * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
865
     * @param string $address The email address to send, resp. to reply to
866
     * @param string $name
867
     * @throws phpmailerException
868
     * @return boolean true on success, false if address already used or invalid in some way
869
     * @access protected
870
     */
871
    protected function addOrEnqueueAnAddress($kind, $address, $name)
872
    {
873
        $address = trim($address);
874
        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
875
        if (($pos = strrpos($address, '@')) === false) {
876
            // At-sign is misssing.
877
            $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
878
            $this->setError($error_message);
879
            $this->edebug($error_message);
880
            if ($this->exceptions) {
881
                throw new phpmailerException($error_message);
882
            }
883
            return false;
884
        }
885
        $params = array($kind, $address, $name);
886
        // Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
887
        if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) {
888
            if ($kind != 'Reply-To') {
889
                if (!array_key_exists($address, $this->RecipientsQueue)) {
890
                    $this->RecipientsQueue[$address] = $params;
891
                    return true;
892
                }
893
            } else {
894
                if (!array_key_exists($address, $this->ReplyToQueue)) {
895
                    $this->ReplyToQueue[$address] = $params;
896
                    return true;
897
                }
898
            }
899
            return false;
900
        }
901
        // Immediately add standard addresses without IDN.
902
        return call_user_func_array(array($this, 'addAnAddress'), $params);
903
    }
904
905
    /**
906
     * Add an address to one of the recipient arrays or to the ReplyTo array.
907
     * Addresses that have been added already return false, but do not throw exceptions.
908
     * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'
909
     * @param string $address The email address to send, resp. to reply to
910
     * @param string $name
911
     * @throws phpmailerException
912
     * @return boolean true on success, false if address already used or invalid in some way
913
     * @access protected
914
     */
915
    protected function addAnAddress($kind, $address, $name = '')
916
    {
917
        if (!in_array($kind, array('to', 'cc', 'bcc', 'Reply-To'))) {
918
            $error_message = $this->lang('Invalid recipient kind: ') . $kind;
919
            $this->setError($error_message);
920
            $this->edebug($error_message);
921
            if ($this->exceptions) {
922
                throw new phpmailerException($error_message);
923
            }
924
            return false;
925
        }
926
        if (!$this->validateAddress($address)) {
927
            $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
928
            $this->setError($error_message);
929
            $this->edebug($error_message);
930
            if ($this->exceptions) {
931
                throw new phpmailerException($error_message);
932
            }
933
            return false;
934
        }
935
        if ($kind != 'Reply-To') {
936
            if (!array_key_exists(strtolower($address), $this->all_recipients)) {
937
                array_push($this->$kind, array($address, $name));
938
                $this->all_recipients[strtolower($address)] = true;
939
                return true;
940
            }
941
        } else {
942
            if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
943
                $this->ReplyTo[strtolower($address)] = array($address, $name);
944
                return true;
945
            }
946
        }
947
        return false;
948
    }
949
950
    /**
951
     * Parse and validate a string containing one or more RFC822-style comma-separated email addresses
952
     * of the form "display name <address>" into an array of name/address pairs.
953
     * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.
954
     * Note that quotes in the name part are removed.
955
     * @param string $addrstr The address list string
956
     * @param bool $useimap Whether to use the IMAP extension to parse the list
957
     * @return array
958
     * @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation
959
     */
960
    public function parseAddresses($addrstr, $useimap = true)
961
    {
962
        $addresses = array();
963
        if ($useimap and function_exists('imap_rfc822_parse_adrlist')) {
964
            //Use this built-in parser if it's available
965
            $list = imap_rfc822_parse_adrlist($addrstr, '');
966
            foreach ($list as $address) {
967
                if ($address->host != '.SYNTAX-ERROR.') {
968
                    if ($this->validateAddress($address->mailbox . '@' . $address->host)) {
969
                        $addresses[] = array(
970
                            'name' => (property_exists($address, 'personal') ? $address->personal : ''),
971
                            'address' => $address->mailbox . '@' . $address->host
972
                        );
973
                    }
974
                }
975
            }
976
        } else {
977
            //Use this simpler parser
978
            $list = explode(',', $addrstr);
979
            foreach ($list as $address) {
980
                $address = trim($address);
981
                //Is there a separate name part?
982
                if (strpos($address, '<') === false) {
983
                    //No separate name, just use the whole thing
984
                    if ($this->validateAddress($address)) {
985
                        $addresses[] = array(
986
                            'name' => '',
987
                            'address' => $address
988
                        );
989
                    }
990
                } else {
991
                    list($name, $email) = explode('<', $address);
992
                    $email = trim(str_replace('>', '', $email));
993
                    if ($this->validateAddress($email)) {
994
                        $addresses[] = array(
995
                            'name' => trim(str_replace(array('"', "'"), '', $name)),
996
                            'address' => $email
997
                        );
998
                    }
999
                }
1000
            }
1001
        }
1002
        return $addresses;
1003
    }
1004
1005
    /**
1006
     * Set the From and FromName properties.
1007
     * @param string $address
1008
     * @param string $name
1009
     * @param boolean $auto Whether to also set the Sender address, defaults to true
1010
     * @throws phpmailerException
1011
     * @return boolean
1012
     */
1013
    public function setFrom($address, $name = '', $auto = true)
1014
    {
1015
        $address = trim($address);
1016
        $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
1017
        // Don't validate now addresses with IDN. Will be done in send().
1018
        if (($pos = strrpos($address, '@')) === false or
1019
            (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and
1020
            !$this->validateAddress($address)) {
1021
            $error_message = $this->lang('invalid_address') . " (setFrom) $address";
1022
            $this->setError($error_message);
1023
            $this->edebug($error_message);
1024
            if ($this->exceptions) {
1025
                throw new phpmailerException($error_message);
1026
            }
1027
            return false;
1028
        }
1029
        $this->From = $address;
1030
        $this->FromName = $name;
1031
        if ($auto) {
1032
            if (empty($this->Sender)) {
1033
                $this->Sender = $address;
1034
            }
1035
        }
1036
        return true;
1037
    }
1038
1039
    /**
1040
     * Return the Message-ID header of the last email.
1041
     * Technically this is the value from the last time the headers were created,
1042
     * but it's also the message ID of the last sent message except in
1043
     * pathological cases.
1044
     * @return string
1045
     */
1046
    public function getLastMessageID()
1047
    {
1048
        return $this->lastMessageID;
1049
    }
1050
1051
    /**
1052
     * Check that a string looks like an email address.
1053
     * @param string $address The email address to check
1054
     * @param string|callable $patternselect A selector for the validation pattern to use :
1055
     * * `auto` Pick best pattern automatically;
1056
     * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
1057
     * * `pcre` Use old PCRE implementation;
1058
     * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
1059
     * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
1060
     * * `noregex` Don't use a regex: super fast, really dumb.
1061
     * Alternatively you may pass in a callable to inject your own validator, for example:
1062
     * PHPMailer::validateAddress('[email protected]', function($address) {
1063
     *     return (strpos($address, '@') !== false);
1064
     * });
1065
     * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
1066
     * @return boolean
1067
     * @static
1068
     * @access public
1069
     */
1070
    public static function validateAddress($address, $patternselect = null)
1071
    {
1072
        if (is_null($patternselect)) {
1073
            $patternselect = self::$validator;
1074
        }
1075
        if (is_callable($patternselect)) {
1076
            return call_user_func($patternselect, $address);
1077
        }
1078
        //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
1079
        if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) {
1080
            return false;
1081
        }
1082
        if (!$patternselect or $patternselect == 'auto') {
1083
            //Check this constant first so it works when extension_loaded() is disabled by safe mode
1084
            //Constant was added in PHP 5.2.4
1085
            if (defined('PCRE_VERSION')) {
1086
                //This pattern can get stuck in a recursive loop in PCRE <= 8.0.2
1087
                if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {