Passed
Branch develop (05352a)
by
unknown
27:04
created

SMTPs::setID()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
/*
3
 * Copyright (C)           Walter Torres        <[email protected]> [with a *lot* of help!]
4
 * Copyright (C) 2005-2015 Laurent Destailleur  <[email protected]>
5
 * Copyright (C) 2006-2011 Regis Houssin
6
 * Copyright (C) 2016      Jonathan TISSEAU     <[email protected]>
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
/**
23
 *	\file       htdocs/core/class/smtps.class.php
24
 *	\brief      Class to construct and send SMTP compliant email, even to a secure
25
 *              SMTP server, regardless of platform.
26
 * Goals:
27
 *  - mime compliant
28
 *  - multiple Reciptiants
29
 *    - TO
30
 *    - CC
31
 *    - BCC
32
 *  - multi-part message
33
 *    - plain text
34
 *    - HTML
35
 *    - inline attachments
36
 *    - attachments
37
 *  - GPG access
38
 * This Class is based off of 'SMTP PHP MAIL' by Dirk Paehl, http://www.paehl.de
39
 */
40
41
42
/**
43
 * 	Class to construct and send SMTP compliant email, even
44
 * 	to a secure SMTP server, regardless of platform.
45
 */
46
class SMTPs
47
{
48
    /**
49
     * Host Name or IP of SMTP Server to use
50
     */
51
    private $_smtpsHost = 'localhost';
52
53
    /**
54
     * SMTP Server Port definition. 25 is default value
55
     * This can be defined via a INI file or via a setter method
56
     */
57
    private $_smtpsPort = '25';
58
59
    /**
60
     * Secure SMTP Server access ID
61
     * This can be defined via a INI file or via a setter method
62
     */
63
    private $_smtpsID = null;
64
65
    /**
66
     * Secure SMTP Server access Password
67
     * This can be defined via a INI file or via a setter method
68
     */
69
    private $_smtpsPW = null;
70
71
    /**
72
     * Who sent the Message
73
     * This can be defined via a INI file or via a setter method
74
     */
75
    private $_msgFrom = null;
76
77
    /**
78
     * Where are replies and errors to be sent to
79
     * This can be defined via a INI file or via a setter method
80
     */
81
    private $_msgReplyTo = null;
82
83
    /**
84
     * Who will the Message be sent to; TO, CC, BCC
85
     * Multi-diminsional array containg addresses the message will
86
     * be sent TO, CC or BCC
87
     */
88
    private $_msgRecipients = null;
89
90
    /**
91
     * Message Subject
92
     */
93
    private $_msgSubject = null;
94
95
    /**
96
     * Message Content
97
     */
98
    private $_msgContent = null;
99
100
    /**
101
     * Custom X-Headers
102
     */
103
    private $_msgXheader = null;
104
105
    /**
106
     * Character set
107
     * Defaulted to 'iso-8859-1'
108
     */
109
    private $_smtpsCharSet = 'iso-8859-1';
110
111
    /**
112
     * Message Sensitivity
113
     * Defaults to ZERO - None
114
     */
115
    private $_msgSensitivity = 0;
116
117
    /**
118
     * Message Sensitivity
119
     */
120
    private $_arySensitivity = array ( false,
121
                                  'Personal',
122
                                  'Private',
123
                                  'Company Confidential' );
124
125
    /**
126
     * Message Sensitivity
127
     * Defaults to 3 - Normal
128
     */
129
    private $_msgPriority = 3;
130
131
    /**
132
     * Message Priority
133
     */
134
    private $_aryPriority = array ( 'Bulk',
135
                                'Highest',
136
                                'High',
137
                                'Normal',
138
                                'Low',
139
                                'Lowest' );
140
141
    /**
142
     * Content-Transfer-Encoding
143
     * Defaulted to 0 - 7bit
144
     */
145
    private $_smtpsTransEncodeType = 0;
146
147
    /**
148
     * Content-Transfer-Encoding
149
     */
150
    private $_smtpsTransEncodeTypes = array( '7bit',               // Simple 7-bit ASCII
151
                                         '8bit',               // 8-bit coding with line termination characters
152
                                         'base64',             // 3 octets encoded into 4 sextets with offset
153
                                         'binary',             // Arbitrary binary stream
154
                                         'mac-binhex40',       // Macintosh binary to hex encoding
155
                                         'quoted-printable',   // Mostly 7-bit, with 8-bit characters encoded as "=HH"
156
                                         'uuencode' );         // UUENCODE encoding
157
158
    /**
159
     * Content-Transfer-Encoding
160
     * Defaulted to '7bit'
161
     */
162
    private $_smtpsTransEncode = '7bit';
163
164
    /**
165
     * Boundary String for MIME seperation
166
     */
167
    private $_smtpsBoundary = null;
168
169
    /**
170
     * Related Boundary
171
     */
172
    private $_smtpsRelatedBoundary = null;
173
174
    /**
175
     * Alternative Boundary
176
     */
177
    private $_smtpsAlternativeBoundary = null;
178
179
    /**
180
     * Determines the method inwhich the message are to be sent.
181
     * - 'sockets' [0] - conect via network to SMTP server - default
182
     * - 'pipe     [1] - use UNIX path to EXE
183
     * - 'phpmail  [2] - use the PHP built-in mail function
184
     * NOTE: Only 'sockets' is implemented
185
     */
186
    private $_transportType = 0;
187
188
    /**
189
     * If '$_transportType' is set to '1', then this variable is used
190
     * to define the UNIX file system path to the sendmail execuable
191
     */
192
    private $_mailPath = '/usr/lib/sendmail';
193
194
    /**
195
     * Sets the SMTP server timeout in seconds.
196
     */
197
    private $_smtpTimeout = 10;
198
199
    /**
200
     * Determines whether to calculate message MD5 checksum.
201
     */
202
    private $_smtpMD5 = false;
203
204
    /**
205
     * Class error codes and messages
206
     */
207
    private $_smtpsErrors = null;
208
209
    /**
210
     * Defines log level
211
     *  0 - no logging
212
     *  1 - connectivity logging
213
     *  2 - message generation logging
214
     *  3 - detail logging
215
     */
216
    private $_log_level = 0;
217
218
    /**
219
     * Place Class in" debug" mode
220
     */
221
    private $_debug = false;
222
223
224
    // @CHANGE LDR
225
    public $log = '';
226
    private $_errorsTo = '';
227
    private $_deliveryReceipt = 0;
228
    private $_trackId = '';
229
    private $_moreInHeader = '';
230
231
232
    /**
233
     * Set delivery receipt
234
     *
235
     * @param	int		$_val		Value
236
     * @return	void
237
     */
238
    public function setDeliveryReceipt($_val = 0)
239
    {
240
        $this->_deliveryReceipt = $_val;
241
    }
242
243
    /**
244
     * get delivery receipt
245
     *
246
     * @return	int		Delivery receipt
247
     */
248
    public function getDeliveryReceipt()
249
    {
250
        return $this->_deliveryReceipt;
251
    }
252
253
    /**
254
     * Set trackid
255
     *
256
     * @param	string		$_val		Value
257
     * @return	void
258
     */
259
    public function setTrackId($_val = '')
260
    {
261
        $this->_trackId = $_val;
262
    }
263
264
    /**
265
     * Set moreInHeader
266
     *
267
     * @param	string		$_val		Value
268
     * @return	void
269
     */
270
    public function setMoreInHeader($_val = '')
271
    {
272
        $this->_moreinheader = $_val;
273
    }
274
275
    /**
276
     * get trackid
277
     *
278
     * @return	string		Track id
279
     */
280
    public function getTrackId()
281
    {
282
        return $this->_trackId;
283
    }
284
285
    /**
286
     * get moreInHeader
287
     *
288
     * @return	string		moreInHeader
289
     */
290
    public function getMoreInHeader()
291
    {
292
        return $this->_moreinheader;
293
    }
294
295
    /**
296
     * Set errors to
297
     *
298
     * @param	string		$_strErrorsTo		Errors to
299
     * @return	void
300
     */
301
    public function setErrorsTo($_strErrorsTo)
302
    {
303
        if ( $_strErrorsTo )
304
        $this->_errorsTo = $this->_strip_email($_strErrorsTo);
305
    }
306
307
    /**
308
     * Get errors to
309
     *
310
     * @param	boolean		$_part		Variant
311
     * @return	string					Errors to
312
     */
313
    public function getErrorsTo($_part = true)
314
    {
315
        $_retValue = '';
316
317
        if ( $_part === true )
318
        $_retValue = $this->_errorsTo;
319
        else
320
        $_retValue = $this->_errorsTo[$_part];
321
322
        return $_retValue;
323
    }
324
325
    /**
326
     * Set debug
327
     *
328
     * @param	boolean		$_vDebug		Value for debug
329
     * @return 	void
330
     */
331
    public function setDebug($_vDebug = false)
332
    {
333
        $this->_debug = $_vDebug;
334
    }
335
336
    /**
337
     * build RECIPIENT List, all addresses who will recieve this message
338
     *
339
     * @return void
340
     */
341
    public function buildRCPTlist()
342
    {
343
        // Pull TO list
344
        $_aryToList = $this->getTO();
345
    }
346
347
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
348
    /**
349
     * Attempt a connection to mail server
350
     *
351
     * @return mixed  $_retVal   Boolean indicating success or failure on connection
352
     */
353
    private function _server_connect()
354
    {
355
        // phpcs:enable
356
        // Default return value
357
        $_retVal = true;
358
359
        // We have to make sure the HOST given is valid
360
        // This is done here because '@fsockopen' will not give me this
361
        // information if it failes to connect because it can't find the HOST
362
        $host=$this->getHost();
363
        $usetls = preg_match('@tls://@i', $host);
364
365
        $host=preg_replace('@tcp://@i', '', $host);	// Remove prefix
366
        $host=preg_replace('@ssl://@i', '', $host);	// Remove prefix
367
        $host=preg_replace('@tls://@i', '', $host);	// Remove prefix
368
369
        // @CHANGE LDR
370
        include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
371
372
        if ( (! is_ip($host)) && ((gethostbyname($host)) == $host))
373
        {
374
            $this->_setErr(99, $host . ' is either offline or is an invalid host name.');
375
            $_retVal = false;
376
        }
377
        else
378
        {
379
            //See if we can connect to the SMTP server
380
            if ($this->socket = @fsockopen(
381
                preg_replace('@tls://@i', '', $this->getHost()),       // Host to 'hit', IP or domain
382
                $this->getPort(),       // which Port number to use
383
                $this->errno,           // actual system level error
0 ignored issues
show
Bug Best Practice introduced by
The property errno does not exist on SMTPs. Did you maybe forget to declare it?
Loading history...
384
                $this->errstr,          // and any text that goes with the error
385
                $this->_smtpTimeout     // timeout for reading/writing data over the socket
386
            )) {
387
                // Fix from PHP SMTP class by 'Chris Ryan'
388
                // Sometimes the SMTP server takes a little longer to respond
389
                // so we will give it a longer timeout for the first read
390
                // Windows still does not have support for this timeout function
391
                if (function_exists('stream_set_timeout')) stream_set_timeout($this->socket, $this->_smtpTimeout, 0);
392
393
                // Check response from Server
394
                if ( $_retVal = $this->server_parse($this->socket, "220") )
395
                $_retVal = $this->socket;
396
            }
397
            // This connection attempt failed.
398
            else
399
            {
400
                // @CHANGE LDR
401
                if (empty($this->errstr)) $this->errstr='Failed to connect with fsockopen host='.$this->getHost().' port='.$this->getPort();
402
                $this->_setErr($this->errno, $this->errstr);
403
                $_retVal = false;
404
            }
405
        }
406
407
        return $_retVal;
408
    }
409
410
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
411
    /**
412
     * Attempt mail server authentication for a secure connection
413
     *
414
     * @return boolean|null  $_retVal   Boolean indicating success or failure of authentication
415
     */
416
    private function _server_authenticate()
417
    {
418
        // phpcs:enable
419
        global $conf;
420
421
        // Send the RFC2554 specified EHLO.
422
        // This improvment as provided by 'SirSir' to
423
        // accomodate both SMTP AND ESMTP capable servers
424
        $host=$this->getHost();
425
        $usetls = preg_match('@tls://@i', $host);
426
427
        $host=preg_replace('@tcp://@i', '', $host);	// Remove prefix
428
        $host=preg_replace('@ssl://@i', '', $host);	// Remove prefix
429
        $host=preg_replace('@tls://@i', '', $host);	// Remove prefix
430
431
        if ($usetls) $host='tls://'.$host;
432
433
        $hosth = $host;
434
435
        if (! empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO))
436
        {
437
            // If the from to is 'aaa <[email protected]>', we will keep 'ccc.com'
438
            $hosth = $this->getFrom('addr');
439
            $hosth = preg_replace('/^.*</', '', $hosth);
440
            $hosth = preg_replace('/>.*$/', '', $hosth);
441
            $hosth = preg_replace('/.*@/', '', $hosth);
442
        }
443
444
        if ( $_retVal = $this->socket_send_str('EHLO ' . $hosth, '250') )
445
        {
446
            if ($usetls)
447
            {
448
                /*
449
                The following dialog illustrates how a client and server can start a TLS STARTTLS session
450
                S: <waits for connection on TCP port 25>
451
                C: <opens connection>
452
                S: 220 mail.imc.org SMTP service ready
453
                C: EHLO mail.ietf.org
454
                S: 250-mail.imc.org offers a warm hug of welcome
455
                S: 250 STARTTLS
456
                C: STARTTLS
457
                S: 220 Go ahead
458
                C: <starts TLS negotiation>
459
                C & S: <negotiate a TLS session>
460
                C & S: <check result of negotiation>
461
                // Second pass EHLO
462
                C: EHLO client-domain.com
463
                S: 250-server-domain.com
464
                S: 250 AUTH LOGIN
465
                C: <continues by sending an SMTP command
466
                */
467
                if (!$_retVal = $this->socket_send_str('STARTTLS', 220))
468
                {
469
                    $this->_setErr(131, 'STARTTLS connection is not supported.');
470
                    return $_retVal;
471
                }
472
473
                // Before 5.6.7:
474
                // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_SSLv2_CLIENT|STREAM_CRYPTO_METHOD_SSLv3_CLIENT
475
                // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
476
                // PHP >= 5.6.7:
477
                // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
478
                // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
479
480
                $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
481
                if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
482
                    $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
483
                    $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
484
                }
485
486
                if (!stream_socket_enable_crypto($this->socket, true, $crypto_method))
487
                {
488
                    $this->_setErr(132, 'STARTTLS connection failed.');
489
                    return $_retVal;
490
                }
491
                // Most server servers expect a 2nd pass of EHLO after TLS is established to get another time
492
                // the answer with list of supported AUTH methods. They may differs between non STARTTLS and with STARTTLS.
493
                if (!$_retVal = $this->socket_send_str('EHLO '.$host, '250'))
494
                {
495
                    $this->_setErr(126, '"' . $host . '" does not support authenticated connections.');
496
                    return $_retVal;
497
                }
498
            }
499
			
500
			// Default authentication method is LOGIN
501
			if (empty($conf->global->MAIL_SMTP_AUTH_TYPE)) $conf->global->MAIL_SMTP_AUTH_TYPE = 'LOGIN';
502
			
503
            // Send Authentication to Server
504
            // Check for errors along the way
505
            switch ($conf->global->MAIL_SMTP_AUTH_TYPE) {
506
                case 'PLAIN':
507
                    $this->socket_send_str('AUTH PLAIN', '334');
508
                    // The error here just means the ID/password combo doesn't work.
509
                    $_retVal = $this->socket_send_str(base64_encode("\0" . $this->_smtpsID . "\0" . $this->_smtpsPW), '235');
510
                    break;
511
                case 'LOGIN':
512
                default:
513
                    $this->socket_send_str('AUTH LOGIN', '334');
514
                    // User name will not return any error, server will take anything we give it.
515
                    $this->socket_send_str(base64_encode($this->_smtpsID), '334');
516
                    // The error here just means the ID/password combo doesn't work.
517
                    // There is not a method to determine which is the problem, ID or password
518
                    $_retVal = $this->socket_send_str(base64_encode($this->_smtpsPW), '235');
519
                    break;
520
            }
521
            if (! $_retVal) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $_retVal of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
522
                $this->_setErr(130, 'Invalid Authentication Credentials.');
523
			}
