Edit PHP version constraint and update Composer dependencies

This commit is contained in:
Paul Nicoué 2025-07-04 15:08:52 +02:00
parent 231e1bce63
commit e5b51981ff
52 changed files with 806 additions and 613 deletions

View file

@ -3,25 +3,32 @@
/**
* Portuguese (European) PHPMailer language file: refer to English translation for definitive list
* @package PHPMailer
* @author Jonadabe <jonadabe@hotmail.com>
* @author João Vieira <mail@joaovieira.eu>
*/
$PHPMAILER_LANG['authenticate'] = 'Erro do SMTP: Não foi possível realizar a autenticação.';
$PHPMAILER_LANG['connect_host'] = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro do SMTP: Os dados foram rejeitados.';
$PHPMAILER_LANG['empty_message'] = 'A mensagem no e-mail está vazia.';
$PHPMAILER_LANG['authenticate'] = 'Erro SMTP: Falha na autenticação.';
$PHPMAILER_LANG['buggy_php'] = 'A sua versão do PHP tem um bug que pode causar mensagens corrompidas. Para resolver, utilize o envio por SMTP, desative a opção mail.add_x_header no ficheiro php.ini, mude para MacOS ou Linux, ou atualize o PHP para a versão 7.0.17+ ou 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'Erro SMTP: Não foi possível ligar ao servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro SMTP: Dados não aceites.';
$PHPMAILER_LANG['empty_message'] = 'A mensagem de e-mail está vazia.';
$PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: ';
$PHPMAILER_LANG['execute'] = 'Não foi possível executar: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder o ficheiro: ';
$PHPMAILER_LANG['file_open'] = 'Abertura do ficheiro: Não foi possível abrir o ficheiro: ';
$PHPMAILER_LANG['from_failed'] = 'Ocorreram falhas nos endereços dos seguintes remententes: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.';
$PHPMAILER_LANG['invalid_address'] = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro do SMTP: O endereço do seguinte destinatário falhou: ';
$PHPMAILER_LANG['signing'] = 'Erro ao assinar: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.';
$PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensão em falta: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível aceder ao ficheiro: ';
$PHPMAILER_LANG['file_open'] = 'Erro ao abrir o ficheiro: ';
$PHPMAILER_LANG['from_failed'] = 'O envio falhou para o seguinte endereço do remetente: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.';
$PHPMAILER_LANG['invalid_address'] = 'Endereço de e-mail inválido: ';
$PHPMAILER_LANG['invalid_header'] = 'Nome ou valor do cabeçalho inválido.';
$PHPMAILER_LANG['invalid_hostentry'] = 'Entrada de host inválida: ';
$PHPMAILER_LANG['invalid_host'] = 'Host inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = 'O cliente de e-mail não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Deve fornecer pelo menos um endereço de destinatário.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro SMTP: Falha no envio para os seguintes destinatários: ';
$PHPMAILER_LANG['signing'] = 'Erro ao assinar: ';
$PHPMAILER_LANG['smtp_code'] = 'Código SMTP: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Informações adicionais SMTP: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Falha na função SMTP connect().';
$PHPMAILER_LANG['smtp_detail'] = 'Detalhes: ';
$PHPMAILER_LANG['smtp_error'] = 'Erro do servidor SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou redefinir a variável: ';

View file

