48 * The SMTP port to use if one is not specified. |
48 * The SMTP port to use if one is not specified. |
49 * |
49 * |
50 * @var int |
50 * @var int |
51 */ |
51 */ |
52 const DEFAULT_PORT = 25; |
52 const DEFAULT_PORT = 25; |
|
53 |
|
54 /** |
|
55 * The SMTPs port to use if one is not specified. |
|
56 * |
|
57 * @var int |
|
58 */ |
|
59 const DEFAULT_SECURE_PORT = 465; |
53 |
60 |
54 /** |
61 /** |
55 * The maximum line length allowed by RFC 5321 section 4.5.3.1.6, |
62 * The maximum line length allowed by RFC 5321 section 4.5.3.1.6, |
56 * *excluding* a trailing CRLF break. |
63 * *excluding* a trailing CRLF break. |
57 * |
64 * |
185 'Microsoft_ESMTP' => '/[0-9]{3} 2.[\d].0 (.*)@(?:.*) Queued mail for delivery/', |
192 'Microsoft_ESMTP' => '/[0-9]{3} 2.[\d].0 (.*)@(?:.*) Queued mail for delivery/', |
186 'Amazon_SES' => '/[\d]{3} Ok (.*)/', |
193 'Amazon_SES' => '/[\d]{3} Ok (.*)/', |
187 'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', |
194 'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', |
188 'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/', |
195 'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/', |
189 'Haraka' => '/[\d]{3} Message Queued \((.*)\)/', |
196 'Haraka' => '/[\d]{3} Message Queued \((.*)\)/', |
|
197 'ZoneMTA' => '/[\d]{3} Message queued as (.*)/', |
190 'Mailjet' => '/[\d]{3} OK queued as (.*)/', |
198 'Mailjet' => '/[\d]{3} OK queued as (.*)/', |
|
199 ]; |
|
200 |
|
201 /** |
|
202 * Allowed SMTP XCLIENT attributes. |
|
203 * Must be allowed by the SMTP server. EHLO response is not checked. |
|
204 * |
|
205 * @see https://www.postfix.org/XCLIENT_README.html |
|
206 * |
|
207 * @var array |
|
208 */ |
|
209 public static $xclient_allowed_attributes = [ |
|
210 'NAME', 'ADDR', 'PORT', 'PROTO', 'HELO', 'LOGIN', 'DESTADDR', 'DESTPORT' |
191 ]; |
211 ]; |
192 |
212 |
193 /** |
213 /** |
194 * The last transaction ID issued in response to a DATA command, |
214 * The last transaction ID issued in response to a DATA command, |
195 * if one was detected. |
215 * if one was detected. |
680 * |
700 * |
681 * @see quit() |
701 * @see quit() |
682 */ |
702 */ |
683 public function close() |
703 public function close() |
684 { |
704 { |
685 $this->setError(''); |
|
686 $this->server_caps = null; |
705 $this->server_caps = null; |
687 $this->helo_rply = null; |
706 $this->helo_rply = null; |
688 if (is_resource($this->smtp_conn)) { |
707 if (is_resource($this->smtp_conn)) { |
689 //Close the connection and cleanup |
708 //Close the connection and cleanup |
690 fclose($this->smtp_conn); |
709 fclose($this->smtp_conn); |
695 |
714 |
696 /** |
715 /** |
697 * Send an SMTP DATA command. |
716 * Send an SMTP DATA command. |
698 * Issues a data command and sends the msg_data to the server, |
717 * Issues a data command and sends the msg_data to the server, |
699 * finalizing the mail transaction. $msg_data is the message |
718 * finalizing the mail transaction. $msg_data is the message |
700 * that is to be send with the headers. Each header needs to be |
719 * that is to be sent with the headers. Each header needs to be |
701 * on a single line followed by a <CRLF> with the message headers |
720 * on a single line followed by a <CRLF> with the message headers |
702 * and the message body being separated by an additional <CRLF>. |
721 * and the message body being separated by an additional <CRLF>. |
703 * Implements RFC 821: DATA <CRLF>. |
722 * Implements RFC 821: DATA <CRLF>. |
704 * |
723 * |
705 * @param string $msg_data Message data to send |
724 * @param string $msg_data Message data to send |
723 |
742 |
724 //Normalize line breaks before exploding |
743 //Normalize line breaks before exploding |
725 $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); |
744 $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); |
726 |
745 |
727 /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field |
746 /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field |
728 * of the first line (':' separated) does not contain a space then it _should_ be a header and we will |
747 * of the first line (':' separated) does not contain a space then it _should_ be a header, and we will |
729 * process all lines before a blank line as headers. |
748 * process all lines before a blank line as headers. |
730 */ |
749 */ |
731 |
750 |
732 $field = substr($lines[0], 0, strpos($lines[0], ':')); |
751 $field = substr($lines[0], 0, strpos($lines[0], ':')); |
733 $in_headers = false; |
752 $in_headers = false; |
963 [250, 251] |
982 [250, 251] |
964 ); |
983 ); |
965 } |
984 } |
966 |
985 |
967 /** |
986 /** |
|
987 * Send SMTP XCLIENT command to server and check its return code. |
|
988 * |
|
989 * @return bool True on success |
|
990 */ |
|
991 public function xclient(array $vars) |
|
992 { |
|
993 $xclient_options = ""; |
|
994 foreach ($vars as $key => $value) { |
|
995 if (in_array($key, SMTP::$xclient_allowed_attributes)) { |
|
996 $xclient_options .= " {$key}={$value}"; |
|
997 } |
|
998 } |
|
999 if (!$xclient_options) { |
|
1000 return true; |
|
1001 } |
|
1002 return $this->sendCommand('XCLIENT', 'XCLIENT' . $xclient_options, 250); |
|
1003 } |
|
1004 |
|
1005 /** |
968 * Send an SMTP RSET command. |
1006 * Send an SMTP RSET command. |
969 * Abort any transaction that is currently in progress. |
1007 * Abort any transaction that is currently in progress. |
970 * Implements RFC 821: RSET <CRLF>. |
1008 * Implements RFC 821: RSET <CRLF>. |
971 * |
1009 * |
972 * @return bool True on success |
1010 * @return bool True on success |