524
        }
525
        else
526
        {
527
            $this->_setErr(126, '"' . $host . '" does not support authenticated connections.');
528
        }
529
530
        return $_retVal;
531
    }
532
533
    /**
534
     * Now send the message
535
     *
536
     * @param  boolean $_bolTestMsg  whether to run this method in 'Test' mode.
537
     * @param  boolean $_bolDebug    whether to log all communication between this Class and the Mail Server.
538
     * @return boolean|null   void
539
     *                 $_strMsg      If this is run in 'Test' mode, the actual message structure will be returned
540
     */
541
    public function sendMsg($_bolTestMsg = false, $_bolDebug = false)
542
    {
543
        global $conf;
544
545
        /**
546
         * Default return value
547
         */
548
        $_retVal = false;
549
550
        // Connect to Server
551
        if ( $this->socket = $this->_server_connect() )
552
        {
553
            // If a User ID *and* a password is given, assume Authentication is desired
554
            if( !empty($this->_smtpsID) && !empty($this->_smtpsPW) )
555
            {
556
                // Send the RFC2554 specified EHLO.
557
                $_retVal = $this->_server_authenticate();
558
            }
559
560
            // This is a "normal" SMTP Server "handshack"
561
            else
562
            {
563
                // Send the RFC821 specified HELO.
564
                $host=$this->getHost();
565
                $usetls = preg_match('@tls://@i', $host);
566
567
                $host=preg_replace('@tcp://@i', '', $host);	// Remove prefix
568
                $host=preg_replace('@ssl://@i', '', $host);	// Remove prefix
569
                $host=preg_replace('@tls://@i', '', $host);	// Remove prefix
570
571
                $hosth = $host;
572
573
                if (! empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO))
574
                {
575
                    // If the from to is 'aaa <[email protected]>', we will keep 'ccc.com'
576
                    $hosth = $this->getFrom('addr');
577
                    $hosth = preg_replace('/^.*</', '', $hosth);
578
                    $hosth = preg_replace('/>.*$/', '', $hosth);
579
                    $hosth = preg_replace('/.*@/', '', $hosth);
580
                }
581
582
                $_retVal = $this->socket_send_str('HELO ' . $hosth, '250');
583
            }
584
585
            // Well, did we get to the server?
586
            if ( $_retVal )
587
            {
588
                // From this point onward most server response codes should be 250
589
                // Specify who the mail is from....
590
                // This has to be the raw email address, strip the "name" off
591
                $this->socket_send_str('MAIL FROM: ' . $this->getFrom('addr'), '250');
592
593
                // 'RCPT TO:' must be given a single address, so this has to loop
594
                // through the list of addresses, regardless of TO, CC or BCC
595
                // and send it out "single file"
596
                foreach ($this->get_RCPT_list() as $_address)
597
                {
598
                    /* Note:
599
                     * BCC email addresses must be listed in the RCPT TO command list,
600
                     * but the BCC header should not be printed under the DATA command.
601
                     * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
602
                     */
603
604
                    /*
605
                     * TODO
606
                     * After each 'RCPT TO:' is sent, we need to make sure it was kosher,
607
                     * if not, the whole message will fail
608
                     * If any email address fails, we will need to RESET the connection,
609
                     * mark the last address as "bad" and start the address loop over again.
610
                     * If any address fails, the entire message fails.
611
                     */
612
                    $this->socket_send_str('RCPT TO: <' . $_address . '>', '250');
613
                }
614
615
                // Tell the server we are ready to start sending data
616
                // with any custom headers...
617
                // This is the last response code we look for until the end of the message.
618
                $this->socket_send_str('DATA', '354');
619
620
                // Now we are ready for the message...
621
                // Ok, all the ingredients are mixed in let's cook this puppy...
622
                $this->socket_send_str($this->getHeader().$this->getBodyContent() . "\r\n" . '.', '250');
623
624
                // Now tell the server we are done and close the socket...
625
                fputs($this->socket, 'QUIT');
626
                fclose($this->socket);
627
            }
628
        }
