diff --git a/README.md b/README.md index c095797..cc369c8 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ Ultimate E-mail Toolkit ======================= -A PHP library of functions designed to handle all of your one-off e-mail needs under a MIT or LGPL license. Instead of relying on the PHP mail() function, this library directly talks to SMTP and POP3 servers just as a regular e-mail client would. The result is a high level of reliability in delivery of e-mail messages to recipients. Functions like ConvertHTMLToText() and MakeValidEmailAddress() make it easy to do complex tasks such as convert ugly HTML input into beautiful plain-text output and analyze an e-mail address to automatically correct common mistakes. All of that while following the various RFCs surrounding e-mail. +A PHP library of functions designed to handle all of your one-off e-mail needs under a MIT or LGPL license. Instead of relying on the PHP mail() function, this library directly talks to SMTP and POP3 servers just as a regular e-mail client would. The result is a high level of reliability in delivery of e-mail messages to recipients. Functions like `ConvertHTMLToText()` and `MakeValidEmailAddress()` make it easy to do complex tasks such as convert ugly HTML input into beautiful plain-text output and analyze an e-mail address to automatically correct common typing mistakes. All of that while following the various RFCs surrounding e-mail. Features -------- -* Carefully follows the many IETF RFC Standards surrounding e-mail. -* Relatively complete and comprehensive, yet easy-to-use SMTP and POP3 libraries. Fully MIME and Unicode-aware. +* Carefully follows the many IETF RFC Standards surrounding e-mail (RFC822, RFC2822, RFC1341, RFC1342, RFC1081, RFC1939, RFC2045, etc). +* Relatively complete and comprehensive, yet easy-to-use SMTP, POP3, and MIME libraries. Fully MIME and Unicode-aware. * Easy to emulate various e-mail client headers. +* `SMTP::ConvertHTMLToText()` to convert ugly HTML into really nice-looking plain text suitable for multipart e-mails. +* `SMTP::MakeValidEmailAddress()` to correctly parse e-mail addresses and automatically correct common typing mistakes. * Has a liberal open source license. MIT or LGPL, your choice. * Designed for relatively painless integration into your project. * Sits on GitHub for all of that pull request and issue tracker goodness to easily submit changes and ideas respectively. -More Information ----------------- +Usage +----- -Documentation, examples, and official downloads of this project sit on the Barebones CMS website: - -http://barebonescms.com/documentation/ultimate_email_toolkit/ +Documentation and examples can be found in the 'docs' directory of this repository. diff --git a/docs/mime_parser.md b/docs/mime_parser.md new file mode 100644 index 0000000..63027ab --- /dev/null +++ b/docs/mime_parser.md @@ -0,0 +1,171 @@ +MIMEParser Class: 'support/mime_parser.php' +=========================================== + +The MIMEParser class extracts content from e-mails retrieved with the POP3 class allowing for deep message analysis and processing. If you are extracting HTML with this, the [TagFilter class](https://github.com/cubiclesoft/ultimate-web-scraper) will prove useful for extracting content from the HTML. + +Example usage: + +```php + "[pop3.yourhost.com]", + "port" => [110 or 995], + "secure" => [true or false] + ); + + $pop3 = new POP3(); + $result = $pop3->Connect("[YOUR e-mail username]", "[YOUR e-mail password]", $pop3options); + if (!$result["success"]) + { + echo "POP3 - Connect(): " . $result["error"] . "\n"; + + exit(); + } + + $result = $pop3->GetMessageList(); + if (!$result["success"]) + { + echo "POP3 - GetMessageList(): " . $result["error"] . "\n"; + + exit(); + } + + $ids = $result["ids"]; + foreach ($ids as $id => $size) + { + // Only retrieve messages under 1MB. + if ($size < 1024768) + { + $result = $pop3->GetNextMessage($id); + if (!$result["success"]) + { + echo "POP3 - GetNextMessage(): " . $result["error"] . "\n"; + + exit(); + } + + $message = $result["message"]; + + // Process the message. + $message = MIMEParser::Parse($result["message"]); +var_dump($message); + + $content = MIMEParser::ExtractContent($message); +var_dump($content); + } + +// $result = $pop3->DeleteMessage($id); +// if (!$result["success"]) +// { +// echo "POP3 - DeleteMessage(): " . $result["error"] . "\n"; +// +// exit(); +// } + } + + $pop3->Disconnect(); +?> +``` + +MIMEParser::ConvertFromRFC1341($data) +------------------------------------- + +Access: public static + +Parameters: + +* $data - A string containing the data to convert. + +Returns: A string containing the converted data. + +This static function converts RFC 1341 encoded data (also known as "Quoted Printable") into 8-bit clean data. 8-bit data (e.g. UTF-8) has to be converted into 7-bit clean ASCII for transport across the Internet. This function reverses the process. + +MIMEParser::ConvertFromRFC1342($data) +------------------------------------- + +Access: public static + +Parameters: + +* $data - A string containing the data to convert. + +Returns: A string containing the converted data. + +This static function converts RFC 1342 encoded header data into UTF-8 data. 8-bit headers have to be converted into 7-bit clean ASCII for transport across the Internet. This function reverses the process. + +MIMEParser::ConvertCharset($data, $incharset, $outcharset) +---------------------------------------------------------- + +Access: public static + +Parameters: + +* $data - A string containing the data to convert. +* $incharset - A string containing the source character encoding. +* $outcharset - A string containing the destination character encoding. + +Returns: A string containing the converted data if successful, a boolean of false on failure. + +This static function converts a string from one character set to another. Translation is done in the following order of preference: iconv(), mb_convert_encoding(), and then utf8_encode()/utf8_decode(). + +MIMEParser::ExplodeHeader($data) +-------------------------------- + +Access: public static + +Parameters: + +* $data - A string containing a MIME header to parse. + +Returns: An array containing the parsed MIME header. + +This static function parses a single MIME header into its component pieces. The first piece's key is an empty string "". The rest are split up by key-value pairs. This function is called by `MIMEParser::Parse()` and `MIMEParser::ExtractContent()`. + +MIMEParser::Parse($data, $depth = 0) +------------------------------------ + +Access: public static + +Parameters: + +* $data - A string containing the MIME data to parse. +* $depth - An internal integer to control recursive call depth (Default is 0). Do not use. + +Returns: An array containing the parsed MIME data. + +This static function parses MIME data into headers, body, and sub-MIME components. It recursively calls itself up to a depth of 10 to parse most MIME content. Do not use the `$depth` parameter when calling this function (second parameter). + +This function is typically used to parse an e-mail message retrieved from a POP3 server. This function can also handle non-MIME e-mail content. + +MIMEParser::ExtractContent($message, $depth = 0) +------------------------------------------------ + +Access: public static + +Parameters: + +* $message - An array from `MIMEParser::Parse()`. +* $depth - An internal integer to control recursive call depth (Default is 0). Do not use. + +This function takes the output from `MIMEParser::Parse()` and extracts "text/plain" and "text/html" components from the message. It recursively calls itself up to a depth of 10 to parse the content. Do not use the `$depth` parameter when calling this function (second parameter). + +This function is typically used to extract just the text and HTML components of a MIME message that have been parsed by `MIMEParser::Parse()`. + +MIMEParser::ReplaceNewlines($replacewith, $data) +------------------------------------------------ + +Access: private static + +Parameters: + +* $replacewith - A string to replace newlines with. +* $data - A string to replace newlines in. + +Returns: A string with newlines replaced. + +This static function replaces any newline combination within the input data with the target newline. All known (DOS, Mac, *NIX) and unknown newline combinations are handled to normalize on the replacement newline string. diff --git a/docs/pop3.md b/docs/pop3.md new file mode 100644 index 0000000..b71f04a --- /dev/null +++ b/docs/pop3.md @@ -0,0 +1,305 @@ +POP3 Class: 'support/pop3.php' +=============================== + +The POP3 class provides routines to communicate with a POP3 server. These function are useful on servers that are configured to require "POP before SMTP" to send e-mail. They can also be used for automation of a script that watches a mailbox for incoming messages and then processes the incoming e-mail as it arrives. + +Example usage of POP before SMTP: + +```php +Your message goes here"; + + // Send the e-mail to the user. + // Change the stuff in '[]' to your server settings. + $smtpoptions = array( + "headers" => SMTP::GetUserAgent("Thunderbird"), + "htmlmessage" => $body, + "textmessage" => SMTP::ConvertHTMLToText($body), + "server" => "[smtp.yourhost.com]", + "port" => [25 or 465], + "secure" => [true or false], + "username" => "[YOUR e-mail username]", + "password" => "[YOUR e-mail password]" + ); + + $pop3options = array( + "server" => "[pop3.yourhost.com]", + "port" => [110 or 995], + "secure" => [true or false] + ); + + $fromaddr = "[YOUR e-mail address]"; + $subject = "Thanks for signing up!"; + $result = SMTP::SendEmail($fromaddr, $toaddr, $subject, $smtpoptions); + if (!$result["success"]) + { + // This is usually the correct thing + // to do to implement POP-before-SMTP. + if ($smtpoptions["username"] != "" && $smtpoptions["password"] != "") + { + $pop3 = new POP3; + $result = $pop3->Connect($smtpoptions["username"], $smtpoptions["password"], $pop3options); + if ($result["success"]) + { + $pop3->Disconnect(); + + $result = SMTP::SendEmail($fromaddr, $toaddr, $subject, $smtpoptions); + } + } + + if (!$result["success"]) + { + echo "Failed to send e-mail.\n"; + + exit(); + } + } +?> +``` + +Example usage of automation: + +```php + "[pop3.yourhost.com]", + "port" => [110 or 995], + "secure" => [true or false] + ); + + $pop3 = new POP3(); + $result = $pop3->Connect("[YOUR e-mail username]", "[YOUR e-mail password]", $pop3options); + if (!$result["success"]) + { + echo "POP3 - Connect(): " . $result["error"] . "\n"; + + exit(); + } + + $result = $pop3->GetMessageList(); + if (!$result["success"]) + { + echo "POP3 - GetMessageList(): " . $result["error"] . "\n"; + + exit(); + } + + $ids = $result["ids"]; + foreach ($ids as $id => $size) + { + // Only retrieve messages under 1MB. + if ($size < 1024768) + { + $result = $pop3->GetNextMessage($id); + if (!$result["success"]) + { + echo "POP3 - GetNextMessage(): " . $result["error"] . "\n"; + + exit(); + } + + $message = $result["message"]; + + // Process the message. + $message = MIMEParser::Parse($result["message"]); +var_dump($message); + + $content = MIMEParser::ExtractContent($message); +var_dump($content); + } + +// $result = $pop3->DeleteMessage($id); +// if (!$result["success"]) +// { +// echo "POP3 - DeleteMessage(): " . $result["error"] . "\n"; +// +// exit(); +// } + } + + $pop3->Disconnect(); +?> +``` + +POP3::__construct() +------------------- + +Access: public + +Parameters: None. + +Returns: Nothing. + +This function initializes the class. + +POP3::GetSSLCiphers($type = "intermediate") +------------------------------------------- + +Access: public static + +Parameters: + +* $type - A string containing one of "modern", "intermediate", or "old" (Default is "intermediate"). + +Returns: A string containing the SSL cipher list to use. + +This static function returns SSL cipher lists extracted from the [Mozilla SSL configuration generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/). + +POP3::GetSafeSSLOpts($cafile = true, $cipherstype = "intermediate") +------------------------------------------------------------------- + +Access: public static + +Parameters: + +* $cafile - A boolean that indicates whether or not to use the internally defined CA file list or a string containing the full path and filename of a CA root certificate file (Default is true). +* $cipherstype - A string containing one of "modern", "intermediate", or "old" (Default is "intermediate"). See GetSSLCiphers() above. + +Returns: An array of SSL context options. + +This static function is used to generate a default "sslopts" array if they are not provided when connecting to an associated secure POP3 server. + +POP3::ProcessSSLOptions(&$options, $key, $host) +----------------------------------------------- + +Access: private static + +Parameters: + +* $options - An array of options. +* $key - A string specifying which SSL options to process. +* $host - A string containing alternate hostname information. + +Returns: Nothing. + +This internal static function processes the "auto_cainfo", "auto_cn_match", and "auto_sni" options for "sslopts" for SSL/TLS context purposes. + +POP3::Connect($username, $password, $options = array()) +------------------------------------------------------- + +Access: public + +Parameters: + +* $username - A string containing the username to use. +* $password - A string containing the password to use. +* $options - An array of options containing connection and class information (Default is array()). + +Returns: A standard array of information. + +This function connects to a POP3 server using the specified username and password. + +The `$options` array can contain: + +* server - A string containing the POP3 server to connect to (Default is "localhost"). +* secure - A boolean that determines whether or not to connect using SSL (Default is false). +* protocol - A string containing the preferred low-level protocol. May be any supported protocol that the PHP stream_get_transports() function supports (e.g. "ssl", "tls", "tlsv1.2", "tcp"). +* port - An integer that specifies which port to connect to (Default is 110 when 'secure' is false, 995 when 'secure' is true). +* connecttimeout - An integer containing the amount of time to wait for the connection to the host to succeed in seconds (Default is 10). +* sslopts - An array of valid SSL context options key-value pairs to use when connection to a SSL-enabled host. Also supports "auto_cainfo", "auto_cn_match", and "auto_sni" options to define several context options automatically. +* debug - A boolean that specifies that every function in the class will return the raw POP3 conversation. +* debug_callback - A string containing a function name of a debugging callback. The callback function must accept three parameters - callback($type, $data, $opts). +* debug_callback_opts - Data to pass as the third parameter to the function specified by the 'debug_callback' option. + +While the `$options` array is optional, the best approach is to be as specific as possible. + +POP3::GetMessageList() +---------------------- + +Access: public + +Parameters: None. + +Returns: A standard array of information. + +This function retrieves the list of message IDs and message sizes on the server. This information is returned in key-value ID and size pairs. + +POP3::GetMessage($id) +--------------------- + +Access: public + +Parameters: + +* $id - An integer containing a valid message ID on the server. + +Returns: A standard array of information. + +Retrieves a single message from the POP3 server that matches the specified message ID. Message IDs are retrieved with `POP3::GetMessageList()`. + +The message is typically processed with the `MIMEParser::Parse()` function and then text and HTML components are further extracted with the `MIMEParser::ExtractContent()` function. + +POP3::DeleteMessage($id) +------------------------ + +Access: public + +Parameters: + +* $id - An integer containing a valid message ID on the server. + +Returns: A standard array of information. + +This function deletes a single message from a POP3 server based on the message ID. Message IDs are retrieved with `POP3::GetMessageList()`. + +POP3::Disconnect() +------------------ + +Access: public + +Parameters: None. + +Returns: A boolean of true if the instance was successfully disconnected from the POP3 server, false otherwise. + +This function disconnects from a POP3 server and performs cleanup for a potential future connection with the same instance. + +POP3::POP3Request($command, &$rawsend, &$rawrecv, $multiline = false) +--------------------------------------------------------------------- + +Access: public + +Parameters: + +* $command - A string containing the POP3 command to send. +* $rawsend - A string to append debugging information to. +* $rawrecv - A string to append debugging information to. +* $multiline - A boolean that indicates that the response is expected to be multiline. + +Returns: A standard array of information. + +This internal function sends a command to the POP3 server and retrieves the response. Drastically simplifies and improves maintainability of the class. + +POP3::GetPOP3Response($multiline) +--------------------------------- + +Access: public + +Parameters: + +* $multiline - A boolean indicating that the caller is expecting the POP3 server to respond with a multiline response. + +Returns: A standard array of information. + +This internal function retrieves a response from a POP3 server. + +POP3::POP3_Translate($format, ...) +---------------------------------- + +Access: _internal_ static + +Parameters: + +* $format - A string containing valid sprintf() format specifiers. + +Returns: A string containing a translation. + +This internal static function takes input strings and translates them from English to some other language if CS_TRANSLATE_FUNC is defined to be a valid PHP function name. diff --git a/docs/smtp.md b/docs/smtp.md new file mode 100644 index 0000000..1b2fb42 --- /dev/null +++ b/docs/smtp.md @@ -0,0 +1,640 @@ +SMTP Class: 'support/smtp.php' +=============================== + +The SMTP class mail sending functionality and e-mail address correction routines. The mail sending functions directly connect to a SMTP/ESMTP server (or use mail()) to send an e-mail and offer more functionality and flexibility than the built-in PHP mail() function. + +I'm not responsible with what you choose to do with these functions. These are incredibly powerful PHP routines that go far beyond what PHP mail() calls typically do. It is easy to create e-mails that look exactly like they came from a real e-mail client and will tend to get through spam filters. + +Due to spam proliferation across the Internet and the fact that each mail server is set up uniquely makes it nearly impossible to diagnose problems with these functions and YOUR mail server. Note that the included test suite in the Ultimate E-mail Toolkit may help with diagnosing mail sending issues. Other than that, you are on your own and, in the event of problems, you should contact your web/e-mail hosting provider. These functions are a good place to start though and offer significantly more functionality than anything you'll likely need. + +Full MIME, Quoted Printable, and binary transfer support. + +Example e-mail address validation: + +```php + +``` + +Example usage: + +```php +Your message goes here"; + + // Send the e-mail to the user. + // Change the stuff in '[]' to your server settings. + $smtpoptions = array( + "headers" => SMTP::GetUserAgent("Thunderbird"), + "htmlmessage" => $body, + "textmessage" => SMTP::ConvertHTMLToText($body), + "server" => "[smtp.yourhost.com]", + "port" => [25 or 465], + "secure" => [true or false], + "username" => "[YOUR e-mail username]", + "password" => "[YOUR e-mail password]" + ); + + $pop3options = array( + "server" => "[pop3.yourhost.com]", + "port" => [110 or 995], + "secure" => [true or false] + ); + + $fromaddr = "[YOUR e-mail address]"; + $subject = "Thanks for signing up!"; + $result = SMTP::SendEmail($fromaddr, $toaddr, $subject, $smtpoptions); + if (!$result["success"]) + { + // This is usually the correct thing + // to do to implement POP-before-SMTP. + if ($smtpoptions["username"] != "" && $smtpoptions["password"] != "") + { + $pop3 = new POP3; + $result = $pop3->Connect($smtpoptions["username"], $smtpoptions["password"], $pop3options); + if ($result["success"]) + { + $pop3->Disconnect(); + + $result = SMTP::SendEmail($fromaddr, $toaddr, $subject, $smtpoptions); + } + } + + if (!$result["success"]) + { + echo "Failed to send e-mail.\n"; + + exit(); + } + } +?> +``` + +SMTP::ConvertToRFC1341($data, $restrictmore = false) +---------------------------------------------------- + +Access: public static + +Parameters: + +* $data - A string containing the data to convert to RFC1341. +* $restrictmore - A boolean that imposes additional character restrictions for EBCDIC transport (Default is false). + +Returns: A string containing the converted data. + +This static function takes an input string of data and converts it into a RFC1341-compliant string. RFC1341 is a hacky workaround to allow 8-bit data to be transmitted cleanly over 7-bit transports (SMTP is a 7-bit transport) in the body of a message. Also known as Quoted Printable. Typically used for e-mail in Latin-based languages (e.g. U.S. English). + +SMTP::ConvertEmailMessageToRFC1341($data, $restrictmore = false) +---------------------------------------------------------------- + +Access: public static + +Parameters: + +* $data - A string containing the data to convert to RFC1341. +* $restrictmore - A boolean that imposes additional character restrictions for EBCDIC transport (Default is false). + +Returns: A string containing the converted data. + +This static function takes an input string of data, converts newlines, and then converts the data into a RFC1341-compliant string. See `SMTP::ConvertToRFC1341()` for details. + +SMTP::ConvertToRFC1342($data, $lang = "UTF-8", $encodeb64 = true) +----------------------------------------------------------------- + +Access: public static + +Parameters: + +* $data - A string containing the data to convert to RFC1342. +* $lang - A string containing a valid character set (Default is "UTF-8"). +* $encodeb64 - A boolean that encodes the output as Base64 (Default is true). + +Returns: A string containing the converted data. + +This static function takes an input string and converts it into a RFC1342-compliant string. RFC1342 is a hacky workaround to allow 8-bit data to be transmitted cleanly over 7-bit transports in an e-mail header. Used primarily to encode the name portion of an e-mail address. + +By default Base64 encoding is used but Quoted Printable can be used: `$encodeb64` can be set to false when `$lang` is "ISO-8859-1" or "US-ASCII". + +SMTP::MakeValidEmailAddress($email, $options = array()) +------------------------------------------------------- + +Access: public static + +Parameters: + +* $email - A string containing an e-mail address to clean up. +* $options - An array containing options that affect the final output (Default is array()). + +Returns: An array containing whether or not conversion was successful, the cleaned up e-mail address, and whether or not the domain passes DNS checks. + +This static function takes an input e-mail address of the form 'local@domain', parses it one character at a time using a state engine, cleans it up of common mistakes, and validates that the resulting domain is valid. For example, "someone@hotmail,com" would become "someone@hotmail.com". This function allows all non-obsolete address formats. + +This function is not a validation routine but it can be used as such. If it successfully completes, just check the resulting e-mail address ('email') for a match with the original. If they match exactly, then the original is valid. This function, however, is much more desirable for its repairing capabilities. It becomes possible to use AJAX to send a query to the server to determine if the address is valid. Instead of saying, "Invalid e-mail address" to the user, it could say, "Did you mean ...?" with the corrected e-mail address. + +The `$options` array can contain the following options: + +* usedns - A boolean that specifies if the function should check for MX and A DNS records for the domain (Default is true). +* nameservers - An array containing IP addresses of DNS servers to use in order of preference (Default is Google DNS). + +Checking for the existence of a SMTP mail server via DNS is a great way to avoid bounced e-mail. DNS checking is done with a slightly modified PEAR::Net_DNS library, which is more versatile than the built-in PHP functions that aren't always available for all platforms. + +E-mail validation/clean up is hard. As of this writing, Dominic Sayers has a decent test suite. This function passes most tests with flying colors - everything except obsolete address formats - and even passes most of the tests that are supposed to "fail" because of the repairing capabilities, which only a state engine could accomplish. + +SMTP::UpdateDNSTTLCache() +------------------------- + +Access: public static + +Parameters: None. + +Returns: Nothing. + +This static function updates the static DNS cache that this class uses for resolving identical domains by removing outdated cache entries (Time-To-Live has expired). + +SMTP::GetDNSRecord($domain, $types, $nameservers, $cache = true) +---------------------------------------------------------------- + +Access: public static + +Parameters: + +* $domain - A string containing a domain name. +* $types - An array of strings containing the DNS record types to look up (Default is array("MX", "A")). +* $nameservers - An array of strings containing the IP addresses of DNS servers to use as resolvers (Default is array("8.8.8.8", "8.8.4.4") - Google DNS). +* $cache - A boolean indicating that the TTL of the domain is to be cached in the SMTP DNS TTL cache (Default is true). + +Returns: A standard array of information. + +This static function retrieves DNS record information for a specific domain and then optionally caches the results to avoid future DNS requests. + +SMTP::EmailAddressesToNamesAndEmail(&$destnames, &$destaddrs, $emailaddrs, $removenames = false, $options = array()) +-------------------------------------------------------------------------------------------------------------------- + +Access: public static + +Parameters: + +* $destnames - An array that receives the names processed. +* $destaddrs - An array that receives e-mail addresses processed. +* $emailaddrs - A string containing names and e-mail addresses to filter and separate. +* $removenames - A boolean that returns no names for $destnames (Default is false). +* $options - An array to pass to `SMTP::MakeValidEmailAddress()` (Default is array()). + +Returns: A boolean of true if at least one valid e-mail address was successfully processed, false otherwise. + +This static function takes a string of '"name" ', 'name ', or 'emailaddr' and extracts each component. Multiple e-mail addresses can be separated with commas (',') [preferred] or semi-colons (';'). + +This function attempts to deal with malformed strings as best as possible but there are limits as to what it can do. `SMTP::MakeValidEmailAddress()` is called for each e-mail address to check its validity. + +SMTP::EmailAddressesToEmailHeaders($emailaddrs, $headername, $multiple = true, $removenames = false, $options = array()) +------------------------------------------------------------------------------------------------------------------------ + +Access: public static + +Parameters: + +* $emailaddrs - A string containing names and e-mail addresses to process. +* $headername - A string containing the header name. +* $multiple - A boolean that allows multiple e-mail addresses in the header (Default is true). +* $removenames - A boolean that will not include names (Default is false). +* $options - An array to pass to MakeValidEmailAddress() (Default is array()). + +Returns: A string containing an e-mail header if the e-mail addresses were successfully processed, an empty string otherwise. + +This static function generates a valid mail header from one or more e-mail addresses. If `$headername` is an empty string, e-mail addresses will be returned without a header name. + +SMTP::GetUserAgent($type) +------------------------- + +Access: public static + +Parameters: + +* $type - A string containing one of "Thunderbird", "Thunderbird2", "OutlookExpress", "Exchange", or "OfficeOutlook". + +Returns: A string containing a valid user agent for the specified e-mail client. + +This static function returns a popular user agent string. These aren't always up-to-date but are usually good enough to get the job done on servers that require a user agent and helps to get past most spam filters. If you feel a string is too out of date, post a message to the forums. + +SMTP::GetTimeLeft($start, $limit) +--------------------------------- + +Access: _internal_ static + +Parameters: + +* $start - A numeric value containing a UNIX timestamp of a start time. +* $limit - A boolean of false or a numeric value containing the maximum amount of time, in seconds, to take from $start. + +Returns: A boolean of false if $limit is false, 0 if the time limit has been reached/exceeded, or a numeric value representing the amount of time left in seconds. + +This internal static function is used to calculate whether an operation has taken too long and then terminate the connection. + +SMTP::ProcessRateLimit($size, $start, $limit, $async) +----------------------------------------------------- + +Access: private static + +Parameters: + +* $size - An integer containing the number of bytes transferred. +* $start - A numeric value containing a UNIX timestamp of a start time. +* $limit - An integer representing the maximum acceptable rate in bytes/sec. +* $async - A boolean indicating whether or not the function should not sleep (async caller). + +Returns: An integer containing the amount of time to wait for (async only), -1 otherwise. + +This internal static function calculates the current rate at which bytes are being transferred over the network. If the rate exceeds the limit, it calculates exactly how long to wait and then sleeps for that amount of time so that the average transfer rate is within the limit. + +SMTP::StreamTimedOut($fp) +------------------------- + +Access: private static + +Parameters: + +* $fp - A valid socket handle. + +Returns: A boolean of true if the underlying socket has timed out, false otherwise. + +This internal static function calls `stream_get_meta_data()` to determine the validity of the socket. + +SMTP::ProcessState__ReadLine(&$state) +------------------------------------- + +Access: private static + +Parameters: + +* $state - A valid SMTP state array. + +Returns: A standard array of information. + +This internal static function attempts to read in a single line of information and return to the caller. + +SMTP::ProcessState__WriteData(&$state) +-------------------------------------- + +Access: private static + +Parameters: + +* $state - A valid SMTP state array. + +Returns: A standard array of information. + +This internal static function attempts to write waiting data out to the socket. + +SMTP::ForceClose(&$state) +------------------------- + +Access: _internal_ static + +Parameters: + +* $state - A valid SMTP state array. + +Returns: Nothing. + +This internal static function forces closes the underlying socket. Any future attempts to use the socket will fail. + +SMTP::CleanupErrorState(&$state, $result) +----------------------------------------- + +Access: private static + +Parameters: + +* $state - A valid SMTP state array. +* $result - A standard array of information. + +Returns: $result unmodified. + +This internal static function looks at an error condition on a socket to determine if the socket should be closed immediately or not. When the state of the socket is in 'async' (non-blocking) mode, the "no_data" error code will be returned quite frequently due to the non-blocking nature of those sockets. + +SMTP::InitSMTPRequest(&$state, $command, $expectedcode, $nextstate, $expectederror) +----------------------------------------------------------------------------------- + +Access: private static + +Parameters: + +* $state - A valid SMTP state array. +* $command - A string containing the command to send to the SMTP server. +* $expectedcode - An integer containing the expected SMTP response code from the server. +* $nextstate - A string containing the state to move to once the server responds with the expected code. +* $expectederror - A string containing error message details to use if the expected code is not returned from the server. + +Returns: Nothing. + +This internal static function sets the internal SMTP state array to prepare for a new request to the server as part of the ongoing communication process. + +SMTP::WantRead(&$state) +----------------------- + +Access: _internal_ static + +Parameters: + +* $state - A valid SMTP state array. + +Returns: A boolean of true if the underlying socket is waiting to read data, false otherwise. + +This internal static function is used to identify if the underlying socket in this state should be used in the read array of a stream_select() call (or equivalent) when the socket is in 'async' (non-blocking) mode. + +SMTP::WantWrite(&$state) +------------------------ + +Access: _internal_ static + +Parameters: + +* $state - A valid SMTP state array. + +Returns: A boolean of true if the underlying socket is waiting to write data, false otherwise. + +This internal static function is used to identify if the underlying socket in this state should be used in the write array of a stream_select() call (or equivalent) when the socket is in 'async' (non-blocking) mode. + +SMTP::ProcessState(&$state) +--------------------------- + +Access: public static + +Parameters: + +* $state - A valid SMTP state array. + +Returns: A standard array of information. + +This internal-ish static function runs the core state engine behind the scenes against the input state. This is the primary workhorse of the SMTP network communication routines. It supports running input states in client mode only. + +SMTP::SMTP_RandomHexString($length) +----------------------------------- + +Access: private static + +Parameters: + +* $length - An integer containing the length of the string to create. + +Returns: A randomly generated string containing hexadecimal letters and numbers (0-9, A-F). + +An internal static function to generate a unique string for the 'Message-ID' portion of an e-mail. + +SMTP::GetSSLCiphers($type = "intermediate") +------------------------------------------- + +Access: public static + +Parameters: + +* $type - A string containing one of "modern", "intermediate", or "old" (Default is "intermediate"). + +Returns: A string containing the SSL cipher list to use. + +This static function returns SSL cipher lists extracted from the [Mozilla SSL configuration generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/). + +SMTP::GetSafeSSLOpts($cafile = true, $cipherstype = "intermediate") +------------------------------------------------------------------- + +Access: public static + +Parameters: + +* $cafile - A boolean that indicates whether or not to use the internally defined CA file list or a string containing the full path and filename of a CA root certificate file (Default is true). +* $cipherstype - A string containing one of "modern", "intermediate", or "old" (Default is "intermediate"). See GetSSLCiphers() above. + +Returns: An array of SSL context options. + +This static function is used to generate a default "sslopts" array if they are not provided when connecting to an associated secure POP3 server. + +SMTP::ProcessSSLOptions(&$options, $key, $host) +----------------------------------------------- + +Access: private static + +Parameters: + +* $options - An array of options. +* $key - A string specifying which SSL options to process. +* $host - A string containing alternate hostname information. + +Returns: Nothing. + +This internal static function processes the "auto_cainfo", "auto_cn_match", and "auto_sni" options for "sslopts" for SSL/TLS context purposes. + +SMTP::SendSMTPEmail($toaddr, $fromaddr, $message, $options = array()) +--------------------------------------------------------------------- + +Access: public static + +Parameters: + +* $toaddr - A string containing one or more e-mail addresses to send to. +* $fromaddr - A string containing the e-mail address this is from. +* $message - A string containing the message to send. +* $options - An array containing various options (Default is array()). + +Returns: A standard array of information. + +This static function sends an e-mail message by directly connecting to a SMTP server. + +The `$options` array can contain all the `$options` for `SMTP::MakeValidEmailAddress()` plus: + +* server - A string containing the SMTP server to connect to (Default is "localhost"). +* port - An integer containing the SMTP port to connect to (Default is 25). +* protocol - A string containing the preferred low-level protocol. May be any supported protocol that the PHP stream_get_transports() function supports (e.g. "ssl", "tls", "tlsv1.2", "tcp"). +* username - A string containing the username to log in to the SMTP server with (Default is ""). +* password - A string containing the password to log in to the SMTP server with (Default is ""). +* connecttimeout - An integer containing the amount of time to wait for the connection to the host to succeed in seconds (Default is 10). +* sslopts - An array of valid SSL context options key-value pairs to use when connection to a SSL-enabled host. Also supports "auto_cainfo", "auto_cn_match", and "auto_sni" options to define several context options automatically. +* debug - A boolean that determines whether or not the raw SMTP conversation will be returned (Default is false). +* debug_callback - A string containing a function name of a debugging callback. The callback function must accept three parameters - callback($type, $data, $opts). +* debug_callback_opts - Data to pass as the third parameter to the function specified by the 'debug_callback' option. +* hostname - A string containing the hostname to send with the HELO/EHLO command (Default is the server's IP address). + +Some SMTP servers may use the HELO/EHLO 'hostname' option for blocking incoming messages via SPF records. + +While it might seem to make sense to connect to the target SMTP server (the "To" address), that isn't how e-mail works. The source SMTP server (the "From" address) is the correct server to connect to. On many web hosts, the mail server is "localhost" but not always. + +Some popular web hosts will block SMTP requests made with this function. PHP mail() also tends to not work on such hosts. The host isn't usually specifically blocking sending e-mail via the web server but rather generally blocking until a POP3 login occurs for the same "From" address. This is known as POP before SMTP. To successfully send e-mail in this situation, you should attempt to send an e-mail and, if it fails, then use the POP3 functions to connect to the mail server. Once the POP3 login is successful, attempt to send the same message again over SMTP. If the message is still blocked, then something else is the problem. + +SMTP::ConvertHTMLToText_TagCallback($stack, &$content, $open, $tagname, &$attrs, $options) +------------------------------------------------------------------------------------------ + +Access: _internal_ static + +Parameters: Standard TagFilterStream 'tag_callback' parameters. + +Returns: array("keep_tag" => false, "keep_interior" => false). + +This internal static function is a standard TagFilterStream 'tag_callback' callback that processes the input tag as `SMTP::ConvertHTMLToText()` converts the HTML to (mostly) visually-pleasing plain text. + +SMTP::ConvertHTMLToText_ContentCallback($stack, $result, &$content, $options) +----------------------------------------------------------------------------- + +Access: _internal_ static + +Parameters: Standard TagFilterStream 'content_callback' parameters. + +Returns: Nothing. + +This internal static function is a standard TagFilterStream 'content_callback' that processes incoming content as `SMTP::ConvertHTMLToText()` converts the HTML to (mostly) visually-pleasing plain text. + +SMTP::ConvertHTMLToText($data) +------------------------------ + +Access: public static + +Parameters: + +* $data - A string containing a HTML document to convert to text. + +Returns: A string containing the formatted text version of the HTML. + +This static function is intended to be used to generate a text version of a HTML document for sending via e-mail but is versatile enough for most other purposes. The function attempts to create a visually appealing version of the text found within the HTML suitable for sending in an e-mail. + +SMTP::MIME_RandomString($length) +-------------------------------- + +Access: private static + +Parameters: + +* $length - An integer containing the target length of the string. + +Returns: A string containing alphanumeric characters suitable for MIME encoding. + +An internal static function to generate MIME headers for e-mails. Note that the output of this function is not actually random. + +SMTP::SendEmailAsync__Handler($mode, &$data, $key, &$info) +---------------------------------------------------------- + +Access: _internal_ static + +Parameters: + +* $mode - A string representing the mode/state to process. +* $data - Mixed content the depends entirely on the $mode. +* $key - A string representing the key associated with an object. +* $info - The information associated with the key. + +Returns: Nothing. + +This internal static callback function is the internal handler for MultiAsyncHandler for the `SMTP::SendEmailAsync()` function. + +SMTP::SendEmailAsync($helper, $key, $callback, $fromaddr, $toaddr, $subject, $options = array()) +------------------------------------------------------------------------------------------------ + +Access: public static + +Parameters: + +* $helper - A MultiAsyncHelper instance. +* $key - A string containing a key to uniquely identify this WebBrowser instance. +* $callback - An optional callback function to receive regular status updates on the request (specify NULL if not needed). The callback function must accept three parameters - callback($key, $url, $result). +* $fromaddr - A string containing the 'From' e-mail address. +* $toaddr - A string containing one or more 'To' e-mail addresses. +* $subject - A string containing the subject of the e-mail. +* $options - An array containing various options for the e-mail. + +Returns: A standard array of information. + +This static function queues the request with the MultiAsyncHandler instance ($helper) for later async/non-blocking processing of the request. Note that this function always succeeds since request failure can't be detected until after processing begins. + +See MultiAsyncHelper for example usage. + +See `SMTP::SendEmail()` for details on the `$options` array. + +SMTP::SendEmail($fromaddr, $toaddr, $subject, $options = array()) +----------------------------------------------------------------- + +Access: public static + +Parameters: + +* $fromaddr - A string containing the 'From' e-mail address. +* $toaddr - A string containing one or more 'To' e-mail addresses. +* $subject - A string containing the subject of the e-mail. +* $options - An array containing various options for the e-mail. + +Returns: An array of processed information, the result of the PHP `mail()` command, or the result of `SMTP::SendSMTPEmail()` depending on the various `$options`. The default behavior is to return the result of `SMTP::SendSMTPEmail()`. + +This static function sends an e-mail message or returns processed data intended to be sent via e-mail. In terms of capabilities, this function does it all: E-mail address validation and cleanup, DNS checking, direct SMTP server communication, plain-text and HTML e-mails, MIME, attachments, etc. It does its best to act like an actual e-mail client. + +The `$options` array can contain all the `$options` for `SMTP::SendSMTPEmail()` plus: + +* replytoaddr - A string containing an e-mail address to use as the 'Reply-To' address (Default is ""). +* ccaddr - A string containing one or more 'CC' e-mail addresses (Default is ""). +* bccaddr - A string containing one or more 'BCC' e-mail addresses (Default is ""). +* headers - A string containing additional e-mail headers. Usually just the result of a call to GetEmailUserAgent() (Default is ""). +* textmessage - A string containing the text version of the message (Default is ""). +* htmlmessage - A string containing the HTML version of the message (Default is ""). +* attachments - An array containing information about zero or more attachments (Default is array()). +* usemail - A boolean that calls the built-in PHP mail() function instead of SendSMTPMail() (Default is false). +* returnresults - A boolean that causes the function to return an array of processed information instead of sending an e-mail (Default is false). + +The optional 'attachments' array can contain a number of different options: + +* type - A string containing the MIME 'Content-Type' of the attachment. Required for each attachment. +* name - A string containing the filename of the attachment. +* location - A string containing a URL contained within the HTML portion of the e-mail. Do not use 'name'. +* cid - A string containing a 'Content-ID' contained within the HTML portion of the e-mail. Do not use 'name'. +* data - A string containing the binary data to attach. + +When specifying an attachment that someone can open, only use 'name'. For inline attachments, such as embedded images, do not use 'name' but use either 'location' or 'cid' instead (avoid using both). Inline images are generally not blocked by e-mail clients. For most web developers who want to use inline images, 'location' is probably the easiest to use but 'cid' is more likely to get through spam filters since that is what most e-mail clients use. + +SMTP::FilenameSafe($filename) +----------------------------- + +Access: private static + +Parameters: + +* $filename - A string containing a filename. + +Returns: A string containing a safe filename prefix. + +This internal static function allows the characters A-Z, a-z, 0-9, '_' (underscore), '.' (period), and '-' (hyphen) through. All other characters are converted to hyphens. Multiple hyphens in a row are converted to one hyphen. So a filename like `index@$%*&^$+hacked?12.php` becomes `index-hacked-12.php`. + +Note that this function still allows file extensions through. You should always add your own file extension when calling this function. + +SMTP::ReplaceNewlines($replacewith, $data) +------------------------------------------ + +Access: private static + +Parameters: + +* $replacewith - A string to replace newlines with. +* $data - A string to replace newlines in. + +Returns: A string with newlines replaced. + +This static function replaces any newline combination within the input data with the target newline. All known (DOS, Mac, *NIX) and unknown newline combinations are handled to normalize on the replacement newline string. + +SMTP::SMTP_Translate($format, ...) +---------------------------------- + +Access: _internal_ static + +Parameters: + +* $format - A string containing valid sprintf() format specifiers. + +Returns: A string containing a translation. + +This internal static function takes input strings and translates them from English to some other language if CS_TRANSLATE_FUNC is defined to be a valid PHP function name.