dolibarr  x.y.z
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  private $_errorsTo = '';
232  private $_deliveryReceipt = 0;
233  private $_trackId = '';
234  private $_moreInHeader = '';
235 
239  private $_options = array();
240 
247  public function setOptions($_options = array())
248  {
249  $this->_options = $_options;
250  }
251 
258  public function setDeliveryReceipt($_val = 0)
259  {
260  $this->_deliveryReceipt = $_val;
261  }
262 
268  public function getDeliveryReceipt()
269  {
270  return $this->_deliveryReceipt;
271  }
272 
279  public function setTrackId($_val = '')
280  {
281  $this->_trackId = $_val;
282  }
283 
290  public function setMoreInHeader($_val = '')
291  {
292  $this->_moreinheader = $_val;
293  }
294 
300  public function getTrackId()
301  {
302  return $this->_trackId;
303  }
304 
310  public function getMoreInHeader()
311  {
312  return $this->_moreinheader;
313  }
314 
321  public function setErrorsTo($_strErrorsTo)
322  {
323  if ($_strErrorsTo) {
324  $this->_errorsTo = $this->_strip_email($_strErrorsTo);
325  }
326  }
327 
334  public function getErrorsTo($_part = true)
335  {
336  $_retValue = '';
337 
338  if ($_part === true) {
339  $_retValue = $this->_errorsTo;
340  } else {
341  $_retValue = $this->_errorsTo[$_part];
342  }
343 
344  return $_retValue;
345  }
346 
353  public function setDebug($_vDebug = false)
354  {
355  $this->_debug = $_vDebug;
356  }
357 
363  public function buildRCPTlist()
364  {
365  // Pull TO list
366  $_aryToList = $this->getTO();
367  }
368 
369  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
375  private function _server_connect()
376  {
377  // phpcs:enable
378  // Default return value
379  $_retVal = true;
380 
381  // We have to make sure the HOST given is valid
382  // This is done here because '@fsockopen' will not give me this
383  // information if it failes to connect because it can't find the HOST
384  $host = $this->getHost();
385  $usetls = preg_match('@tls://@i', $host);
386 
387  $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
388  $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
389  $host = preg_replace('@tls://@i', '', $host); // Remove prefix
390 
391  // @CHANGE LDR
392  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
393 
394  if ((!is_ip($host)) && ((gethostbyname($host)) == $host)) {
395  $this->_setErr(99, $host.' is either offline or is an invalid host name.');
396  $_retVal = false;
397  } else {
398  if (function_exists('stream_socket_client') && !empty($this->_options)) {
399  $socket_context = stream_context_create($this->_options); // An array of options for stream_context_create()
400  $this->socket = @stream_socket_client(
401  preg_replace('@tls://@i', '', $this->getHost()).// Host to 'hit', IP or domain
402  ':'.$this->getPort(), // which Port number to use
403  $this->errno, // actual system level error
404  $this->errstr, // and any text that goes with the error
405  $this->_smtpTimeout, // timeout for reading/writing data over the socket
406  STREAM_CLIENT_CONNECT,
407  $socket_context // Options for connection
408  );
409  } else {
410  $this->socket = @fsockopen(
411  preg_replace('@tls://@i', '', $this->getHost()), // Host to 'hit', IP or domain
412  $this->getPort(), // which Port number to use
413  $this->errno, // actual system level error
414  $this->errstr, // and any text that goes with the error
415  $this->_smtpTimeout // timeout for reading/writing data over the socket
416  );
417  }
418 
419  //See if we can connect to the SMTP server
420  if (is_resource($this->socket)) {
421  // Fix from PHP SMTP class by 'Chris Ryan'
422  // Sometimes the SMTP server takes a little longer to respond
423  // so we will give it a longer timeout for the first read
424  // Windows still does not have support for this timeout function
425  if (function_exists('stream_set_timeout')) {
426  stream_set_timeout($this->socket, $this->_smtpTimeout, 0);
427  }
428 
429  // Check response from Server
430  if ($_retVal = $this->server_parse($this->socket, "220")) {
431  $_retVal = $this->socket;
432  }
433  } else {
434  // This connection attempt failed.
435  // @CHANGE LDR
436  if (empty($this->errstr)) {
437  $this->errstr = 'Failed to connect with fsockopen host='.$this->getHost().' port='.$this->getPort();
438  }
439  $this->_setErr($this->errno, $this->errstr);
440  $_retVal = false;
441  }
442  }
443 
444  return $_retVal;
445  }
446 
447  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
453  private function _server_authenticate()
454  {
455  // phpcs:enable
456  global $conf;
457 
458  // Send the RFC2554 specified EHLO.
459  // This improvment as provided by 'SirSir' to
460  // accomodate both SMTP AND ESMTP capable servers
461  $host = $this->getHost();
462  $usetls = preg_match('@tls://@i', $host);
463 
464  $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
465  $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
466  $host = preg_replace('@tls://@i', '', $host); // Remove prefix
467 
468  if ($usetls && !empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) {
469  $host = 'tls://'.$host;
470  }
471 
472  $hosth = $host; // so for example 'localhost' or 'smtp-relay.gmail.com'
473 
474  if (!empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
475  if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
476  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name
477  $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO;
478  } else {
479  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from.
480  // So if the from to is 'aaa <bbb@ccc.com>', we will keep 'ccc.com'
481  $hosth = $this->getFrom('addr');
482  $hosth = preg_replace('/^.*</', '', $hosth);
483  $hosth = preg_replace('/>.*$/', '', $hosth);
484  $hosth = preg_replace('/.*@/', '', $hosth);
485  }
486  }
487 
488  if ($_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) {
489  if ($usetls) {
490  /*
491  The following dialog illustrates how a client and server can start a TLS STARTTLS session:
492  S: <waits for connection on TCP port 25>
493  C: <opens connection>
494  S: 220 mail.imc.org SMTP service ready
495  C: EHLO mail.ietf.org
496  S: 250-mail.imc.org offers a warm hug of welcome
497  S: 250 STARTTLS
498  C: STARTTLS
499  S: 220 Go ahead
500  C: <starts TLS negotiation>
501  C & S: <negotiate a TLS session>
502  C & S: <check result of negotiation>
503  // Second pass EHLO
504  C: EHLO client-domain.com
505  S: 250-server-domain.com
506  S: 250 AUTH LOGIN
507  C: <continues by sending an SMTP command
508 
509  Another example here:
510  S: 220 smtp.server.com Simple Mail Transfer Service Ready
511  C: EHLO client.example.com
512  S: 250-smtp.server.com Hello client.example.com
513  S: 250-SIZE 1000000
514  S: 250-AUTH LOGIN PLAIN CRAM-MD5
515  S: 250-STARTTLS
516  S: 250 HELP
517  C: STARTTLS
518  S: 220 TLS go ahead
519  C: EHLO client.example.com *
520  S: 250-smtp.server.com Hello client.example.com
521  S: 250-SIZE 1000000
522  S: 250-AUTH LOGIN PLAIN CRAM-MD5
523  S: 250 HELP
524  C: AUTH LOGIN
525  S: 334 VXNlcm5hbWU6
526  C: adlxdkej
527  S: 334 UGFzc3dvcmQ6
528  C: lkujsefxlj
529  S: 235 2.7.0 Authentication successful
530  C: MAIL FROM:<mail@samlogic.com>
531  S: 250 OK
532  C: RCPT TO:<john@mail.com>
533  S: 250 OK
534  C: DATA
535  S: 354 Send message, end with a "." on a line by itself
536  C: <The message data (body text, subject, e-mail header, attachments etc) is sent>
537  S .
538  S: 250 OK, message accepted for delivery: queued as 12345
539  C: QUIT
540  S: 221 Bye
541  */
542  if (!$_retVal = $this->socket_send_str('STARTTLS', 220)) {
543  $this->_setErr(131, 'STARTTLS connection is not supported.');
544  return $_retVal;
545  }
546 
547  // Before 5.6.7:
548  // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_SSLv2_CLIENT|STREAM_CRYPTO_METHOD_SSLv3_CLIENT
549  // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
550  // PHP >= 5.6.7:
551  // STREAM_CRYPTO_METHOD_SSLv23_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT|STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
552  // STREAM_CRYPTO_METHOD_TLS_CLIENT = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
553 
554  $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
555  if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
556  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
557  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
558  }
559 
560  if (!stream_socket_enable_crypto($this->socket, true, $crypto_method)) {
561  $this->_setErr(132, 'STARTTLS connection failed.');
562  return $_retVal;
563  }
564  // Most servers expect a 2nd pass of EHLO after TLS is established to get another time
565  // the answer with list of supported AUTH methods. They may differs between non STARTTLS and with STARTTLS.
566  if (! $_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) {
567  $this->_setErr(126, '"'.$hosth.'" does not support authenticated connections. Error after sending EHLO '.$hosth);
568  return $_retVal;
569  }
570  }
571 
572  // Default authentication method is LOGIN
573  if (empty($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE)) {
574  $conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE = 'LOGIN';
575  }
576 
577  // Send Authentication to Server
578  // Check for errors along the way
579  switch ($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE) {
580  case 'NONE':
581  // 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.
582  $_retVal = true;
583  break;
584  case 'PLAIN':
585  $this->socket_send_str('AUTH PLAIN', '334');
586  // The error here just means the ID/password combo doesn't work.
587  $_retVal = $this->socket_send_str(base64_encode("\0".$this->_smtpsID."\0".$this->_smtpsPW), '235');
588  break;
589  case 'XOAUTH2':
590  // "user=$email\1auth=Bearer $token\1\1"
591  $user = $this->_smtpsID;
592  $token = $this->_smtpsToken;
593  $initRes = "user=".$user."\001auth=Bearer ".$token."\001\001";
594  $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($initRes), '235');
595  if (!$_retVal) {
596  $this->_setErr(130, 'Error when asking for AUTH XOAUTH2');
597  }
598  break;
599  case 'LOGIN': // most common case
600  default:
601  $_retVal = $this->socket_send_str('AUTH LOGIN', '334');
602  if (!$_retVal) {
603  $this->_setErr(130, 'Error when asking for AUTH LOGIN');
604  } else {
605  // User name will not return any error, server will take anything we give it.
606  $this->socket_send_str(base64_encode($this->_smtpsID), '334');
607  // The error here just means the ID/password combo doesn't work.
608  // There is no method to determine which is the problem, ID or password
609  $_retVal = $this->socket_send_str(base64_encode($this->_smtpsPW), '235');
610  }
611  break;
612  }
613  if (!$_retVal) {
614  $this->_setErr(130, 'Invalid Authentication Credentials.');
615  }
616  } else {
617  $this->_setErr(126, '"'.$host.'" does not support authenticated connections. Error after sending EHLO '.$hosth);
618  }
619 
620  return $_retVal;
621  }
622 
628  public function sendMsg()
629  {
630  global $conf;
631 
635  $_retVal = false;
636 
637  // Connect to Server
638  if ($this->socket = $this->_server_connect()) {
639  // If a User ID *and* a password is given, assume Authentication is desired
640  if (!empty($this->_smtpsID) && (!empty($this->_smtpsPW) || !empty($this->_smtpsToken))) {
641  // Send the RFC2554 specified EHLO.
642  $_retVal = $this->_server_authenticate();
643  } else {
644  // This is a "normal" SMTP Server "handshack"
645  // Send the RFC821 specified HELO.
646  $host = $this->getHost();
647  $usetls = preg_match('@tls://@i', $host);
648 
649  $host = preg_replace('@tcp://@i', '', $host); // Remove prefix
650  $host = preg_replace('@ssl://@i', '', $host); // Remove prefix
651  $host = preg_replace('@tls://@i', '', $host); // Remove prefix
652 
653  if ($usetls && !empty($conf->global->MAIN_SMTPS_ADD_TLS_TO_HOST_FOR_HELO)) {
654  $host = 'tls://'.$host;
655  }
656 
657  $hosth = $host;
658 
659  if (!empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
660  if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) {
661  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name
662  $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO;
663  } else {
664  // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from.
665  // If the from to is 'aaa <bbb@ccc.com>', we will keep 'ccc.com'
666  $hosth = $this->getFrom('addr');
667  $hosth = preg_replace('/^.*</', '', $hosth);
668  $hosth = preg_replace('/>.*$/', '', $hosth);
669  $hosth = preg_replace('/.*@/', '', $hosth);
670  }
671  }
672 
673  $_retVal = $this->socket_send_str('HELO '.$hosth, '250');
674  }
675 
676  // Well, did we get to the server?
677  if ($_retVal) {
678  // From this point onward most server response codes should be 250
679  // Specify who the mail is from....
680  // This has to be the raw email address, strip the "name" off
681  $resultmailfrom = $this->socket_send_str('MAIL FROM: '.$this->getFrom('addr'), '250');
682  if (!$resultmailfrom) {
683  fclose($this->socket);
684  return false;
685  }
686 
687  // 'RCPT TO:' must be given a single address, so this has to loop
688  // through the list of addresses, regardless of TO, CC or BCC
689  // and send it out "single file"
690  foreach ($this->get_RCPT_list() as $_address) {
691  /* Note:
692  * BCC email addresses must be listed in the RCPT TO command list,
693  * but the BCC header should not be printed under the DATA command.
694  * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
695  */
696 
697  /*
698  * TODO
699  * After each 'RCPT TO:' is sent, we need to make sure it was kosher,
700  * if not, the whole message will fail
701  * If any email address fails, we will need to RESET the connection,
702  * mark the last address as "bad" and start the address loop over again.
703  * If any address fails, the entire message fails.
704  */
705  $this->socket_send_str('RCPT TO: <'.$_address.'>', '250');
706  }
707 
708  // Tell the server we are ready to start sending data
709  // with any custom headers...
710  // This is the last response code we look for until the end of the message.
711  $this->socket_send_str('DATA', '354');
712 
713  // Now we are ready for the message...
714  // Ok, all the ingredients are mixed in let's cook this puppy...
715  $this->socket_send_str($this->getHeader().$this->getBodyContent()."\r\n".'.', '250');
716 
717  // Now tell the server we are done and close the socket...
718  fputs($this->socket, 'QUIT');
719  fclose($this->socket);
720  }
721  }
722 
723  return $_retVal;
724  }
725 
726  // =============================================================
727  // ** Setter & Getter methods
728 
729  // ** Basic System configuration
730 
756  public function setConfig($_strConfigPath = null)
757  {
762  $_retVal = true;
763 
764  // if we have a path...
765  if (!empty($_strConfigPath)) {
766  // If the path is not valid, this will NOT generate an error,
767  // it will simply return false.
768  if (!@include $_strConfigPath) {
769  $this->_setErr(110, '"'.$_strConfigPath.'" is not a valid path.');
770  $_retVal = false;
771  }
772  } else {
773  // Read the Systems php.ini file
774  // Set these properties ONLY if they are set in the php.ini file.
775  // Otherwise the default values will be used.
776  if ($_host = ini_get('SMTPs')) {
777  $this->setHost($_host);
778  }
779 
780  if ($_port = ini_get('smtp_port')) {
781  $this->setPort($_port);
782  }
783 
784  if ($_from = ini_get('sendmail_from')) {
785  $this->setFrom($_from);
786  }
787  }
788 
789  // Send back what we have
790  return $_retVal;
791  }
792 
802  public function setTransportType($_type = 0)
803  {
804  if ((is_numeric($_type)) && (($_type >= 0) && ($_type <= 3))) {
805  $this->_transportType = $_type;
806  }
807  }
808 
817  public function getTransportType()
818  {
819  return $this->_transportType;
820  }
821 
829  public function setMailPath($_path)
830  {
831  // This feature is not yet implemented
832  return true;
833 
834  //if ( $_path ) $this->_mailPath = $_path;
835  }
836 
845  public function setHost($_strHost)
846  {
847  if ($_strHost) {
848  $this->_smtpsHost = $_strHost;
849  }
850  }
851 
858  public function getHost()
859  {
860  return $this->_smtpsHost;
861  }
862 
871  public function setPort($_intPort)
872  {
873  if ((is_numeric($_intPort)) &&
874  (($_intPort >= 1) && ($_intPort <= 65536))) {
875  $this->_smtpsPort = $_intPort;
876  }
877  }
878 
885  public function getPort()
886  {
887  return $this->_smtpsPort;
888  }
889 
896  public function setID($_strID)
897  {
898  $this->_smtpsID = $_strID;
899  }
900 
906  public function getID()
907  {
908  return $this->_smtpsID;
909  }
910 
917  public function setPW($_strPW)
918  {
919  $this->_smtpsPW = $_strPW;
920  }
921 
927  public function getPW()
928  {
929  return $this->_smtpsPW;
930  }
931 
938  public function setToken($_strToken)
939  {
940  $this->_smtpsToken = $_strToken;
941  }
942 
948  public function getToken()
949  {
950  return $this->_smtpsToken;
951  }
952 
960  public function setCharSet($_strCharSet)
961  {
962  if ($_strCharSet) {
963  $this->_smtpsCharSet = $_strCharSet;
964  }
965  }
966 
972  public function getCharSet()
973  {
974  return $this->_smtpsCharSet;
975  }
976 
992  public function setTransEncode($_strTransEncode)
993  {
994  if (array_search($_strTransEncode, $this->_smtpsTransEncodeTypes)) {
995  $this->_smtpsTransEncode = $_strTransEncode;
996  }
997  }
998 
1004  public function getTransEncode()
1005  {
1006  return $this->_smtpsTransEncode;
1007  }
1008 
1025  public function setTransEncodeType($_strTransEncodeType)
1026  {
1027  if (array_search($_strTransEncodeType, $this->_smtpsTransEncodeTypes)) {
1028  $this->_smtpsTransEncodeType = $_strTransEncodeType;
1029  }
1030  }
1031 
1037  public function getTransEncodeType()
1038  {
1039  return $this->_smtpsTransEncodeTypes[$this->_smtpsTransEncodeType];
1040  }
1041 
1042 
1043  // ** Message Construction
1044 
1051  public function setFrom($_strFrom)
1052  {
1053  if ($_strFrom) {
1054  $this->_msgFrom = $this->_strip_email($_strFrom);
1055  }
1056  }
1057 
1064  public function getFrom($_part = true)
1065  {
1066  $_retValue = '';
1067 
1068  if ($_part === true) {
1069  $_retValue = $this->_msgFrom;
1070  } else {
1071  $_retValue = $this->_msgFrom[$_part];
1072  }
1073 
1074  return $_retValue;
1075  }
1076 
1083  public function setReplyTo($_strReplyTo)
1084  {
1085  if ($_strReplyTo) {
1086  $this->_msgReplyTo = $this->_strip_email($_strReplyTo);
1087  }
1088  }
1089 
1096  public function getReplyTo($_part = true)
1097  {
1098  $_retValue = '';
1099 
1100  if ($_part === true) {
1101  $_retValue = $this->_msgReplyTo;
1102  } else {
1103  $_retValue = $this->_msgReplyTo[$_part];
1104  }
1105 
1106  return $_retValue;
1107  }
1108 
1121  private function _buildAddrList($_type, $_addrList)
1122  {
1123  // Pull existing list
1124  $aryHost = $this->_msgRecipients;
1125 
1126  // Only run this if we have something
1127  if (!empty($_addrList)) {
1128  // $_addrList can be a STRING or an array
1129  if (is_string($_addrList)) {
1130  // This could be a COMMA delimited string
1131  if (strstr($_addrList, ',')) {
1132  // "explode "list" into an array
1133  $_addrList = explode(',', $_addrList);
1134  } else {
1135  // Stick it in an array
1136  $_addrList = array($_addrList);
1137  }
1138  }
1139 
1140  // take the array of addresses and split them further
1141  foreach ($_addrList as $_strAddr) {
1142  // Strip off the end '>'
1143  $_strAddr = str_replace('>', '', $_strAddr);
1144 
1145  // Seperate "Real Name" from eMail address
1146  $_tmpaddr = null;
1147  $_tmpaddr = explode('<', $_strAddr);
1148 
1149  // We have a "Real Name" and eMail address
1150  if (count($_tmpaddr) == 2) {
1151  $_tmpHost = explode('@', $_tmpaddr[1]);
1152  $_tmpaddr[0] = trim($_tmpaddr[0], ' ">');
1153  $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = $_tmpaddr[0];
1154  } else {
1155  // We only have an eMail address
1156  // Strip off the beggining '<'
1157  $_strAddr = str_replace('<', '', $_strAddr);
1158 
1159  $_tmpHost = explode('@', $_strAddr);
1160  $_tmpHost[0] = trim($_tmpHost[0]);
1161  $_tmpHost[1] = trim($_tmpHost[1]);
1162 
1163  $aryHost[$_tmpHost[1]][$_type][$_tmpHost[0]] = '';
1164  }
1165  }
1166  }
1167  // replace list
1168  $this->_msgRecipients = $aryHost;
1169  }
1170 
1171  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1188  private function _strip_email($_strAddr)
1189  {
1190  // phpcs:enable
1191  // Keep the orginal
1192  $_aryEmail['org'] = $_strAddr;
1193 
1194  // Set entire string to Lower Case
1195  $_strAddr = strtolower($_strAddr);
1196 
1197  // Drop "stuff' off the end
1198  $_strAddr = trim($_strAddr, ' ">');
1199 
1200  // Seperate "Real Name" from eMail address, if we have one
1201  $_tmpAry = explode('<', $_strAddr);
1202 
1203  // Do we have a "Real name"
1204  if (count($_tmpAry) == 2) {
1205  // We may not really have a "Real Name"
1206  if ($_tmpAry[0]) {
1207  $_aryEmail['real'] = trim($_tmpAry[0], ' ">');
1208  }
1209 
1210  $_aryEmail['addr'] = $_tmpAry[1];
1211  } else {
1212  $_aryEmail['addr'] = $_tmpAry[0];
1213  }
1214 
1215  // Pull User Name and Host.tld apart
1216  list($_aryEmail['user'], $_aryEmail['host']) = explode('@', $_aryEmail['addr']);
1217 
1218  // Put the brackets back around the address
1219  $_aryEmail['addr'] = '<'.$_aryEmail['addr'].'>';
1220 
1221  return $_aryEmail;
1222  }
1223 
1224  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1232  public function get_RCPT_list()
1233  {
1234  // phpcs:enable
1238  $_RCPT_list = array();
1239 
1240  // walk down Recipients array and pull just email addresses
1241  foreach ($this->_msgRecipients as $_host => $_list) {
1242  foreach ($_list as $_subList) {
1243  foreach ($_subList as $_name => $_addr) {
1244  // build RCPT list
1245  $_RCPT_list[] = $_name.'@'.$_host;
1246  }
1247  }
1248  }
1249 
1250  return $_RCPT_list;
1251  }
1252 
1253  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1260  public function get_email_list($_which = null)
1261  {
1262  // phpcs:enable
1263  // We need to know which address segment to pull
1264  if ($_which) {
1265  // Make sure we have addresses to process
1266  if ($this->_msgRecipients) {
1267  $_RCPT_list = array();
1268  // walk down Recipients array and pull just email addresses
1269  foreach ($this->_msgRecipients as $_host => $_list) {
1270  if ($this->_msgRecipients[$_host][$_which]) {
1271  foreach ($this->_msgRecipients[$_host][$_which] as $_addr => $_realName) {
1272  if ($_realName) { // @CHANGE LDR
1273  $_realName = '"'.$_realName.'"';
1274  $_RCPT_list[] = $_realName.' <'.$_addr.'@'.$_host.'>';
1275  } else {
1276  $_RCPT_list[] = $_addr.'@'.$_host;
1277  }
1278  }
1279  }
1280  }
1281 
1282  return implode(', ', $_RCPT_list);
1283  } else {
1284  $this->_setErr(101, 'No eMail Address for message to be sent to.');
1285  return false;
1286  }
1287  } else {
1288  $this->_setErr(102, 'eMail type not defined.');
1289  return false;
1290  }
1291  }
1292 
1299  public function setTO($_addrTo)
1300  {
1301  if ($_addrTo) {
1302  $this->_buildAddrList('to', $_addrTo);
1303  }
1304  }
1305 
1311  public function getTo()
1312  {
1313  return $this->get_email_list('to');
1314  }
1315 
1322  public function setCC($_strCC)
1323  {
1324  if ($_strCC) {
1325  $this->_buildAddrList('cc', $_strCC);
1326  }
1327  }
1328 
1334  public function getCC()
1335  {
1336  return $this->get_email_list('cc');
1337  }
1338 
1345  public function setBCC($_strBCC)
1346  {
1347  if ($_strBCC) {
1348  $this->_buildAddrList('bcc', $_strBCC);
1349  }
1350  }
1351 
1357  public function getBCC()
1358  {
1359  return $this->get_email_list('bcc');
1360  }
1361 
1368  public function setSubject($_strSubject = '')
1369  {
1370  if ($_strSubject) {
1371  $this->_msgSubject = $_strSubject;
1372  }
1373  }
1374 
1380  public function getSubject()
1381  {
1382  return $this->_msgSubject;
1383  }
1384 
1390  public function getHeader()
1391  {
1392  global $conf;
1393 
1394  $_header = 'From: '.$this->getFrom('org')."\r\n"
1395  . 'To: '.$this->getTO()."\r\n";
1396 
1397  if ($this->getCC()) {
1398  $_header .= 'Cc: '.$this->getCC()."\r\n";
1399  }
1400 
1401  /* Note:
1402  * BCC email addresses must be listed in the RCPT TO command list,
1403  * but the BCC header should not be printed under the DATA command.
1404  * So it is included into the function sendMsg() but not here.
1405  * http://stackoverflow.com/questions/2750211/sending-bcc-emails-using-a-smtp-server
1406  */
1407  /*
1408  if ( $this->getBCC() )
1409  $_header .= 'Bcc: ' . $this->getBCC() . "\r\n";
1410  */
1411 
1412  $host = dol_getprefix('email');
1413 
1414  //NOTE: Message-ID should probably contain the username of the user who sent the msg
1415  $_header .= 'Subject: '.$this->getSubject()."\r\n";
1416  $_header .= 'Date: '.date("r")."\r\n";
1417 
1418  $trackid = $this->getTrackId();
1419  if ($trackid) {
1420  // References is kept in response and Message-ID is returned into In-Reply-To:
1421  $_header .= 'Message-ID: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n";
1422  $_header .= 'References: <'.time().'.SMTPs-dolibarr-'.$trackid.'@'.$host.">\r\n";
1423  $_header .= 'X-Dolibarr-TRACKID: '.$trackid.'@'.$host."\r\n";
1424  } else {
1425  $_header .= 'Message-ID: <'.time().'.SMTPs@'.$host.">\r\n";
1426  }
1427  if (!empty($_SERVER['REMOTE_ADDR'])) {
1428  $_header .= "X-RemoteAddr: ".$_SERVER['REMOTE_ADDR']."\r\n";
1429  }
1430  if ($this->getMoreInHeader()) {
1431  $_header .= $this->getMoreInHeader(); // Value must include the "\r\n";
1432  }
1433 
1434  //$_header .=
1435  // 'Read-Receipt-To: ' . $this->getFrom( 'org' ) . "\r\n"
1436  // 'Return-Receipt-To: ' . $this->getFrom( 'org' ) . "\r\n";
1437 
1438  if ($this->getSensitivity()) {
1439  $_header .= 'Sensitivity: '.$this->getSensitivity()."\r\n";
1440  }
1441 
1442  if ($this->_msgPriority != 3) {
1443  $_header .= $this->getPriority();
1444  }
1445 
1446 
1447  // @CHANGE LDR
1448  if ($this->getDeliveryReceipt()) {
1449  $_header .= 'Disposition-Notification-To: '.$this->getFrom('addr')."\r\n";
1450  }
1451  if ($this->getErrorsTo()) {
1452  $_header .= 'Errors-To: '.$this->getErrorsTo('addr')."\r\n";
1453  }
1454  if ($this->getReplyTo()) {
1455  $_header .= "Reply-To: ".$this->getReplyTo('addr')."\r\n";
1456  }
1457 
1458  $_header .= 'X-Mailer: Dolibarr version '.DOL_VERSION.' (using SMTPs Mailer)'."\r\n";
1459  $_header .= 'X-Dolibarr-Option: '.($conf->global->MAIN_MAIL_USE_MULTI_PART ? 'MAIN_MAIL_USE_MULTI_PART' : 'No MAIN_MAIL_USE_MULTI_PART')."\r\n";
1460  $_header .= 'Mime-Version: 1.0'."\r\n";
1461 
1462 
1463  return $_header;
1464  }
1465 
1473  public function setBodyContent($strContent, $strType = 'plain')
1474  {
1475  //if ( $strContent )
1476  //{
1477  if ($strType == 'html') {
1478  $strMimeType = 'text/html';
1479  } else {
1480  $strMimeType = 'text/plain';
1481  }
1482 
1483  // Make RFC821 Compliant, replace bare linefeeds
1484  $strContent = preg_replace("/(?<!\r)\n/si", "\r\n", $strContent);
1485 
1486  $strContentAltText = '';
1487  if ($strType == 'html') {
1488  // Similar code to forge a text from html is also in CMailFile.class.php
1489  $strContentAltText = preg_replace('/<head><title>.*<\/style><\/head>/', '', $strContent);
1490  $strContentAltText = preg_replace("/<br\s*[^>]*>/", " ", $strContentAltText);
1491  $strContentAltText = html_entity_decode(strip_tags($strContentAltText));
1492  $strContentAltText = trim(wordwrap($strContentAltText, 75, "\r\n"));
1493  }
1494 
1495  // Make RFC2045 Compliant
1496  //$strContent = rtrim(chunk_split($strContent)); // Function chunck_split seems ko if not used on a base64 content
1497  $strContent = rtrim(wordwrap($strContent, 75, "\r\n")); // TODO Using this method creates unexpected line break on text/plain content.
1498 
1499  $this->_msgContent[$strType] = array();
1500 
1501  $this->_msgContent[$strType]['mimeType'] = $strMimeType;
1502  $this->_msgContent[$strType]['data'] = $strContent;
1503  $this->_msgContent[$strType]['dataText'] = $strContentAltText;
1504 
1505  if ($this->getMD5flag()) {
1506  $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3);
1507  }
1508  //}
1509  }
1510 
1516  public function getBodyContent()
1517  {
1518  global $conf;
1519 
1520  // Generate a new Boundary string
1521  $this->_setBoundary();
1522 
1523  // What type[s] of content do we have
1524  $_types = array_keys($this->_msgContent);
1525 
1526  // How many content types do we have
1527  $keyCount = count($_types);
1528 
1529  // If we have ZERO, we have a problem
1530  if ($keyCount === 0) {
1531  die("Sorry, no content");
1532  } elseif ($keyCount === 1 && empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1533  // If we have ONE, we can use the simple format
1534  $_msgData = $this->_msgContent;
1535  $_msgData = $_msgData[$_types[0]];
1536 
1537  $content = 'Content-Type: '.$_msgData['mimeType'].'; charset="'.$this->getCharSet().'"'."\r\n"
1538  . 'Content-Transfer-Encoding: '.$this->getTransEncodeType()."\r\n"
1539  . 'Content-Disposition: inline'."\r\n"
1540  . 'Content-Description: Message'."\r\n";
1541 
1542  if ($this->getMD5flag()) {
1543  $content .= 'Content-MD5: '.$_msgData['md5']."\r\n";
1544  }
1545 
1546  $content .= "\r\n"
1547  . $_msgData['data']."\r\n";
1548  } elseif ($keyCount >= 1 || !empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1549  // If we have more than ONE, we use the multi-part format
1550  // Since this is an actual multi-part message
1551  // We need to define a content message Boundary
1552  // NOTE: This was 'multipart/alternative', but Windows based mail servers have issues with this.
1553 
1554  //$content = 'Content-Type: multipart/related; boundary="' . $this->_getBoundary() . '"' . "\r\n";
1555  $content = 'Content-Type: multipart/mixed; boundary="'.$this->_getBoundary('mixed').'"'."\r\n";
1556 
1557  // . "\r\n"
1558  // . 'This is a multi-part message in MIME format.' . "\r\n";
1559  $content .= "Content-Transfer-Encoding: 8bit\r\n";
1560  $content .= "\r\n";
1561 
1562  $content .= "--".$this->_getBoundary('mixed')."\r\n";
1563 
1564  if (key_exists('image', $this->_msgContent)) { // If inline image found
1565  $content .= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"'."\r\n";
1566  $content .= "\r\n";
1567  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1568  }
1569 
1570 
1571  // $this->_msgContent must be sorted with key 'text' or 'html' first then 'image' then 'attachment'
1572 
1573 
1574  // Loop through message content array
1575  foreach ($this->_msgContent as $type => $_content) {
1576  if ($type == 'attachment') {
1577  // loop through all attachments
1578  foreach ($_content as $_file => $_data) {
1579  $content .= "--".$this->_getBoundary('mixed')."\r\n"
1580  . 'Content-Disposition: attachment; filename="'.$_data['fileName'].'"'."\r\n"
1581  . 'Content-Type: '.$_data['mimeType'].'; name="'.$_data['fileName'].'"'."\r\n"
1582  . 'Content-Transfer-Encoding: base64'."\r\n"
1583  . 'Content-Description: '.$_data['fileName']."\r\n";
1584  if (!empty($_data['cid'])) {
1585  $content .= "X-Attachment-Id: ".$_data['cid']."\r\n";
1586  $content .= "Content-ID: <".$_data['cid'].">\r\n";
1587  }
1588  if ($this->getMD5flag()) {
1589  $content .= 'Content-MD5: '.$_data['md5']."\r\n";
1590  }
1591 
1592  $content .= "\r\n".$_data['data']."\r\n\r\n";
1593  }
1594  } elseif ($type == 'image') {
1595  // @CHANGE LDR
1596  // loop through all images
1597  foreach ($_content as $_image => $_data) {
1598  $content .= "--".$this->_getBoundary('related')."\r\n"; // always related for an inline image
1599 
1600  $content .= 'Content-Type: '.$_data['mimeType'].'; name="'.$_data['imageName'].'"'."\r\n"
1601  . 'Content-Transfer-Encoding: base64'."\r\n"
1602  . 'Content-Disposition: inline; filename="'.$_data['imageName'].'"'."\r\n"
1603  . 'Content-ID: <'.$_data['cid'].'> '."\r\n";
1604 
1605  if ($this->getMD5flag()) {
1606  $content .= 'Content-MD5: '.$_data['md5']."\r\n";
1607  }
1608 
1609  $content .= "\r\n"
1610  . $_data['data']."\r\n";
1611  }
1612 
1613  // always end related and end alternative after inline images
1614  $content .= "--".$this->_getBoundary('related')."--\r\n";
1615  $content .= "\r\n--".$this->_getBoundary('alternative')."--\r\n";
1616  $content .= "\r\n";
1617  } else {
1618  if (key_exists('image', $this->_msgContent)) {
1619  $content .= "Content-Type: text/plain; charset=".$this->getCharSet()."\r\n";
1620  $content .= "\r\n".($_content['dataText'] ? $_content['dataText'] : strip_tags($_content['data']))."\r\n"; // Add plain text message
1621  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1622  $content .= 'Content-Type: multipart/related; boundary="'.$this->_getBoundary('related').'"'."\r\n";
1623  $content .= "\r\n";
1624  $content .= "--".$this->_getBoundary('related')."\r\n";
1625  }
1626 
1627  if (!key_exists('image', $this->_msgContent) && $_content['dataText'] && !empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1628  // Add plain text message part before html part
1629  $content .= 'Content-Type: multipart/alternative; boundary="'.$this->_getBoundary('alternative').'"'."\r\n";
1630  $content .= "\r\n";
1631  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1632 
1633  $content .= "Content-Type: text/plain; charset=".$this->getCharSet()."\r\n";
1634  $content .= "\r\n".$_content['dataText']."\r\n";
1635  $content .= "--".$this->_getBoundary('alternative')."\r\n";
1636  }
1637 
1638  $content .= 'Content-Type: '.$_content['mimeType'].'; charset='.$this->getCharSet();
1639 
1640  $content .= "\r\n";
1641 
1642  if ($this->getMD5flag()) {
1643  $content .= 'Content-MD5: '.$_content['md5']."\r\n";
1644  }
1645 
1646  $content .= "\r\n".$_content['data']."\r\n";
1647 
1648  if (!key_exists('image', $this->_msgContent) && $_content['dataText'] && !empty($conf->global->MAIN_MAIL_USE_MULTI_PART)) {
1649  // Add plain text message part after html part
1650  $content .= "--".$this->_getBoundary('alternative')."--\r\n";
1651  }
1652 
1653  $content .= "\r\n";
1654  }
1655  }
1656 
1657  $content .= "--".$this->_getBoundary('mixed').'--'."\r\n";
1658  }
1659 
1660  return $content;
1661  }
1662 
1673  public function setAttachment($strContent, $strFileName = 'unknown', $strMimeType = 'unknown', $strCid = '')
1674  {
1675  if ($strContent) {
1676  $strContent = rtrim(chunk_split(base64_encode($strContent), 76, "\r\n")); // 76 max is defined into http://tools.ietf.org/html/rfc2047
1677 
1678  $this->_msgContent['attachment'][$strFileName]['mimeType'] = $strMimeType;
1679  $this->_msgContent['attachment'][$strFileName]['fileName'] = $strFileName;
1680  $this->_msgContent['attachment'][$strFileName]['data'] = $strContent;
1681  $this->_msgContent['attachment'][$strFileName]['cid'] = $strCid; // If defined, it means this attachment must be shown inline
1682 
1683  if ($this->getMD5flag()) {
1684  $this->_msgContent['attachment'][$strFileName]['md5'] = dol_hash($strContent, 3);
1685  }
1686  }
1687  }
1688 
1689 
1690  // @CHANGE LDR
1691 
1702  public function setImageInline($strContent, $strImageName = 'unknown', $strMimeType = 'unknown', $strImageCid = 'unknown')
1703  {
1704  if ($strContent) {
1705  $this->_msgContent['image'][$strImageName]['mimeType'] = $strMimeType;
1706  $this->_msgContent['image'][$strImageName]['imageName'] = $strImageName;
1707  $this->_msgContent['image'][$strImageName]['cid'] = $strImageCid;
1708  $this->_msgContent['image'][$strImageName]['data'] = $strContent;
1709 
1710  if ($this->getMD5flag()) {
1711  $this->_msgContent['image'][$strImageName]['md5'] = dol_hash($strContent, 3);
1712  }
1713  }
1714  }
1715  // END @CHANGE LDR
1716 
1717 
1729  public function setSensitivity($_value = 0)
1730  {
1731  if ((is_numeric($_value)) &&
1732  (($_value >= 0) && ($_value <= 3))) {
1733  $this->_msgSensitivity = $_value;
1734  }
1735  }
1736 
1747  public function getSensitivity()
1748  {
1749  return $this->_arySensitivity[$this->_msgSensitivity];
1750  }
1751 
1765  public function setPriority($_value = 3)
1766  {
1767  if ((is_numeric($_value)) &&
1768  (($_value >= 0) && ($_value <= 5))) {
1769  $this->_msgPriority = $_value;
1770  }
1771  }
1772 
1785  public function getPriority()
1786  {
1787  return 'Importance: '.$this->_aryPriority[$this->_msgPriority]."\r\n"
1788  . 'Priority: '.$this->_aryPriority[$this->_msgPriority]."\r\n"
1789  . 'X-Priority: '.$this->_msgPriority.' ('.$this->_aryPriority[$this->_msgPriority].')'."\r\n";
1790  }
1791 
1798  public function setMD5flag($_flag = false)
1799  {
1800  $this->_smtpMD5 = $_flag;
1801  }
1802 
1808  public function getMD5flag()
1809  {
1810  return $this->_smtpMD5;
1811  }
1812 
1821  public function setXheader($strXdata)
1822  {
1823  if ($strXdata) {
1824  $this->_msgXheader[] = $strXdata;
1825  }
1826  }
1827 
1833  public function getXheader()
1834  {
1835  return $this->_msgXheader;
1836  }
1837 
1843  private function _setBoundary()
1844  {
1845  $this->_smtpsBoundary = "multipart_x.".time().".x_boundary";
1846  $this->_smtpsRelatedBoundary = 'mul_'.dol_hash(uniqid("dolibarr2"), 3);
1847  $this->_smtpsAlternativeBoundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3);
1848  }
1849 
1856  private function _getBoundary($type = 'mixed')
1857  {
1858  if ($type == 'mixed') {
1859  return $this->_smtpsBoundary;
1860  } elseif ($type == 'related') {
1862  } elseif ($type == 'alternative') {
1864  }
1865  }
1866 
1867  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1876  public function server_parse($socket, $response)
1877  {
1878  // phpcs:enable
1883  $_retVal = true;
1884 
1885  $server_response = '';
1886 
1887  // avoid infinite loop
1888  $limit = 0;
1889 
1890  while (substr($server_response, 3, 1) != ' ' && $limit < 100) {
1891  if (!($server_response = fgets($socket, 256))) {
1892  $this->_setErr(121, "Couldn't get mail server response codes");
1893  $_retVal = false;
1894  break;
1895  }
1896  $this->log .= $server_response;
1897  $limit++;
1898  }
1899 
1900  if (!(substr($server_response, 0, 3) == $response)) {
1901  $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse:".$server_response);
1902  $_retVal = false;
1903  }
1904 
1905  return $_retVal;
1906  }
1907 
1908  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1917  public function socket_send_str($_strSend, $_returnCode = null, $CRLF = "\r\n")
1918  {
1919  // phpcs:enable
1920  if ($this->_debug) {
1921  $this->log .= $_strSend; // @CHANGE LDR for log
1922  }
1923  fputs($this->socket, $_strSend.$CRLF);
1924  if ($this->_debug) {
1925  $this->log .= ' ('.$_returnCode.')'.$CRLF;
1926  }
1927 
1928  if ($_returnCode) {
1929  return $this->server_parse($this->socket, $_returnCode);
1930  }
1931  }
1932 
1933  // =============================================================
1934  // ** Error handling methods
1935 
1943  private function _setErr($_errNum, $_errMsg)
1944  {
1945  $this->_smtpsErrors[] = array(
1946  'num' => $_errNum,
1947  'msg' => $_errMsg,
1948  );
1949  }
1950 
1956  public function getErrors()
1957  {
1958  $_errMsg = array();
1959 
1960  if (is_array($this->_smtpsErrors)) {
1961  foreach ($this->_smtpsErrors as $_err => $_info) {
1962  $_errMsg[] = 'Error ['.$_info['num'].']: '.$_info['msg'];
1963  }
1964  }
1965 
1966  return implode("\n", $_errMsg);
1967  }
1968 }
1969 
1970 
1971 // =============================================================
1972 // ** CSV Version Control Info
1973 
Class to construct and send SMTP compliant email, even to a secure SMTP server, regardless of platfor...
Definition: smtps.class.php:47
$_smtpsToken
Token in case we use OAUTH2.
Definition: smtps.class.php:74
_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 errors codes and messages for Class.
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.
Definition: smtps.class.php:51
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.
Definition: smtps.class.php:86
$_smtpsID
Secure SMTP Server access ID This can be defined via a INI file or via a setter method.
Definition: smtps.class.php:63
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.
Definition: smtps.class.php:80
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.
Definition: smtps.class.php:57
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.
Definition: smtps.class.php:98
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.
Definition: smtps.class.php:69
getTransportType()
Return the method inwhich the message is to be sent.
setMailPath($_path)
Path to the sendmail execuable.
$_msgContent
Message Content.
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...
Definition: smtps.class.php:93
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....
dol_hash($chain, $type='0')
Returns a hash (non reversible encryption) of a string.