629
630
        return $_retVal;
631
    }
632
633
    // =============================================================
634
    // ** Setter & Getter methods
635
636
    // ** Basic System configuration
637
638
    /**
639
     * setConfig() is used to populate select class properties from either
640
     * a user defined INI file or the systems 'php.ini' file
641
     *
642
     * If a user defined INI is to be used, the files complete path is passed
643
     * as the method single parameter. The INI can define any class and/or
644
     * user properties. Only properties defined within this file will be setter
645
     * and/or orverwritten
646
     *
647
     * If the systems 'php.ini' file is to be used, the method is called without
648
     * parameters. In this case, only HOST, PORT and FROM properties will be set
649
     * as they are the only properties that are defined within the 'php.ini'.
650
     *
651
     * If secure SMTP is to be used, the user ID and Password can be defined with
652
     * the user INI file, but the properties are not defined with the systems
653
     * 'php.ini'file, they must be defined via their setter methods
654
     *
655
     * This method can be called twice, if desired. Once without a parameter to
656
     * load the properties as defined within the systems 'php.ini' file, and a
657
     * second time, with a path to a user INI file for other properties to be
658
     * defined.
659
     *
660
     * @param mixed $_strConfigPath path to config file or VOID
661
     * @return boolean
662
     */
663
    public function setConfig($_strConfigPath = null)
664
    {
665
        /**
666
         * Returns constructed SELECT Object string or boolean upon failure
667
         * Default value is set at true
668
         */
669
        $_retVal = true;
670
671
        // if we have a path...
672
        if ( ! empty($_strConfigPath) )
673
        {
674
            // If the path is not valid, this will NOT generate an error,
675
            // it will simply return false.
676
            if ( ! @include $_strConfigPath)
677
            {
678
                $this->_setErr(110, '"' . $_strConfigPath . '" is not a valid path.');
679
                $_retVal = false;
680
            }
681
        }
682
683
        // Read the Systems php.ini file
684
        else
685
        {
686
            // Set these properties ONLY if they are set in the php.ini file.
687
            // Otherwise the default values will be used.
688
            if ( $_host = ini_get('SMTPs') )
689
            $this->setHost($_host);
690
691
            if ( $_port = ini_get('smtp_port') )
692
            $this->setPort($_port);
693
694
            if ( $_from = ini_get('sendmail_from') )
695
            $this->setFrom($_from);
696
        }
697
698
        // Send back what we have
699
        return $_retVal;
700
    }
701
702
    /**
703
     * Determines the method inwhich the messages are to be sent.
704
     * - 'sockets' [0] - conect via network to SMTP server
705
     * - 'pipe     [1] - use UNIX path to EXE
706
     * - 'phpmail  [2] - use the PHP built-in mail function
707
     *
708
     * @param int $_type  Interger value representing Mail Transport Type
709
     * @return void
710
     */
711
    public function setTransportType($_type = 0)
712
    {
713
        if ((is_numeric($_type)) && (($_type >= 0) && ($_type <= 3))) {
714
            $this->_transportType = $_type;
715
        }
716
    }
717
718
    /**
719
     * Return the method inwhich the message is to be sent.
720
     * - 'sockets' [0] - conect via network to SMTP server
721
     * - 'pipe     [1] - use UNIX path to EXE
722
     * - 'phpmail  [2] - use the PHP built-in mail function
723
     *
724
     * @return int $_strHost Host Name or IP of the Mail Server to use
725
     */
726
    public function getTransportType()
727
    {
728
        return $this->_transportType;
729
    }
730
731
    /**
732
     * Path to the sendmail execuable
733
     *
734
     * @param string $_path Path to the sendmail execuable
735
     * @return boolean
736
     *
737
     */
738
    public function setMailPath($_path)
739
    {
740
        // This feature is not yet implemented
741
        return true;
742
743
        //if ( $_path ) $this->_mailPath = $_path;
744
    }
745
746
    /**
747
     * Defines the Host Name or IP of the Mail Server to use.
748
     * This is defaulted to 'localhost'
749
     * This is  used only with 'socket' based mail transmission
750
     *
751
     * @param 	string 	$_strHost 		Host Name or IP of the Mail Server to use
752
     * @return 	void
753
     */
754
    public function setHost($_strHost)
755
    {
756
        if ( $_strHost )
757
        $this->_smtpsHost = $_strHost;
758
    }
759
760
    /**
761
     * Retrieves the Host Name or IP of the Mail Server to use
762
     * This is  used only with 'socket' based mail transmission
763
     *
764
     * @return 	string 	$_strHost 		Host Name or IP of the Mail Server to use
765
     */
766
    public function getHost()
767
    {
768
        return $this->_smtpsHost;
769
    }
770
771
    /**
772
     * Defines the Port Number of the Mail Server to use
773
     * This is defaulted to '25'
774
     * This is  used only with 'socket' based mail transmission
775
     *
776
     * @param 	int 	$_intPort 		Port Number of the Mail Server to use
777
     * @return 	void
778
     */
779
    public function setPort($_intPort)
780
    {
781
        if ( ( is_numeric($_intPort) ) &&
782
        ( ( $_intPort >= 1 ) && ( $_intPort <= 65536 ) ) )
783
        $this->_smtpsPort = $_intPort;
784
    }
785
786
    /**
787
     * Retrieves the Port Number of the Mail Server to use
788
     * This is  used only with 'socket' based mail transmission
789
     *
790
     * @return 	string 		Port Number of the Mail Server to use
791
     */
792
    public function getPort()
793
    {
794
        return $this->_smtpsPort;
795
    }
796
797
    /**
798
     * User Name for authentication on Mail Server
799
     *
800
     * @param 	string 	$_strID 	User Name for authentication on Mail Server
801
     * @return 	void
802
     */
803
    public function setID($_strID)
804
    {
805
        $this->_smtpsID = $_strID;
806
    }
807
808
    /**
809
     * Retrieves the User Name for authentication on Mail Server
810
     *
811
     * @return string 	User Name for authentication on Mail Server
812
     */
813
    public function getID()
814
    {
815
        return $this->_smtpsID;
816
    }
817
818
    /**
819
     * User Password for authentication on Mail Server
820
     *
821
     * @param 	string 	$_strPW 	User Password for authentication on Mail Server
822
     * @return 	void
823
     */
824
    public function setPW($_strPW)
825
    {
826
        $this->_smtpsPW = $_strPW;
827
    }
828
829
    /**
830
     * Retrieves the User Password for authentication on Mail Server
831
     *
832
     * @return 	string 		User Password for authentication on Mail Server
833
     */
834
    public function getPW()
835
    {
836
        return $this->_smtpsPW;
837
    }
838
839
    /**
840
     * Character set used for current message
841
     * Character set is defaulted to 'iso-8859-1';
842
     *
843
     * @param string $_strCharSet Character set used for current message
844
     * @return void
845
     */
846
    public function setCharSet($_strCharSet)
847
    {
848
        if ( $_strCharSet )
849
        $this->_smtpsCharSet = $_strCharSet;
850
    }
851
852
    /**
853
     * Retrieves the Character set used for current message
854
     *
855
     * @return string $_smtpsCharSet Character set used for current message
856
     */
857
    public function getCharSet()
858
    {
859
        return $this->_smtpsCharSet;
860
    }
861
862
    /**
863
     * Content-Transfer-Encoding, Defaulted to '7bit'
864
     * This can be changed for 2byte characers sets
865
     * Known Encode Types
866
     *  - 7bit               Simple 7-bit ASCII
867
     *  - 8bit               8-bit coding with line termination characters
868
     *  - base64             3 octets encoded into 4 sextets with offset
869
     *  - binary             Arbitrary binary stream
870
     *  - mac-binhex40       Macintosh binary to hex encoding
871
     *  - quoted-printable   Mostly 7-bit, with 8-bit characters encoded as "=HH"
872
     *  - uuencode           UUENCODE encoding
873
     *
874
     * @param string $_strTransEncode Content-Transfer-Encoding
875
     * @return void
876
     */
877
    public function setTransEncode($_strTransEncode)
878
    {
879
        if (array_search($_strTransEncode, $this->_smtpsTransEncodeTypes))
880
        $this->_smtpsTransEncode = $_strTransEncode;
881
    }
882
883
    /**
884
     * Retrieves the Content-Transfer-Encoding
885
     *
886
     * @return string $_smtpsTransEncode Content-Transfer-Encoding
887
     */
888
    public function getTransEncode()
889
    {
890
        return $this->_smtpsTransEncode;
891
    }
