Skip to content

Commit f1135f9

Browse files
swissspidyclaude
andauthored
Fix wp plugin list fatal on WordPress < 5.3 and quiet the wp-compat false positives (#543)
Co-authored-by: Pascal Birchler <pascal.birchler@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3d4ea50 commit f1135f9

3 files changed

Lines changed: 84 additions & 1 deletion

File tree

‎features/plugin-list-wporg-status.feature‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,50 @@ Feature: Check the status of plugins on WordPress.org
110110
| wordpress-importer | active | 2025-09-26 |
111111
| no-longer-in-directory | closed | 2017-11-13 |
112112
| never-wporg | | |
113+
114+
@less-than-wp-5.3
115+
Scenario: The wp.org last updated date is still rendered on WordPress < 5.3
116+
Given a WP install
117+
And I run `wp option update timezone_string Asia/Tokyo`
118+
And a wp-content/plugins/wporg-dated/wporg-dated.php file:
119+
"""
120+
<?php
121+
/**
122+
* Plugin Name: Plugin with a WordPress.org release date
123+
* Version: 1.0.0
124+
*/
125+
"""
126+
And that HTTP requests to https://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request%5Blocale%5D=en_US&request%5Bslug%5D=wporg-dated will respond with:
127+
"""
128+
HTTP/1.1 200
129+
Content-Type: application/json
130+
131+
{
132+
"name": "Plugin with a WordPress.org release date",
133+
"slug": "wporg-dated",
134+
"last_updated": "2025-09-26 9:07pm GMT"
135+
}
136+
"""
137+
And that HTTP requests to https://plugins.trac.wordpress.org/log/wporg-dated/?limit=1&mode=stop_on_copy&format=rss will respond with:
138+
"""
139+
HTTP/1.1 200
140+
Content-Type: application/rss+xml;charset=utf-8
141+
142+
<?xml version="1.0"?>
143+
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
144+
<channel>
145+
<item>
146+
<pubDate>Fri, 26 Sep 2025 21:07:26 GMT</pubDate>
147+
</item>
148+
</channel>
149+
</rss>
150+
"""
151+
152+
# wp_date() only exists since WordPress 5.3, so this goes through the
153+
# get_date_from_gmt() fallback. The pubDate above is 21:07 UTC, which is already
154+
# the next day in Asia/Tokyo, so this also pins that the fallback renders in the
155+
# site timezone rather than in UTC.
156+
When I run `wp plugin list --fields=name,wporg_last_updated`
157+
Then STDOUT should be a table containing rows:
158+
| name | wporg_last_updated |
159+
| wporg-dated | 2025-09-27 |

‎phpstan.neon.dist‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,27 @@ parameters:
1414
- identifier: missingType.property
1515
- identifier: missingType.parameter
1616
- identifier: missingType.return
17+
18+
# johnbillion/wp-compat checks every WordPress symbol against the WordPress 4.9
19+
# baseline that wp-cli-tests configures. It only recognizes function_exists() and
20+
# method_exists() guards, so it cannot see the `wp_version_compare()` checks that
21+
# gate the plugin dependency features, and reports those as errors.
22+
#
23+
# The entries below match on the message as well as the identifier, so that a call to
24+
# something introduced later than the version each feature is gated on still gets
25+
# reported rather than swallowed by a file-wide ignore.
26+
27+
# `wp plugin install --with-dependencies` aborts on WordPress < 6.5 in
28+
# `Plugin_Command::install()`, before reaching `get_plugin_dependencies()`, and
29+
# `wp plugin install-dependencies` does the same check in the command method itself.
30+
-
31+
identifier: WPCompat.methodNotAvailable
32+
message: '#^WP_Plugin_Dependencies::(get_dependencies|initialize)\(\) is only available since WordPress version 6\.5\.0\.$#'
33+
path: src/Plugin_Command.php
34+
35+
# WordPress 5.3 only formalized the already documented `...$arg` parameter of
36+
# `do_action()` by adding it to the function signature. Additional arguments were
37+
# collected through `func_get_args()` before that.
38+
-
39+
identifier: WPCompat.parameterNotAvailable.doaction.arg
40+
path: src/Plugin_Command.php

‎src/Plugin_Command.php‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,19 @@ protected function get_wporg_data( $plugin_name ) {
11221122
if ( false !== $xml ) {
11231123
$xml_pub_date = $xml->xpath( '//pubDate' );
11241124
if ( $xml_pub_date ) {
1125-
$data['last_updated'] = wp_date( 'Y-m-d', strtotime( $xml_pub_date[0] ) ?: null );
1125+
$pub_date = strtotime( $xml_pub_date[0] ) ?: null;
1126+
1127+
if ( function_exists( 'wp_date' ) ) {
1128+
$data['last_updated'] = wp_date( 'Y-m-d', $pub_date );
1129+
} else {
1130+
// wp_date() is WordPress 5.3+. get_date_from_gmt() renders in the site
1131+
// timezone the same way, without date_i18n()'s pre-5.3 contract of
1132+
// expecting a timestamp that already has the offset added to it.
1133+
$data['last_updated'] = get_date_from_gmt(
1134+
gmdate( 'Y-m-d H:i:s', $pub_date ?? time() ),
1135+
'Y-m-d'
1136+
);
1137+
}
11261138
}
11271139
}
11281140
}

0 commit comments

Comments
 (0)