@ -580,6 +580,10 @@ class PHPMailer
* May be a callable to inject your own validator, but there are several built-in validators.
* The default validator uses PHP's FILTER_VALIDATE_EMAIL filter_var option.
*
* If CharSet is UTF8, the validator is left at the default value,
* and you send to addresses that use non-ASCII local parts, then
* PHPMailer automatically changes to the 'eai' validator.
*
* @see PHPMailer::validateAddress()
*
* @var string|callable
@ -659,6 +663,14 @@ class PHPMailer
*/
protected $ReplyToQueue = [];
/**
* Whether the need for SMTPUTF8 has been detected. Set by
* preSend() if necessary.
*
* @var bool
*/
public $UseSMTPUTF8 = false;
/**
* The array of attachments.
*
@ -756,7 +768,7 @@ class PHPMailer
*
* @var string
*/
const VERSION = '6.9.3';
const VERSION = '6.10.0';
/**
* Error severity: message only, continue processing.
@ -1110,19 +1122,22 @@ class PHPMailer
$params = [$kind, $address, $name];
//Enqueue addresses with IDN until we know the PHPMailer::$CharSet.
//Domain is assumed to be whatever is after the last @ symbol in the address
if (static::idnSupported() && $this->has8bitChars(substr($address, ++$pos))) {
if ('Reply-To' !== $kind) {
if (!array_key_exists($address, $this->RecipientsQueue)) {
$this->RecipientsQueue[$address] = $params;
if ($this->has8bitChars(substr($address, ++$pos))) {
if (static::idnSupported()) {
if ('Reply-To' !== $kind) {
if (!array_key_exists($address, $this->RecipientsQueue)) {
$this->RecipientsQueue[$address] = $params;
return true;
}
} elseif (!array_key_exists($address, $this->ReplyToQueue)) {
$this->ReplyToQueue[$address] = $params;
return true;
}
} elseif (!array_key_exists($address, $this->ReplyToQueue)) {
$this->ReplyToQueue[$address] = $params;
return true;
}
//We have an 8-bit domain, but we are missing the necessary extensions to support it
//Or we are already sending to this address
return false;
}
@ -1160,6 +1175,15 @@ class PHPMailer
*/
protected function addAnAddress($kind, $address, $name = '')
{
if (
self::$validator === 'php' &&
((bool) preg_match('/[\x80-\xFF]/', $address))
) {
//The caller has not altered the validator and is sending to an address
//with UTF-8, so assume that they want UTF-8 support instead of failing
$this->CharSet = self::CHARSET_UTF8;
self::$validator = 'eai';
}
if (!in_array($kind, ['to', 'cc', 'bcc', 'Reply-To'])) {
$error_message = sprintf(
'%s: %s',
@ -1362,6 +1386,7 @@ class PHPMailer
* * `pcre` Use old PCRE implementation;
* * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
* * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
* * `eai` Use a pattern similar to the HTML5 spec for 'email' and to firefox, extended to support EAI (RFC6530).
* * `noregex` Don't use a regex: super fast, really dumb.
* Alternatively you may pass in a callable to inject your own validator, for example:
*
@ -1432,6 +1457,24 @@ class PHPMailer
'[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',
$address
);
case 'eai':
/*
* This is the pattern used in the HTML5 spec for validation of 'email' type
* form input elements (as above), modified to accept Unicode email addresses.
* This is also more lenient than Firefox' html5 spec, in order to make the regex faster.
* 'eai' is an acronym for Email Address Internationalization.
* This validator is selected automatically if you attempt to use recipient addresses
* that contain Unicode characters in the local part.
*
* @see https://html.spec.whatwg.org/#e-mail-state-(type=email)
* @see https://en.wikipedia.org/wiki/International_email
*/
return (bool) preg_match(
'/^[-\p{L}\p{N}\p{M}.!#$%&\'*+\/=?^_`{|}~]+@[\p{L}\p{N}\p{M}](?:[\p{L}\p{N}\p{M}-]{0,61}' .
'[\p{L}\p{N}\p{M}])?(?:\.[\p{L}\p{N}\p{M}]' .
'(?:[-\p{L}\p{N}\p{M}]{0,61}[\p{L}\p{N}\p{M}])?)*$/usD',
$address
);
case 'php':
default:
return filter_var($address, FILTER_VALIDATE_EMAIL) !== false;
@ -1565,9 +1608,26 @@ class PHPMailer
$this->error_count = 0; //Reset errors
$this->mailHeader = '';
//The code below tries to support full use of Unicode,
//while remaining compatible with legacy SMTP servers to
//the greatest degree possible: If the message uses
//Unicode in the local parts of any addresses, it is sent
//using SMTPUTF8. If not, it it sent using
//punycode-encoded domains and plain SMTP.
if (
static::CHARSET_UTF8 === strtolower($this->CharSet) &&
($this->anyAddressHasUnicodeLocalPart($this->RecipientsQueue) ||
$this->anyAddressHasUnicodeLocalPart(array_keys($this->all_recipients)) ||
$this->anyAddressHasUnicodeLocalPart($this->ReplyToQueue) ||
$this->addressHasUnicodeLocalPart($this->From))
) {
$this->UseSMTPUTF8 = true;
}
//Dequeue recipient and Reply-To addresses with IDN
foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
$params[1] = $this->punyencodeAddress($params[1]);
if (!$this->UseSMTPUTF8) {
$params[1] = $this->punyencodeAddress($params[1]);
}
call_user_func_array([$this, 'addAnAddress'], $params);
}
if (count($this->to) + count($this->cc) + count($this->bcc) < 1) {
@ -2058,6 +2118,11 @@ class PHPMailer
if (!$this->smtpConnect($this->SMTPOptions)) {
throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
}
//If we have recipient addresses that need Unicode support,
//but the server doesn't support it, stop here
if ($this->UseSMTPUTF8 && !$this->smtp->getServerExt('SMTPUTF8')) {
throw new Exception($this->lang('no_smtputf8'), self::STOP_CRITICAL);
}
//Sender already validated in preSend()
if ('' === $this->Sender) {
$smtp_from = $this->From;
@ -2159,6 +2224,7 @@ class PHPMailer
$this->smtp->setDebugLevel($this->SMTPDebug);
$this->smtp->setDebugOutput($this->Debugoutput);
$this->smtp->setVerp($this->do_verp);
$this->smtp->setSMTPUTF8($this->UseSMTPUTF8);
if ($this->Host === null) {
$this->Host = 'localhost';
}
@ -2356,6 +2422,7 @@ class PHPMailer
'smtp_detail' => 'Detail: ',
'smtp_error' => 'SMTP server error: ',
'variable_set' => 'Cannot set or reset variable: ',
'no_smtputf8' => 'Server does not support SMTPUTF8 needed to send to Unicode addresses',
];
if (empty($lang_path)) {
//Calculate an absolute path so it can work if CWD is not here
@ -2870,7 +2937,9 @@ class PHPMailer
$bodyEncoding = $this->Encoding;
$bodyCharSet = $this->CharSet;
//Can we do a 7-bit downgrade?
if (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) {
if ($this->UseSMTPUTF8) {
$bodyEncoding = static::ENCODING_8BIT;
} elseif (static::ENCODING_8BIT === $bodyEncoding && !$this->has8bitChars($this->Body)) {
$bodyEncoding = static::ENCODING_7BIT;
//All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
$bodyCharSet = static::CHARSET_ASCII;
@ -3507,7 +3576,8 @@ class PHPMailer
/**
* Encode a header value (not including its label) optimally.
* Picks shortest of Q, B, or none. Result includes folding if needed.
* See RFC822 definitions for phrase, comment and text positions.
* See RFC822 definitions for phrase, comment and text positions,
* and RFC2047 for inline encodings.
*
* @param string $str The header value to encode
* @param string $position What context the string will be used in
@ -3516,6 +3586,11 @@ class PHPMailer
*/
public function encodeHeader($str, $position = 'text')
{
$position = strtolower($position);
if ($this->UseSMTPUTF8 && !("comment" === $position)) {
return trim(static::normalizeBreaks($str));
}
$matchcount = 0;
switch (strtolower($position)) {
case 'phrase':
@ -4180,7 +4255,7 @@ class PHPMailer
if ('smtp' === $this->Mailer && null !== $this->smtp) {
$lasterror = $this->smtp->getError();
if (!empty($lasterror['error'])) {
$msg .= $this->lang('smtp_error') . $lasterror['error'];
$msg .= ' ' . $this->lang('smtp_error') . $lasterror['error'];
if (!empty($lasterror['detail'])) {
$msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail'];
}
@ -4267,6 +4342,45 @@ class PHPMailer
return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false;
}
/**
* Check whether the supplied address uses Unicode in the local part.
*
* @return bool
*/
protected function addressHasUnicodeLocalPart($address)
{
return (bool) preg_match('/[\x80-\xFF].*@/', $address);
}
/**
* Check whether any of the supplied addresses use Unicode in the local part.
*
* @return bool
*/
protected function anyAddressHasUnicodeLocalPart($addresses)
{
foreach ($addresses as $address) {
if (is_array($address)) {
$address = $address[0];
}
if ($this->addressHasUnicodeLocalPart($address)) {
return true;
}
}
return false;
}
/**
* Check whether the message requires SMTPUTF8 based on what's known so far.
*
* @return bool
*/
public function needsSMTPUTF8()
{
return $this->UseSMTPUTF8;
}
/**
* Get an error message in the current language.
*

View file

@ -46,7 +46,7 @@ class POP3
*
* @var string
*/
const VERSION = '6.9.3';
const VERSION = '6.10.0';
/**
* Default POP3 port number.

View file

@ -35,7 +35,7 @@ class SMTP
*
* @var string
*/
const VERSION = '6.9.3';
const VERSION = '6.10.0';
/**
* SMTP line break constant.
@ -159,6 +159,15 @@ class SMTP
*/
public $do_verp = false;
/**
* Whether to use SMTPUTF8.
*
* @see https://www.rfc-editor.org/rfc/rfc6531
*
* @var bool
*/
public $do_smtputf8 = false;
/**
* The timeout value for connection, in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2.
@ -913,7 +922,15 @@ class SMTP
* $from. Returns true if successful or false otherwise. If True
* the mail transaction is started and then one or more recipient
* commands may be called followed by a data command.
* Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF>.
* Implements RFC 821: MAIL <SP> FROM:<reverse-path> <CRLF> and
* two extensions, namely XVERP and SMTPUTF8.
*
* The server's EHLO response is not checked. If use of either
* extensions is enabled even though the server does not support
* that, mail submission will fail.
*
* XVERP is documented at https://www.postfix.org/VERP_README.html
* and SMTPUTF8 is specified in RFC 6531.
*
* @param string $from Source address of this message
*
@ -922,10 +939,11 @@ class SMTP
public function mail($from)
{
$useVerp = ($this->do_verp ? ' XVERP' : '');
$useSmtputf8 = ($this->do_smtputf8 ? ' SMTPUTF8' : '');
return $this->sendCommand(
'MAIL FROM',
'MAIL FROM:<' . $from . '>' . $useVerp,
'MAIL FROM:<' . $from . '>' . $useSmtputf8 . $useVerp,
250
);
}
@ -1364,6 +1382,26 @@ class SMTP
return $this->do_verp;
}
/**
* Enable or disable use of SMTPUTF8.
*
* @param bool $enabled
*/
public function setSMTPUTF8($enabled = false)
{
$this->do_smtputf8 = $enabled;
}
/**
* Get SMTPUTF8 use.
*
* @return bool
*/
public function getSMTPUTF8()
{
return $this->do_smtputf8;
}
/**
* Set error messages and codes.
*