dolibarr  17.0.2
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 
46 class 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 
103  private $_msgContent = null;
104 
108  private $_msgXheader = null;
109 
114  private $_smtpsCharSet = 'iso-8859-1';
115 
120  private $_msgSensitivity = 0;
121 
125  private $_arySensitivity = array(false,
126  'Personal',
127  'Private',
128  'Company Confidential');
129 
134  private $_msgPriority = 3;
135 
139  private $_aryPriority = array('Bulk',
140  'Highest',
141  'High',
142  'Normal',
143  'Low',
144  'Lowest');
145 
151 
155  private $_smtpsTransEncodeTypes = array('7bit', // Simple 7-bit ASCII
156  '8bit', // 8-bit coding with line termination characters
157  'base64', // 3 octets encoded into 4 sextets with offset
158  'binary', // Arbitrary binary stream
159  'mac-binhex40', // Macintosh binary to hex encoding
160  'quoted-printable', // Mostly 7-bit, with 8-bit characters encoded as "=HH"
161  'uuencode'); // UUENCODE encoding
162 
167  private $_smtpsTransEncode = '7bit';
168 
172  private $_smtpsBoundary = null;
173 
177  private $_smtpsRelatedBoundary = null;
178 
183 
191  private $_transportType = 0;
192 
197  private $_mailPath = '/usr/lib/sendmail';
198 
202  private $_smtpTimeout = 10;
203 
207  private $_smtpMD5 = false;
208 
212  private $_smtpsErrors = null;
213 
221  private $_log_level = 0;
222 
226  private $_debug = false;
227 
228 
229  // @CHANGE LDR
230  public $log = '';
231  public $lastretval = '';
232  private $_errorsTo = '';
233  private $_deliveryReceipt = 0;
234  private $_trackId = '';
235  private $_moreinheader = '';
236 
240  private $_options = array();
241 
248  public function setOptions($_options = array())
249  {
250  $this->_options = $_options;
251  }
252 
259  public function setDeliveryReceipt($_val = 0)
260  {
261  $this->_deliveryReceipt = $_val;
262  }
263 
269  public function getDeliveryReceipt()
270  {
271  return $this->_deliveryReceipt;
272  }
273 
280  public function setTrackId($_val = '')
281  {
282  $this->_trackId = $_val;
283  }
284 
291  public function setMoreInHeader($_val = '')
292  {
293  $this->_moreinheader = $_val;
294  }
295 
301  public function getTrackId()
302  {
303  return $this->_trackId;
304  }
305 
311  public function getMoreInHeader()
312  {
313  return $this->_moreinheader;
314  }
315 
322  public function setErrorsTo($_strErrorsTo)
323  {
324  if ($_strErrorsTo) {
325  $this->_errorsTo = $this->_strip_email($_strErrorsTo);
326  }
327  }
328 
335  public function getErrorsTo($_part = true)
336  {
337  $_retValue = '';
338 
339  if ($_part === true) {
340  $_retValue = $this->_errorsTo;
341  } else {
342  $_retValue = $this->_errorsTo[$_part];
343  }
344 
345  return $_retValue;
346  }
347 
354  public function setDebug($_vDebug = false)
355  {
356  $this->_debug = $_vDebug;
357  }
358 
364  public function buildRCPTlist()
365  {
366  // Pull TO list
367  $_aryToList = $this->getTO();
368  }
369 
370  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
376  private function _server_connect()
377  {
378  // phpcs:enable
379  // Default return value
380  $_retVal = true;
381 
382  // We have to make sure the HOST given is valid
383  // This is done here because '@fsockopen' will not give me this
384  // information if it failes to connect because it can't find the HOST
385  $host = $this->getHost();
386  $usetls = preg_match('@tls://@i', $host);
387 
388  $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
389  $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
390  $host = preg_replace('@tls://@i', '', $host); // Remove prefix
391 
392  // @CHANGE LDR
393  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
394 
395  if ((!is_ip($host)) && ((gethostbyname($host)) == $host)) {
396  $this->_setErr(99, $host.' is either offline or is an invalid host name.');
397  $_retVal = false;
398  } else {
399  if (function_exists('stream_socket_client') && !empty($this->_options)) {
400  $socket_context = stream_context_create($this->_options); // An array of options for stream_context_create()
401  $this->socket = @stream_socket_client(
402  preg_replace('@tls://@i', '', $this->getHost()).// Host to 'hit', IP or domain
403  ':'.$this->getPort(), // which Port number to use
404  $this->errno, // actual system level error
405  $this->errstr, // and any text that goes with the error
406  $this->_smtpTimeout, // timeout for reading/writing data over the socket
407  STREAM_CLIENT_CONNECT,
408  $socket_context // Options for connection
409  );
410  } else {
411  $this->socket = @fsockopen(
412  preg_replace('@tls://@i', '', $this->getHost()), // Host to 'hit', IP or domain
413  $this->getPort(), // which Port number to use
414  $this->errno, // actual system level error
415  $this->errstr, // and any text that goes with the error
416  $this->_smtpTimeout // timeout for reading/writing data over the socket
417  );
418  }
419 
420  //See if we can connect to the SMTP server
421  if (is_resource($this->socket)) {
422  // Fix from PHP SMTP class by 'Chris Ryan'
423  // Sometimes the SMTP server takes a little longer to respond
424  // so we will give it a longer timeout for the first read
425  // Windows still does not have support for this timeout function
426  if (function_exists('stream_set_timeout')) {
427  stream_set_timeout($this->socket, $this->_smtpTimeout, 0);
428  }
429 
430  // Check response from Server
431  if ($_retVal = $this->server_parse($this->socket, "220")) {
432  $_retVal = $this->socket;
433  }
434  } else {
435  // This connection attempt failed.
436  // @CHANGE LDR
437  if (empty($this->errstr)) {
438  $this->errstr = 'Failed to connect with fsockopen host='.$this->getHost().' port='.$this->getPort();
439  }
440  $this->_setErr($this->errno, $this->errstr);
441  $_retVal = false;
442  }
443  }
444 
445  return $_retVal;
446  }
447 
448  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
454  private function _server_authenticate()
455  {
456  // phpcs:enable
457  global $conf;
458 
459  // Send the RFC2554 specified EHLO.
460  // This improvment as provided by 'SirSir' to
461  // accomodate both SMTP AND ESMTP capable servers
462  $host = $this->getHost();
463  $usetls = preg_match('@tls://@i', $host);
464 
465  $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
466  $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
467  $host = preg_replace('@tls://@i', '', $host); // Remove prefix
468 
469  if ($usetls && !empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) {
470  $host = 'tls://'.$host;
471  }
472 
473  $hosth = $host; // so for example 'localhost' or 'smtp-relay.gmail.com'
474 
475  if (!empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
476  if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
477  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name
478  $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO;
479  } else {
480  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from.
481  // So if the from to is 'aaa <bbb@ccc.com>', we will keep 'ccc.com'
482  $hosth = $this->getFrom('addr');
483  $hosth = preg_replace('/^.*</', '', $hosth);
484  $hosth = preg_replace('/>.*$/', '', $hosth);
485  $hosth = preg_replace('/.*@/', '', $hosth);
486  }
487  }
488 
489  if ($_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) {
490  if ($usetls) {
491  /*
492  The following dialog illustrates how a client and server can start a TLS STARTTLS session:
493  S: <waits for connection on TCP port 25>
494  C: <opens connection>
495  S: 220 mail.imc.org SMTP service ready
496  C: EHLO mail.ietf.org
497  S: 250-mail.imc.org offers a warm hug of welcome
498  S: 250 STARTTLS
499  C: STARTTLS
500  S: 220 Go ahead
501  C: <starts TLS negotiation>
502  C & S: <negotiate a TLS session>
503  C & S: <check result of negotiation>
504  // Second pass EHLO
505  C: EHLO client-domain.com
506  S: 250-server-domain.com
507  S: 250 AUTH LOGIN
508  C: <continues by sending an SMTP command
509 
510  Another example here:
511  S: 220 smtp.server.com Simple Mail Transfer Service Ready
512  C: EHLO client.example.com
513  S: 250-smtp.server.com Hello client.example.com
514  S: 250-SIZE 1000000
515  S: 250-AUTH LOGIN PLAIN CRAM-MD5
516  S: 250-STARTTLS
517  S: 250 HELP
518  C: STARTTLS
519  S: 220 TLS go ahead
520  C: EHLO client.example.com *
521  S: 250-smtp.server.com Hello client.example.com
522  S: 250-SIZE 1000000
523  S: 250-AUTH LOGIN PLAIN CRAM-MD5
524  S: 250 HELP
525  C: AUTH LOGIN
526  S: 334 VXNlcm5hbWU6
527  C: adlxdkej
528  S: 334 UGFzc3dvcmQ6
529  C: lkujsefxlj
530  S: 235 2.7.0 Authentication successful
531  C: MAIL FROM:<mail@samlogic.com>
532  S: 250 OK
533  C: RCPT TO:<john@mail.com>
534  S: 250 OK
535  C: DATA
536  S: 354 Send message, end with a "." on a line by itself
537  C: <The message data (body text, subject, e-mail header, attachments etc) is sent>
538  S .
539  S: 250 OK, message accepted for delivery: queued as 12345
540  C: QUIT
541  S: 221 Bye
542  */
543  if (!$_retVal = $this->socket_send_str('STARTTLS', 220)) {
544  $this->_setErr(131, 'STARTTLS connection is not supported.');
545  return $_retVal;
546  }
547 
548  // Before 5.6.7:
549  // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_SSLv2_CLIENT|STREAM_CRYPTO_METHOD_SSLv3_CLIENT
550  // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
551  // PHP >= 5.6.7:
552  // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
553  // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
554 
555  $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
556  if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
557  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
558  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
559  }
560 
561  if (!stream_socket_enable_crypto($this->socket, true, $crypto_method)) {
562  $this->_setErr(132, 'STARTTLS connection failed.');
563  return $_retVal;
564  }
565  // Most servers expect a 2nd pass of EHLO after TLS is established to get another time
566  // the answer with list of supported AUTH methods. They may differs between non STARTTLS and with STARTTLS.
567  if (! $_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) {
568  $this->_setErr(126, '"'.$hosth.'" does not support authenticated connections or temporary error. Error after 2nd sending EHLO '.$hosth.' : '.$this->lastretval);
569  return $_retVal;
570  }
571  }
572 
573  // Default authentication method is LOGIN
574  if (empty($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE)) {
575  $conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE = 'LOGIN';
576  }
577 
578  // Send Authentication to Server
579  // Check for errors along the way
580  switch ($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE) {
581  case 'NONE':
582  // 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.
583  $_retVal = true;
584  break;
585  case 'PLAIN':
586  $this->socket_send_str('AUTH PLAIN', '334');
587  // The error here just means the ID/password combo doesn't work.
588  $_retVal = $this->socket_send_str(base64_encode("\0".$this->_smtpsID."\0".$this->_smtpsPW), '235');
589  break;
590  case 'XOAUTH2':
591  // "user=$email\1auth=Bearer $token\1\1"
592  $user = $this->_smtpsID;
593  $token = $this->_smtpsToken;
594  $initRes = "user=".$user."\001auth=Bearer ".$token."\001\001";
595  $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($initRes), '235');
596  if (!$_retVal) {
597  $this->_setErr(130, 'Error when asking for AUTH XOAUTH2');
598  }
599  break;
600  case 'LOGIN': // most common case
601  default:
602  $_retVal = $this->socket_send_str('AUTH LOGIN', '334');
603  if (!$_retVal) {
604  $this->_setErr(130, 'Error when asking for AUTH LOGIN');
605  } else {
606  // User name will not return any error, server will take anything we give it.
607  $this->socket_send_str(base64_encode($this->_smtpsID), '334');
608  // The error here just means the ID/password combo doesn't work.
609  // There is no method to determine which is the problem, ID or password
610  $_retVal = $this->socket_send_str(base64_encode($this->_smtpsPW), '235');
611  }
612  break;
613  }
614  if (!$_retVal) {
615  $this->_setErr(130, 'Invalid Authentication Credentials.');
616  }
617  } else {
618  $this->_setErr(126, '"'.$host.'" does not support authenticated connections or temporary error. Error after sending EHLO '.$hosth.' : '.$this->lastretval);
619  }
620 
621  return $_retVal;
622  }
623 
629  public function sendMsg()
630  {
631  global $conf;
632 
636  $_retVal = false;
637 
638  // Connect to Server
639  if ($this->socket = $this->_server_connect()) {
640  // If a User ID *and* a password is given, assume Authentication is desired
641  if (!empty($this->_smtpsID) && (!empty($this->_smtpsPW) || !empty($this->_smtpsToken))) {
642  // Send the RFC2554 specified EHLO.
643  $_retVal = $this->_server_authenticate();
644  } else {
645  // This is a "normal" SMTP Server "handshack"
646  // Send the RFC821 specified HELO.
647  $host = $this->getHost();
648  $usetls = preg_match('@tls://@i', $host);
649 
650  $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
651  $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
652  $host = preg_replace('@tls://@i', '', $host); // Remove prefix
653 
654  if ($usetls && !empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) {
655  $host = 'tls://'.$host;
656  }
657 
658  $hosth = $host;
659 
660  if (!empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
661  if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
662  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name
663  $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO;
664  } else {
665  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from.
666  // If the from to is 'aaa <bbb@ccc.com>', we will keep 'ccc.com'
667  $hosth = $this->getFrom('addr');
668  $hosth = preg_replace('/^.*</', '', $hosth);
669  $hosth = preg_replace('/>.*$/', '', $hosth);
670  $hosth = preg_replace('/.*@/', '', $hosth);
671  }
672  }
673 
674  // Send the HELO message to the SMTP server
675  $_retVal = $this->socket_send_str('HELO '.$hosth, '250');
676  }
677 
678  // Well, did we get the server answer with correct code ?
679  if ($_retVal) {
680  // From this point onward most server response codes should be 250
681  // Specify who the mail is from....
682  // This has to be the raw email address, strip the "name" off
683  $resultmailfrom = $this->socket_send_str('MAIL FROM: '.$this->getFrom('addr'), '250');
684  if (!$resultmailfrom) {
685  fclose($this->socket);
686  return false;
687  }
688 
689  // 'RCPT TO:' must be given a single address, so this has to loop
690  // through the list of addresses, regardless of TO, CC or BCC
691  // and send it out "single file"
692  foreach ($this->get_RCPT_list() as $_address) {
693  /* Note:
694  * BCC email addresses must be listed in the RCPT TO command list,
695  * but the BCC header should not be printed under the DATA command.
696  * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
697  */
698 
699  /*
700  * TODO
701  * After each 'RCPT TO:' is sent, we need to make sure it was kosher,
702  * if not, the whole message will fail
703  * If any email address fails, we will need to RESET the connection,
704  * mark the last address as "bad" and start the address loop over again.
705  * If any address fails, the entire message fails.
706  */
707  $this->socket_send_str('RCPT TO: <'.$_address.'>', '250');
708  }
709 
710  // Tell the server we are ready to start sending data
711  // with any custom headers...
712  // This is the last response code we look for until the end of the message.
713  $this->socket_send_str('DATA', '354');
714 
715  // Now we are ready for the message...
716  // Ok, all the ingredients are mixed in let's cook this puppy...
717  $this->socket_send_str($this->getHeader().$this->getBodyContent()."\r\n".'.', '250');
718 
719  // Now tell the server we are done and close the socket...
720  fputs($this->socket, 'QUIT');
721  } else {
722  // We got error code into $this->lastretval
723  }
724 
725  fclose($this->socket);
726  }
727 
728  return $_retVal;
729  }
730 
731  // =============================================================
732  // ** Setter & Getter methods
733 
734  // ** Basic System configuration
735 
761  public function setConfig($_strConfigPath = null)
762  {
767  $_retVal = true;
768 
769  // if we have a path...
770  if (!empty($_strConfigPath)) {
771  // If the path is not valid, this will NOT generate an error,
772  // it will simply return false.
773  if (!@include $_strConfigPath) {
774  $this->_setErr(110, '"'.$_strConfigPath.'" is not a valid path.');
775  $_retVal = false;
776  }
777  } else {
778  // Read the Systems php.ini file
779  // Set these properties ONLY if they are set in the php.ini file.
780  // Otherwise the default values will be used.
781  if ($_host = ini_get('SMTPs')) {
782  $this->setHost($_host);
783  }
784 
785  if ($_port = ini_get('smtp_port')) {
786  $this->setPort($_port);
787  }
788 
789  if ($_from = ini_get('sendmail_from')) {
790  $this->setFrom($_from);
791  }
792  }
793 
794  // Send back what we have
795  return $_retVal;
796  }
797 
807  public function setTransportType($_type = 0)
808  {
809  if ((is_numeric($_type)) && (($_type >= 0) && ($_type <= 3))) {
810  $this->_transportType = $_type;
811  }
812  }
813 
822  public function getTransportType()
823  {
824  return $this->_transportType;
825  }
826 
834  public function setMailPath($_path)
835  {
836  // This feature is not yet implemented
837  return true;
838 
839  //if ( $_path ) $this->_mailPath = $_path;
840  }
841 
850  public function setHost($_strHost)
851  {
852  if ($_strHost) {
853  $this->_smtpsHost = $_strHost;
854  }
855  }
856 
863  public function getHost()
864  {
865  return $this->_smtpsHost;
866  }
867 
876  public function setPort($_intPort)
877  {
878  if ((is_numeric($_intPort)) &&
879  (($_intPort >= 1) && ($_intPort <= 65536))) {
880  $this->_smtpsPort = $_intPort;
881  }
882  }
883 
890  public function getPort()
891  {
892  return $this->_smtpsPort;
893  }
894 
901  public function setID($_strID)
902  {
903  $this->_smtpsID = $_strID;
904  }
905 
911  public function getID()
912  {
913  return $this->_smtpsID;
914  }
915 
922  public function setPW($_strPW)
923  {
924  $this->_smtpsPW = $_strPW;
925  }
926 
932  public function getPW()
933  {
934  return $this->_smtpsPW;
935  }
936 
943  public function setToken($_strToken)
944  {
945  $this->_smtpsToken = $_strToken;
946  }
947 
953  public function getToken()
954  {
955  return $this->_smtpsToken;
956  }
957 
965  public function setCharSet($_strCharSet)
966  {
967  if ($_strCharSet) {
968  $this->_smtpsCharSet = $_strCharSet;
969  }
970  }
971 
977  public function getCharSet()
978  {
979  return $this->_smtpsCharSet;
980  }
981 
997  public function setTransEncode($_strTransEncode)
998  {
999  if (array_search($_strTransEncode, $this->_smtpsTransEncodeTypes)) {
1000  $this->_smtpsTransEncode = $_strTransEncode;
1001  }
1002  }
1003 
1009  public function getTransEncode()
1010  {
1011  return $this->_smtpsTransEncode;
1012  }
1013 
1030  public function setTransEncodeType($_strTransEncodeType)
1031  {
1032  if (array_search($_strTransEncodeType, $this->_smtpsTransEncodeTypes)) {
1033  $this->_smtpsTransEncodeType = $_strTransEncodeType;
1034  }
1035  }
1036 
1042  public function getTransEncodeType()
1043  {
1044  return $this->_smtpsTransEncodeTypes[$this->_smtpsTransEncodeType];
1045  }
1046 
1047 
1048  // ** Message Construction
1049 
1056  public function setFrom($_strFrom)
1057  {
1058  if ($_strFrom) {
1059  $this->_msgFrom = $this->_strip_email($_strFrom);
1060  }
1061  }
1062 
1069  public function getFrom($_part = true)
1070  {
1071  $_retValue = '';
1072 
1073  if ($_part === true) {
1074  $_retValue = $this->_msgFrom;
1075  } else {
1076  $_retValue = $this->_msgFrom[$_part];
1077  }
1078 
1079  return $_retValue;
1080  }
1081 
1088  public function setReplyTo($_strReplyTo)
1089  {
1090  if ($_strReplyTo) {
1091  $this->_msgReplyTo = $this->_strip_email($_strReplyTo);
1092  }
1093  }
1094 
1101  public function getReplyTo($_part = true)
1102  {
1103  $_retValue = '';
1104 
1105  if ($_part === true) {
1106  $_retValue = $this->_msgReplyTo;
1107  } else {
1108  $_retValue = $this->_msgReplyTo[$_part];
1109  }
1110 
1111  return $_retValue;
1112  }
1113 
1126  private function _buildAddrList($_type, $_addrList)
1127  {
1128  // Pull existing list
1129  $aryHost = $this->_msgRecipients;
1130 
1131  // Only run this if we have something
1132  if (!empty($_addrList)) {
1133  // $_addrList can be a STRING or an array
1134  if (is_string($_addrList)) {
1135  // This could be a COMMA delimited string
1136  if (strstr($_addrList, ',')) {
1137  // "explode "list" into an array
1138  $_addrList = explode(',', $_addrList);
1139  } else {
1140  // Stick it in an array
1141  $_addrList = array($_addrList);
1142  }
1143  }
1144 
1145  // take the array of addresses and split them further
1146  foreach ($_addrList as $_strAddr) {
1147  // Strip off the end '>'
1148  $_strAddr = str_replace('>', '', $_strAddr);
1149 
1150  // Seperate "Real Name" from eMail address
1151  $_tmpaddr = null;
1152  $_tmpaddr = explode('<', $_strAddr);
1153 
1154  // We have a "Real Name" and eMail address
1155  if (count($_tmpaddr) == 2) {
1156  $_tmpHost = explode('@', $_tmpaddr[1]);
1157  $_tmpaddr[0] = trim($_tmpaddr[0], ' ">');
1158  $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = $_tmpaddr[0];
1159  } else {
1160  // We only have an eMail address
1161  // Strip off the beggining '<'
1162  $_strAddr = str_replace('<', '', $_strAddr);
1163 
1164  $_tmpHost = explode('@', $_strAddr);
1165  $_tmpHost[0] = trim($_tmpHost[0]);
1166  $_tmpHost[1] = trim($_tmpHost[1]);
1167 
1168  $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = '';
1169  }
1170  }
1171  }
1172  // replace list
1173  $this->_msgRecipients = $aryHost;
1174  }
1175 
1176  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1193  private function _strip_email($_strAddr)
1194  {
1195  // phpcs:enable
1196  // Keep the orginal
1197  $_aryEmail['org'] = $_strAddr;
1198 
1199  // Set entire string to Lower Case
1200  $_strAddr = strtolower($_strAddr);
1201 
1202  // Drop "stuff' off the end
1203  $_strAddr = trim($_strAddr, ' ">');
1204 
1205  // Seperate "Real Name" from eMail address, if we have one
1206  $_tmpAry = explode('<', $_strAddr);
1207 
1208  // Do we have a "Real name"
1209  if (count($_tmpAry) == 2) {
1210  // We may not really have a "Real Name"
1211  if ($_tmpAry[0]) {
1212  $_aryEmail['real'] = trim($_tmpAry[0], ' ">');
1213  }
1214 
1215  $_aryEmail['addr'] = $_tmpAry[1];
1216  } else {
1217  $_aryEmail['addr'] = $_tmpAry[0];
1218  }
1219 
1220  // Pull User Name and Host.tld apart
1221  list($_aryEmail['user'], $_aryEmail['host']) = explode('@', $_aryEmail['addr']);
1222 
1223  // Put the brackets back around the address
1224  $_aryEmail['addr'] = '<'.$_aryEmail['addr'].'>';
1225 
1226  return $_aryEmail;
1227  }
1228 
1229  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1237  public function get_RCPT_list()
1238  {
1239  // phpcs:enable
1243  $_RCPT_list = array();
1244 
1245  // walk down Recipients array and pull just email addresses
1246  foreach ($this->_msgRecipients as $_host => $_list) {
1247  foreach ($_list as $_subList) {
1248  foreach ($_subList as $_name => $_addr) {
1249  // build RCPT list
1250  $_RCPT_list[] = $_name.'@'.$_host;
1251  }
1252  }
1253  }
1254 
1255  return $_RCPT_list;
1256  }
1257 
1258  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1265  public function get_email_list($_which = null)
1266  {
1267  // phpcs:enable
1268  // We need to know which address segment to pull
1269  if ($_which) {
1270  // Make sure we have addresses to process
1271  if ($this->_msgRecipients) {
1272  $_RCPT_list = array();
1273  // walk down Recipients array and pull just email addresses
1274  foreach ($this->_msgRecipients as $_host => $_list) {
1275  if (!empty($this->_msgRecipients[$_host][$_which])) {
1276  foreach ($this->_msgRecipients[$_host][$_which] as $_addr => $_realName) {
1277  if ($_realName) { // @CHANGE LDR
1278  $_realName = '"'.$_realName.'"';
1279  $_RCPT_list[] = $_realName.' <'.$_addr.'@'.$_host.'>';
1280  } else {
1281  $_RCPT_list[] = $_addr.'@'.$_host;
1282  }
1283  }
1284  }
1285  }
1286 
1287  return implode(', ', $_RCPT_list);
1288  } else {
1289  $this->_setErr(101, 'No eMail Address for message to be sent to.');
1290  return false;
1291  }
1292  } else {
1293  $this->_setErr(102, 'eMail type not defined.');
1294  return false;
1295  }
1296  }
1297 
1304  public function setTO($_addrTo)
1305  {
1306  if ($_addrTo) {
1307  $this->_buildAddrList('to', $_addrTo);
1308  }
1309  }
1310 
1316  public function getTo()
1317  {
1318  return $this->get_email_list('to');
1319  }
1320 
1327  public function setCC($_strCC)
1328  {
1329  if ($_strCC) {
1330  $this->_buildAddrList('cc', $_strCC);
1331  }
1332  }
1333 
1339  public function getCC()
1340  {
1341  return $this->get_email_list('cc');
1342  }
1343 
1350  public function setBCC($_strBCC)
1351  {
1352  if ($_strBCC) {
1353  $this->_buildAddrList('bcc', $_strBCC);
1354  }
1355  }
1356 
1362  public function getBCC()
1363  {
1364  return $this->get_email_list('bcc');
1365  }
1366 
1373  public function setSubject($_strSubject = '')
1374  {
1375  if ($_strSubject) {
1376  $this->_msgSubject = $_strSubject;
1377  }
1378  }
1379 
1385  public function getSubject()
1386  {
1387  return $this->_msgSubject;
1388  }
1389 
1395  public function getHeader()
1396  {
1397  global $conf;
1398 
1399  $_header = 'From: '.$this->getFrom('org')."\r\n"
1400  . 'To: '.$this->getTO()."\r\n";
1401 
1402  if ($this->getCC()) {
1403  $_header .= 'Cc: '.$this->getCC()."\r\n";
1404  }
1405 
1406  /* Note:
1407  * BCC email addresses must be listed in the RCPT TO command list,
1408  * but the BCC header should not be printed under the DATA command.
1409  * So it is included into the function sendMsg() but not here.
1410  * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
1411  */
1412  /*
1413  if ( $this->getBCC() )
1414  $_header .= 'Bcc: ' . $this->getBCC() . "\r\n";
1415  */
1416 
1417  $host = dol_getprefix('email');
1418 
1419  //NOTE: Message-ID should probably contain the username of the user who sent the msg
1420  $_header .= 'Subject: '.$this->getSubject()."\r\n";
1421  $_header .= 'Date: '.date("r")."\r\n";
1422 
1423  $trackid = $this->getTrackId();
1424  if ($trackid) {
1425  // References is kept in response and Message-ID is returned into In-Reply-To:
1426  $_header .= 'Message-ID: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n";
1427  $_header .= 'References: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n";
1428  $_header .= 'X-Dolibarr-TRACKID: '.$trackid.'@'.$host."\r\n";
1429  } else {
1430  $_header .= 'Message-ID: <'.time().'.SMTPs@'.$host.">\r\n";
1431  }
1432  if (!empty($_SERVER['REMOTE_ADDR'])) {
1433  $_header .= "X-RemoteAddr: ".$_SERVER['REMOTE_ADDR']."\r\n";
1434  }
1435  if ($this->getMoreInHeader()) {
1436  $_header .= $this->getMoreInHeader(); // Value must include the "\r\n";
1437  }
1438 
1439  //$_header .=
1440  // 'Read-Receipt-To: ' . $this->getFrom( 'org' ) . "\r\n"
1441  // 'Return-Receipt-To: ' . $this->getFrom( 'org' ) . "\r\n";
1442 
1443  if ($this->getSensitivity()) {
1444  $_header .= 'Sensitivity: '.$this->getSensitivity()."\r\n";
1445  }
1446 
1447  if ($this->_msgPriority != 3) {
1448  $_header .= $this->getPriority();
1449  }
1450 
1451 
1452  // @CHANGE LDR
1453  if ($this->getDeliveryReceipt()) {
1454  $_header .= 'Disposition-Notification-To: '.$this->getFrom('addr')."\r\n";
1455  }
1456  if ($this->getErrorsTo()) {
1457  $_header .= 'Errors-To: '.$this->getErrorsTo('addr')."\r\n";
1458  }
1459  if ($this->getReplyTo()) {
1460  $_header .= "Reply-To: ".$this->getReplyTo('addr')."\r\n";
1461  }
1462 
1463  $_header .= 'X-Mailer: Dolibarr version '.DOL_VERSION.' (using SMTPs Mailer)'."\r\n";
1464  $_header .= 'X-Dolibarr-Option: '.($conf->global->MAIN_MAIL_USE_MULTI_PART ? 'MAIN_MAIL_USE_MULTI_PART' : 'No MAIN_MAIL_USE_MULTI_PART')."\r\n";
1465  $_header .= 'Mime-Version: 1.0'."\r\n";
1466 
1467 
1468  return $_header;
1469  }
1470 
1478  public function setBodyContent($strContent, $strType = 'plain')
1479  {
1480  //if ( $strContent )
1481  //{
1482  if ($strType == 'html') {
1483  $strMimeType = 'text/html';
1484  } else {
1485  $strMimeType = 'text/plain';
1486  }
1487 
1488  // Make RFC821 Compliant, replace bare linefeeds
1489  $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent);
1490 
1491  $strContentAltText = '';
1492  if ($strType == 'html') {
1493  // Similar code to forge a text from html is also in CMailFile.class.php
1494  $strContentAltText = preg_replace('/<head><title>.*<\/style><\/head>/', '', $strContent);
1495  $strContentAltText = preg_replace("/<br\s*[^>]*>/", " ", $strContentAltText);
1496  $strContentAltText = html_entity_decode(strip_tags($strContentAltText));
1497  $strContentAltText = trim(wordwrap($strContentAltText, 75, "\r\n"));
1498  }
1499 
1500  // Make RFC2045 Compliant
1501  //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content
1502  $strContent = rtrim(wordwrap($strContent, 75, "\r\n")); // TODO Using this method creates unexpected line break on text/plain content.
1503 
1504  $this->_msgContent[$strType] = array();
1505 
1506  $this->_msgContent[$strType]['mimeType'] = $strMimeType;
1507  $this->_msgContent[$strType]['data'] = $strContent;
1508  $this->_msgContent[$strType]['dataText'] = $strContentAltText;
1509 
1510  if ($this->getMD5flag()) {
1511  $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3);
1512  }
1513  //}
1514  }
1515 
1521  public function getBodyContent()
1522  {
1523  global $conf;
1524 
1525  // Generate a new Boundary string
1526  $this->_setBoundary();
1527 
1528  // What type[s] of content do we have
1529  $_types = array_keys($this->_msgContent);
1530 
1531  // How many content types do we have
1532  $keyCount = count($_types);
1533 
1534  // If we have ZERO, we have a problem
1535  if ($keyCount === 0) {
1536  die("Sorry, no content");
1537  } elseif ($keyCount === 1 && empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1538  // If we have ONE, we can use the simple format
1539  $_msgData = $this->_msgContent;
1540  $_msgData = $_msgData[$_types[0]];
1541 
1542  $content = 'Content-Type: '.$_msgData['mimeType'].'; charset="'.$this->getCharSet().'"'."\r\n"
1543  . 'Content-Transfer-Encoding: '.$this->getTransEncodeType()."\r\n"
1544  . 'Content-Disposition: inline'."\r\n"
1545  . 'Content-Description: Message'."\r\n";
1546 
1547  if ($this->getMD5flag()) {
1548  $content .= 'Content-MD5: '.$_msgData['md5']."\r\n";
1549  }
1550 
1551  $content .= "\r\n"
1552  . $_msgData['data']."\r\n";
1553  } elseif ($keyCount >= 1 || !empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1554  // If we have more than ONE, we use the multi-part format
1555  // Since this is an actual multi-part message
1556  // We need to define a content message Boundary
1557  // NOTE: This was 'multipart/alternative', but Windows based mail servers have issues with this.
1558 
1559  //$content = 'Content-Type: multipart/related; boundary="' . $this->_getBoundary() . '"' . "\r\n";
1560  $content = 'Content-Type: multipart/mixed; boundary="'.$this->_getBoundary('mixed').'"'."\r\n";
1561 
1562  // . "\r\n"
1563  // . 'This is a multi-part message in MIME format.' . "\r\n";
1564  $content .= "Content-Transfer-Encoding: 8bit\r\n";
1565  $content .= "\r\n";
1566 
1567  $content .= "--".$this->_getBoundary('mixed')."\r\n";
1568 
1569  if (key_exists('image', $this->_msgContent)) { // If inline image found
1570  $content .= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"'."\r\n";
1571  $content .= "\r\n";
1572  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1573  }
1574 
1575 
1576  // $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment'
1577 
1578 
1579  // Loop through message content array
1580  foreach ($this->_msgContent as $type => $_content) {
1581  if ($type == 'attachment') {
1582  // loop through all attachments
1583  foreach ($_content as $_file => $_data) {
1584  $content .= "--".$this->_getBoundary('mixed')."\r\n"
1585  . 'Content-Disposition: attachment; filename="'.$_data['fileName'].'"'."\r\n"
1586  . 'Content-Type: '.$_data['mimeType'].'; name="'.$_data['fileName'].'"'."\r\n"
1587  . 'Content-Transfer-Encoding: base64'."\r\n"
1588  . 'Content-Description: '.$_data['fileName']."\r\n";
1589  if (!empty($_data['cid'])) {
1590  $content .= "X-Attachment-Id: ".$_data['cid']."\r\n";
1591  $content .= "Content-ID: <".$_data['cid'].">\r\n";
1592  }
1593  if ($this->getMD5flag()) {
1594  $content .= 'Content-MD5: '.$_data['md5']."\r\n";
1595  }
1596 
1597  $content .= "\r\n".$_data['data']."\r\n\r\n";
1598  }
1599  } elseif ($type == 'image') {
1600  // @CHANGE LDR
1601  // loop through all images
1602  foreach ($_content as $_image => $_data) {
1603  $content .= "--".$this->_getBoundary('related')."\r\n"; // always related for an inline image
1604 
1605  $content .= 'Content-Type: '.$_data['mimeType'].'; name="'.$_data['imageName'].'"'."\r\n"
1606  . 'Content-Transfer-Encoding: base64'."\r\n"
1607  . 'Content-Disposition: inline; filename="'.$_data['imageName'].'"'."\r\n"
1608  . 'Content-ID: <'.$_data['cid'].'> '."\r\n";
1609 
1610  if ($this->getMD5flag()) {
1611  $content .= 'Content-MD5: '.$_data['md5']."\r\n";
1612  }
1613 
1614  $content .= "\r\n"
1615  . $_data['data']."\r\n";
1616  }
1617 
1618  // always end related and end alternative after inline images
1619  $content .= "--".$this->_getBoundary('related')."--\r\n";
1620  $content .= "\r\n--".$this->_getBoundary('alternative')."--\r\n";
1621  $content .= "\r\n";
1622  } else {
1623  if (key_exists('image', $this->_msgContent)) {
1624  $content .= "Content-Type: text/plain; charset=".$this->getCharSet()."\r\n";
1625  $content .= "\r\n".($_content['dataText'] ? $_content['dataText'] : strip_tags($_content['data']))."\r\n"; // Add plain text message
1626  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1627  $content .= 'Content-Type: multipart/related; boundary="'.$this->_getBoundary('related').'"'."\r\n";
1628  $content .= "\r\n";
1629  $content .= "--".$this->_getBoundary('related')."\r\n";
1630  }
1631 
1632  if (!key_exists('image', $this->_msgContent) && $_content['dataText'] && !empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1633  // Add plain text message part before html part
1634  $content .= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"'."\r\n";
1635  $content .= "\r\n";
1636  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1637 
1638  $content .= "Content-Type: text/plain; charset=".$this->getCharSet()."\r\n";
1639  $content .= "\r\n".$_content['dataText']."\r\n";
1640  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1641  }
1642 
1643  $content .= 'Content-Type: '.$_content['mimeType'].'; charset='.$this->getCharSet();
1644 
1645  $content .= "\r\n";
1646 
1647  if ($this->getMD5flag()) {
1648  $content .= 'Content-MD5: '.$_content['md5']."\r\n";
1649  }
1650 
1651  $content .= "\r\n".$_content['data']."\r\n";
1652 
1653  if (!key_exists('image', $this->_msgContent) && $_content['dataText'] && !empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1654  // Add plain text message part after html part
1655  $content .= "--".$this->_getBoundary('alternative')."--\r\n";
1656  }
1657 
1658  $content .= "\r\n";
1659  }
1660  }
1661 
1662  $content .= "--".$this->_getBoundary('mixed').'--'."\r\n";
1663  }
1664 
1665  return $content;
1666  }
1667 
1678  public function setAttachment($strContent, $strFileName = 'unknown', $strMimeType = 'unknown', $strCid = '')
1679  {
1680  if ($strContent) {
1681  $strContent = rtrim(chunk_split(base64_encode($strContent), 76, "\r\n")); // 76 max is defined into http://tools.ietf.org/html/rfc2047
1682 
1683  $this->_msgContent['attachment'][$strFileName]['mimeType'] = $strMimeType;
1684  $this->_msgContent['attachment'][$strFileName]['fileName'] = $strFileName;
1685  $this->_msgContent['attachment'][$strFileName]['data'] = $strContent;
1686  $this->_msgContent['attachment'][$strFileName]['cid'] = $strCid; // If defined, it means this attachment must be shown inline
1687 
1688  if ($this->getMD5flag()) {
1689  $this->_msgContent['attachment'][$strFileName]['md5'] = dol_hash($strContent, 3);
1690  }
1691  }
1692  }
1693 
1694 
1695  // @CHANGE LDR
1696 
1707  public function setImageInline($strContent, $strImageName = 'unknown', $strMimeType = 'unknown', $strImageCid = 'unknown')
1708  {
1709  if ($strContent) {
1710  $this->_msgContent['image'][$strImageName]['mimeType'] = $strMimeType;
1711  $this->_msgContent['image'][$strImageName]['imageName'] = $strImageName;
1712  $this->_msgContent['image'][$strImageName]['cid'] = $strImageCid;
1713  $this->_msgContent['image'][$strImageName]['data'] = $strContent;
1714 
1715  if ($this->getMD5flag()) {
1716  $this->_msgContent['image'][$strImageName]['md5'] = dol_hash($strContent, 3);
1717  }
1718  }
1719  }
1720  // END @CHANGE LDR
1721 
1722 
1734  public function setSensitivity($_value = 0)
1735  {
1736  if ((is_numeric($_value)) &&
1737  (($_value >= 0) && ($_value <= 3))) {
1738  $this->_msgSensitivity = $_value;
1739  }
1740  }
1741 
1752  public function getSensitivity()
1753  {
1754  return $this->_arySensitivity[$this->_msgSensitivity];
1755  }
1756 
1770  public function setPriority($_value = 3)
1771  {
1772  if ((is_numeric($_value)) &&
1773  (($_value >= 0) && ($_value <= 5))) {
1774  $this->_msgPriority = $_value;
1775  }
1776  }
1777 
1790  public function getPriority()
1791  {
1792  return 'Importance: '.$this->_aryPriority[$this->_msgPriority]."\r\n"
1793  . 'Priority: '.$this->_aryPriority[$this->_msgPriority]."\r\n"
1794  . 'X-Priority: '.$this->_msgPriority.' ('.$this->_aryPriority[$this->_msgPriority].')'."\r\n";
1795  }
1796 
1803  public function setMD5flag($_flag = false)
1804  {
1805  $this->_smtpMD5 = $_flag;
1806  }
1807 
1813  public function getMD5flag()
1814  {
1815  return $this->_smtpMD5;
1816  }
1817 
1826  public function setXheader($strXdata)
1827  {
1828  if ($strXdata) {
1829  $this->_msgXheader[] = $strXdata;
1830  }
1831  }
1832 
1838  public function getXheader()
1839  {
1840  return $this->_msgXheader;
1841  }
1842 
1848  private function _setBoundary()
1849  {
1850  $this->_smtpsBoundary = "multipart_x.".time().".x_boundary";
1851  $this->_smtpsRelatedBoundary = 'mul_'.dol_hash(uniqid("dolibarr2"), 3);
1852  $this->_smtpsAlternativeBoundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3);
1853  }
1854 
1861  private function _getBoundary($type = 'mixed')
1862  {
1863  if ($type == 'mixed') {
1864  return $this->_smtpsBoundary;
1865  } elseif ($type == 'related') {
1867  } elseif ($type == 'alternative') {
1869  }
1870  }
1871 
1872  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1883  public function server_parse($socket, $response)
1884  {
1885  // phpcs:enable
1890  $_retVal = true;
1891 
1892  $server_response = '';
1893 
1894  // avoid infinite loop
1895  $limit = 0;
1896 
1897  while (substr($server_response, 3, 1) != ' ' && $limit < 100) {
1898  if (!($server_response = fgets($socket, 256))) {
1899  $this->_setErr(121, "Couldn't get mail server response codes");
1900  $_retVal = false;
1901  break;
1902  }
1903  $this->log .= $server_response;
1904  $limit++;
1905  }
1906 
1907  $this->lastretval = substr($server_response, 0, 3);
1908 
1909  if (!(substr($server_response, 0, 3) == $response)) {
1910  $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse: ".$server_response);
1911  $_retVal = false;
1912  }
1913 
1914  return $_retVal;
1915  }
1916 
1917  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1926  public function socket_send_str($_strSend, $_returnCode = null, $CRLF = "\r\n")
1927  {
1928  // phpcs:enable
1929  if ($this->_debug) {
1930  $this->log .= $_strSend; // @CHANGE LDR for log
1931  }
1932  fputs($this->socket, $_strSend.$CRLF);
1933  if ($this->_debug) {
1934  $this->log .= ' ('.$_returnCode.')'.$CRLF;
1935  }
1936 
1937  if ($_returnCode) {
1938  return $this->server_parse($this->socket, $_returnCode);
1939  }
1940 
1941  return null;
1942  }
1943 
1944  // =============================================================
1945  // ** Error handling methods
1946 
1954  private function _setErr($_errNum, $_errMsg)
1955  {
1956  $this->_smtpsErrors[] = array(
1957  'num' => $_errNum,
1958  'msg' => $_errMsg,
1959  );
1960  }
1961 
1967  public function getErrors()
1968  {
1969  $_errMsg = array();
1970 
1971  if (is_array($this->_smtpsErrors)) {
1972  foreach ($this->_smtpsErrors as $_err => $_info) {
1973  $_errMsg[] = 'Error ['.$_info['num'].']: '.$_info['msg'];
1974  }
1975  }
1976 
1977  return implode("\n", $_errMsg);
1978  }
1979 }
1980 
1981 
1982 // =============================================================
1983 // ** CSV Version Control Info
1984 
SMTPs\$_msgXheader
$_msgXheader
Custom X-Headers.
Definition: smtps.class.php:108
SMTPs\setTransEncode
setTransEncode($_strTransEncode)
Content-Transfer-Encoding, Defaulted to '7bit' This can be changed for 2byte characers sets Known Enc...
Definition: smtps.class.php:997
SMTPs\setReplyTo
setReplyTo($_strReplyTo)
Reply-To Address from which mail will be the reply-to.
Definition: smtps.class.php:1088
SMTPs\$_msgReplyTo
$_msgReplyTo
Where are replies and errors to be sent to This can be defined via a INI file or via a setter method.
Definition: smtps.class.php:86
SMTPs\getBodyContent
getBodyContent()
Retrieves the Message Content.
Definition: smtps.class.php:1521
SMTPs\getPort
getPort()
Retrieves the Port Number of the Mail Server to use This is used only with 'socket' based mail transm...
Definition: smtps.class.php:890
SMTPs\getSensitivity
getSensitivity()
Returns Message Content Sensitivity string Message Sensitivity values:
Definition: smtps.class.php:1752
SMTPs\setTrackId
setTrackId($_val='')
Set trackid.
Definition: smtps.class.php:280
SMTPs\_strip_email
_strip_email($_strAddr)
Returns an array of the various parts of an email address This assumes a well formed address:
Definition: smtps.class.php:1193
SMTPs\$_smtpsCharSet
$_smtpsCharSet
Character set Defaulted to 'iso-8859-1'.
Definition: smtps.class.php:114
SMTPs\getTo
getTo()
Retrieves the TO Address[es] inwhich to send mail to.
Definition: smtps.class.php:1316
SMTPs\setTransportType
setTransportType($_type=0)
Determines the method inwhich the messages are to be sent.
Definition: smtps.class.php:807
SMTPs\setToken
setToken($_strToken)
User token for OAUTH2.
Definition: smtps.class.php:943
SMTPs\getID
getID()
Retrieves the User Name for authentication on Mail Server.
Definition: smtps.class.php:911
SMTPs\get_RCPT_list
get_RCPT_list()
Returns an array of bares addresses for use with 'RCPT TO:' This is a "build as you go" method.
Definition: smtps.class.php:1237
SMTPs\setTO
setTO($_addrTo)
TO Address[es] inwhich to send mail to.
Definition: smtps.class.php:1304
SMTPs\$_msgSubject
$_msgSubject
Message Subject.
Definition: smtps.class.php:98
SMTPs\get_email_list
get_email_list($_which=null)
Returns an array of addresses for a specific type; TO, CC or BCC.
Definition: smtps.class.php:1265
SMTPs\$_smtpsPort
$_smtpsPort
SMTP Server Port definition.
Definition: smtps.class.php:57
SMTPs\getPW
getPW()
Retrieves the User Password for authentication on Mail Server.
Definition: smtps.class.php:932
SMTPs\_setErr
_setErr($_errNum, $_errMsg)
Defines errors codes and messages for Class.
Definition: smtps.class.php:1954
SMTPs\setMailPath
setMailPath($_path)
Path to the sendmail execuable.
Definition: smtps.class.php:834
SMTPs\getBCC
getBCC()
Retrieves the BCC Address[es] inwhich to send mail to.
Definition: smtps.class.php:1362
SMTPs
Class to construct and send SMTP compliant email, even to a secure SMTP server, regardless of platfor...
Definition: smtps.class.php:46
SMTPs\$_msgRecipients
$_msgRecipients
Who will the Message be sent to; TO, CC, BCC Multi-diminsional array containg addresses the message w...
Definition: smtps.class.php:93
SMTPs\setPW
setPW($_strPW)
User Password for authentication on Mail Server.
Definition: smtps.class.php:922
SMTPs\setHost
setHost($_strHost)
Defines the Host Name or IP of the Mail Server to use.
Definition: smtps.class.php:850
SMTPs\getCC
getCC()
Retrieves the CC Address[es] inwhich to send mail to.
Definition: smtps.class.php:1339
SMTPs\setPriority
setPriority($_value=3)
Message Content Priority Message Priority values:
Definition: smtps.class.php:1770
SMTPs\getErrors
getErrors()
Returns applicative errors codes and messages for Class (not the SMTP error code)
Definition: smtps.class.php:1967
SMTPs\setDebug
setDebug($_vDebug=false)
Set debug.
Definition: smtps.class.php:354
SMTPs\getTransEncodeType
getTransEncodeType()
Retrieves the Content-Transfer-Encoding.
Definition: smtps.class.php:1042
SMTPs\$_smtpsRelatedBoundary
$_smtpsRelatedBoundary
Related Boundary.
Definition: smtps.class.php:177
SMTPs\_setBoundary
_setBoundary()
Generates Random string for MIME message Boundary.
Definition: smtps.class.php:1848
SMTPs\getFrom
getFrom($_part=true)
Retrieves the Address from which mail will be sent.
Definition: smtps.class.php:1069
SMTPs\setImageInline
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...
Definition: smtps.class.php:1707
SMTPs\$_options
$_options
An array of options for stream_context_create()
Definition: smtps.class.php:240
SMTPs\_server_connect
_server_connect()
Attempt a connection to mail server.
Definition: smtps.class.php:376
SMTPs\setPort
setPort($_intPort)
Defines the Port Number of the Mail Server to use This is defaulted to '25' This is used only with 's...
Definition: smtps.class.php:876
SMTPs\$_aryPriority
$_aryPriority
Message Priority.
Definition: smtps.class.php:139
SMTPs\setBCC
setBCC($_strBCC)
BCC Address[es] inwhich to send mail to.
Definition: smtps.class.php:1350
SMTPs\setTransEncodeType
setTransEncodeType($_strTransEncodeType)
Content-Transfer-Encoding, Defaulted to '0' [ZERO] This can be changed for 2byte characers sets Known...
Definition: smtps.class.php:1030
SMTPs\socket_send_str
socket_send_str($_strSend, $_returnCode=null, $CRLF="\r\n")
Send str.
Definition: smtps.class.php:1926
dol_hash
dol_hash($chain, $type='0')
Returns a hash (non reversible encryption) of a string.
Definition: security.lib.php:215
SMTPs\$_debug
$_debug
Place Class in" debug" mode.
Definition: smtps.class.php:226
SMTPs\setSubject
setSubject($_strSubject='')
Message Subject.
Definition: smtps.class.php:1373
SMTPs\getSubject
getSubject()
Retrieves the Message Subject.
Definition: smtps.class.php:1385
SMTPs\setXheader
setXheader($strXdata)
Message X-Header Content This is a simple "insert".
Definition: smtps.class.php:1826
SMTPs\getDeliveryReceipt
getDeliveryReceipt()
get delivery receipt
Definition: smtps.class.php:269
SMTPs\getErrorsTo
getErrorsTo($_part=true)
Get errors to.
Definition: smtps.class.php:335
SMTPs\getReplyTo
getReplyTo($_part=true)
Retrieves the Address from which mail will be the reply-to.
Definition: smtps.class.php:1101
SMTPs\$_mailPath
$_mailPath
If '$_transportType' is set to '1', then this variable is used to define the UNIX file system path to...
Definition: smtps.class.php:197
SMTPs\getCharSet
getCharSet()
Retrieves the Character set used for current message.
Definition: smtps.class.php:977
SMTPs\sendMsg
sendMsg()
Now send the message.
Definition: smtps.class.php:629
SMTPs\setAttachment
setAttachment($strContent, $strFileName='unknown', $strMimeType='unknown', $strCid='')
File attachments are added to the content array as sub-arrays, allowing for multiple attachments for ...
Definition: smtps.class.php:1678
SMTPs\setMD5flag
setMD5flag($_flag=false)
Set flag which determines whether to calculate message MD5 checksum.
Definition: smtps.class.php:1803
SMTPs\getMoreInHeader
getMoreInHeader()
get moreInHeader
Definition: smtps.class.php:311
SMTPs\setDeliveryReceipt
setDeliveryReceipt($_val=0)
Set delivery receipt.
Definition: smtps.class.php:259
SMTPs\setCharSet
setCharSet($_strCharSet)
Character set used for current message Character set is defaulted to 'iso-8859-1';.
Definition: smtps.class.php:965
SMTPs\getXheader
getXheader()
Retrieves the Message X-Header Content.
Definition: smtps.class.php:1838
SMTPs\setConfig
setConfig($_strConfigPath=null)
setConfig() is used to populate select class properties from either a user defined INI file or the sy...
Definition: smtps.class.php:761
SMTPs\$_msgPriority
$_msgPriority
Message Sensitivity Defaults to 3 - Normal.
Definition: smtps.class.php:134
SMTPs\$_smtpsAlternativeBoundary
$_smtpsAlternativeBoundary
Alternative Boundary.
Definition: smtps.class.php:182
SMTPs\$_msgFrom
$_msgFrom
Who sent the Message This can be defined via a INI file or via a setter method.
Definition: smtps.class.php:80
SMTPs\setID
setID($_strID)
User Name for authentication on Mail Server.
Definition: smtps.class.php:901
SMTPs\$_arySensitivity
$_arySensitivity
Message Sensitivity.
Definition: smtps.class.php:125
SMTPs\setErrorsTo
setErrorsTo($_strErrorsTo)
Set errors to.
Definition: smtps.class.php:322
SMTPs\setMoreInHeader
setMoreInHeader($_val='')
Set moreInHeader.
Definition: smtps.class.php:291
SMTPs\$_smtpsToken
$_smtpsToken
Token in case we use OAUTH2.
Definition: smtps.class.php:74
SMTPs\_buildAddrList
_buildAddrList($_type, $_addrList)
Inserts given addresses into structured format.
Definition: smtps.class.php:1126
SMTPs\buildRCPTlist
buildRCPTlist()
build RECIPIENT List, all addresses who will recieve this message
Definition: smtps.class.php:364
SMTPs\setBodyContent
setBodyContent($strContent, $strType='plain')
Message Content.
Definition: smtps.class.php:1478
SMTPs\$_smtpsHost
$_smtpsHost
Host Name or IP of SMTP Server to use.
Definition: smtps.class.php:51
SMTPs\getMD5flag
getMD5flag()
Gets flag which determines whether to calculate message MD5 checksum.
Definition: smtps.class.php:1813
SMTPs\$_smtpsPW
$_smtpsPW
Secure SMTP Server access Password This can be defined via a INI file or via a setter method.
Definition: smtps.class.php:69
SMTPs\setOptions
setOptions($_options=array())
Set delivery receipt.
Definition: smtps.class.php:248
SMTPs\_server_authenticate
_server_authenticate()
Attempt mail server authentication for a secure connection.
Definition: smtps.class.php:454
SMTPs\getTransEncode
getTransEncode()
Retrieves the Content-Transfer-Encoding.
Definition: smtps.class.php:1009
SMTPs\$_smtpTimeout
$_smtpTimeout
Sets the SMTP server timeout in seconds.
Definition: smtps.class.php:202
SMTPs\$_smtpsTransEncodeTypes
$_smtpsTransEncodeTypes
Content-Transfer-Encoding.
Definition: smtps.class.php:155
SMTPs\getPriority
getPriority()
Message Content Priority Message Priority values:
Definition: smtps.class.php:1790
SMTPs\server_parse
server_parse($socket, $response)
This function has been modified as provided by SirSir to allow multiline responses when using SMTP Ex...
Definition: smtps.class.php:1883
SMTPs\$_smtpsTransEncodeType
$_smtpsTransEncodeType
Content-Transfer-Encoding Defaulted to 0 - 7bit.
Definition: smtps.class.php:150
SMTPs\$_msgSensitivity
$_msgSensitivity
Message Sensitivity Defaults to ZERO - None.
Definition: smtps.class.php:120
SMTPs\getToken
getToken()
Retrieves the User token for OAUTH2.
Definition: smtps.class.php:953
SMTPs\setFrom
setFrom($_strFrom)
FROM Address from which mail will be sent.
Definition: smtps.class.php:1056
SMTPs\getTrackId
getTrackId()
get trackid
Definition: smtps.class.php:301
SMTPs\$_smtpsErrors
$_smtpsErrors
Class error codes and messages.
Definition: smtps.class.php:212
SMTPs\$_log_level
$_log_level
Defines log level 0 - no logging 1 - connectivity logging 2 - message generation logging 3 - detail l...
Definition: smtps.class.php:221
SMTPs\$_smtpsID
$_smtpsID
Secure SMTP Server access ID This can be defined via a INI file or via a setter method.
Definition: smtps.class.php:63
SMTPs\$_transportType
$_transportType
Determines the method inwhich the message are to be sent.
Definition: smtps.class.php:191
SMTPs\setCC
setCC($_strCC)
CC Address[es] inwhich to send mail to.
Definition: smtps.class.php:1327
is_ip
is_ip($ip)
This function evaluates a string that should be a valid IPv4 Note: For ip 169.254....
Definition: functions2.lib.php:2018
SMTPs\getHeader
getHeader()
Constructes and returns message header.
Definition: smtps.class.php:1395
SMTPs\getTransportType
getTransportType()
Return the method inwhich the message is to be sent.
Definition: smtps.class.php:822
SMTPs\setSensitivity
setSensitivity($_value=0)
Message Content Sensitivity Message Sensitivity values:
Definition: smtps.class.php:1734
SMTPs\$_msgContent
$_msgContent
Message Content.
Definition: smtps.class.php:103
SMTPs\$_smtpMD5
$_smtpMD5
Determines whether to calculate message MD5 checksum.
Definition: smtps.class.php:207
SMTPs\$_smtpsTransEncode
$_smtpsTransEncode
Content-Transfer-Encoding Defaulted to '7bit'.
Definition: smtps.class.php:167
SMTPs\getHost
getHost()
Retrieves the Host Name or IP of the Mail Server to use This is used only with 'socket' based mail tr...
Definition: smtps.class.php:863
SMTPs\_getBoundary
_getBoundary($type='mixed')
Retrieves the MIME message Boundary.
Definition: smtps.class.php:1861
SMTPs\$_smtpsBoundary
$_smtpsBoundary
Boundary String for MIME seperation.
Definition: smtps.class.php:172