Merge pull request #3276 from jrfnl/feature/use-phpcompatibility-10.0

Use PHPCompatibility 10.0.0(-alpha1)
This commit is contained in:
Marcus Bointon 2025-11-25 07:58:05 +01:00 committed by GitHub
commit 6631e9049e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 51 additions and 35 deletions

View File

@ -42,8 +42,8 @@
"doctrine/annotations": "^1.2.6 || ^1.13.3", "doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2", "php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5", "phpcompatibility/php-compatibility": "^10.0.0@dev",
"squizlabs/php_codesniffer": "^3.7.2", "squizlabs/php_codesniffer": "^3.13.5",
"yoast/phpunit-polyfills": "^1.0.4" "yoast/phpunit-polyfills": "^1.0.4"
}, },
"suggest": { "suggest": {
@ -56,8 +56,11 @@
"league/oauth2-google": "Needed for Google XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging", "psr/log": "For optional PSR-3 debug logging",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication",
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example"
}, },
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"PHPMailer\\PHPMailer\\": "src/" "PHPMailer\\PHPMailer\\": "src/"

View File

@ -83,26 +83,24 @@ if (!$mail->send()) {
echo 'Message sent!'; echo 'Message sent!';
//Section 2: IMAP //Section 2: IMAP
//Uncomment these to save your message in the 'Sent Mail' folder. //Uncomment these to save your message in the 'Sent Mail' folder.
#if (save_mail($mail)) { #save_mail($mail->getSentMIMEMessage());
# echo "Message saved!";
#}
} }
//Section 2: IMAP //Section 2: IMAP
//IMAP commands requires the PHP IMAP Extension, found at: https://php.net/manual/en/imap.setup.php //This example uses the directorytree/imapengine IMAP library: https://imapengine.com
//Function to call which uses the PHP imap_*() functions to save messages: https://php.net/manual/en/book.imap.php //Earlier versions of this code used the deprecated PHP imap_* functions.
//You can use imap_getmailboxes($imapStream, '/imap/ssl', '*' ) to get a list of available folders or labels, this can function save_mail($message)
//be useful if you are trying to get this working on a non-Gmail IMAP server.
function save_mail($mail)
{ {
//You can change 'Sent Mail' to any other folder or tag $mailbox = new \DirectoryTree\ImapEngine\Mailbox([
$path = '{imap.gmail.com:993/imap/ssl}[Gmail]/Sent Mail'; 'host' => 'imap.gmail.com',
'port' => 993,
'encryption' => 'ssl',
'username' => 'user@example.com',
'password' => 'password',
]);
//Tell your server to open an IMAP connection using the same username and password as you used for SMTP // Find the "sent" messages folder yours may have a different name.
$imapStream = imap_open($path, $mail->Username, $mail->Password); $folder = $mailbox->folders()->find('Sent Mail');
$result = imap_append($imapStream, $path, $mail->getSentMIMEMessage()); $folder->messages()->append($message);
imap_close($imapStream);
return $result;
} }

View File

