Skip to content

Commit 3369608

Browse files
committed
Build/Test Tools: Introduce automated PHP compatibility checking.
This change introduces a new Composer script, `compat` that will scan the codebase for (detectable) potential PHP compatibility issues using the `PHP_CodeSniffer` and a custom ruleset based off of the `PHPCompayibilityWP` ruleset (`phpcompat.xml.dist`). The command will be run as a separate job within each Travis build. While many compatibility issues and false positives have already been corrected in this commit and other Trac tickets, there are still some remaining. For that reason, the job is allowed to fail while the remainder of the potential compatibility issues are investigated and addressed. After those are resolved, the job should be set as required to pass to help prevent new compatibility issues from being introduced. Props desrosj, jrf, all PHPCompatibilityWP and PHPCompatibility contributors. Fixes #46152. git-svn-id: https://develop.svn.wordpress.org/trunk@46290 602fd350-edb4-49c9-b593-d223f7449a82
1 parent bad0295 commit 3369608

12 files changed

Lines changed: 251 additions & 17 deletions

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ matrix:
2929
name: PHP Linting
3030
- env: WP_TRAVISCI=travis:js WP_INSTALL=false
3131
name: JS Tests
32+
- env: WP_TRAVISCI=test:compat COMPOSER_INSTALL=true NPM_INSTALL=false WP_INSTALL=false
33+
name: "PHP Compatibility Check"
3234
- env: LOCAL_PHP=7.3-fpm WP_TRAVISCI=test:php
3335
name: "PHPUnit Tests: PHP 7.3"
3436
- env: LOCAL_PHP=7.3-fpm LOCAL_PHP_MEMCACHED=true WP_TRAVISCI=test:php
@@ -46,6 +48,7 @@ matrix:
4648
- env: LOCAL_PHP=8.0-fpm WP_TRAVISCI=test:php
4749
name: "PHPUnit Tests: PHP 8.0"
4850
allow_failures:
51+
- env: WP_TRAVISCI=test:compat COMPOSER_INSTALL=true NPM_INSTALL=false WP_INSTALL=false
4952
- env: LOCAL_PHP=7.4-fpm WP_TRAVISCI=test:php
5053
- env: LOCAL_PHP=8.0-fpm WP_TRAVISCI=test:php
5154
fast_finish: true
@@ -120,6 +123,8 @@ script:
120123
docker-compose run --rm php composer format &&
121124
docker-compose run --rm php composer lint:errors &&
122125
docker-compose run --rm php composer lint tests
126+
elif [[ "$WP_TRAVISCI" == "test:compat" ]]; then
127+
docker-compose run --rm php composer compat
123128
else
124129
npm run grunt $WP_TRAVISCI
125130
fi

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
},
1515
"require-dev": {
1616
"dealerdirect/phpcodesniffer-composer-installer": "~0.5.0",
17-
"wp-coding-standards/wpcs": "~2.1.0"
17+
"wp-coding-standards/wpcs": "~2.1.0",
18+
"phpcompatibility/phpcompatibility-wp": "^2.1.0"
1819
},
1920
"scripts": {
21+
"compat": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --standard=phpcompat.xml.dist --report=summary,source",
2022
"format": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf --report=summary,source --cache -d memory_limit=256M",
2123
"lint": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --report=summary,source --cache -d memory_limit=256M",
2224
"lint:errors": "@lint -n"

composer.lock

Lines changed: 162 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

phpcompat.xml.dist

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?xml version="1.0"?>
2+
<ruleset name="WordPress PHP Compatibility">
3+
<description>Apply PHP compatibility checks to all WordPress Core files</description>
4+
5+
<rule ref="PHPCompatibilityWP"/>
6+
7+
<!-- WordPress Core currently supports PHP 5.6+ -->
8+
<config name="testVersion" value="5.6-"/>
9+
10+
<!-- Only scan PHP files. -->
11+
<arg name="extensions" value="php"/>
12+
13+
<!-- Whenever possible, cache the scan results and re-use those for unchanged files on the next scan. -->
14+
<arg name="cache"/>
15+
16+
<!-- Set the memory limit to 256M.
17+
For most standard PHP configurations, this means the memory limit will temporarily be raised.
18+
Ref: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#specifying-phpini-settings
19+
-->
20+
<ini name="memory_limit" value="256M"/>
21+
22+
<!-- Strip the filepaths down to the relevant bit. -->
23+
<arg name="basepath" value="./"/>
24+
25+
<!-- Check up to 20 files simultaneously. -->
26+
<arg name="parallel" value="20"/>
27+
28+
<!-- Show sniff codes in all reports -->
29+
<arg value="ps"/>
30+
31+
<!-- For now, only the files in src are scanned. -->
32+
<file>./src/</file>
33+
34+
<!-- Code which doesn't go into production may have different requirements. -->
35+
<exclude-pattern>/node_modules/*</exclude-pattern>
36+
37+
<!--
38+
Currently, there are no dependencies managed by Composer.
39+
This will need to be modified when that changes to ensure external packages meet compatibility requirements.
40+
-->
41+
<exclude-pattern>/vendor/*</exclude-pattern>
42+
43+
<!--
44+
PHPCompatibilityParagonieRandomCompat prevents false positives in `random_compat`.
45+
However, because these files are included in a non-standard path, false positives are triggered in WordPress Core.
46+
-->
47+
<rule ref="PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated">
48+
<exclude-pattern>/random_compat/byte_safe_strings\.php$</exclude-pattern>
49+
</rule>
50+
<rule ref="PHPCompatibility.Constants.RemovedConstants.mcrypt_dev_urandomDeprecatedRemoved">
51+
<exclude-pattern>/random_compat/random_bytes_mcrypt\.php$</exclude-pattern>
52+
</rule>
53+
<rule ref="PHPCompatibility.Extensions.RemovedExtensions.mcryptDeprecatedRemoved">
54+
<exclude-pattern>/random_compat/random_bytes_mcrypt\.php$</exclude-pattern>
55+
</rule>
56+
<rule ref="PHPCompatibility.FunctionUse.RemovedFunctions.mcrypt_create_ivDeprecatedRemoved">
57+
<exclude-pattern>/random_compat/random_bytes_mcrypt\.php$</exclude-pattern>
58+
</rule>
59+
60+
<!-- Whitelist the WP DB Class for use of `mysql_` extension in PHP < 7.0. -->
61+
<rule ref="PHPCompatibility.Extensions.RemovedExtensions">
62+
<exclude-pattern>/src/wp-includes/wp-db\.php</exclude-pattern>
63+
</rule>
64+
</ruleset>

src/wp-admin/includes/class-wp-debug-data.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ static function debug_data() {
728728
if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
729729
$client_version = $wpdb->dbh->client_info;
730730
} else {
731-
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info
731+
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
732732
if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
733733
$client_version = $matches[0];
734734
} else {

src/wp-admin/includes/class-wp-site-health.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ private function prepare_sql_data() {
158158
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
159159
$mysql_server_type = mysqli_get_server_info( $wpdb->dbh );
160160
} else {
161-
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info
161+
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
162162
$mysql_server_type = mysql_get_server_info( $wpdb->dbh );
163163
}
164164

@@ -1171,7 +1171,7 @@ public function get_test_utf8mb4_support() {
11711171
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info
11721172
$mysql_client_version = mysqli_get_client_info();
11731173
} else {
1174-
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info
1174+
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
11751175
$mysql_client_version = mysql_get_client_info();
11761176
}
11771177

src/wp-admin/includes/file.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,7 @@ function verify_file_signature( $filename, $signatures, $filename_for_errors = f
12801280
),
12811281
array(
12821282
'php' => phpversion(),
1283+
// phpcs:ignore PHPCompatibility.Constants.NewConstants.sodium_library_versionFound
12831284
'sodium' => defined( 'SODIUM_LIBRARY_VERSION' ) ? SODIUM_LIBRARY_VERSION : ( defined( 'ParagonIE_Sodium_Compat::VERSION_STRING' ) ? ParagonIE_Sodium_Compat::VERSION_STRING : false ),
12841285
)
12851286
);
@@ -1313,6 +1314,7 @@ function verify_file_signature( $filename, $signatures, $filename_for_errors = f
13131314
),
13141315
array(
13151316
'php' => phpversion(),
1317+
// phpcs:ignore PHPCompatibility.Constants.NewConstants.sodium_library_versionFound
13161318
'sodium' => defined( 'SODIUM_LIBRARY_VERSION' ) ? SODIUM_LIBRARY_VERSION : ( defined( 'ParagonIE_Sodium_Compat::VERSION_STRING' ) ? ParagonIE_Sodium_Compat::VERSION_STRING : false ),
13171319
'polyfill_is_fast' => false,
13181320
'max_execution_time' => ini_get( 'max_execution_time' ),
@@ -1386,6 +1388,7 @@ function verify_file_signature( $filename, $signatures, $filename_for_errors = f
13861388
'skipped_key' => $skipped_key,
13871389
'skipped_sig' => $skipped_signature,
13881390
'php' => phpversion(),
1391+
// phpcs:ignore PHPCompatibility.Constants.NewConstants.sodium_library_versionFound
13891392
'sodium' => defined( 'SODIUM_LIBRARY_VERSION' ) ? SODIUM_LIBRARY_VERSION : ( defined( 'ParagonIE_Sodium_Compat::VERSION_STRING' ) ? ParagonIE_Sodium_Compat::VERSION_STRING : false ),
13901393
)
13911394
);

src/wp-admin/includes/upgrade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2475,7 +2475,7 @@ function get_alloptions_110() {
24752475
* @param string $setting Option name.
24762476
* @return mixed
24772477
*/
2478-
function __get_option( $setting ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore
2478+
function __get_option( $setting ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
24792479
global $wpdb;
24802480

24812481
if ( $setting == 'home' && defined( 'WP_HOME' ) ) {

src/wp-includes/author-template.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,6 @@ function is_multi_author() {
565565
* @since 3.2.0
566566
* @access private
567567
*/
568-
function __clear_multi_author_cache() { //phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore
568+
function __clear_multi_author_cache() { //phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
569569
delete_transient( 'is_multi_author' );
570570
}

src/wp-includes/deprecated.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,7 +1798,7 @@ function _nc( $single, $plural, $number, $domain = 'default' ) {
17981798
* @deprecated 2.8.0 Use _n()
17991799
* @see _n()
18001800
*/
1801-
function __ngettext( ...$args ) {
1801+
function __ngettext( ...$args ) { // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
18021802
_deprecated_function( __FUNCTION__, '2.8.0', '_n()' );
18031803
return _n( ...$args );
18041804
}
@@ -1810,7 +1810,7 @@ function __ngettext( ...$args ) {
18101810
* @deprecated 2.8.0 Use _n_noop()
18111811
* @see _n_noop()
18121812
*/
1813-
function __ngettext_noop( ...$args ) {
1813+
function __ngettext_noop( ...$args ) { // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.FunctionDoubleUnderscore
18141814
_deprecated_function( __FUNCTION__, '2.8.0', '_n_noop()' );
18151815
return _n_noop( ...$args );
18161816

0 commit comments

Comments
 (0)