CWIS Developer Documentation
Email.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # FILE: Email.php
4 #
5 # Part of the ScoutLib application support library
6 # Copyright 2012-2015 Edward Almasy and Internet Scout Research Group
7 # http://scout.wisc.edu
8 #
9 
14 class Email
15 {
16 
17  # ---- PUBLIC INTERFACE --------------------------------------------------
18  /*@(*/
20 
28  public function Send()
29  {
30  # if whitelist set
31  if (count(self::$RecipientWhitelist))
32  {
33  # save recipient list and then pare it down based on whitelist
34  $SavedTo = $this->To;
35  $NewTo = array();
36  foreach ($this->To as $To)
37  {
38  foreach (self::$RecipientWhitelist as $White)
39  {
40  $White = trim($White);
41  if ($White[0] != substr($White, 0, -1))
42  {
43  $White = "/".$White."/";
44  }
45  if (preg_match($White, $To))
46  {
47  $NewTo[] = $To;
48  continue 2;
49  }
50  }
51  }
52  $this->To = $NewTo;
53  }
54 
55  # if there are recipients
56  $Result = TRUE;
57  if (count($this->To))
58  {
59  switch (self::$DeliveryMethod)
60  {
61  case self::METHOD_PHPMAIL:
62  # use PHPMailer to send multipart alternative messages because
63  # they can be tricky to construct properly
64  if ($this->HasAlternateBody())
65  {
66  $Result = $this->SendViaPhpMailerLib();
67  }
68 
69  # otherwise, just use the built-in mail() function
70  else
71  {
72  $Result = $this->SendViaPhpMailFunc();
73  }
74  break;
75 
76  case self::METHOD_SMTP:
77  $Result = $this->SendViaSmtp();
78  break;
79  }
80  }
81 
82  # if recipient list saved
83  if (isset($SavedTo))
84  {
85  # restore recipient list
86  $this->To = $SavedTo;
87  }
88 
89  # report to caller whether message was sent
90  return $Result;
91  }
92 
101  public static function ToWhitelist($NewValue = NULL)
102  {
103  if ($NewValue !== NULL)
104  {
105  self::$RecipientWhitelist = $NewValue;
106  }
107  return self::$RecipientWhitelist;
108  }
109 
110  /*@(*/
112 
118  public function Body($NewValue = NULL)
119  {
120  if ($NewValue !== NULL) { $this->Body = $NewValue; }
121  return $this->Body;
122  }
123 
129  public function AlternateBody($NewValue = NULL)
130  {
131  # set the plain-text alternative if a parameter is given
132  if (func_num_args() > 0)
133  {
134  $this->AlternateBody = $NewValue;
135  }
136 
137  return $this->AlternateBody;
138  }
139 
145  public function Subject($NewValue = NULL)
146  {
147  if ($NewValue !== NULL) { $this->Subject = $NewValue; }
148  return $this->Subject;
149  }
150 
159  public function From($NewAddress = NULL, $NewName = NULL)
160  {
161  if ($NewAddress !== NULL)
162  {
163  $NewAddress = trim($NewAddress);
164  if ($NewName !== NULL)
165  {
166  $NewName = trim($NewName);
167  $this->From = $NewName." <".$NewAddress.">";
168  }
169  else
170  {
171  $this->From = $NewAddress;
172  }
173  }
174  return $this->From;
175  }
176 
183  public static function DefaultFrom($NewValue = NULL)
184  {
185  if ($NewValue !== NULL) { self::$DefaultFrom = $NewValue; }
186  return self::$DefaultFrom;
187  }
188 
197  public function ReplyTo($NewAddress = NULL, $NewName = NULL)
198  {
199  if ($NewAddress !== NULL)
200  {
201  $NewAddress = trim($NewAddress);
202  if ($NewName !== NULL)
203  {
204  $NewName = trim($NewName);
205  $this->ReplyTo = $NewName." <".$NewAddress.">";
206  }
207  else
208  {
209  $this->ReplyTo = $NewAddress;
210  }
211  }
212  return $this->ReplyTo;
213  }
214 
222  public function To($NewValue = NULL)
223  {
224  if ($NewValue !== NULL)
225  {
226  if (!is_array($NewValue))
227  {
228  $this->To = array($NewValue);
229  }
230  else
231  {
232  $this->To = $NewValue;
233  }
234  }
235  return $this->To;
236  }
237 
245  public function CC($NewValue = NULL)
246  {
247  if ($NewValue !== NULL)
248  {
249  if (!is_array($NewValue))
250  {
251  $this->CC = array($NewValue);
252  }
253  else
254  {
255  $this->CC = $NewValue;
256  }
257  }
258  return $this->CC;
259  }
260 
268  public function BCC($NewValue = NULL)
269  {
270  if ($NewValue !== NULL)
271  {
272  if (!is_array($NewValue))
273  {
274  $this->BCC = array($NewValue);
275  }
276  else
277  {
278  $this->BCC = $NewValue;
279  }
280  }
281  return $this->BCC;
282  }
283 
288  public function AddHeaders($NewHeaders)
289  {
290  # add new headers to list
291  $this->Headers = array_merge($this->Headers, $NewHeaders);
292  }
293 
300  public function CharSet($NewValue = NULL)
301  {
302  # set the plain-text alternative if a parameter is given
303  if (func_num_args() > 0)
304  {
305  $this->CharSet = $NewValue;
306  }
307 
308  return $this->CharSet;
309  }
310 
316  public static function LineEnding($NewValue = NULL)
317  {
318  if (!is_null($NewValue))
319  {
320  self::$LineEnding = $NewValue;
321  }
322 
323  return self::$LineEnding;
324  }
325 
338  public static function WrapHtmlAsNecessary(
339  $Html, $MaxLineLength=998, $LineEnding="\r\n")
340  {
341  # the regular expression used to find long lines
342  $LongLineRegExp = '/[^\r\n]{'.($MaxLineLength+1).',}/';
343 
344  # find all lines that are too long
345  preg_match_all($LongLineRegExp, $Html, $Matches,
346  PREG_PATTERN_ORDER|PREG_OFFSET_CAPTURE);
347 
348  # no changes are necessary
349  if (!count($Matches))
350  {
351  return $Html;
352  }
353 
354  # go backwards so that the HTML can be edited in place without messing
355  # with the offsets
356  for ($i = count($Matches[0]) - 1; $i >= 0; $i--)
357  {
358  # extract the line text and its offset within the string
359  list($Line, $Offset) = $Matches[0][$i];
360 
361  # first try to get the line under the limit without being too
362  # aggressive
363  $BetterLine = self::ConvertHtmlWhiteSpace($Line, FALSE, $LineEnding);
364  $WasAggressive = "No";
365 
366  # if the line is still too long, be more aggressive with replacing
367  # horizontal whitespace
368  if (preg_match($LongLineRegExp, $BetterLine))
369  {
370  $BetterLine = self::ConvertHtmlWhiteSpace($Line, TRUE, $LineEnding);
371  $WasAggressive = "Yes";
372  }
373 
374  # tack on an HTML comment stating that the line was wrapped and give
375  # some additional info
376  $BetterLine = $LineEnding."<!-- Line was wrapped. Aggressive: "
377  .$WasAggressive.", Max: ".$MaxLineLength.", Actual: "
378  .strlen($Line)." -->".$LineEnding.$BetterLine;
379 
380  # replace the line within the HTML
381  $Html = substr_replace($Html, $BetterLine, $Offset, strlen($Line));
382  }
383 
384  return $Html;
385  }
386 
394  public static function TestLineEndings($Value, $LineEnding)
395  {
396  # the number of \r in the string
397  $NumCR = substr_count($Value, "\r");
398 
399  # LF
400  if ($LineEnding == "\n")
401  {
402  return $NumCR === 0;
403  }
404 
405  # the number of \n in the string
406  $NumLF = substr_count($Value, "\n");
407 
408  # CR
409  if ($LineEnding == "\r")
410  {
411  return $NumLF === 0;
412  }
413 
414  # the number of \r\n in the string
415  $NumCRLF = substr_count($Value, "\r\n");
416 
417  # CRLF. also check CRLF to make sure CR and LF appear together and in
418  # the correct order
419  return $NumCR === $NumLF && $NumLF === $NumCRLF;
420  }
421 
427  public static function ConvertHtmlToPlainText($Html)
428  {
429  # remove newlines
430  $Text = str_replace(array("\r", "\n"), "", $Html);
431 
432  # convert HTML breaks to newlines
433  $Text = preg_replace('/<br\s*\/?>/', "\n", $Text);
434 
435  # strip remaining tags
436  $Text = strip_tags($Text);
437 
438  # convert HTML entities to their plain-text equivalents
439  $Text = html_entity_decode($Text);
440 
441  # single quotes aren't always handled
442  $Text = str_replace('&#39;', "'", $Text);
443 
444  # remove HTML entities that have no equivalents
445  $Text = preg_replace('/&(#[0-9]{1,6}|[a-zA-Z0-9]{1,6});/', "", $Text);
446 
447  # return the plain text version
448  return $Text;
449  }
450  /*@(*/
452 
459  public static function DeliveryMethod($NewValue = NULL)
460  {
461  if ($NewValue !== NULL)
462  {
463  self::$DeliveryMethod = $NewValue;
464  }
465  return self::$DeliveryMethod;
466  }
468  const METHOD_PHPMAIL = 1;
470  const METHOD_SMTP = 2;
471 
477  public static function Server($NewValue = NULL)
478  {
479  if ($NewValue !== NULL) { self::$Server = $NewValue; }
480  return self::$Server;
481  }
482 
488  public static function Port($NewValue = NULL)
489  {
490  if ($NewValue !== NULL) { self::$Port = $NewValue; }
491  return self::$Port;
492  }
493 
499  public static function UserName($NewValue = NULL)
500  {
501  if ($NewValue !== NULL) { self::$UserName = $NewValue; }
502  return self::$UserName;
503  }
504 
510  public static function Password($NewValue = NULL)
511  {
512  if ($NewValue !== NULL) { self::$Password = $NewValue; }
513  return self::$Password;
514  }
515 
521  public static function UseAuthentication($NewValue = NULL)
522  {
523  if ($NewValue !== NULL) { self::$UseAuthentication = $NewValue; }
524  return self::$UseAuthentication;
525  }
526 
534  public static function DeliverySettings($NewSettings = NULL)
535  {
536  if ($NewSettings !== NULL)
537  {
538  $Settings = unserialize($NewSettings);
539  self::$DeliveryMethod = $Settings["DeliveryMethod"];
540  self::$Server = $Settings["Server"];
541  self::$Port = $Settings["Port"];
542  self::$UserName = $Settings["UserName"];
543  self::$Password = $Settings["Password"];
544  self::$UseAuthentication = $Settings["UseAuthentication"];
545  }
546  else
547  {
548  $Settings["DeliveryMethod"] = self::$DeliveryMethod;
549  $Settings["Server"] = self::$Server;
550  $Settings["Port"] = self::$Port;
551  $Settings["UserName"] = self::$UserName;
552  $Settings["Password"] = self::$Password;
553  $Settings["UseAuthentication"] = self::$UseAuthentication;
554  }
555  return serialize($Settings);
556  }
557 
566  public static function DeliverySettingsOkay()
567  {
568  # start out with error list clear
569  self::$DeliverySettingErrorList = array();
570 
571  # test based on delivery method
572  switch (self::$DeliveryMethod)
573  {
574  case self::METHOD_PHPMAIL:
575  # always report success
576  $SettingsOkay = TRUE;
577  break;
578 
579  case self::METHOD_SMTP:
580  # set up PHPMailer for test
581  $PMail = new PHPMailer(TRUE);
582  $PMail->IsSMTP();
583  $PMail->SMTPAuth = self::$UseAuthentication;
584  $PMail->Host = self::$Server;
585  $PMail->Port = self::$Port;
586  $PMail->Username = self::$UserName;
587  $PMail->Password = self::$Password;
588 
589  # test settings
590  try
591  {
592  $SettingsOkay = $PMail->SmtpConnect();
593  }
594  # if test failed
595  catch (phpmailerException $Except)
596  {
597  # translate PHPMailer error message to possibly bad settings
598  switch ($Except->getMessage())
599  {
600  case 'SMTP Error: Could not authenticate.':
601  self::$DeliverySettingErrorList = array(
602  "UseAuthentication",
603  "UserName",
604  "Password",
605  );
606  break;
607 
608  case 'SMTP Error: Could not connect to SMTP host.':
609  self::$DeliverySettingErrorList = array(
610  "Server",
611  "Port",
612  );
613  break;
614 
615  case 'Language string failed to load: tls':
616  self::$DeliverySettingErrorList = array("TLS");
617  break;
618 
619  default:
620  self::$DeliverySettingErrorList = array("UNKNOWN");
621  break;
622  }
623 
624  # make sure failure is reported
625  $SettingsOkay = FALSE;
626  }
627  break;
628  }
629 
630  # report result to caller
631  return $SettingsOkay;
632  }
633 
638  public static function DeliverySettingErrors()
639  {
640  return self::$DeliverySettingErrorList;
641  }
642 
643 
644  # ---- PRIVATE INTERFACE -------------------------------------------------
645 
646  private $AlternateBody = "";
647  private $BCC = array();
648  private $Body = "";
649  private $CC = array();
650  private $CharSet;
651  private $From = "";
652  private $Headers = array();
653  private $ReplyTo = "";
654  private $Subject = "";
655  private $To = array();
656  private $Whitelist = array();
657 
658  private static $DefaultFrom = "";
659  private static $DeliveryMethod = self::METHOD_PHPMAIL;
660  private static $DeliverySettingErrorList = array();
661  private static $LineEnding = "\r\n";
662  private static $Password = "";
663  private static $Port = 25;
664  private static $RecipientWhitelist = array();
665  private static $Server;
666  private static $UseAuthentication = FALSE;
667  private static $UserName = "";
668 
673  private function SendViaPhpMailFunc()
674  {
675  # Contrary to the PHP documentation, line endings for PHP's
676  # mail function should be the system native line endings.
677  #
678  # see https://bugs.php.net/bug.php?id=15841 for details
679 
680  # Use the system line endings
681  $LE = PHP_EOL;
682 
683  # build basic headers list
684  $From = strlen($this->From) ? $this->From : self::$DefaultFrom;
685  $Headers = "From: ".self::CleanHeaderValue($From).$LE;
686  $Headers .= $this->BuildAddresseeLine("Cc", $this->CC);
687  $Headers .= $this->BuildAddresseeLine("Bcc", $this->BCC);
688  $Headers .= "Reply-To: ".self::CleanHeaderValue(
689  strlen($this->ReplyTo) ? $this->ReplyTo : $this->From).$LE;
690 
691  # add additional headers
692  foreach ($this->Headers as $ExtraHeader)
693  {
694  $Headers .= $ExtraHeader.$LE;
695  }
696 
697  # build recipient list
698  $To = "";
699  $Separator = "";
700  foreach ($this->To as $Recipient)
701  {
702  $To .= $Separator.$Recipient;
703  $Separator = ", ";
704  }
705 
706  # normalize message body line endings
707  $Body = $this->NormalizeLineEndings($this->Body, $LE);
708 
709  # send message
710  $Result = mail($To, $this->Subject, $Body, $Headers);
711 
712  # report to caller whether attempt to send succeeded
713  return $Result;
714  }
715 
721  private function SendViaPhpMailerLib()
722  {
723  # create and initialize PHPMailer
724  $PMail = new PHPMailer();
725  $PMail->LE = self::$LineEnding;
726  $PMail->Subject = $this->Subject;
727  $PMail->Body = $this->Body;
728  $PMail->IsHTML(FALSE);
729 
730  # default values for the sender's name and address
731  $Name = "";
732  $Address = $this->From;
733 
734  # if the address contains a name and address, they need to extracted
735  # because PHPMailer requires that they are set as two different
736  # parameters
737  if (preg_match("/ </", $this->From))
738  {
739  $Pieces = explode(" ", $this->From);
740  $Address = array_pop($Pieces);
741  $Address = preg_replace("/[<>]+/", "", $Address);
742  $Name = trim(implode($Pieces, " "));
743  }
744 
745  # add the sender
746  $PMail->SetFrom($Address, $Name);
747 
748  # add each recipient
749  foreach ($this->To as $Recipient)
750  {
751  $PMail->AddAddress($Recipient);
752  }
753 
754  # add any extra header lines
755  foreach ($this->Headers as $ExtraHeader)
756  {
757  $PMail->AddCustomHeader($ExtraHeader);
758  }
759 
760  # add the charset if it's set
761  if (isset($this->CharSet))
762  {
763  $PMail->CharSet = strtolower($this->CharSet);
764  }
765 
766  # add the alternate plain-text body if it's set
767  if ($this->HasAlternateBody())
768  {
769  $PMail->AltBody = $this->AlternateBody;
770  }
771 
772  # set up SMTP if necessary
773  if (self::$DeliveryMethod == self::METHOD_SMTP)
774  {
775  $PMail->IsSMTP();
776  $PMail->SMTPAuth = self::$UseAuthentication;
777  $PMail->Host = self::$Server;
778  $PMail->Port = self::$Port;
779  $PMail->Username = self::$UserName;
780  $PMail->Password = self::$Password;
781  }
782 
783  # send message
784  $Result = $PMail->Send();
785 
786  # report to caller whether attempt to send succeeded
787  return $Result;
788  }
789 
794  private function SendViaSmtp()
795  {
796  # send via PHPMailer because it's capable of handling SMTP
797  return $this->SendViaPhpMailerLib();
798  }
799 
806  private function BuildAddresseeLine($Label, $Recipients)
807  {
808  $Line = "";
809  if (count($Recipients))
810  {
811  $Line .= $Label.": ";
812  $Separator = "";
813  foreach ($Recipients as $Recipient)
814  {
815  $Line .= $Separator.self::CleanHeaderValue($Recipient);
816  $Separator = ", ";
817  }
818  $Line .= self::$LineEnding;
819  }
820  return $Line;
821  }
822 
827  private function HasAlternateBody()
828  {
829  return isset($this->AlternateBody) && strlen(trim($this->AlternateBody)) > 0;
830  }
831 
837  private static function CleanHeaderValue($Value)
838  {
839  # (regular expression taken from sanitizeHeaders() function in
840  # Mail PEAR package)
841  return preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
842  "", $Value);
843  }
844 
851  private static function NormalizeLineEndings($Value, $LineEnding)
852  {
853  return preg_replace('/\r\n|\r|\n/', $LineEnding, $Value);
854  }
855 
870  protected static function ConvertHtmlWhiteSpace(
871  $Html, $Aggressive=FALSE, $LineEnding="\r\n")
872  {
873  $HtmlLength = strlen($Html);
874 
875  # tags that should have their inner HTML left alone
876  $IgnoredTags = array('script', 'style', 'textarea', 'title');
877 
878  # values for determining context
879  $InTag = FALSE;
880  $InClosingTag = FALSE;
881  $InIgnoredTag = FALSE;
882  $InAttribute = FALSE;
883  $TagName = NULL;
884  $IgnoredTagName = NULL;
885  $AttributeDelimiter = NULL;
886 
887  # loop through each character of the string
888  for ($i = 0; $i < $HtmlLength; $i++)
889  {
890  $Char = $Html{$i};
891 
892  # beginning of a tag
893  if ($Char == "<" && !$InTag)
894  {
895  $InTag = TRUE;
896  $InAttribute = FALSE;
897  $AttributeDelimiter = NULL;
898 
899  # do some lookaheads to get the tag name and to see if the tag
900  # is a closing tag
901  list($InClosingTag, $TagName) = self::GetTagInfo($Html, $i);
902 
903  # moving into an ignored tag
904  if (!$InClosingTag && in_array($TagName, $IgnoredTags))
905  {
906  $InIgnoredTag = TRUE;
907  $IgnoredTagName = $TagName;
908  }
909 
910  continue;
911  }
912 
913  # end of a tag
914  if ($Char == ">" && $InTag && !$InAttribute)
915  {
916  # moving out of an ignored tag
917  if ($InClosingTag && $InIgnoredTag && $TagName == $IgnoredTagName)
918  {
919  $InIgnoredTag = FALSE;
920  $IgnoredTagName = NULL;
921  }
922 
923  $InTag = FALSE;
924  $InClosingTag = FALSE;
925  $InAttribute = FALSE;
926  $TagName = NULL;
927  $AttributeDelimiter = NULL;
928 
929  continue;
930  }
931 
932  # attribute delimiter characters
933  if ($Char == "'" || $Char == '"')
934  {
935  # beginning of an attribute
936  if (!$InAttribute)
937  {
938  $InAttribute = TRUE;
939  $AttributeDelimiter = $Char;
940  continue;
941  }
942 
943  # end of the attribute
944  if ($InAttribute && $Char == $AttributeDelimiter)
945  {
946  $InAttribute = FALSE;
947  $AttributeDelimiter = NULL;
948  continue;
949  }
950  }
951 
952  # whitespace inside of a tag but outside of an attribute can be
953  # safely converted to a newline
954  if ($InTag && !$InAttribute && preg_match('/\s/', $Char))
955  {
956  $Html{$i} = $LineEnding;
957  continue;
958  }
959 
960  # whitespace outside of a tag can be safely converted to a newline
961  # when not in one of the ignored tags, but only do so if horizontal
962  # space is at a premium because it can make the resulting HTML
963  # difficult to read
964  if ($Aggressive && !$InTag && !$InIgnoredTag && preg_match('/\s/', $Char))
965  {
966  $Html{$i} = $LineEnding;
967  continue;
968  }
969  }
970 
971  return $Html;
972  }
973 
982  protected static function GetTagInfo($Html, $TagBegin)
983  {
984  $HtmlLength = strlen($Html);
985 
986  # default return values
987  $InClosingTag = FALSE;
988  $TagName = NULL;
989 
990  # if at the end of the string and lookaheads aren't possible
991  if ($TagBegin + 1 >= $HtmlLength)
992  {
993  return array($InClosingTag, $TagName);
994  }
995 
996  # do a lookahead for whether it's a closing tag
997  if ($Html{$TagBegin+1} == "/")
998  {
999  $InClosingTag = TRUE;
1000  }
1001 
1002  # determine whether to offset by one or two to get the tag name
1003  $TagStart = $InClosingTag ? $TagBegin + 2 : $TagBegin + 1;
1004 
1005  # do a lookahead for the tag name
1006  for ($i = $TagStart; $i < $HtmlLength; $i++)
1007  {
1008  $Char = $Html{$i};
1009 
1010  # stop getting the tag name if whitespace is found and something is
1011  # available for the tag name
1012  if (strlen($TagName) && preg_match('/[\r\n\s]/', $Char))
1013  {
1014  break;
1015  }
1016 
1017  # stop getting the tag name if the character is >
1018  if ($Char == ">")
1019  {
1020  break;
1021  }
1022 
1023  $TagName .= $Char;
1024  }
1025 
1026  # comment "tag"
1027  if (substr($TagName, 0, 3) == "!--")
1028  {
1029  return array($InClosingTag, "!--");
1030  }
1031 
1032  # remove characters that aren't part of a valid tag name
1033  $TagName = preg_replace('/[^a-zA-Z0-9]/', '', $TagName);
1034 
1035  return array($InClosingTag, $TagName);
1036  }
1037 }
1038 
From($NewAddress=NULL, $NewName=NULL)
Get/set message sender.
Definition: Email.php:159
static Server($NewValue=NULL)
Get/set server for mail delivery.
Definition: Email.php:477
static DeliveryMethod($NewValue=NULL)
Get/set mail delivery method.
Definition: Email.php:459
static WrapHtmlAsNecessary($Html, $MaxLineLength=998, $LineEnding="\r\n")
Wrap HTML in an e-mail as necessary to get its lines less than some max length.
Definition: Email.php:338
To($NewValue=NULL)
Get/set message recipient(s).
Definition: Email.php:222
static DeliverySettings($NewSettings=NULL)
Get/set serialized (opaque text) version of delivery settings.
Definition: Email.php:534
ReplyTo($NewAddress=NULL, $NewName=NULL)
Get/set message "Reply-To" address.
Definition: Email.php:197
static ToWhitelist($NewValue=NULL)
Set whitelist of acceptable recipient addresses.
Definition: Email.php:101
static DeliverySettingsOkay()
Test delivery settings and report their validity.
Definition: Email.php:566
static LineEnding($NewValue=NULL)
Specify the character sequence that should be used to end lines.
Definition: Email.php:316
static DeliverySettingErrors()
Return array with list of delivery setting errors (if any).
Definition: Email.php:638
CharSet($NewValue=NULL)
Specify a character encoding for the message.
Definition: Email.php:300
Electronic mail message.
Definition: Email.php:14
static DefaultFrom($NewValue=NULL)
Get/set default "From" address.
Definition: Email.php:183
static GetTagInfo($Html, $TagBegin)
Get the tag name and whether it&#39;s a closing tag from a tag that begins at a specific offset within so...
Definition: Email.php:982
Send()
Mail the message.
Definition: Email.php:28
AddHeaders($NewHeaders)
Specify additional message headers to be included.
Definition: Email.php:288
const METHOD_PHPMAIL
Deliver using PHP&#39;s internal mail() mechanism.
Definition: Email.php:468
BCC($NewValue=NULL)
Get/set message BCC list.
Definition: Email.php:268
Body($NewValue=NULL)
Get/set message body.
Definition: Email.php:118
static Port($NewValue=NULL)
Get/set port number for mail delivery.
Definition: Email.php:488
static UserName($NewValue=NULL)
Get/set user name for mail delivery.
Definition: Email.php:499
AlternateBody($NewValue=NULL)
Get/set the plain-text alternative to the body.
Definition: Email.php:129
Subject($NewValue=NULL)
Get/set message subject.
Definition: Email.php:145
const METHOD_SMTP
Deliver using SMTP.
Definition: Email.php:470
static Password($NewValue=NULL)
Get/set password for mail delivery.
Definition: Email.php:510
static ConvertHtmlToPlainText($Html)
Try as best as possible to convert HTML to plain text.
Definition: Email.php:427
static UseAuthentication($NewValue=NULL)
Get/set whether to use authentication for mail delivery.
Definition: Email.php:521
static TestLineEndings($Value, $LineEnding)
Test the line endings in a value to see if they all match the given line ending.
Definition: Email.php:394
CC($NewValue=NULL)
Get/set message CC list.
Definition: Email.php:245
static ConvertHtmlWhiteSpace($Html, $Aggressive=FALSE, $LineEnding="\r\n")
Convert horizontal white space with no semantic value to vertical white space when possible...
Definition: Email.php:870