@ -8,7 +8,7 @@
use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception; use PHPMailer\PHPMailer\Exception;
error_reporting(E_STRICT | E_ALL); error_reporting(E_ALL);
date_default_timezone_set('Etc/UTC'); date_default_timezone_set('Etc/UTC');
@ -51,7 +51,10 @@ foreach ($result as $row) {
try { try {
$mail->addAddress($row['email'], $row['full_name']); $mail->addAddress($row['email'], $row['full_name']);
} catch (Exception $e) { } catch (Exception $e) {
echo 'Invalid address skipped: ' . htmlspecialchars($row['email']) . '<br>'; printf(
'Invalid address skipped: %s<br>',
htmlspecialchars($row['email'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401)
);
continue; continue;
} }
if (!empty($row['photo'])) { if (!empty($row['photo'])) {
@ -66,8 +69,11 @@ foreach ($result as $row) {
try { try {
$mail->send(); $mail->send();
echo 'Message sent to :' . htmlspecialchars($row['full_name']) . ' (' . printf(
htmlspecialchars($row['email']) . ')<br>'; 'Message sent to : %s (%s)<br>',
htmlspecialchars($row['full_name'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401),
htmlspecialchars($row['email'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401)
);
//Mark it as sent in the DB //Mark it as sent in the DB
mysqli_query( mysqli_query(
$mysql, $mysql,
@ -75,7 +81,11 @@ foreach ($result as $row) {
mysqli_real_escape_string($mysql, $row['email']) . "'" mysqli_real_escape_string($mysql, $row['email']) . "'"
); );
} catch (Exception $e) { } catch (Exception $e) {
echo 'Mailer Error (' . htmlspecialchars($row['email']) . ') ' . $mail->ErrorInfo . '<br>'; printf(
'Mailer Error (%s) %s<br>',
htmlspecialchars($row['email'], ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401),
$mail->ErrorInfo
);
//Reset the connection to abort sending this message //Reset the connection to abort sending this message
//The loop will continue trying to send to the rest of the list //The loop will continue trying to send to the rest of the list
$mail->getSMTPInstance()->reset(); $mail->getSMTPInstance()->reset();

View File

@ -54,7 +54,7 @@ if (array_key_exists('userfile', $_FILES)) {
<input type="submit" value="Send File"> <input type="submit" value="Send File">
</form> </form>
<?php } else { <?php } else {
echo htmlspecialchars($msg); echo htmlspecialchars($msg, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
} ?> } ?>
</body> </body>
</html> </html>

View File

@ -54,7 +54,7 @@ if (array_key_exists('userfile', $_FILES)) {
<input type="submit" value="Send Files"> <input type="submit" value="Send Files">
</form> </form>
<?php } else { <?php } else {
echo htmlspecialchars($msg); echo htmlspecialchars($msg, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
} ?> } ?>
</body> </body>
</html> </html>

View File

@ -178,5 +178,5 @@ if (!isset($_GET['code'])) {
); );
//Use this to interact with an API on the users behalf //Use this to interact with an API on the users behalf
//Use this to get a new access token if the old one expires //Use this to get a new access token if the old one expires
echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken()); echo 'Refresh Token: ', htmlspecialchars($token->getRefreshToken(), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
} }

View File

@ -27,14 +27,7 @@
<exclude name="PSR2.Methods.MethodDeclaration.Underscore"/> <exclude name="PSR2.Methods.MethodDeclaration.Underscore"/>
<exclude name="PSR12.Properties.ConstantVisibility.NotFound"/> <exclude name="PSR12.Properties.ConstantVisibility.NotFound"/>
</rule> </rule>
<rule ref="PHPCompatibility"> <rule ref="PHPCompatibility"/>
<exclude name="PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_1_clientFound"/>
<exclude name="PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_2_clientFound"/>
<exclude name="PHPCompatibility.Constants.RemovedConstants.intl_idna_variant_2003Deprecated"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.random_bytesFound"/>
<exclude name="PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated"/>
<exclude name="PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet"/>
</rule>
<!-- <!--

View File

@ -876,6 +876,7 @@ class PHPMailer
private function mailPassthru($to, $subject, $body, $header, $params) private function mailPassthru($to, $subject, $body, $header, $params)
{ {
//Check overloading of mail function to avoid double-encoding //Check overloading of mail function to avoid double-encoding
// phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecatedRemoved
if ((int)ini_get('mbstring.func_overload') & 1) { if ((int)ini_get('mbstring.func_overload') & 1) {
$subject = $this->secureHeader($subject); $subject = $this->secureHeader($subject);
} else { } else {
@ -1257,8 +1258,10 @@ class PHPMailer
$addresses = []; $addresses = [];
if (function_exists('imap_rfc822_parse_adrlist')) { if (function_exists('imap_rfc822_parse_adrlist')) {
//Use this built-in parser if it's available //Use this built-in parser if it's available
// phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.imap_rfc822_parse_adrlistRemoved -- wrapped in function_exists()
$list = imap_rfc822_parse_adrlist($addrstr, ''); $list = imap_rfc822_parse_adrlist($addrstr, '');
// Clear any potential IMAP errors to get rid of notices being thrown at end of script. // Clear any potential IMAP errors to get rid of notices being thrown at end of script.
// phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.imap_errorsRemoved -- wrapped in function_exists()
imap_errors(); imap_errors();
foreach ($list as $address) { foreach ($list as $address) {
if ( if (
@ -1585,9 +1588,11 @@ class PHPMailer
); );
} elseif (defined('INTL_IDNA_VARIANT_2003')) { } elseif (defined('INTL_IDNA_VARIANT_2003')) {
//Fall back to this old, deprecated/removed encoding //Fall back to this old, deprecated/removed encoding
// phpcs:ignore PHPCompatibility.Constants.RemovedConstants.intl_idna_variant_2003DeprecatedRemoved
$punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_2003); $punycode = idn_to_ascii($domain, $errorcode, \INTL_IDNA_VARIANT_2003);
} else { } else {
//Fall back to a default we don't know about //Fall back to a default we don't know about
// phpcs:ignore PHPCompatibility.ParameterValues.NewIDNVariantDefault.NotSet
$punycode = idn_to_ascii($domain, $errorcode); $punycode = idn_to_ascii($domain, $errorcode);
} }
if (false !== $punycode) { if (false !== $punycode) {
@ -2958,6 +2963,7 @@ class PHPMailer
$bytes = ''; $bytes = '';
if (function_exists('random_bytes')) { if (function_exists('random_bytes')) {
try { try {
// phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.random_bytesFound -- Wrapped in function_exists.
$bytes = random_bytes($len); $bytes = random_bytes($len);
} catch (\Exception $e) { } catch (\Exception $e) {
//Do nothing //Do nothing
@ -5113,12 +5119,14 @@ class PHPMailer
} }
if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) { if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) {
if (\PHP_MAJOR_VERSION < 8) { if (\PHP_MAJOR_VERSION < 8) {
// phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.openssl_pkey_freeDeprecated
openssl_pkey_free($privKey); openssl_pkey_free($privKey);
} }
return base64_encode($signature); return base64_encode($signature);
} }
if (\PHP_MAJOR_VERSION < 8) { if (\PHP_MAJOR_VERSION < 8) {
// phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.openssl_pkey_freeDeprecated
openssl_pkey_free($privKey); openssl_pkey_free($privKey);
} }

View File

@ -494,7 +494,9 @@ class SMTP
//PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
//so add them back in manually if we can //so add them back in manually if we can
if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) { if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
// phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_2_clientFound
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
// phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_1_clientFound
$crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
} }

View File

@ -8,6 +8,8 @@
* Note: this test fixture uses a syntax (backticks) which has been deprecated in PHP 8.5 and * Note: this test fixture uses a syntax (backticks) which has been deprecated in PHP 8.5 and
* is slated for removal in PHP 9.0. * is slated for removal in PHP 9.0.
* For that reason, the file is excluded from the linting check on PHP 8.5 and above. * For that reason, the file is excluded from the linting check on PHP 8.5 and above.
*
* @phpcs:disable PHPCompatibility.LanguageConstructs.RemovedLanguageConstructs.t_backtickDeprecated
*/ */
$PHPMAILER_LANG['extension_missing'] = 'Confirming that test fixture was loaded correctly (yz).'; $PHPMAILER_LANG['extension_missing'] = 'Confirming that test fixture was loaded correctly (yz).';