892
893
    /**
894
     * Content-Transfer-Encoding, Defaulted to '0' [ZERO]
895
     * This can be changed for 2byte characers sets
896
     * Known Encode Types
897
     *  - [0] 7bit               Simple 7-bit ASCII
898
     *  - [1] 8bit               8-bit coding with line termination characters
899
     *  - [2] base64             3 octets encoded into 4 sextets with offset
900
     *  - [3] binary             Arbitrary binary stream
901
     *  - [4] mac-binhex40       Macintosh binary to hex encoding
902
     *  - [5] quoted-printable   Mostly 7-bit, with 8-bit characters encoded as "=HH"
903
     *  - [6] uuencode           UUENCODE encoding
904
     *
905
     * @param string $_strTransEncodeType Content-Transfer-Encoding
906
     * @return void
907
     *
908
     */
909
    public function setTransEncodeType($_strTransEncodeType)
910
    {
911
        if (array_search($_strTransEncodeType, $this->_smtpsTransEncodeTypes))
912
        $this->_smtpsTransEncodeType = $_strTransEncodeType;
913
    }
914
915
    /**
916
     * Retrieves the Content-Transfer-Encoding
917
     *
918
     * @return 	string 		Content-Transfer-Encoding
919
     */
920
    public function getTransEncodeType()
921
    {
922
        return $this->_smtpsTransEncodeTypes[$this->_smtpsTransEncodeType];
923
    }
924
925
926
    // ** Message Construction
927
928
    /**
929
     * FROM Address from which mail will be sent
930
     *
931
     * @param 	string 	$_strFrom 	Address from which mail will be sent
932
     * @return 	void
933
     */
934
    public function setFrom($_strFrom)
935
    {
936
        if ( $_strFrom )
937
        $this->_msgFrom = $this->_strip_email($_strFrom);
938
    }
939
940
    /**
941
     * Retrieves the Address from which mail will be sent
942
     *
943
     * @param  	boolean $_part		To "strip" 'Real name' from address
944
     * @return 	string 				Address from which mail will be sent
945
     */
946
    public function getFrom($_part = true)
947
    {
948
        $_retValue = '';
949
950
        if ( $_part === true )
951
        $_retValue = $this->_msgFrom;
952
        else
953
        $_retValue = $this->_msgFrom[$_part];
954
955
        return $_retValue;
956
    }
957
958
    /**
959
     * Reply-To Address from which mail will be the reply-to
960
     *
961
     * @param 	string 	$_strReplyTo 	Address from which mail will be the reply-to
962
     * @return 	void
963
     */
964
    public function setReplyTo($_strReplyTo)
965
    {
966
        if ( $_strReplyTo )
967
            $this->_msgReplyTo = $this->_strip_email($_strReplyTo);
968
    }
969
970
    /**
971
     * Retrieves the Address from which mail will be the reply-to
972
     *
973
     * @param  	boolean $_part		To "strip" 'Real name' from address
974
     * @return 	string 				Address from which mail will be the reply-to
975
     */
976
    public function getReplyTo($_part = true)
977
    {
978
        $_retValue = '';
979
980
        if ( $_part === true )
981
            $_retValue = $this->_msgReplyTo;
982
        else
983
            $_retValue = $this->_msgReplyTo[$_part];
984
985
        return $_retValue;
986
    }
987
988
    /**
989
     * Inserts given addresses into structured format.
990
     * This method takes a list of given addresses, via an array
991
     * or a COMMA delimted string, and inserts them into a highly
992
     * structured array. This array is designed to remove duplicate
993
     * addresses and to sort them by Domain.
994
     *
995
     * @param 	string 	$_type 			TO, CC, or BCC lists to add addrresses into
996
     * @param 	mixed 	$_addrList 		Array or COMMA delimited string of addresses
997
     * @return void
998
     *
999
     */
1000
    private function _buildAddrList($_type, $_addrList)
1001
    {
1002
        // Pull existing list
1003
        $aryHost = $this->_msgRecipients;
1004
1005
        // Only run this if we have something
1006
        if ( !empty($_addrList))
1007
        {
1008
            // $_addrList can be a STRING or an array
1009
            if ( is_string($_addrList) )
1010
            {
1011
                // This could be a COMMA delimited string
1012
                if ( strstr($_addrList, ',') )
1013
                // "explode "list" into an array
1014
                $_addrList = explode(',', $_addrList);
1015
1016
                // Stick it in an array
1017
                else
1018
                $_addrList = array($_addrList);
1019
            }
1020
1021
            // take the array of addresses and split them further
1022
            foreach ($_addrList as $_strAddr)
1023
            {
1024
                // Strip off the end '>'
1025
                $_strAddr = str_replace('>', '', $_strAddr);
1026
1027
                // Seperate "Real Name" from eMail address
1028
                $_tmpaddr = null;
1029
                $_tmpaddr = explode('<', $_strAddr);
1030
1031
                // We have a "Real Name" and eMail address
1032
                if ( count($_tmpaddr) == 2 )
1033
                {
1034
                    $_tmpHost = explode('@', $_tmpaddr[1]);
1035
                    $_tmpaddr[0] = trim($_tmpaddr[0], ' ">');
1036
                    $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = $_tmpaddr[0];
1037
                }
1038
                // We only have an eMail address
1039
                else
1040
                {
1041
                    // Strip off the beggining '<'
1042
                    $_strAddr = str_replace('<', '', $_strAddr);
1043
1044
                    $_tmpHost = explode('@', $_strAddr);
1045
                    $_tmpHost[0] = trim($_tmpHost[0]);
1046
                    $_tmpHost[1] = trim($_tmpHost[1]);
1047
1048
                    $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = '';
1049
                }
1050
            }
1051
        }
1052
        // replace list
1053
        $this->_msgRecipients = $aryHost;
1054
    }
1055
1056
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1057
    /**
1058
     * Returns an array of the various parts of an email address
1059
     * This assumes a well formed address:
1060
     * - "Real name" <[email protected]>
1061
     * - "Real Name" is optional
1062
     * - if "Real Name" does not exist, the angle brackets are optional
1063
     * This will split an email address into 4 or 5 parts.
1064
     * - $_aryEmail[org]  = orignal string
1065
     * - $_aryEmail[real] = "real name" - if there is one
1066
     * - $_aryEmail[addr] = address part "[email protected]"
1067
     * - $_aryEmail[host] = "domain.tld"
1068
     * - $_aryEmail[user] = "userName"
1069
     *
1070
     *	@param		string		$_strAddr		Email address
1071
     * 	@return 	array	 					An array of the various parts of an email address
1072
     */
1073
    private function _strip_email($_strAddr)
1074
    {
1075
        // phpcs:enable
1076
        // Keep the orginal
1077
        $_aryEmail['org'] = $_strAddr;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$_aryEmail was never initialized. Although not strictly required by PHP, it is generally a good practice to add $_aryEmail = array(); before regardless.
Loading history...
1078
1079
        // Set entire string to Lower Case
1080
        $_strAddr = strtolower($_strAddr);
1081
1082
        // Drop "stuff' off the end
1083
        $_strAddr = trim($_strAddr, ' ">');
1084
1085
        // Seperate "Real Name" from eMail address, if we have one
1086
        $_tmpAry = explode('<', $_strAddr);
1087
1088
        // Do we have a "Real name"
1089
        if ( count($_tmpAry) == 2 )
1090
        {
1091
            // We may not really have a "Real Name"
1092
            if ( $_tmpAry[0])
1093
            $_aryEmail['real'] = trim($_tmpAry[0], ' ">');
1094
1095
            $_aryEmail['addr'] = $_tmpAry[1];
1096
        }
1097
        else
1098
        $_aryEmail['addr'] = $_tmpAry[0];
1099
1100
        // Pull User Name and Host.tld apart
1101
        list($_aryEmail['user'], $_aryEmail['host'] ) = explode('@', $_aryEmail['addr']);
1102
1103
        // Put the brackets back around the address
1104
        $_aryEmail['addr'] = '<' . $_aryEmail['addr'] . '>';
1105
1106
        return $_aryEmail;
1107
    }
1108
1109
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1110
    /**
1111
     * Returns an array of bares addresses for use with 'RCPT TO:'
1112
     * This is a "build as you go" method. Each time this method is called
1113
     * the underlaying array is destroyed and reconstructed.
1114
     *
1115
     * @return 		array		Returns an array of bares addresses
1116
     */
1117
    public function get_RCPT_list()
1118
    {
1119
        // phpcs:enable
1120
        /**
1121
         * An array of bares addresses for use with 'RCPT TO:'
1122
         */
1123
        $_RCPT_list=array();
1124
1125
        // walk down Recipients array and pull just email addresses
1126
        foreach ($this->_msgRecipients as $_host => $_list)
1127
        {
1128
            foreach ($_list as $_subList)
1129
            {
1130
                foreach ($_subList as $_name => $_addr)
1131
                {
1132
                    // build RCPT list
1133
                    $_RCPT_list[] = $_name . '@' . $_host;
1134
                }
1135
            }
1136
        }
1137
1138
        return $_RCPT_list;
1139
    }
1140
1141
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1142
    /**
1143
     * Returns an array of addresses for a specific type; TO, CC or BCC
1144
     *
1145
     * @param 		string 	       $_which 	    Which collection of addresses to return ('to', 'cc', 'bcc')
1146
     * @return 		string|false 				Array of emaill address
1147
     */
1148
    public function get_email_list($_which = null)
