|
|
@@ -357,6 +357,13 @@ class PHPMailer
|
|
|
*/
|
|
|
public $AuthType = '';
|
|
|
|
|
|
+ /**
|
|
|
+ * SMTP SMTPXClient command attibutes
|
|
|
+ *
|
|
|
+ * @var array
|
|
|
+ */
|
|
|
+ protected $SMTPXClient = [];
|
|
|
+
|
|
|
/**
|
|
|
* An implementation of the PHPMailer OAuthTokenProvider interface.
|
|
|
*
|
|
|
@@ -750,7 +757,7 @@ class PHPMailer
|
|
|
*
|
|
|
* @var string
|
|
|
*/
|
|
|
- const VERSION = '6.8.1';
|
|
|
+ const VERSION = '6.9.1';
|
|
|
|
|
|
/**
|
|
|
* Error severity: message only, continue processing.
|
|
|
@@ -1571,6 +1578,10 @@ class PHPMailer
|
|
|
|
|
|
//Validate From, Sender, and ConfirmReadingTo addresses
|
|
|
foreach (['From', 'Sender', 'ConfirmReadingTo'] as $address_kind) {
|
|
|
+ if ($this->{$address_kind} === null) {
|
|
|
+ $this->{$address_kind} = '';
|
|
|
+ continue;
|
|
|
+ }
|
|
|
$this->{$address_kind} = trim($this->{$address_kind});
|
|
|
if (empty($this->{$address_kind})) {
|
|
|
continue;
|
|
|
@@ -1997,6 +2008,38 @@ class PHPMailer
|
|
|
return $this->smtp;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Provide SMTP XCLIENT attributes
|
|
|
+ *
|
|
|
+ * @param string $name Attribute name
|
|
|
+ * @param ?string $value Attribute value
|
|
|
+ *
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public function setSMTPXclientAttribute($name, $value)
|
|
|
+ {
|
|
|
+ if (!in_array($name, SMTP::$xclient_allowed_attributes)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (isset($this->SMTPXClient[$name]) && $value === null) {
|
|
|
+ unset($this->SMTPXClient[$name]);
|
|
|
+ } elseif ($value !== null) {
|
|
|
+ $this->SMTPXClient[$name] = $value;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Get SMTP XCLIENT attributes
|
|
|
+ *
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public function getSMTPXclientAttributes()
|
|
|
+ {
|
|
|
+ return $this->SMTPXClient;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Send mail via SMTP.
|
|
|
* Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
|
|
|
@@ -2025,6 +2068,9 @@ class PHPMailer
|
|
|
} else {
|
|
|
$smtp_from = $this->Sender;
|
|
|
}
|
|
|
+ if (count($this->SMTPXClient)) {
|
|
|
+ $this->smtp->xclient($this->SMTPXClient);
|
|
|
+ }
|
|
|
if (!$this->smtp->mail($smtp_from)) {
|
|
|
$this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
|
|
|
throw new Exception($this->ErrorInfo, self::STOP_CRITICAL);
|
|
|
@@ -2187,10 +2233,17 @@ class PHPMailer
|
|
|
$this->smtp->hello($hello);
|
|
|
//Automatically enable TLS encryption if:
|
|
|
//* it's not disabled
|
|
|
+ //* we are not connecting to localhost
|
|
|
//* we have openssl extension
|
|
|
//* we are not already using SSL
|
|
|
//* the server offers STARTTLS
|
|
|
- if ($this->SMTPAutoTLS && $sslext && 'ssl' !== $secure && $this->smtp->getServerExt('STARTTLS')) {
|
|
|
+ if (
|
|
|
+ $this->SMTPAutoTLS &&
|
|
|
+ $this->Host !== 'localhost' &&
|
|
|
+ $sslext &&
|
|
|
+ $secure !== 'ssl' &&
|
|
|
+ $this->smtp->getServerExt('STARTTLS')
|
|
|
+ ) {
|
|
|
$tls = true;
|
|
|
}
|
|
|
if ($tls) {
|
|
|
@@ -4047,6 +4100,79 @@ class PHPMailer
|
|
|
$this->CustomHeader = [];
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Clear a specific custom header by name or name and value.
|
|
|
+ * $name value can be overloaded to contain
|
|
|
+ * both header name and value (name:value).
|
|
|
+ *
|
|
|
+ * @param string $name Custom header name
|
|
|
+ * @param string|null $value Header value
|
|
|
+ *
|
|
|
+ * @return bool True if a header was replaced successfully
|
|
|
+ */
|
|
|
+ public function clearCustomHeader($name, $value = null)
|
|
|
+ {
|
|
|
+ if (null === $value && strpos($name, ':') !== false) {
|
|
|
+ //Value passed in as name:value
|
|
|
+ list($name, $value) = explode(':', $name, 2);
|
|
|
+ }
|
|
|
+ $name = trim($name);
|
|
|
+ $value = (null === $value) ? null : trim($value);
|
|
|
+
|
|
|
+ foreach ($this->CustomHeader as $k => $pair) {
|
|
|
+ if ($pair[0] == $name) {
|
|
|
+ // We remove the header if the value is not provided or it matches.
|
|
|
+ if (null === $value || $pair[1] == $value) {
|
|
|
+ unset($this->CustomHeader[$k]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Replace a custom header.
|
|
|
+ * $name value can be overloaded to contain
|
|
|
+ * both header name and value (name:value).
|
|
|
+ *
|
|
|
+ * @param string $name Custom header name
|
|
|
+ * @param string|null $value Header value
|
|
|
+ *
|
|
|
+ * @return bool True if a header was replaced successfully
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public function replaceCustomHeader($name, $value = null)
|
|
|
+ {
|
|
|
+ if (null === $value && strpos($name, ':') !== false) {
|
|
|
+ //Value passed in as name:value
|
|
|
+ list($name, $value) = explode(':', $name, 2);
|
|
|
+ }
|
|
|
+ $name = trim($name);
|
|
|
+ $value = (null === $value) ? '' : trim($value);
|
|
|
+
|
|
|
+ $replaced = false;
|
|
|
+ foreach ($this->CustomHeader as $k => $pair) {
|
|
|
+ if ($pair[0] == $name) {
|
|
|
+ if ($replaced) {
|
|
|
+ unset($this->CustomHeader[$k]);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (strpbrk($name . $value, "\r\n") !== false) {
|
|
|
+ if ($this->exceptions) {
|
|
|
+ throw new Exception($this->lang('invalid_header'));
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ $this->CustomHeader[$k] = [$name, $value];
|
|
|
+ $replaced = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Add an error message to the error container.
|
|
|
*
|