Skip to content

Commit eed75b2

Browse files
committed
feat: Enhance compatibility checks for plugins with tested upto WordPress version
1 parent 38c3584 commit eed75b2

File tree

2 files changed

+196
-2
lines changed

2 files changed

+196
-2
lines changed

src/wp-admin/includes/class-wp-plugins-list-table.php

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,30 @@ public function prepare_items() {
150150
$plugins['dropins'] = get_dropins();
151151
}
152152

153+
/**
154+
* REPLACE WITH (or ADD AFTER the above code):
155+
*/
153156
if ( current_user_can( 'update_plugins' ) ) {
154157
$current = get_site_transient( 'update_plugins' );
158+
// echo '<pre>';
159+
// echo print_r( $current->response, true );
160+
// echo '</pre>';
155161
foreach ( (array) $plugins['all'] as $plugin_file => $plugin_data ) {
162+
// Check if plugin has an available update.
156163
if ( isset( $current->response[ $plugin_file ] ) ) {
164+
157165
$plugins['all'][ $plugin_file ]['update'] = true;
158166
$plugins['upgrade'][ $plugin_file ] = $plugins['all'][ $plugin_file ];
167+
168+
// Merge additional API data from update response.
169+
// This includes: slug, tested, requires, requires_php, etc.
170+
$api_data = (array) $current->response[ $plugin_file ];
171+
$plugins['all'][ $plugin_file ] = array_merge( $plugins['all'][ $plugin_file ], $api_data );
172+
173+
} elseif ( isset( $current->no_update[ $plugin_file ] ) ) {
174+
// Plugin is up-to-date, but we still want API data (tested, requires, etc.)
175+
$api_data = (array) $current->no_update[ $plugin_file ];
176+
$plugins['all'][ $plugin_file ] = array_merge( $plugins['all'][ $plugin_file ], $api_data );
159177
}
160178
}
161179
}
@@ -454,7 +472,8 @@ public function search_box( $text, $input_id ) {
454472
?>
455473
<p class="search-box">
456474
<label for="<?php echo esc_attr( $input_id ); ?>"><?php echo $text; ?></label>
457-
<input type="search" id="<?php echo esc_attr( $input_id ); ?>" class="wp-filter-search" name="s" value="<?php _admin_search_query(); ?>" />
475+
<input type="search" id="<?php echo esc_attr( $input_id ); ?>" class="wp-filter-search" name="s"
476+
value="<?php _admin_search_query(); ?>" />
458477
<?php submit_button( $text, 'hide-if-js', '', false, array( 'id' => 'search-submit' ) ); ?>
459478
</p>
460479
<?php
@@ -759,6 +778,54 @@ public function single_row( $item ) {
759778
$compatible_php = is_php_version_compatible( $requires_php );
760779
$compatible_wp = is_wp_version_compatible( $requires_wp );
761780

781+
if ( ! function_exists( 'plugins_api' ) ) {
782+
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
783+
}
784+
785+
$plugin_information = plugins_api(
786+
'plugin_information',
787+
array(
788+
'slug' => $plugin_slug,
789+
'fields' => array(
790+
'sections' => false,
791+
'rating' => false,
792+
'downloaded' => false,
793+
'last_updated' => false,
794+
'banners' => false,
795+
'icons' => false,
796+
'active_installs' => false,
797+
'short_description' => false,
798+
'tags' => false,
799+
'compatibility' => false,
800+
'contributors' => false,
801+
'ratings' => false,
802+
'screenshots' => false,
803+
'support_url' => false,
804+
'added' => false,
805+
'homepage' => false,
806+
'download_link' => false,
807+
'upgrade_notice' => false,
808+
'versions' => false,
809+
'business_model' => false,
810+
'repository_url' => false,
811+
'commercial_support_url' => false,
812+
'donate_link' => false,
813+
'preview_link' => false,
814+
)
815+
)
816+
);
817+
818+
$tested_wp = null;
819+
$tested_compatible = true;
820+
821+
if ( ! is_wp_error( $plugin_information ) && isset( $plugin_information->tested ) ) {
822+
$tested_wp = $plugin_information->tested;
823+
}
824+
825+
if ( null !== $tested_wp ) {
826+
$tested_compatible = is_tested_wp_version_compatible( $tested_wp );
827+
}
828+
762829
$has_dependents = WP_Plugin_Dependencies::has_dependents( $plugin_file );
763830
$has_active_dependents = WP_Plugin_Dependencies::has_active_dependents( $plugin_file );
764831
$has_unmet_dependencies = WP_Plugin_Dependencies::has_unmet_dependencies( $plugin_file );
@@ -1510,6 +1577,100 @@ public function single_row( $item ) {
15101577
* 'search', 'paused', 'auto-update-enabled', 'auto-update-disabled'.
15111578
*/
15121579
do_action( "after_plugin_row_{$plugin_file}", $plugin_file, $plugin_data, $status );
1580+
1581+
if ( ! $tested_compatible ) {
1582+
global $wp_version;
1583+
$show_compat_warning = true;
1584+
$compat_message = sprintf(
1585+
/* translators: 1: Current WordPress version, 2: Version the plugin was tested up to. */
1586+
__( 'This plugin has not been tested with your current version of WordPress (%1$s). It may still work, but consider checking for an update or contacting the plugin author. Last tested with WordPress %2$s.' ),
1587+
$wp_version,
1588+
$tested_wp,
1589+
);
1590+
1591+
/**
1592+
* Filters whether to show compatibility warning for a plugin.
1593+
*
1594+
* @since 6.8.0
1595+
*
1596+
* @param bool $show_compat_warning Whether to show the compatibility warning.
1597+
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
1598+
* @param array $plugin_data An array of plugin data. See get_plugin_data()
1599+
* and the {@see 'plugin_row_meta'} filter for the list
1600+
* of possible values.
1601+
* @param string $tested_wp The WordPress version the plugin was tested up to.
1602+
* @param string $wp_version Current WordPress version.
1603+
*/
1604+
$show_compat_warning = apply_filters(
1605+
'show_plugin_compatibility_warning',
1606+
$show_compat_warning,
1607+
$plugin_file,
1608+
$plugin_data,
1609+
$tested_wp,
1610+
$wp_version
1611+
);
1612+
1613+
/**
1614+
* Filters the compatibility warning message for a plugin.
1615+
*
1616+
* @since 6.8.0
1617+
*
1618+
* @param string $compat_message The compatibility warning message.
1619+
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
1620+
* @param array $plugin_data An array of plugin data. See get_plugin_data()
1621+
* and the {@see 'plugin_row_meta'} filter for the list
1622+
* of possible values.
1623+
* @param string $tested_wp The WordPress version the plugin was tested up to.
1624+
* @param string $wp_version Current WordPress version.
1625+
*/
1626+
$compat_message = apply_filters(
1627+
'plugin_compatibility_warning_message',
1628+
$compat_message,
1629+
$plugin_file,
1630+
$plugin_data,
1631+
$tested_wp,
1632+
$wp_version
1633+
);
1634+
1635+
if ( $show_compat_warning && ! empty( $compat_message ) ) {
1636+
printf(
1637+
'<tr class="plugin-update-tr%s" id="%s" data-slug="%s" data-plugin="%s"><td colspan="%s" class="plugin-update colspanchange">',
1638+
$is_active ? ' active' : ' inactive',
1639+
esc_attr( $plugin_slug . '-compat-warning' ),
1640+
esc_attr( $plugin_slug ),
1641+
esc_attr( $plugin_file ),
1642+
esc_attr( $this->get_column_count() )
1643+
);
1644+
1645+
$details_url = '';
1646+
$details_link = '';
1647+
1648+
if ( current_user_can( 'install_plugins' ) ) {
1649+
$details_url = network_admin_url(
1650+
'plugin-install.php?tab=plugin-information&plugin=' . $plugin_data['slug'] .
1651+
'&TB_iframe=true&width=600&height=550'
1652+
);
1653+
1654+
$details_link = sprintf(
1655+
' <a href="%s" class="thickbox open-plugin-details-modal" aria-label="%s">%s</a>',
1656+
esc_url( $details_url ),
1657+
/* translators: %s: Plugin name. */
1658+
esc_attr( sprintf( __( 'More information about %s' ), $plugin_data['Name'] ) ),
1659+
__( 'View details' )
1660+
);
1661+
}
1662+
1663+
wp_admin_notice(
1664+
$compat_message . $details_link,
1665+
array(
1666+
'type' => 'warning',
1667+
'additional_classes' => array( 'notice-alt', 'inline' ),
1668+
)
1669+
);
1670+
1671+
echo '</td></tr>';
1672+
}
1673+
}
15131674
}
15141675

15151676
/**

src/wp-includes/functions.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8971,10 +8971,43 @@ function is_wp_version_compatible( $required ) {
89718971
$required = substr( $trimmed, 0, -2 );
89728972
}
89738973
}
8974-
89758974
return empty( $required ) || version_compare( $version, $required, '>=' );
89768975
}
89778976

8977+
/**
8978+
* Checks compatibility with the tested WordPress version.
8979+
*
8980+
* @since 6.9.0
8981+
*
8982+
* @global string $_wp_tests_wp_version The WordPress version string. Used only in Core tests.
8983+
*
8984+
* @param string $required Maximum required WordPress version.
8985+
* @return bool True if required version is compatible, false if not.
8986+
*/
8987+
function is_tested_wp_version_compatible( $required ) {
8988+
if (
8989+
defined( 'WP_RUN_CORE_TESTS' )
8990+
&& WP_RUN_CORE_TESTS
8991+
&& isset( $GLOBALS['_wp_tests_wp_version'] )
8992+
) {
8993+
$wp_version = $GLOBALS['_wp_tests_wp_version'];
8994+
} else {
8995+
$wp_version = wp_get_wp_version();
8996+
}
8997+
8998+
// Strip off any -alpha, -RC, -beta, -src suffixes.
8999+
list( $version ) = explode( '-', $wp_version );
9000+
9001+
if ( is_string( $required ) ) {
9002+
$trimmed = trim( $required );
9003+
9004+
if ( substr_count( $trimmed, '.' ) > 1 && str_ends_with( $trimmed, '.0' ) ) {
9005+
$required = substr( $trimmed, 0, -2 );
9006+
}
9007+
}
9008+
return version_compare( $version, $required, '<=' );
9009+
}
9010+
89789011
/**
89799012
* Checks compatibility with the current PHP version.
89809013
*

0 commit comments

Comments
 (0)