1149
    {
1150
        // phpcs:enable
1151
        // We need to know which address segment to pull
1152
        if ( $_which )
1153
        {
1154
            // Make sure we have addresses to process
1155
            if ( $this->_msgRecipients )
1156
            {
1157
                $_RCPT_list=array();
1158
                // walk down Recipients array and pull just email addresses
1159
                foreach ($this->_msgRecipients as $_host => $_list)
1160
                {
1161
                    if ( $this->_msgRecipients[$_host][$_which] )
1162
                    {
1163
                        foreach ($this->_msgRecipients[$_host][$_which] as $_addr => $_realName)
1164
                        {
1165
                            if ( $_realName )	// @CHANGE LDR
1166
                            {
1167
                                $_realName = '"' . $_realName . '"';
1168
                                $_RCPT_list[] = $_realName . ' <' . $_addr . '@' . $_host . '>';
1169
                            }
1170
                            else
1171
                            {
1172
                                $_RCPT_list[] = $_addr . '@' . $_host;
1173
                            }
1174
                        }
1175
                    }
1176
                }
1177
1178
                return implode(', ', $_RCPT_list);
1179
            }
1180
            else
1181
            {
1182
                $this->_setErr(101, 'No eMail Address for message to be sent to.');
1183
                return false;
1184
            }
1185
        }
1186
        else
1187
        {
1188
            $this->_setErr(102, 'eMail type not defined.');
1189
            return false;
1190
        }
1191
    }
1192
1193
    /**
1194
     * TO Address[es] inwhich to send mail to
1195
     *
1196
     * @param 	string 	$_addrTo 	TO Address[es] inwhich to send mail to
1197
     * @return 	void
1198
     */
1199
    public function setTO($_addrTo)
1200
    {
1201
        if ( $_addrTo )
1202
        $this->_buildAddrList('to', $_addrTo);
1203
    }
1204
1205
    /**
1206
     * Retrieves the TO Address[es] inwhich to send mail to
1207
     *
1208
     * @return 	string 	TO Address[es] inwhich to send mail to
1209
     */
1210
    public function getTo()
1211
    {
1212
        return $this->get_email_list('to');
1213
    }
1214
1215
    /**
1216
     * CC Address[es] inwhich to send mail to
1217
     *
1218
     * @param 	string	$_strCC		CC Address[es] inwhich to send mail to
1219
     * @return 	void
1220
     */
1221
    public function setCC($_strCC)
1222
    {
1223
        if ( $_strCC )
1224
        $this->_buildAddrList('cc', $_strCC);
1225
    }
1226
1227
    /**
1228
     * Retrieves the CC Address[es] inwhich to send mail to
1229
     *
1230
     * @return 	string 		CC Address[es] inwhich to send mail to
1231
     */
1232
    public function getCC()
1233
    {
1234
        return $this->get_email_list('cc');
1235
    }
1236
1237
    /**
1238
     * BCC Address[es] inwhich to send mail to
1239
     *
1240
     * @param 	string		$_strBCC	Recipients BCC Address[es] inwhich to send mail to
1241
     * @return 	void
1242
     */
1243
    public function setBCC($_strBCC)
1244
    {
1245
        if ( $_strBCC )
1246
        $this->_buildAddrList('bcc', $_strBCC);
1247
    }
1248
1249
    /**
1250
     * Retrieves the BCC Address[es] inwhich to send mail to
1251
     *
1252
     * @return 	string		BCC Address[es] inwhich to send mail to
1253
     */
1254
    public function getBCC()
1255
    {
1256
        return $this->get_email_list('bcc');
1257
    }
1258
1259
    /**
1260
     * Message Subject
1261
     *
1262
     * @param 	string 	$_strSubject	Message Subject
1263
     * @return 	void
1264
     */
1265
    public function setSubject($_strSubject = '')
1266
    {
1267
        if ( $_strSubject )
1268
        $this->_msgSubject = $_strSubject;
1269
    }
1270
1271
    /**
1272
     * Retrieves the Message Subject
1273
     *
1274
     * @return 	string 		Message Subject
1275
     */
1276
    public function getSubject()
1277
    {
1278
        return $this->_msgSubject;
1279
    }
1280
1281
    /**
1282
     * Constructes and returns message header
1283
     *
1284
     * @return string Complete message header
1285
     */
1286
    public function getHeader()
1287
    {
1288
        global $conf;
1289
1290
        $_header = 'From: '       . $this->getFrom('org') . "\r\n"
1291
        . 'To: '         . $this->getTO()          . "\r\n";
1292
1293
        if ( $this->getCC() )
1294
        $_header .= 'Cc: ' . $this->getCC()  . "\r\n";
1295
1296
        /* Note:
1297
         * BCC email addresses must be listed in the RCPT TO command list,
1298
         * but the BCC header should not be printed under the DATA command.
1299
         * So it is included into the function sendMsg() but not here.
1300
         * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
1301
         */
1302
        /*
1303
        if ( $this->getBCC() )
1304
        $_header .= 'Bcc: ' . $this->getBCC()  . "\r\n";
1305
        */
1306
1307
        $host=$this->getHost();
1308
        $usetls = preg_match('@tls://@i', $host);
1309
1310
        $host=preg_replace('@tcp://@i', '', $host);	// Remove prefix
1311
        $host=preg_replace('@ssl://@i', '', $host);	// Remove prefix
1312
        $host=preg_replace('@tls://@i', '', $host);	// Remove prefix
1313
1314
        $host=dol_getprefix('email');
1315
1316
        //NOTE: Message-ID should probably contain the username of the user who sent the msg
1317
        $_header .= 'Subject: '    . $this->getSubject()     . "\r\n";
1318
        $_header .= 'Date: '       . date("r")               . "\r\n";
1319
1320
        $trackid = $this->getTrackId();
1321
        if ($trackid)
1322
        {
1323
            // References is kept in response and Message-ID is returned into In-Reply-To:
1324
            $_header .= 'Message-ID: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n";
1325
            $_header .= 'References: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n";
1326
            $_header .= 'X-Dolibarr-TRACKID: ' . $trackid . '@' . $host . "\r\n";
1327
        }
1328
        else
1329
        {
1330
            $_header .= 'Message-ID: <' . time() . '.SMTPs@' . $host . ">\r\n";
1331
        }
1332
        if (! empty($_SERVER['REMOTE_ADDR'])) $_header .= "X-RemoteAddr: " . $_SERVER['REMOTE_ADDR']. "\r\n";
1333
        if ( $this->getMoreInHeader() )
1334
            $_header .= $this->getMoreInHeader();     // Value must include the "\r\n";
1335
1336
        //$_header .=
1337
        //                 'Read-Receipt-To: '   . $this->getFrom( 'org' ) . "\r\n"
1338
        //                 'Return-Receipt-To: ' . $this->getFrom( 'org' ) . "\r\n";
1339
1340
        if ( $this->getSensitivity() )
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->getSensitivity() targeting SMTPs::getSensitivity() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1341
        $_header .= 'Sensitivity: ' . $this->getSensitivity()  . "\r\n";
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->getSensitivity() targeting SMTPs::getSensitivity() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1342
1343
        if ( $this->_msgPriority != 3 )
1344
        $_header .= $this->getPriority();
1345
1346
1347
        // @CHANGE LDR
1348
        if ( $this->getDeliveryReceipt() )
1349
            $_header .= 'Disposition-Notification-To: '.$this->getFrom('addr') . "\r\n";
1350
        if ( $this->getErrorsTo() )
1351
            $_header .= 'Errors-To: '.$this->getErrorsTo('addr') . "\r\n";
1352
        if ( $this->getReplyTo() )
1353
            $_header .= "Reply-To: ".$this->getReplyTo('addr') ."\r\n";
1354
1355
        $_header .= 'X-Mailer: Dolibarr version ' . DOL_VERSION .' (using SMTPs Mailer)' . "\r\n";
1356
        $_header .= 'X-Dolibarr-Option: '.($conf->global->MAIN_MAIL_USE_MULTI_PART?'MAIN_MAIL_USE_MULTI_PART':'No MAIN_MAIL_USE_MULTI_PART') . "\r\n";
1357
        $_header .= 'Mime-Version: 1.0' . "\r\n";
1358
1359
1360
        return $_header;
1361
    }
1362
1363
    /**
1364
     * Message Content
1365
     *
1366
     * @param 	string 	$strContent		Message Content
1367
     * @param	string	$strType		Type
1368
     * @return 	void
1369
     */
1370
    public function setBodyContent($strContent, $strType = 'plain')
1371
    {
1372
        //if ( $strContent )
1373
        //{
1374
        if ( $strType == 'html' )
1375
        $strMimeType = 'text/html';
1376
        else
1377
        $strMimeType = 'text/plain';
1378
1379
        // Make RFC821 Compliant, replace bare linefeeds
1380
        $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent);
1381
1382
        $strContentAltText = '';
1383
        if ($strType == 'html')
1384
        {
1385
            // Similar code to forge a text from html is also in CMailFile.class.php
1386
            $strContentAltText = preg_replace("/<br\s*[^>]*>/", " ", $strContent);
1387
            $strContentAltText = html_entity_decode(strip_tags($strContentAltText));
1388
            $strContentAltText = rtrim(wordwrap($strContentAltText, 75, "\r\n"));
1389
        }
1390
1391
        // Make RFC2045 Compliant
1392
        //$strContent = rtrim(chunk_split($strContent));    // Function chunck_split seems ko if not used on a base64 content
1393
        $strContent = rtrim(wordwrap($strContent, 75, "\r\n"));   // TODO Using this method creates unexpected line break on text/plain content.
1394
1395
        $this->_msgContent[$strType] = array();
1396
1397
        $this->_msgContent[$strType]['mimeType'] = $strMimeType;
1398
        $this->_msgContent[$strType]['data']     = $strContent;
1399
        $this->_msgContent[$strType]['dataText'] = $strContentAltText;
1400
1401
        if ( $this->getMD5flag() )
1402
        $this->_msgContent[$strType]['md5']      = dol_hash($strContent, 3);
1403
        //}
1404
    }
1405
1406
    /**
1407
     * Retrieves the Message Content
1408
     *
1409
     * @return 	string			Message Content
1410
     */
1411
    public function getBodyContent()
