dolibarr 19.0.4
smtps.class.php
Go to the documentation of this file.
1<?php
2/*
3 * Copyright (C) Walter Torres <walter@torres.ws> [with a *lot* of help!]
4 * Copyright (C) 2005-2015 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2006-2011 Regis Houssin
6 * Copyright (C) 2016 Jonathan TISSEAU <jonathan.tisseau@86dev.fr>
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
46class SMTPs
47{
51 private $_smtpsHost = 'localhost';
52
57 private $_smtpsPort = '25';
58
63 private $_smtpsID = null;
64
69 private $_smtpsPW = null;
70
74 private $_smtpsToken = null;
75
80 private $_msgFrom = null;
81
86 private $_msgReplyTo = null;
87
93 private $_msgRecipients = null;
94
98 private $_msgSubject = null;
99
105 private $_msgContent = array();
106
110 private $_msgXheader = null;
111
116 private $_smtpsCharSet = 'iso-8859-1';
117
122 private $_msgSensitivity = 0;
123
127 private $_arySensitivity = array(false,
128 'Personal',
129 'Private',
130 'Company Confidential');
131
136 private $_msgPriority = 3;
137
141 private $_aryPriority = array('Bulk',
142 'Highest',
143 'High',
144 'Normal',
145 'Low',
146 'Lowest');
147
153
157 private $_smtpsTransEncodeTypes = array('7bit', // Simple 7-bit ASCII
158 '8bit', // 8-bit coding with line termination characters
159 'base64', // 3 octets encoded into 4 sextets with offset
160 'binary', // Arbitrary binary stream
161 'mac-binhex40', // Macintosh binary to hex encoding
162 'quoted-printable', // Mostly 7-bit, with 8-bit characters encoded as "=HH"
163 'uuencode'); // UUENCODE encoding
164
169 private $_smtpsTransEncode = '7bit';
170
174 private $_smtpsBoundary = null;
175
180
185
193 private $_transportType = 0;
194
199 private $_mailPath = '/usr/lib/sendmail';
200
204 private $_smtpTimeout = 10;
205
209 private $_smtpMD5 = false;
210
214 private $_smtpsErrors = null;
215
223 private $_log_level = 0;
224
228 private $_debug = false;
229
230
231 // @CHANGE LDR
232 public $log = '';
233 public $lastretval = '';
234
238 public $socket;
239
243 public $errno;
244
248 public $errstr;
249
250 private $_errorsTo = '';
251 private $_deliveryReceipt = 0;
252 private $_trackId = '';
253 private $_moreinheader = '';
254
258 private $_options = array();
259
266 public function setOptions($_options = array())
267 {
268 $this->_options = $_options;
269 }
270
277 public function setDeliveryReceipt($_val = 0)
278 {
279 $this->_deliveryReceipt = $_val;
280 }
281
287 public function getDeliveryReceipt()
288 {
289 return $this->_deliveryReceipt;
290 }
291
298 public function setTrackId($_val = '')
299 {
300 $this->_trackId = $_val;
301 }
302
309 public function setMoreInHeader($_val = '')
310 {
311 $this->_moreinheader = $_val;
312 }
313
319 public function getTrackId()
320 {
321 return $this->_trackId;
322 }
323
329 public function getMoreInHeader()
330 {
331 return $this->_moreinheader;
332 }
333
340 public function setErrorsTo($_strErrorsTo)
341 {
342 if ($_strErrorsTo) {
343 $this->_errorsTo = $this->_strip_email($_strErrorsTo);
344 }
345 }
346
353 public function getErrorsTo($_part = true)
354 {
355 $_retValue = '';
356
357 if ($_part === true) {
358 $_retValue = $this->_errorsTo;
359 } else {
360 $_retValue = $this->_errorsTo[$_part];
361 }
362
363 return $_retValue;
364 }
365
372 public function setDebug($_vDebug = false)
373 {
374 $this->_debug = $_vDebug;
375 }
376
382 public function buildRCPTlist()
383 {
384 // Pull TO list
385 $_aryToList = $this->getTO();
386 }
387
388 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
394 private function _server_connect()
395 {
396 // phpcs:enable
397 // Default return value
398 $_retVal = true;
399
400 // We have to make sure the HOST given is valid
401 // This is done here because '@fsockopen' will not give me this
402 // information if it failes to connect because it can't find the HOST
403 $host = $this->getHost();
404 $usetls = preg_match('@tls://@i', $host);
405
406 $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
407 $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
408 $host = preg_replace('@tls://@i', '', $host); // Remove prefix
409
410 // @CHANGE LDR
411 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
412
413 if ((!is_ip($host)) && ((gethostbyname($host)) == $host)) {
414 $this->_setErr(99, $host.' is either offline or is an invalid host name.');
415 $_retVal = false;
416 } else {
417 if (function_exists('stream_socket_client') && !empty($this->_options)) {
418 $socket_context = stream_context_create($this->_options); // An array of options for stream_context_create()
419 $this->socket = @stream_socket_client(
420 preg_replace('@tls://@i', '', $this->getHost()).// Host to 'hit', IP or domain
421 ':'.$this->getPort(), // which Port number to use
422 $this->errno, // actual system level error
423 $this->errstr, // and any text that goes with the error
424 $this->_smtpTimeout, // timeout for reading/writing data over the socket
425 STREAM_CLIENT_CONNECT,
426 $socket_context // Options for connection
427 );
428 } else {
429 $this->socket = @fsockopen(
430 preg_replace('@tls://@i', '', $this->getHost()), // Host to 'hit', IP or domain
431 $this->getPort(), // which Port number to use
432 $this->errno, // actual system level error
433 $this->errstr, // and any text that goes with the error
434 $this->_smtpTimeout // timeout for reading/writing data over the socket
435 );
436 }
437
438 //See if we can connect to the SMTP server
439 if (is_resource($this->socket)) {
440 // Fix from PHP SMTP class by 'Chris Ryan'
441 // Sometimes the SMTP server takes a little longer to respond
442 // so we will give it a longer timeout for the first read
443 // Windows still does not have support for this timeout function
444 if (function_exists('stream_set_timeout')) {
445 stream_set_timeout($this->socket, $this->_smtpTimeout, 0);
446 }
447
448 // Check response from Server
449 if ($_retVal = $this->server_parse($this->socket, "220")) {
450 $_retVal = $this->socket;
451 }
452 } else {
453 // This connection attempt failed.
454 // @CHANGE LDR
455 if (empty($this->errstr)) {
456 $this->errstr = 'Failed to connect with fsockopen host='.$this->getHost().' port='.$this->getPort();
457 }
458 $this->_setErr($this->errno, $this->errstr);
459 $_retVal = false;
460 }
461 }
462
463 return $_retVal;
464 }
465
466 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
472 private function _server_authenticate()
473 {
474 // phpcs:enable
475 global $conf;
476
477 require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
478 // Send the RFC2554 specified EHLO.
479 // This improvment as provided by 'SirSir' to
480 // accomodate both SMTP AND ESMTP capable servers
481 $host = $this->getHost();
482 $usetls = preg_match('@tls://@i', $host);
483
484 $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
485 $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
486 $host = preg_replace('@tls://@i', '', $host); // Remove prefix
487
488 if ($usetls && getDolGlobalString('MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO')) {
489 $host = 'tls://'.$host;
490 }
491
492 $hosth = $host; // so for example 'localhost' or 'smtp-relay.gmail.com'
493
494 if (getDolGlobalString('MAIL_SMTP_USE_FROM_FOR_HELO')) {
495 if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
496 // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name
497 $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO;
498 } elseif (getDolGlobalInt('MAIL_SMTP_USE_FROM_FOR_HELO') == 1) {
499 // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from.
500 // So if the from to is 'aaa <bbb@ccc.com>', we will keep 'ccc.com'
501 $hosth = $this->getFrom('addr');
502 $hosth = preg_replace('/^.*</', '', $hosth);
503 $hosth = preg_replace('/>.*$/', '', $hosth);
504 $hosth = preg_replace('/.*@/', '', $hosth);
505 } elseif (getDolGlobalInt('MAIL_SMTP_USE_FROM_FOR_HELO') == 2) {
506 // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 2, we use the domain in the $dolibarr_main_url_root.
507 global $dolibarr_main_url_root;
508 $hosth = getDomainFromURL($dolibarr_main_url_root, 1);
509 }
510 }
511
512 if ($_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) {
513 if ($usetls) {
514 /*
515 The following dialog illustrates how a client and server can start a TLS STARTTLS session:
516 S: <waits for connection on TCP port 25>
517 C: <opens connection>
518 S: 220 mail.imc.org SMTP service ready
519 C: EHLO mail.ietf.org
520 S: 250-mail.imc.org offers a warm hug of welcome
521 S: 250 STARTTLS
522 C: STARTTLS
523 S: 220 Go ahead
524 C: <starts TLS negotiation>
525 C & S: <negotiate a TLS session>
526 C & S: <check result of negotiation>
527 // Second pass EHLO
528 C: EHLO client-domain.com
529 S: 250-server-domain.com
530 S: 250 AUTH LOGIN
531 C: <continues by sending an SMTP command
532
533 Another example here:
534 S: 220 smtp.server.com Simple Mail Transfer Service Ready
535 C: EHLO client.example.com
536 S: 250-smtp.server.com Hello client.example.com
537 S: 250-SIZE 1000000
538 S: 250-AUTH LOGIN PLAIN CRAM-MD5
539 S: 250-STARTTLS
540 S: 250 HELP
541 C: STARTTLS
542 S: 220 TLS go ahead
543 C: EHLO client.example.com *
544 S: 250-smtp.server.com Hello client.example.com
545 S: 250-SIZE 1000000
546 S: 250-AUTH LOGIN PLAIN CRAM-MD5
547 S: 250 HELP
548 C: AUTH LOGIN
549 S: 334 VXNlcm5hbWU6
550 C: adlxdkej
551 S: 334 UGFzc3dvcmQ6
552 C: lkujsefxlj
553 S: 235 2.7.0 Authentication successful
554 C: MAIL FROM:<mail@samlogic.com>
555 S: 250 OK
556 C: RCPT TO:<john@mail.com>
557 S: 250 OK
558 C: DATA
559 S: 354 Send message, end with a "." on a line by itself
560 C: <The message data (body text, subject, e-mail header, attachments etc) is sent>
561 S .
562 S: 250 OK, message accepted for delivery: queued as 12345
563 C: QUIT
564 S: 221 Bye
565 */
566 if (!$_retVal = $this->socket_send_str('STARTTLS', 220)) {
567 $this->_setErr(131, 'STARTTLS connection is not supported.');
568 return $_retVal;
569 }
570
571 // Before 5.6.7:
572 // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_SSLv2_CLIENT|STREAM_CRYPTO_METHOD_SSLv3_CLIENT
573 // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
574 // PHP >= 5.6.7:
575 // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
576 // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
577
578 $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
579 if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
580 $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
581 $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
582 }
583
584 if (!stream_socket_enable_crypto($this->socket, true, $crypto_method)) {
585 $this->_setErr(132, 'STARTTLS connection failed.');
586 return $_retVal;
587 }
588 // Most servers expect a 2nd pass of EHLO after TLS is established to get another time
589 // the answer with list of supported AUTH methods. They may differs between non STARTTLS and with STARTTLS.
590 if (! $_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) {
591 $this->_setErr(126, '"'.$hosth.'" does not support authenticated connections or temporary error. Error after 2nd sending EHLO '.$hosth.' : '.$this->lastretval);
592 return $_retVal;
593 }
594 }
595
596 // Default authentication method is LOGIN
597 if (!getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE')) {
598 $conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE = 'LOGIN';
599 }
600
601 // Send Authentication to Server
602 // Check for errors along the way
603 switch ($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE) {
604 case 'NONE':
605 // Do not send the 'AUTH type' message. For test purpose, if you don't need authentication, it is better to not enter login/pass into setup.
606 $_retVal = true;
607 break;
608 case 'PLAIN':
609 $this->socket_send_str('AUTH PLAIN', '334');
610 // The error here just means the ID/password combo doesn't work.
611 $_retVal = $this->socket_send_str(base64_encode("\0".$this->_smtpsID."\0".$this->_smtpsPW), '235');
612 break;
613 case 'XOAUTH2':
614 // "user=$email\1auth=Bearer $token\1\1"
615 $user = $this->_smtpsID;
616 $token = $this->_smtpsToken;
617 $initRes = "user=".$user."\001auth=Bearer ".$token."\001\001";
618 $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($initRes), '235');
619 if (!$_retVal) {
620 $this->_setErr(130, 'Error when asking for AUTH XOAUTH2');
621 }
622 break;
623 case 'LOGIN': // most common case
624 default:
625 $_retVal = $this->socket_send_str('AUTH LOGIN', '334');
626 if (!$_retVal) {
627 $this->_setErr(130, 'Error when asking for AUTH LOGIN');
628 } else {
629 // User name will not return any error, server will take anything we give it.
630 $this->socket_send_str(base64_encode($this->_smtpsID), '334');
631 // The error here just means the ID/password combo doesn't work.
632 // There is no method to determine which is the problem, ID or password
633 $_retVal = $this->socket_send_str(base64_encode($this->_smtpsPW), '235');
634 }
635 break;
636 }
637 if (!$_retVal) {
638 $this->_setErr(130, 'Invalid Authentication Credentials.');
639 }
640 } else {
641 $this->_setErr(126, '"'.$host.'" does not support authenticated connections or temporary error. Error after sending EHLO '.$hosth.' : '.$this->lastretval);
642 }
643
644 return $_retVal;
645 }
646
652 public function sendMsg()
653 {
654 global $conf;
655
656 require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
657
658 // Default return value
659 $_retVal = false;
660
661 // Connect to Server
662 if ($this->socket = $this->_server_connect()) {
663 // If a User ID *and* a password is given, assume Authentication is desired
664 if (!empty($this->_smtpsID) && (!empty($this->_smtpsPW) || !empty($this->_smtpsToken))) {
665 // Send the RFC2554 specified EHLO.
666 $_retVal = $this->_server_authenticate();
667 } else {
668 // This is a "normal" SMTP Server "handshack"
669 // Send the RFC821 specified HELO.
670 $host = $this->getHost();
671 $usetls = preg_match('@tls://@i', $host);
672
673 $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
674 $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
675 $host = preg_replace('@tls://@i', '', $host); // Remove prefix
676
677 if ($usetls && getDolGlobalString('MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO')) {
678 $host = 'tls://'.$host;
679 }
680
681 $hosth = $host;
682
683 if (getDolGlobalString('MAIL_SMTP_USE_FROM_FOR_HELO')) {
684 if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
685 // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name
686 $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO;
687 } elseif (getDolGlobalInt('MAIL_SMTP_USE_FROM_FOR_HELO') == 1) {
688 // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from.
689 // So if the from to is 'aaa <bbb@ccc.com>', we will keep 'ccc.com'
690 $hosth = $this->getFrom('addr');
691 $hosth = preg_replace('/^.*</', '', $hosth);
692 $hosth = preg_replace('/>.*$/', '', $hosth);
693 $hosth = preg_replace('/.*@/', '', $hosth);
694 } elseif (getDolGlobalInt('MAIL_SMTP_USE_FROM_FOR_HELO') == 2) {
695 // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 2, we use the domain in the $dolibarr_main_url_root.
696 global $dolibarr_main_url_root;
697 $hosth = getDomainFromURL($dolibarr_main_url_root, 1);
698 }
699 }
700
701 // Send the HELO message to the SMTP server
702 $_retVal = $this->socket_send_str('HELO '.$hosth, '250');
703 }
704
705 // Well, did we get the server answer with correct code ?
706 if ($_retVal) {
707 // From this point onward most server response codes should be 250
708 // Specify who the mail is from....
709 // This has to be the raw email address, strip the "name" off
710 $resultmailfrom = $this->socket_send_str('MAIL FROM: '.$this->getFrom('addr'), '250');
711 if (!$resultmailfrom) {
712 fclose($this->socket);
713 return false;
714 }
715
716 // 'RCPT TO:' must be given a single address, so this has to loop
717 // through the list of addresses, regardless of TO, CC or BCC
718 // and send it out "single file"
719 foreach ($this->get_RCPT_list() as $_address) {
720 /* Note:
721 * BCC email addresses must be listed in the RCPT TO command list,
722 * but the BCC header should not be printed under the DATA command.
723 * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
724 */
725
726 /*
727 * TODO
728 * After each 'RCPT TO:' is sent, we need to make sure it was kosher,
729 * if not, the whole message will fail
730 * If any email address fails, we will need to RESET the connection,
731 * mark the last address as "bad" and start the address loop over again.
732 * If any address fails, the entire message fails.
733 */
734 $this->socket_send_str('RCPT TO: <'.$_address.'>', '250');
735 }
736
737 // Tell the server we are ready to start sending data
738 // with any custom headers...
739 // This is the last response code we look for until the end of the message.
740 $this->socket_send_str('DATA', '354');
741
742 // Now we are ready for the message...
743 // Ok, all the ingredients are mixed in let's cook this puppy...
744 $this->socket_send_str($this->getHeader().$this->getBodyContent()."\r\n".'.', '250');
745
746 // Now tell the server we are done and close the socket...
747 fputs($this->socket, 'QUIT');
748 } else {
749 // We got error code into $this->lastretval
750 }
751
752 fclose($this->socket);
753 }
754
755 return $_retVal;
756 }
757
758 // =============================================================
759 // ** Setter & Getter methods
760
761 // ** Basic System configuration
762
788 public function setConfig($_strConfigPath = null)
789 {
794 $_retVal = true;
795
796 // if we have a path...
797 if (!empty($_strConfigPath)) {
798 // If the path is not valid, this will NOT generate an error,
799 // it will simply return false.
800 if (!@include $_strConfigPath) {
801 $this->_setErr(110, '"'.$_strConfigPath.'" is not a valid path.');
802 $_retVal = false;
803 }
804 } else {
805 // Read the Systems php.ini file
806 // Set these properties ONLY if they are set in the php.ini file.
807 // Otherwise the default values will be used.
808 if ($_host = ini_get('SMTPs')) {
809 $this->setHost($_host);
810 }
811
812 if ($_port = ini_get('smtp_port')) {
813 $this->setPort($_port);
814 }
815
816 if ($_from = ini_get('sendmail_from')) {
817 $this->setFrom($_from);
818 }
819 }
820
821 // Send back what we have
822 return $_retVal;
823 }
824
834 public function setTransportType($_type = 0)
835 {
836 if ((is_numeric($_type)) && (($_type >= 0) && ($_type <= 3))) {
837 $this->_transportType = $_type;
838 }
839 }
840
849 public function getTransportType()
850 {
852 }
853
861 public function setMailPath($_path)
862 {
863 // This feature is not yet implemented
864 return true;
865
866 //if ( $_path ) $this->_mailPath = $_path;
867 }
868
877 public function setHost($_strHost)
878 {
879 if ($_strHost) {
880 $this->_smtpsHost = $_strHost;
881 }
882 }
883
890 public function getHost()
891 {
892 return $this->_smtpsHost;
893 }
894
903 public function setPort($_intPort)
904 {
905 if ((is_numeric($_intPort)) &&
906 (($_intPort >= 1) && ($_intPort <= 65536))) {
907 $this->_smtpsPort = $_intPort;
908 }
909 }
910
917 public function getPort()
918 {
919 return $this->_smtpsPort;
920 }
921
928 public function setID($_strID)
929 {
930 $this->_smtpsID = $_strID;
931 }
932
938 public function getID()
939 {
940 return $this->_smtpsID;
941 }
942
949 public function setPW($_strPW)
950 {
951 $this->_smtpsPW = $_strPW;
952 }
953
959 public function getPW()
960 {
961 return $this->_smtpsPW;
962 }
963
970 public function setToken($_strToken)
971 {
972 $this->_smtpsToken = $_strToken;
973 }
974
980 public function getToken()
981 {
982 return $this->_smtpsToken;
983 }
984
992 public function setCharSet($_strCharSet)
993 {
994 if ($_strCharSet) {
995 $this->_smtpsCharSet = $_strCharSet;
996 }
997 }
998
1004 public function getCharSet()
1005 {
1006 return $this->_smtpsCharSet;
1007 }
1008
1024 public function setTransEncode($_strTransEncode)
1025 {
1026 if (array_search($_strTransEncode, $this->_smtpsTransEncodeTypes)) {
1027 $this->_smtpsTransEncode = $_strTransEncode;
1028 }
1029 }
1030
1036 public function getTransEncode()
1037 {
1039 }
1040
1057 public function setTransEncodeType($_strTransEncodeType)
1058 {
1059 if (array_search($_strTransEncodeType, $this->_smtpsTransEncodeTypes)) {
1060 $this->_smtpsTransEncodeType = $_strTransEncodeType;
1061 }
1062 }
1063
1069 public function getTransEncodeType()
1070 {
1071 return $this->_smtpsTransEncodeTypes[$this->_smtpsTransEncodeType];
1072 }
1073
1074
1075 // ** Message Construction
1076
1083 public function setFrom($_strFrom)
1084 {
1085 if ($_strFrom) {
1086 $this->_msgFrom = $this->_strip_email($_strFrom);
1087 }
1088 }
1089
1096 public function getFrom($_part = true)
1097 {
1098 $_retValue = '';
1099
1100 if ($_part === true) {
1101 $_retValue = $this->_msgFrom;
1102 } else {
1103 $_retValue = $this->_msgFrom[$_part];
1104 }
1105
1106 return $_retValue;
1107 }
1108
1115 public function setReplyTo($_strReplyTo)
1116 {
1117 if ($_strReplyTo) {
1118 $this->_msgReplyTo = $this->_strip_email($_strReplyTo);
1119 }
1120 }
1121
1128 public function getReplyTo($_part = true)
1129 {
1130 $_retValue = '';
1131
1132 if ($_part === true) {
1133 $_retValue = $this->_msgReplyTo;
1134 } else {
1135 $_retValue = $this->_msgReplyTo[$_part];
1136 }
1137
1138 return $_retValue;
1139 }
1140
1151 private function _buildAddrList($_type, $_addrList)
1152 {
1153 // Pull existing list
1154 $aryHost = $this->_msgRecipients;
1155
1156 // Only run this if we have something
1157 if (!empty($_addrList)) {
1158 // $_addrList can be a STRING or an array
1159 if (is_string($_addrList)) {
1160 // This could be a COMMA delimited string
1161 if (strstr($_addrList, ',')) {
1162 // "explode "list" into an array
1163 $_addrList = explode(',', $_addrList);
1164 } else {
1165 // Stick it in an array
1166 $_addrList = array($_addrList);
1167 }
1168 }
1169
1170 // take the array of addresses and split them further
1171 foreach ($_addrList as $_strAddr) {
1172 // Strip off the end '>'
1173 $_strAddr = str_replace('>', '', $_strAddr);
1174
1175 // Seperate "Real Name" from eMail address
1176 $_tmpaddr = null;
1177 $_tmpaddr = explode('<', $_strAddr);
1178
1179 // We have a "Real Name" and eMail address
1180 if (count($_tmpaddr) == 2) {
1181 $_tmpHost = explode('@', $_tmpaddr[1]);
1182 $_tmpaddr[0] = trim($_tmpaddr[0], ' ">');
1183 $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = $_tmpaddr[0];
1184 } else {
1185 // We only have an eMail address
1186 // Strip off the beggining '<'
1187 $_strAddr = str_replace('<', '', $_strAddr);
1188
1189 $_tmpHost = explode('@', $_strAddr);
1190 $_tmpHost[0] = trim($_tmpHost[0]);
1191 $_tmpHost[1] = trim($_tmpHost[1]);
1192
1193 $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = '';
1194 }
1195 }
1196 }
1197 // replace list
1198 $this->_msgRecipients = $aryHost;
1199 }
1200
1201 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1218 private function _strip_email($_strAddr)
1219 {
1220 // phpcs:enable
1221 // Keep the orginal
1222 $_aryEmail['org'] = $_strAddr;
1223
1224 // Set entire string to Lower Case
1225 $_strAddr = strtolower($_strAddr);
1226
1227 // Drop "stuff' off the end
1228 $_strAddr = trim($_strAddr, ' ">');
1229
1230 // Seperate "Real Name" from eMail address, if we have one
1231 $_tmpAry = explode('<', $_strAddr);
1232
1233 // Do we have a "Real name"
1234 if (count($_tmpAry) == 2) {
1235 // We may not really have a "Real Name"
1236 if ($_tmpAry[0]) {
1237 $_aryEmail['real'] = trim($_tmpAry[0], ' ">');
1238 }
1239
1240 $_aryEmail['addr'] = $_tmpAry[1];
1241 } else {
1242 $_aryEmail['addr'] = $_tmpAry[0];
1243 }
1244
1245 // Pull User Name and Host.tld apart
1246 $_tmpHost = explode('@', $_aryEmail['addr']);
1247 $_aryEmail['user'] = $_tmpHost[0];
1248 $_aryEmail['host'] = $_tmpHost[1];
1249
1250 // Put the brackets back around the address
1251 $_aryEmail['addr'] = '<'.$_aryEmail['addr'].'>';
1252
1253 return $_aryEmail;
1254 }
1255
1256 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1264 public function get_RCPT_list()
1265 {
1266 // phpcs:enable
1270 $_RCPT_list = array();
1271
1272 // walk down Recipients array and pull just email addresses
1273 foreach ($this->_msgRecipients as $_host => $_list) {
1274 foreach ($_list as $_subList) {
1275 foreach ($_subList as $_name => $_addr) {
1276 // build RCPT list
1277 $_RCPT_list[] = $_name.'@'.$_host;
1278 }
1279 }
1280 }
1281
1282 return $_RCPT_list;
1283 }
1284
1285 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1292 public function get_email_list($_which = null)
1293 {
1294 // phpcs:enable
1295 // We need to know which address segment to pull
1296 if ($_which) {
1297 // Make sure we have addresses to process
1298 if ($this->_msgRecipients) {
1299 $_RCPT_list = array();
1300 // walk down Recipients array and pull just email addresses
1301 foreach ($this->_msgRecipients as $_host => $_list) {
1302 if (!empty($this->_msgRecipients[$_host][$_which])) {
1303 foreach ($this->_msgRecipients[$_host][$_which] as $_addr => $_realName) {
1304 if ($_realName) { // @CHANGE LDR
1305 $_realName = '"'.$_realName.'"';
1306 $_RCPT_list[] = $_realName.' <'.$_addr.'@'.$_host.'>';
1307 } else {
1308 $_RCPT_list[] = $_addr.'@'.$_host;
1309 }
1310 }
1311 }
1312 }
1313
1314 return implode(', ', $_RCPT_list);
1315 } else {
1316 $this->_setErr(101, 'No eMail Address for message to be sent to.');
1317 return false;
1318 }
1319 } else {
1320 $this->_setErr(102, 'eMail type not defined.');
1321 return false;
1322 }
1323 }
1324
1331 public function setTO($_addrTo)
1332 {
1333 if ($_addrTo) {
1334 $this->_buildAddrList('to', $_addrTo);
1335 }
1336 }
1337
1343 public function getTo()
1344 {
1345 return $this->get_email_list('to');
1346 }
1347
1354 public function setCC($_strCC)
1355 {
1356 if ($_strCC) {
1357 $this->_buildAddrList('cc', $_strCC);
1358 }
1359 }
1360
1366 public function getCC()
1367 {
1368 return $this->get_email_list('cc');
1369 }
1370
1377 public function setBCC($_strBCC)
1378 {
1379 if ($_strBCC) {
1380 $this->_buildAddrList('bcc', $_strBCC);
1381 }
1382 }
1383
1389 public function getBCC()
1390 {
1391 return $this->get_email_list('bcc');
1392 }
1393
1400 public function setSubject($_strSubject = '')
1401 {
1402 if ($_strSubject) {
1403 $this->_msgSubject = $_strSubject;
1404 }
1405 }
1406
1412 public function getSubject()
1413 {
1414 return $this->_msgSubject;
1415 }
1416
1422 public function getHeader()
1423 {
1424 global $conf;
1425
1426 $_header = 'From: '.$this->getFrom('org')."\r\n"
1427 . 'To: '.$this->getTO()."\r\n";
1428
1429 if ($this->getCC()) {
1430 $_header .= 'Cc: '.$this->getCC()."\r\n";
1431 }
1432
1433 /* Note:
1434 * BCC email addresses must be listed in the RCPT TO command list,
1435 * but the BCC header should not be printed under the DATA command.
1436 * So it is included into the function sendMsg() but not here.
1437 * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
1438 */
1439 /*
1440 if ( $this->getBCC() )
1441 $_header .= 'Bcc: ' . $this->getBCC() . "\r\n";
1442 */
1443
1444 $host = dol_getprefix('email');
1445
1446 //NOTE: Message-ID should probably contain the username of the user who sent the msg
1447 $_header .= 'Subject: '.$this->getSubject()."\r\n";
1448 $_header .= 'Date: '.date("r")."\r\n";
1449
1450 $trackid = $this->getTrackId();
1451 if ($trackid) {
1452 $_header .= 'Message-ID: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n";
1453 $_header .= 'X-Dolibarr-TRACKID: '.$trackid.'@'.$host."\r\n";
1454 // References and In-Reply-To: will be set by caller
1455 //$_header .= 'References: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n";
1456 } else {
1457 $_header .= 'Message-ID: <'.time().'.SMTPs@'.$host.">\r\n";
1458 }
1459 if (!empty($_SERVER['REMOTE_ADDR'])) {
1460 $_header .= "X-RemoteAddr: ".$_SERVER['REMOTE_ADDR']."\r\n";
1461 }
1462 if ($this->getMoreInHeader()) {
1463 $_header .= $this->getMoreInHeader(); // Value must include the "\r\n";
1464 }
1465
1466 if ($this->getSensitivity()) {
1467 $_header .= 'Sensitivity: '.$this->getSensitivity()."\r\n";
1468 }
1469
1470 if ($this->_msgPriority != 3) {
1471 $_header .= $this->getPriority();
1472 }
1473
1474
1475 // @CHANGE LDR
1476 if ($this->getDeliveryReceipt()) {
1477 $_header .= 'Disposition-Notification-To: '.$this->getFrom('addr')."\r\n";
1478 }
1479 if ($this->getErrorsTo()) {
1480 $_header .= 'Errors-To: '.$this->getErrorsTo('addr')."\r\n";
1481 }
1482 if ($this->getReplyTo()) {
1483 $_header .= "Reply-To: ".$this->getReplyTo('addr')."\r\n";
1484 }
1485
1486 $_header .= 'X-Mailer: Dolibarr version '.DOL_VERSION.' (using SMTPs Mailer)'."\r\n";
1487 $_header .= 'X-Dolibarr-Option: '.($conf->global->MAIN_MAIL_USE_MULTI_PART ? 'MAIN_MAIL_USE_MULTI_PART' : 'No MAIN_MAIL_USE_MULTI_PART')."\r\n";
1488 $_header .= 'Mime-Version: 1.0'."\r\n";
1489
1490 // TODO Add also $this->references and In-Reply-To
1491
1492 return $_header;
1493 }
1494
1502 public function setBodyContent($strContent, $strType = 'plain')
1503 {
1504 //if ( $strContent )
1505 //{
1506 if ($strType == 'html') {
1507 $strMimeType = 'text/html';
1508 } else {
1509 $strMimeType = 'text/plain';
1510 }
1511
1512 // Make RFC821 Compliant, replace bare linefeeds
1513 $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent);
1514
1515 $strContentAltText = '';
1516 if ($strType == 'html') {
1517 // Similar code to forge a text from html is also in CMailFile.class.php
1518 $strContentAltText = preg_replace('/<head><title>.*<\/style><\/head>/', '', $strContent);
1519 $strContentAltText = preg_replace("/<br\s*[^>]*>/", " ", $strContentAltText);
1520 $strContentAltText = html_entity_decode(strip_tags($strContentAltText));
1521 $strContentAltText = trim(wordwrap($strContentAltText, 75, "\r\n"));
1522 }
1523
1524 // Make RFC2045 Compliant
1525 //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content
1526 $strContent = rtrim(wordwrap($strContent, 75, "\r\n")); // TODO Using this method creates unexpected line break on text/plain content.
1527
1528 $this->_msgContent[$strType] = array();
1529
1530 $this->_msgContent[$strType]['mimeType'] = $strMimeType;
1531 $this->_msgContent[$strType]['data'] = $strContent;
1532 $this->_msgContent[$strType]['dataText'] = $strContentAltText;
1533
1534 if ($this->getMD5flag()) {
1535 $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3);
1536 }
1537 //}
1538 }
1539
1545 public function getBodyContent()
1546 {
1547 global $conf;
1548
1549 // Generate a new Boundary string
1550 $this->_setBoundary();
1551
1552 // What type[s] of content do we have
1553 $_types = array_keys($this->_msgContent);
1554
1555 // How many content types do we have
1556 $keyCount = count($_types);
1557
1558 // If we have ZERO, we have a problem
1559 if ($keyCount === 0) {
1560 die("Sorry, no content");
1561 } elseif ($keyCount === 1 && !getDolGlobalString('MAIN_MAIL_USE_MULTI_PART')) {
1562 // If we have ONE, we can use the simple format
1563 $_msgData = $this->_msgContent;
1564 $_msgData = $_msgData[$_types[0]];
1565
1566 $content = 'Content-Type: '.$_msgData['mimeType'].'; charset="'.$this->getCharSet().'"'."\r\n"
1567 . 'Content-Transfer-Encoding: '.$this->getTransEncodeType()."\r\n"
1568 . 'Content-Disposition: inline'."\r\n"
1569 . 'Content-Description: Message'."\r\n";
1570
1571 if ($this->getMD5flag()) {
1572 $content .= 'Content-MD5: '.$_msgData['md5']."\r\n";
1573 }
1574
1575 $content .= "\r\n"
1576 . $_msgData['data']."\r\n";
1577 } elseif ($keyCount >= 1 || getDolGlobalString('MAIN_MAIL_USE_MULTI_PART')) {
1578 // If we have more than ONE, we use the multi-part format
1579 // Since this is an actual multi-part message
1580 // We need to define a content message Boundary
1581 // NOTE: This was 'multipart/alternative', but Windows based mail servers have issues with this.
1582
1583 //$content = 'Content-Type: multipart/related; boundary="' . $this->_getBoundary() . '"' . "\r\n";
1584 $content = 'Content-Type: multipart/mixed; boundary="'.$this->_getBoundary('mixed').'"'."\r\n";
1585
1586 // . "\r\n"
1587 // . 'This is a multi-part message in MIME format.' . "\r\n";
1588 $content .= "Content-Transfer-Encoding: 8bit\r\n";
1589 $content .= "\r\n";
1590
1591 $content .= "--".$this->_getBoundary('mixed')."\r\n";
1592
1593 if (key_exists('image', $this->_msgContent)) { // If inline image found
1594 $content .= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"'."\r\n";
1595 $content .= "\r\n";
1596 $content .= "--".$this->_getBoundary('alternative')."\r\n";
1597 }
1598
1599
1600 // $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment'
1601
1602
1603 // Loop through message content array
1604 foreach ($this->_msgContent as $type => $_content) {
1605 if ($type == 'attachment') {
1606 // loop through all attachments
1607 foreach ($_content as $_file => $_data) {
1608 $content .= "--".$this->_getBoundary('mixed')."\r\n"
1609 . 'Content-Disposition: attachment; filename="'.$_data['fileName'].'"'."\r\n"
1610 . 'Content-Type: '.$_data['mimeType'].'; name="'.$_data['fileName'].'"'."\r\n"
1611 . 'Content-Transfer-Encoding: base64'."\r\n"
1612 . 'Content-Description: '.$_data['fileName']."\r\n";
1613 if (!empty($_data['cid'])) {
1614 $content .= "X-Attachment-Id: ".$_data['cid']."\r\n";
1615 $content .= "Content-ID: <".$_data['cid'].">\r\n";
1616 }
1617 if ($this->getMD5flag()) {
1618 $content .= 'Content-MD5: '.$_data['md5']."\r\n";
1619 }
1620
1621 $content .= "\r\n".$_data['data']."\r\n\r\n";
1622 }
1623 } elseif ($type == 'image') {
1624 // @CHANGE LDR
1625 // loop through all images
1626 foreach ($_content as $_image => $_data) {
1627 $content .= "--".$this->_getBoundary('related')."\r\n"; // always related for an inline image
1628
1629 $content .= 'Content-Type: '.$_data['mimeType'].'; name="'.$_data['imageName'].'"'."\r\n"
1630 . 'Content-Transfer-Encoding: base64'."\r\n"
1631 . 'Content-Disposition: inline; filename="'.$_data['imageName'].'"'."\r\n"
1632 . 'Content-ID: <'.$_data['cid'].'> '."\r\n";
1633
1634 if ($this->getMD5flag()) {
1635 $content .= 'Content-MD5: '.$_data['md5']."\r\n";
1636 }
1637
1638 $content .= "\r\n"
1639 . $_data['data']."\r\n";
1640 }
1641
1642 // always end related and end alternative after inline images
1643 $content .= "--".$this->_getBoundary('related')."--\r\n";
1644 $content .= "\r\n--".$this->_getBoundary('alternative')."--\r\n";
1645 $content .= "\r\n";
1646 } else {
1647 if (key_exists('image', $this->_msgContent)) {
1648 $content .= "Content-Type: text/plain; charset=".$this->getCharSet()."\r\n";
1649 $content .= "\r\n".($_content['dataText'] ? $_content['dataText'] : strip_tags($_content['data']))."\r\n"; // Add plain text message
1650 $content .= "--".$this->_getBoundary('alternative')."\r\n";
1651 $content .= 'Content-Type: multipart/related; boundary="'.$this->_getBoundary('related').'"'."\r\n";
1652 $content .= "\r\n";
1653 $content .= "--".$this->_getBoundary('related')."\r\n";
1654 }
1655
1656 if (!key_exists('image', $this->_msgContent) && $_content['dataText'] && getDolGlobalString('MAIN_MAIL_USE_MULTI_PART')) {
1657 // Add plain text message part before html part
1658 $content .= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"'."\r\n";
1659 $content .= "\r\n";
1660 $content .= "--".$this->_getBoundary('alternative')."\r\n";
1661
1662 $content .= "Content-Type: text/plain; charset=".$this->getCharSet()."\r\n";
1663 $content .= "\r\n".$_content['dataText']."\r\n";
1664 $content .= "--".$this->_getBoundary('alternative')."\r\n";
1665 }
1666
1667 $content .= 'Content-Type: '.$_content['mimeType'].'; charset='.$this->getCharSet();
1668
1669 $content .= "\r\n";
1670
1671 if ($this->getMD5flag()) {
1672 $content .= 'Content-MD5: '.$_content['md5']."\r\n";
1673 }
1674
1675 $content .= "\r\n".$_content['data']."\r\n";
1676
1677 if (!key_exists('image', $this->_msgContent) && $_content['dataText'] && getDolGlobalString('MAIN_MAIL_USE_MULTI_PART')) {
1678 // Add plain text message part after html part
1679 $content .= "--".$this->_getBoundary('alternative')."--\r\n";
1680 }
1681
1682 $content .= "\r\n";
1683 }
1684 }
1685
1686 $content .= "--".$this->_getBoundary('mixed').'--'."\r\n";
1687 }
1688
1689 return $content;
1690 }
1691
1702 public function setAttachment($strContent, $strFileName = 'unknown', $strMimeType = 'unknown', $strCid = '')
1703 {
1704 if ($strContent) {
1705 $strContent = rtrim(chunk_split(base64_encode($strContent), 76, "\r\n")); // 76 max is defined into http://tools.ietf.org/html/rfc2047
1706
1707 $this->_msgContent['attachment'][$strFileName]['mimeType'] = $strMimeType;
1708 $this->_msgContent['attachment'][$strFileName]['fileName'] = $strFileName;
1709 $this->_msgContent['attachment'][$strFileName]['data'] = $strContent;
1710 $this->_msgContent['attachment'][$strFileName]['cid'] = $strCid; // If defined, it means this attachment must be shown inline
1711
1712 if ($this->getMD5flag()) {
1713 $this->_msgContent['attachment'][$strFileName]['md5'] = dol_hash($strContent, 3);
1714 }
1715 }
1716 }
1717
1718
1719 // @CHANGE LDR
1720
1731 public function setImageInline($strContent, $strImageName = 'unknown', $strMimeType = 'unknown', $strImageCid = 'unknown')
1732 {
1733 if ($strContent) {
1734 $this->_msgContent['image'][$strImageName]['mimeType'] = $strMimeType;
1735 $this->_msgContent['image'][$strImageName]['imageName'] = $strImageName;
1736 $this->_msgContent['image'][$strImageName]['cid'] = $strImageCid;
1737 $this->_msgContent['image'][$strImageName]['data'] = $strContent;
1738
1739 if ($this->getMD5flag()) {
1740 $this->_msgContent['image'][$strImageName]['md5'] = dol_hash($strContent, 3);
1741 }
1742 }
1743 }
1744 // END @CHANGE LDR
1745
1746
1758 public function setSensitivity($_value = 0)
1759 {
1760 if ((is_numeric($_value)) &&
1761 (($_value >= 0) && ($_value <= 3))) {
1762 $this->_msgSensitivity = $_value;
1763 }
1764 }
1765
1776 public function getSensitivity()
1777 {
1778 return $this->_arySensitivity[$this->_msgSensitivity];
1779 }
1780
1794 public function setPriority($_value = 3)
1795 {
1796 if ((is_numeric($_value)) &&
1797 (($_value >= 0) && ($_value <= 5))) {
1798 $this->_msgPriority = $_value;
1799 }
1800 }
1801
1814 public function getPriority()
1815 {
1816 return 'Importance: '.$this->_aryPriority[$this->_msgPriority]."\r\n"
1817 . 'Priority: '.$this->_aryPriority[$this->_msgPriority]."\r\n"
1818 . 'X-Priority: '.$this->_msgPriority.' ('.$this->_aryPriority[$this->_msgPriority].')'."\r\n";
1819 }
1820
1827 public function setMD5flag($_flag = false)
1828 {
1829 $this->_smtpMD5 = $_flag;
1830 }
1831
1837 public function getMD5flag()
1838 {
1839 return $this->_smtpMD5;
1840 }
1841
1850 public function setXheader($strXdata)
1851 {
1852 if ($strXdata) {
1853 $this->_msgXheader[] = $strXdata;
1854 }
1855 }
1856
1862 public function getXheader()
1863 {
1864 return $this->_msgXheader;
1865 }
1866
1872 private function _setBoundary()
1873 {
1874 $this->_smtpsBoundary = "multipart_x.".time().".x_boundary";
1875 $this->_smtpsRelatedBoundary = 'mul_'.dol_hash(uniqid("dolibarr2"), 3);
1876 $this->_smtpsAlternativeBoundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3);
1877 }
1878
1885 private function _getBoundary($type = 'mixed')
1886 {
1887 if ($type == 'mixed') {
1888 return $this->_smtpsBoundary;
1889 } elseif ($type == 'related') {
1891 } elseif ($type == 'alternative') {
1893 }
1894 return '';
1895 }
1896
1897 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1908 public function server_parse($socket, $response)
1909 {
1910 // phpcs:enable
1915 $_retVal = true;
1916
1917 $server_response = '';
1918
1919 // avoid infinite loop
1920 $limit = 0;
1921
1922 while (substr($server_response, 3, 1) != ' ' && $limit < 100) {
1923 if (!($server_response = fgets($socket, 256))) {
1924 $this->_setErr(121, "Couldn't get mail server response codes");
1925 $_retVal = false;
1926 break;
1927 }
1928 $this->log .= $server_response;
1929 $limit++;
1930 }
1931
1932 $this->lastretval = substr($server_response, 0, 3);
1933
1934 if (!(substr($server_response, 0, 3) == $response)) {
1935 $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse: ".$server_response);
1936 $_retVal = false;
1937 }
1938
1939 return $_retVal;
1940 }
1941
1942 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1951 public function socket_send_str($_strSend, $_returnCode = null, $CRLF = "\r\n")
1952 {
1953 // phpcs:enable
1954 if ($this->_debug) {
1955 $this->log .= $_strSend; // @CHANGE LDR for log
1956 }
1957 fputs($this->socket, $_strSend.$CRLF);
1958 if ($this->_debug) {
1959 $this->log .= ' ('.$_returnCode.')'.$CRLF;
1960 }
1961
1962 if ($_returnCode) {
1963 return $this->server_parse($this->socket, $_returnCode);
1964 }
1965
1966 return null;
1967 }
1968
1969 // =============================================================
1970 // ** Error handling methods
1971
1979 private function _setErr($_errNum, $_errMsg)
1980 {
1981 $this->_smtpsErrors[] = array(
1982 'num' => $_errNum,
1983 'msg' => $_errMsg,
1984 );
1985 }
1986
1992 public function getErrors()
1993 {
1994 $_errMsg = array();
1995
1996 if (is_array($this->_smtpsErrors)) {
1997 foreach ($this->_smtpsErrors as $_err => $_info) {
1998 $_errMsg[] = 'Error ['.$_info['num'].']: '.$_info['msg'];
1999 }
2000 }
2001
2002 return implode("\n", $_errMsg);
2003 }
2004}
2005
2006
2007// =============================================================
2008// ** CSV Version Control Info
2009
Class to construct and send SMTP compliant email, even to a secure SMTP server, regardless of platfor...
$_smtpsToken
Token in case we use OAUTH2.
_getBoundary($type='mixed')
Retrieves the MIME message Boundary.
setConfig($_strConfigPath=null)
setConfig() is used to populate select class properties from either a user defined INI file or the sy...
sendMsg()
Now send the message.
$_arySensitivity
Message Sensitivity.
$_smtpsCharSet
Character set Defaulted to 'iso-8859-1'.
getErrors()
Returns applicative errors codes and messages for Class (not the SMTP error code)
setCharSet($_strCharSet)
Character set used for current message Character set is defaulted to 'iso-8859-1';.
setSubject($_strSubject='')
Message Subject.
getPriority()
Message Content Priority Message Priority values:
$_smtpsHost
Host Name or IP of SMTP Server to use.
getMD5flag()
Gets flag which determines whether to calculate message MD5 checksum.
socket_send_str($_strSend, $_returnCode=null, $CRLF="\r\n")
Send str.
_strip_email($_strAddr)
Returns an array of the various parts of an email address This assumes a well formed address:
getTransEncodeType()
Retrieves the Content-Transfer-Encoding.
setTrackId($_val='')
Set trackid.
setToken($_strToken)
User token for OAUTH2.
buildRCPTlist()
build RECIPIENT List, all addresses who will recieve this message
getBodyContent()
Retrieves the Message Content.
_buildAddrList($_type, $_addrList)
Inserts given addresses into structured format.
setOptions($_options=array())
Set delivery receipt.
_server_connect()
Attempt a connection to mail server.
setBodyContent($strContent, $strType='plain')
Message Content.
server_parse($socket, $response)
This function has been modified as provided by SirSir to allow multiline responses when using SMTP Ex...
setTransportType($_type=0)
Determines the method inwhich the messages are to be sent.
getBCC()
Retrieves the BCC Address[es] inwhich to send mail to.
$_smtpsTransEncodeTypes
Content-Transfer-Encoding.
setAttachment($strContent, $strFileName='unknown', $strMimeType='unknown', $strCid='')
File attachments are added to the content array as sub-arrays, allowing for multiple attachments for ...
_setBoundary()
Generates Random string for MIME message Boundary.
getTo()
Retrieves the TO Address[es] inwhich to send mail to.
setPort($_intPort)
Defines the Port Number of the Mail Server to use This is defaulted to '25' This is used only with 's...
getID()
Retrieves the User Name for authentication on Mail Server.
setBCC($_strBCC)
BCC Address[es] inwhich to send mail to.
setReplyTo($_strReplyTo)
Reply-To Address from which mail will be the reply-to.
getToken()
Retrieves the User token for OAUTH2.
setSensitivity($_value=0)
Message Content Sensitivity Message Sensitivity values:
setCC($_strCC)
CC Address[es] inwhich to send mail to.
$_msgReplyTo
Where are replies and errors to be sent to This can be defined via a INI file or via a setter method.
$_smtpsID
Secure SMTP Server access ID This can be defined via a INI file or via a setter method.
setTO($_addrTo)
TO Address[es] inwhich to send mail to.
setTransEncodeType($_strTransEncodeType)
Content-Transfer-Encoding, Defaulted to '0' [ZERO] This can be changed for 2byte characers sets Known...
get_email_list($_which=null)
Returns an array of addresses for a specific type; TO, CC or BCC.
setMD5flag($_flag=false)
Set flag which determines whether to calculate message MD5 checksum.
getCharSet()
Retrieves the Character set used for current message.
getCC()
Retrieves the CC Address[es] inwhich to send mail to.
getDeliveryReceipt()
get delivery receipt
getTrackId()
get trackid
setFrom($_strFrom)
FROM Address from which mail will be sent.
get_RCPT_list()
Returns an array of bares addresses for use with 'RCPT TO:' This is a "build as you go" method.
_server_authenticate()
Attempt mail server authentication for a secure connection.
setID($_strID)
User Name for authentication on Mail Server.
getMoreInHeader()
get moreInHeader
$_log_level
Defines log level 0 - no logging 1 - connectivity logging 2 - message generation logging 3 - detail l...
getPW()
Retrieves the User Password for authentication on Mail Server.
getSubject()
Retrieves the Message Subject.
getXheader()
Retrieves the Message X-Header Content.
$_msgFrom
Who sent the Message This can be defined via a INI file or via a setter method.
setErrorsTo($_strErrorsTo)
Set errors to.
$_smtpsTransEncodeType
Content-Transfer-Encoding Defaulted to 0 - 7bit.
setImageInline($strContent, $strImageName='unknown', $strMimeType='unknown', $strImageCid='unknown')
Image attachments are added to the content array as sub-arrays, allowing for multiple images for each...
$_smtpsTransEncode
Content-Transfer-Encoding Defaulted to '7bit'.
$_smtpTimeout
Sets the SMTP server timeout in seconds.
$_smtpsRelatedBoundary
Related Boundary.
setHost($_strHost)
Defines the Host Name or IP of the Mail Server to use.
$_msgPriority
Message Sensitivity Defaults to 3 - Normal.
$_smtpsPort
SMTP Server Port definition.
getFrom($_part=true)
Retrieves the Address from which mail will be sent.
getHost()
Retrieves the Host Name or IP of the Mail Server to use This is used only with 'socket' based mail tr...
$_msgSensitivity
Message Sensitivity Defaults to ZERO - None.
setPW($_strPW)
User Password for authentication on Mail Server.
$_smtpsErrors
Class error codes and messages.
$_msgSubject
Message Subject.
getReplyTo($_part=true)
Retrieves the Address from which mail will be the reply-to.
setPriority($_value=3)
Message Content Priority Message Priority values:
setMoreInHeader($_val='')
Set moreInHeader.
$_smtpMD5
Determines whether to calculate message MD5 checksum.
$_smtpsAlternativeBoundary
Alternative Boundary.
$_aryPriority
Message Priority.
$_smtpsBoundary
Boundary String for MIME seperation.
getErrorsTo($_part=true)
Get errors to.
getSensitivity()
Returns Message Content Sensitivity string Message Sensitivity values:
getPort()
Retrieves the Port Number of the Mail Server to use This is used only with 'socket' based mail transm...
$_msgXheader
Custom X-Headers.
$_options
An array of options for stream_context_create()
$_smtpsPW
Secure SMTP Server access Password This can be defined via a INI file or via a setter method.
getTransportType()
Return the method inwhich the message is to be sent.
setMailPath($_path)
Path to the sendmail execuable.
getTransEncode()
Retrieves the Content-Transfer-Encoding.
setTransEncode($_strTransEncode)
Content-Transfer-Encoding, Defaulted to '7bit' This can be changed for 2byte characers sets Known Enc...
$_mailPath
If '$_transportType' is set to '1', then this variable is used to define the UNIX file system path to...
setDebug($_vDebug=false)
Set debug.
$_msgRecipients
Who will the Message be sent to; TO, CC, BCC Multi-diminsional array containg addresses the message w...
setDeliveryReceipt($_val=0)
Set delivery receipt.
_setErr($_errNum, $_errMsg)
Defines errors codes and messages for Class.
getHeader()
Constructes and returns message header.
$_debug
Place Class in" debug" mode.
setXheader($strXdata)
Message X-Header Content This is a simple "insert".
$_transportType
Determines the method inwhich the message are to be sent.
is_ip($ip)
This function evaluates a string that should be a valid IPv4 Note: For ip 169.254....
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
getDomainFromURL($url, $mode=0)
Function get second level domain name.
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.