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