1412
    {
1413
        global $conf;
1414
1415
        // Generate a new Boundary string
1416
        $this->_setBoundary();
1417
1418
        // What type[s] of content do we have
1419
        $_types = array_keys($this->_msgContent);
1420
1421
        // How many content types do we have
1422
        $keyCount = count($_types);
1423
1424
        // If we have ZERO, we have a problem
1425
        if( $keyCount === 0 )
1426
        die("Sorry, no content");
1427
1428
        // If we have ONE, we can use the simple format
1429
        elseif( $keyCount === 1 && empty($conf->global->MAIN_MAIL_USE_MULTI_PART))
1430
        {
1431
            $_msgData = $this->_msgContent;
1432
            $_msgData = $_msgData[$_types[0]];
1433
1434
            $content = 'Content-Type: ' . $_msgData['mimeType'] . '; charset="' . $this->getCharSet() . '"' . "\r\n"
1435
            . 'Content-Transfer-Encoding: ' . $this->getTransEncodeType() . "\r\n"
1436
            . 'Content-Disposition: inline'  . "\r\n"
1437
            . 'Content-Description: Message' . "\r\n";
1438
1439
            if ( $this->getMD5flag() )
1440
            $content .= 'Content-MD5: ' . $_msgData['md5'] . "\r\n";
1441
1442
            $content .= "\r\n"
1443
            .  $_msgData['data'] . "\r\n";
1444
        }
1445
1446
        // If we have more than ONE, we use the multi-part format
1447
        elseif( $keyCount >= 1 || ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))
1448
        {
1449
            // Since this is an actual multi-part message
1450
            // We need to define a content message Boundary
1451
            // NOTE: This was 'multipart/alternative', but Windows based mail servers have issues with this.
1452
1453
            //$content = 'Content-Type: multipart/related; boundary="' . $this->_getBoundary() . '"'   . "\r\n";
1454
            $content = 'Content-Type: multipart/mixed; boundary="' . $this->_getBoundary('mixed') . '"'   . "\r\n";
1455
1456
            //                     . "\r\n"
1457
            //                     . 'This is a multi-part message in MIME format.' . "\r\n";
1458
            $content .= "Content-Transfer-Encoding: 8bit\r\n";
1459
            $content .= "\r\n";
1460
1461
            $content .= "--" . $this->_getBoundary('mixed') . "\r\n";
1462
1463
            if (key_exists('image', $this->_msgContent))     // If inline image found
1464
            {
1465
                $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n";
1466
                $content .= "\r\n";
1467
                $content .= "--" . $this->_getBoundary('alternative') . "\r\n";
1468
            }
1469
1470
1471
            // $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment'
1472
1473
1474
            // Loop through message content array
1475
            foreach ($this->_msgContent as $type => $_content)
1476
            {
1477
                if ( $type == 'attachment' )
1478
                {
1479
                    // loop through all attachments
1480
                    foreach ($_content as $_file => $_data)
1481
                    {
1482
                        $content .= "--" . $this->_getBoundary('mixed') . "\r\n"
1483
                        .  'Content-Disposition: attachment; filename="' . $_data['fileName'] . '"' . "\r\n"
1484
                        .  'Content-Type: ' . $_data['mimeType'] . '; name="' . $_data['fileName'] . '"' . "\r\n"
1485
                        .  'Content-Transfer-Encoding: base64' . "\r\n"
1486
                        .  'Content-Description: ' . $_data['fileName'] ."\r\n";
1487
1488
                        if ( $this->getMD5flag() )
1489
                        $content .= 'Content-MD5: ' . $_data['md5'] . "\r\n";
1490
1491
                        $content .= "\r\n" .  $_data['data'] . "\r\n\r\n";
1492
                    }
1493
                }
1494
                // @CHANGE LDR
1495
                elseif ( $type == 'image' )
1496
                {
1497
                    // loop through all images
1498
                    foreach ($_content as $_image => $_data)
1499
                    {
1500
                        $content .= "--" . $this->_getBoundary('related') . "\r\n";  // always related for an inline image
1501
1502
                        $content .= 'Content-Type: ' . $_data['mimeType'] . '; name="' . $_data['imageName'] . '"' . "\r\n"
1503
                        .  'Content-Transfer-Encoding: base64' . "\r\n"
1504
                        .  'Content-Disposition: inline; filename="' . $_data['imageName'] . '"' . "\r\n"
1505
                        .  'Content-ID: <' . $_data['cid'] . '> ' . "\r\n";
1506
1507
                        if ( $this->getMD5flag() )
1508
                        $content .= 'Content-MD5: ' . $_data['md5'] . "\r\n";
1509
1510
                        $content .= "\r\n"
1511
                        . $_data['data'] . "\r\n";
1512
                    }
1513
1514
                    // always end related and end alternative after inline images
1515
                    $content.= "--" . $this->_getBoundary('related') . "--" . "\r\n";
1516
                    $content.= "\r\n" . "--" . $this->_getBoundary('alternative') . "--" . "\r\n";
1517
                    $content.= "\r\n";
1518
                }
1519
                else
1520
                {
1521
                    if (key_exists('image', $this->_msgContent))
1522
                    {
1523
                        $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n";
1524
                        $content.= "\r\n" . ($_content['dataText']?$_content['dataText']:strip_tags($_content['data'])) . "\r\n"; // Add plain text message
1525
                        $content.= "--" . $this->_getBoundary('alternative') . "\r\n";
1526
                        $content.= 'Content-Type: multipart/related; boundary="' . $this->_getBoundary('related') . '"' . "\r\n";
1527
                        $content.= "\r\n";
1528
                        $content.= "--" . $this->_getBoundary('related') . "\r\n";
1529
                    }
1530
1531
                    if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))  // Add plain text message part before html part
1532
                    {
1533
                        $content.= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"' . "\r\n";
1534
                        $content .= "\r\n";
1535
                           $content .= "--" . $this->_getBoundary('alternative') . "\r\n";
1536
1537
                           $content.= "Content-Type: text/plain; charset=" . $this->getCharSet() . "\r\n";
1538
                           $content.= "\r\n". $_content['dataText'] . "\r\n";
1539
                           $content.= "--" . $this->_getBoundary('alternative') . "\r\n";
1540
                    }
1541
1542
                    $content .= 'Content-Type: ' . $_content['mimeType'] . '; '
1543
                    //                             . 'charset="' . $this->getCharSet() . '"';
1544
                    . 'charset=' . $this->getCharSet() . '';
1545
1546
                    //                    $content .= ( $type == 'html') ? '; name="HTML Part"' : '';
1547
                    $content .=  "\r\n";
1548
                    //                    $content .= 'Content-Transfer-Encoding: ';
1549
                    //                    $content .= ($type == 'html') ? 'quoted-printable' : $this->getTransEncodeType();
1550
                    //                    $content .=  "\r\n"
1551
                    //                             . 'Content-Disposition: inline'  . "\r\n"
1552
                    //                             . 'Content-Description: ' . $type . ' message' . "\r\n";
1553
1554
                    if ( $this->getMD5flag() )
1555
                    $content .= 'Content-MD5: ' . $_content['md5'] . "\r\n";
1556
1557
                    $content .= "\r\n"	. $_content['data'] . "\r\n";
1558
1559
                    if (! key_exists('image', $this->_msgContent) && $_content['dataText'] && ! empty($conf->global->MAIN_MAIL_USE_MULTI_PART))  // Add plain text message part after html part
1560
                    {
1561
                        $content.= "--" . $this->_getBoundary('alternative') . "--". "\r\n";
1562
                    }
1563
1564
                    $content .= "\r\n";
1565
                }
1566
            }
1567
1568
            // Close message boundries
1569
            //            $content .= "\r\n--" . $this->_getBoundary() . '--' . "\r\n" ;
1570
            $content .= "--" . $this->_getBoundary('mixed') . '--' . "\r\n" ;
1571
        }
1572
1573
        return $content;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $content does not seem to be defined for all execution paths leading up to this point.
Loading history...
1574
    }
1575
1576
    /**
1577
     * File attachments are added to the content array as sub-arrays,
1578
     * allowing for multiple attachments for each outbound email
1579
     *
1580
     * @param string $strContent  File data to attach to message
1581
     * @param string $strFileName File Name to give to attachment
1582
     * @param string $strMimeType File Mime Type of attachment
1583
     * @return void
1584
     */
1585
    public function setAttachment($strContent, $strFileName = 'unknown', $strMimeType = 'unknown')
1586
    {
1587
        if ( $strContent )
1588
        {
1589
            $strContent = rtrim(chunk_split(base64_encode($strContent), 76, "\r\n"));    // 76 max is defined into http://tools.ietf.org/html/rfc2047
1590
1591
            $this->_msgContent['attachment'][$strFileName]['mimeType'] = $strMimeType;
1592
            $this->_msgContent['attachment'][$strFileName]['fileName'] = $strFileName;
1593
            $this->_msgContent['attachment'][$strFileName]['data']     = $strContent;
1594
1595
            if ( $this->getMD5flag() )
1596
            $this->_msgContent['attachment'][$strFileName]['md5']      = dol_hash($strContent, 3);
1597
        }
1598
    }
1599
1600
1601
    // @CHANGE LDR
1602
1603
    /**
1604
     * Image attachments are added to the content array as sub-arrays,
1605
     * allowing for multiple images for each outbound email
1606
     *
1607
     * @param 	string $strContent  	Image data to attach to message
1608
     * @param 	string $strImageName 	Image Name to give to attachment
1609
     * @param 	string $strMimeType 	Image Mime Type of attachment
1610
     * @param 	string $strImageCid		CID
1611
     * @return 	void
1612
     */
1613
    public function setImageInline($strContent, $strImageName = 'unknown', $strMimeType = 'unknown', $strImageCid = 'unknown')
1614
    {
1615
        if ($strContent)
1616
        {
1617
            $this->_msgContent['image'][$strImageName]['mimeType'] = $strMimeType;
1618
            $this->_msgContent['image'][$strImageName]['imageName'] = $strImageName;
1619
            $this->_msgContent['image'][$strImageName]['cid']      = $strImageCid;
1620
            $this->_msgContent['image'][$strImageName]['data']     = $strContent;
1621
1622
            if ( $this->getMD5flag() )
1623
            $this->_msgContent['image'][$strImageName]['md5']      = dol_hash($strContent, 3);
1624
        }
1625
    }
1626
    // END @CHANGE LDR
1627
1628
1629
    /**
1630
     * Message Content Sensitivity
1631
     * Message Sensitivity values:
1632
     *   - [0] None - default
1633
     *   - [1] Personal
1634
     *   - [2] Private
1635
     *   - [3] Company Confidential
1636
     *
1637
     * @param 	integer	$_value		Message Sensitivity
1638
     * @return 	void
1639
     */
1640
    public function setSensitivity($_value = 0)
1641
    {
1642
        if ( ( is_numeric($_value) ) &&
1643
        ( ( $_value >= 0 ) && ( $_value <= 3 ) ) )
1644
        $this->_msgSensitivity = $_value;
1645
    }
1646
1647
    /**
1648
     * Returns Message Content Sensitivity string
1649
     * Message Sensitivity values:
1650
     *   - [0] None - default
1651
     *   - [1] Personal
1652
     *   - [2] Private
1653
     *   - [3] Company Confidential
1654
     *
1655
     * @return 	void
1656
     */
1657
    public function getSensitivity()
1658
    {
1659
        return $this->_arySensitivity[$this->_msgSensitivity];
1660
    }
1661
1662
    /**
1663
     * Message Content Priority
1664
     * Message Priority values:
1665
     *  - [0] 'Bulk'
1666
     *  - [1] 'Highest'
1667
     *  - [2] 'High'
1668
     *  - [3] 'Normal' - default
1669
     *  - [4] 'Low'
1670
     *  - [5] 'Lowest'
1671
     *
1672
     * @param 	integer 	$_value 	Message Priority
1673
     * @return 	void
1674
     */
1675
    public function setPriority($_value = 3)
1676
    {
1677
        if ( ( is_numeric($_value) ) &&
1678
        ( ( $_value >= 0 ) && ( $_value <= 5 ) ) )
1679
        $this->_msgPriority = $_value;
1680
    }
1681
1682
    /**
1683
     * Message Content Priority
1684
     * Message Priority values:
1685
     *  - [0] 'Bulk'
1686
     *  - [1] 'Highest'
1687
     *  - [2] 'High'
1688
     *  - [3] 'Normal' - default
1689
     *  - [4] 'Low'
1690
     *  - [5] 'Lowest'
1691
     *
1692
     * @return string
1693
     */
1694
    public function getPriority()
1695
    {
1696
        return 'Importance: ' . $this->_aryPriority[$this->_msgPriority] . "\r\n"
1697
        . 'Priority: '   . $this->_aryPriority[$this->_msgPriority] . "\r\n"
1698
        . 'X-Priority: ' . $this->_msgPriority . ' (' . $this->_aryPriority[$this->_msgPriority] . ')' . "\r\n";
1699
    }
1700
1701
    /**
1702
     * Set flag which determines whether to calculate message MD5 checksum.
1703
     *
1704
     * @param 	string 	$_flag		Message Priority
1705
     * @return 	void
1706
     */
1707
    public function setMD5flag($_flag = false)
1708
    {
1709
        $this->_smtpMD5 = $_flag;
1710
    }
1711
1712
    /**
1713
     * Gets flag which determines whether to calculate message MD5 checksum.
1714
     *
1715
     * @return 	boolean 				Message Priority
1716
     */
1717
    public function getMD5flag()
1718
    {
1719
        return $this->_smtpMD5;
1720
    }
1721
1722
    /**
1723
     * Message X-Header Content
1724
     * This is a simple "insert". Whatever is given will be placed
1725
     * "as is" into the Xheader array.
1726
     *
1727
     * @param string $strXdata Message X-Header Content
1728
     * @return void
1729
     */
1730
    public function setXheader($strXdata)
1731
    {
1732
        if ( $strXdata )
1733
        $this->_msgXheader[] = $strXdata;
1734
    }
1735
1736
    /**
1737
     * Retrieves the Message X-Header Content
1738
     *
1739
     * @return string[] $_msgContent Message X-Header Content
1740
     */
1741
    public function getXheader()
1742
    {
1743
        return $this->_msgXheader;
1744
    }
1745
1746
    /**
1747
     * Generates Random string for MIME message Boundary
1748
     *
1749
     * @return void
1750
     */
1751
    private function _setBoundary()
1752
    {
1753
        $this->_smtpsBoundary = "multipart_x." . time() . ".x_boundary";
1754
        $this->_smtpsRelatedBoundary = 'mul_'.dol_hash(uniqid("dolibarr2"), 3);
1755
        $this->_smtpsAlternativeBoundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3);
1756
    }
1757
1758
    /**
1759
     * Retrieves the MIME message Boundary
1760
     *
1761
     * @param  string $type				Type of boundary
1762
     * @return string $_smtpsBoundary 	MIME message Boundary
1763
     */
1764
    private function _getBoundary($type = 'mixed')
1765
    {
1766
        if ($type == 'mixed') return $this->_smtpsBoundary;
1767
        elseif ($type == 'related') return $this->_smtpsRelatedBoundary;
1768
        elseif ($type == 'alternative') return $this->_smtpsAlternativeBoundary;
1769
    }
1770
1771
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1772
    /**
1773
     * This function has been modified as provided by SirSir to allow multiline responses when
1774
     * using SMTP Extensions
1775
     *
1776
     * @param	resource    $socket			Socket handler
1777
     * @param	string		$response		Response. Example: "550 5.7.1  https://support.google.com/a/answer/6140680#invalidcred j21sm814390wre.3"
1778
     * @return	boolean						True or false
1779
     */
1780
    public function server_parse($socket, $response)
1781
    {
1782
        // phpcs:enable
1783
        /**
1784
         * Returns constructed SELECT Object string or boolean upon failure
1785
         * Default value is set at true
1786
         */
1787
        $_retVal = true;
1788
1789
        $server_response = '';
1790
1791
        // avoid infinite loop
1792
        $limit=0;
1793
1794
        while (substr($server_response, 3, 1) != ' ' && $limit<100)
1795
        {
1796
            if (! ($server_response = fgets($socket, 256)))
1797
            {
1798
                $this->_setErr(121, "Couldn't get mail server response codes");
1799
                $_retVal = false;
1800
                break;
1801
            }
1802
            $limit++;
1803
        }
1804
1805
        if (! (substr($server_response, 0, 3) == $response))
1806
        {
1807
            $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse: $server_response");
1808
            $_retVal = false;
1809
        }
1810
1811
        return $_retVal;
1812
    }
1813
1814
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1815
    /**
1816
     * Send str
1817
     *
1818
     * @param	string		$_strSend		String to send
1819
     * @param 	string		$_returnCode	Return code
1820
     * @param 	string		$CRLF			CRLF
1821
     * @return 	boolean|null						True or false
1822
     */
1823
    public function socket_send_str($_strSend, $_returnCode = null, $CRLF = "\r\n")
1824
    {
1825
        // phpcs:enable
1826
        if ($this->_debug) $this->log.=$_strSend;	// @CHANGE LDR for log
1827
        fputs($this->socket, $_strSend . $CRLF);
1828
        if ($this->_debug) $this->log.=' ('.$_returnCode.')' . $CRLF;
1829
1830
        if ( $_returnCode )
1831
        return $this->server_parse($this->socket, $_returnCode);
1832
    }
1833
1834
    // =============================================================
1835
    // ** Error handling methods
1836
1837
    /**
1838
     * Defines errors codes and messages for Class
1839
     *
1840
     * @param  int    $_errNum  Error Code Number
1841
     * @param  string $_errMsg  Error Message
1842
     * @return void
1843
     */
1844
    private function _setErr($_errNum, $_errMsg)
1845
    {
1846
        $this->_smtpsErrors[] = array(
1847
            'num' => $_errNum,
1848
            'msg' => $_errMsg,
1849
        );
1850
    }
1851
1852
    /**
1853
     * Returns errors codes and messages for Class
1854
     *
1855
     * @return string $_errMsg  Error Message
1856
     */
1857
    public function getErrors()
1858
    {
1859
        $_errMsg = array();
1860
1861
        if (is_array($this->_smtpsErrors))
1862
        {
1863
            foreach ($this->_smtpsErrors as $_err => $_info)
1864
            {
1865
                $_errMsg[] = 'Error [' . $_info['num'] .']: '. $_info['msg'];
1866
            }
1867
        }
1868
1869
        return implode("\n", $_errMsg);
1870
    }
1871
}
1872
1873
1874
// =============================================================
1875
// ** CSV Version Control Info
1876
1877
/**
1878
 * Revision      2011/09/12 07:49:59  eldy
1879
 * Doxygen
1880
 *
1881
 * Revision      2011/09/06 06:53:53  hregis
1882
 * Fix: use dol_hash instead md5 php function
1883
 *
1884
 * Revision      2011/09/03 00:14:27  eldy
1885
 * Doxygen
1886
 *
1887
 * Revision      2011/08/28 14:24:23  eldy
1888
 * Doxygen
1889
 *
1890
 * Revision      2011/07/12 22:19:02  eldy
1891
 * Fix: Attachment fails if content was empty
1892
 *
1893
 * Revision      2011/06/20 23:17:50  hregis
1894
 * Fix: use best structure of mail
1895
 *
1896
 * Revision      2010/04/13 20:58:37  eldy
1897
 * Fix: Can provide ip address on smtps. Better error reporting.
1898
 *
1899
 * Revision      2010/04/13 20:30:25  eldy
1900
 * Fix: Can provide ip address on smtps. Better error reporting.
1901
 *
1902
 * Revision      2010/01/12 13:02:07  hregis
1903
 * Fix: missing attach-files
1904
 *
1905
 * Revision      2009/11/01 14:16:30  eldy
1906
 * Fix: Sending mail with SMTPS was not working.
1907
 *
1908
 * Revision      2009/10/20 13:14:47  hregis
1909
 * Fix: function "split" is deprecated since php 5.3.0
1910
 *
1911
 * Revision      2009/05/13 19:10:07  eldy
1912
 * New: Can use inline images.Everything seems to work with thunderbird and webmail gmail. New to be tested on other mail browsers.
1913
 *
1914
 * Revision      2009/05/13 14:49:30  eldy
1915
 * Fix: Make code so much simpler and solve a lot of problem with new version.
1916
 *
1917
 * Revision      2009/02/09 00:04:35  eldy
1918
 * Added support for SMTPS protocol
1919
 *
1920
 * Revision       2008/04/16 23:11:45  eldy
1921
 * New: Add action "Test server connectivity"
1922
 *
1923
 * Revision 1.18  2007/01/12 22:17:08  ongardie
1924
 * - Added full_http_site_root() to utils-misc.php
1925
 * - Made SMTPs' getError() easier to use
1926
 * - Improved activity modified emails
1927
 *
1928
 * Revision 1.17  2006/04/05 03:15:40  ongardie
1929
 * -Fixed method name typo that resulted in a fatal error.
1930
 *
1931
 * Revision 1.16  2006/03/08 04:05:25  jswalter
1932
 *  - '$_smtpsTransEncode' was removed and '$_smtpsTransEncodeType' is now used
1933
 *  - '$_smtpsTransEncodeType' is defaulted to ZERO
1934
 *  - corrected 'setCharSet()'  internal vars
1935
 *  - defined '$_mailPath'
1936
 *  - added '$_smtpMD5' as a class property
1937
 *  - added 'setMD5flag()' to set above property
1938
 *  - added 'getMD5flag()' to retrieve above property
1939
 *  - 'setAttachment()' will add an MD5 checksum to attachements if above property is set
1940
 *  - 'setBodyContent()' will add an MD5 checksum to message parts if above property is set
1941
 *  - 'getBodyContent()' will insert the MD5 checksum for messages and attachments if above property is set
1942
 *  - removed leading dashes from message boundry
1943
 *  - added propery "Close message boundry" tomessage block
1944
 *  - corrected some comments in various places
1945
 *  - removed some incorrect comments in others
1946
 *
1947
 * Revision 1.15  2006/02/21 02:00:07  vanmer
1948
 * - patch to add support for sending to exim mail server
1949
 * - thanks to Diego Ongaro at ETSZONE ([email protected])
1950
 *
1951
 * Revision 1.14  2005/08/29 16:22:10  jswalter
1952
 *  - change 'multipart/alternative' to 'multipart/mixed', but Windows based mail servers have issues with this.
1953
 * Bug 594
1954
 *
1955
 * Revision 1.13  2005/08/21 01:57:30  vanmer
1956
 * - added initialization for array if no recipients exist
1957
 *
1958
 * Revision 1.12  2005/08/20 12:04:30  braverock
1959
 * - remove potentially binary characters from Message-ID
1960
 * - add getHost to get the hostname of the mailserver
1961
 * - add username to Message-ID header
1962
 *
1963
 * Revision 1.11  2005/08/20 11:49:48  braverock
1964
 * - fix typos in boundary
1965
 * - remove potentially illegal characters from boundary
1966
 *
1967
 * Revision 1.10  2005/08/19 20:39:32  jswalter
1968
 *  - added _server_connect()' as a seperate method to handle server connectivity.
1969
 *  - added '_server_authenticate()' as a seperate method to handle server authentication.
1970
 *  - 'sendMsg()' now uses the new methods to handle server communication.
1971
 *  - modified 'server_parse()' and 'socket_send_str()' to give error codes and messages.
1972
 *
1973
 * Revision 1.9  2005/08/19 15:40:18  jswalter
1974
 *  - IMPORTANT: 'setAttachement()' is now spelled correctly: 'setAttachment()'
1975
 *  - added additional comment to several methods
1976
 *  - added '$_smtpsTransEncodeTypes' array to limit encode types
1977
 *  - added parameters to 'sendMsg()' for future development around debugging and logging
1978
 *  - added error code within 'setConfig()' if the given path is not found
1979
 *  - 'setTransportType()' now has parameter validation
1980
 *     [this still is not implemented]
1981
 *  - 'setPort()' now does parameter validation
1982
 *  - 'setTransEncode()' now has parameter validation against '$_smtpsTransEncodeTypes'
1983
 *  - modified 'get_email_list()' to handle error handling
1984
 *  - 'setSensitivity()' now has parameter validation
1985
 *  - 'setPriority()' now has parameter validation
1986
 *
1987
 * Revision 1.8  2005/06/24 21:00:20  jswalter
1988
 *   - corrected comments
1989
 *   - corrected the defualt value for 'setPriority()'
1990
 *   - modified 'setAttachement()' to process multiple attachments correctly
1991
 *   - modified 'getBodyContent()' to handle multiple attachments
1992
 * Bug 310
1993
 *
1994
 * Revision 1.7  2005/05/19 21:12:34  braverock
1995
 * - replace chunk_split() with wordwrap() to fix funky wrapping of templates
1996
 *
1997
 * Revision 1.6  2005/04/25 04:55:06  jswalter
1998
 *  - cloned from Master Version
1999
 *
2000
 * Revision 1.10  2005/04/25 04:54:10  walter
2001
 *  - "fixed" 'getBodyContent()' to handle a "simple" text only message
2002
 *
2003
 * Revision 1.9  2005/04/25 03:52:01  walter
2004
 *  - replace closing curly bracket. Removed it in last revision!
2005
 *
2006
 * Revision 1.8  2005/04/25 02:29:49  walter
2007
 *  - added '$_transportType' and its getter/setter methods.
2008
 *    for future use. NOT yet implemented.
2009
 *  - in 'sendMsg()', added HOST validation check
2010
 *  - added error check for initial Socket Connection
2011
 *  - created new method 'socket_send_str()' to process socket
2012
 *    communication in a unified means. Socket calls within
2013
 *    'sendMsg()' have been modified to use this new method.
2014
 *  - expanded comments in 'setConfig()'
2015
 *  - added "error" check on PHP ini file properties. If these
2016
 *    properties not set within the INI file, the default values
2017
 *    will be used.
2018
 *  - modified 'get_RCPT_list()' to reset itself each time it is called
2019
 *  - modified 'setBodyContent()' to store data in a sub-array for better
2020
 *    parsing within the 'getBodyContent()' method
2021
 *  - modified 'getBodyContent()' to process contents array better.
2022
 *    Also modified to handle attachements.
2023
 *  - added 'setAttachement()' so files and other data can be attached
2024
 *    to messages
2025
 *  - added '_setErr()' and 'getErrors()' as an attempt to begin an error
2026
 *    handling process within this class
2027
 *
2028
 * Revision 1.7  2005/04/13 15:23:50  walter
2029
 *  - made 'CC' a conditional insert
2030
 *  - made 'BCC' a conditional insert
2031
 *  - fixed 'Message-ID'
2032
 *  - corrected 'getSensitivity()'
2033
 *  - modified '$_aryPriority[]' to proper values
2034
 *  - updated 'setConfig()' to handle external Ini or 'php.ini'
2035
 *
2036
 * Revision 1.6  2005/03/15 17:34:06  walter
2037
 *  - corrected Message Sensitivity property and method comments
2038
 *  - added array to Message Sensitivity
2039
 *  - added getSensitivity() method to use new Sensitivity array
2040
 *  - created seters and getter for Priority with new Prioity value array property
2041
 *  - changed config file include from 'include_once'
2042
 *  - modified getHeader() to ustilize new Message Sensitivity and Priorty properties
2043
 *
2044
 * Revision 1.5  2005/03/14 22:25:27  walter
2045
 *  - added references
2046
 *  - added Message sensitivity as a property with Getter/Setter methods
2047
 *  - boundary is now a property with Getter/Setter methods
2048
 *  - added 'builtRCPTlist()'
2049
 *  - 'sendMsg()' now uses Object properties and methods to build message
2050
 *  - 'setConfig()' to load external file
2051
 *  - 'setForm()' will "strip" the email address out of "address" string
2052
 *  - modifed 'getFrom()' to handle "striping" the email address
2053
 *  - '_buildArrayList()' creates a multi-dimensional array of addresses
2054
 *    by domain, TO, CC & BCC and then by User Name.
2055
 *  - '_strip_email()' pulls email address out of "full Address" string'
2056
 *  - 'get_RCPT_list()' pulls out "bare" emaill address form address array
2057
 *  - 'getHeader()' builds message Header from Object properties
2058
 *  - 'getBodyContent()' builds full messsage body, even multi-part
2059
 *
2060
 * Revision 1.4  2005/03/02 20:53:35  walter
2061
 *  - core Setters & Getters defined
2062
 *  - added additional Class Properties
2063
 *
2064
 * Revision 1.3  2005/03/02 18:51:51  walter
2065
 *  - added base 'Class Properties'
2066
 *
2067
 * Revision 1.2  2005/03/01 19:37:52  walter
2068
 *  - CVS logging tags
2069
 *  - more comments
2070
 *  - more "shell"
2071
 *  - some constants
2072
 *
2073
 * Revision 1.1  2005/03/01 19:22:49  walter
2074
 *  - initial commit
2075
 *  - basic shell with some commets
2076
 *
2077
 */
2078