diff -r be944660c56a -r 3d72ae0968f4 wp/wp-admin/includes/class-wp-plugins-list-table.php --- a/wp/wp-admin/includes/class-wp-plugins-list-table.php Wed Sep 21 18:19:35 2022 +0200 +++ b/wp/wp-admin/includes/class-wp-plugins-list-table.php Tue Sep 27 16:37:53 2022 +0200 @@ -739,6 +739,12 @@ $restrict_network_active = false; $restrict_network_only = false; + $requires_php = isset( $plugin_data['RequiresPHP'] ) ? $plugin_data['RequiresPHP'] : null; + $requires_wp = isset( $plugin_data['RequiresWP'] ) ? $plugin_data['RequiresWP'] : null; + + $compatible_php = is_php_version_compatible( $requires_php ); + $compatible_wp = is_wp_version_compatible( $requires_wp ); + if ( 'mustuse' === $context ) { $is_active = true; } elseif ( 'dropins' === $context ) { @@ -792,14 +798,21 @@ } } else { if ( current_user_can( 'manage_network_plugins' ) ) { - $actions['activate'] = sprintf( - '%s', - wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ) . '&plugin_status=' . $context . '&paged=' . $page . '&s=' . $s, 'activate-plugin_' . $plugin_file ), - esc_attr( $plugin_id_attr ), - /* translators: %s: Plugin name. */ - esc_attr( sprintf( _x( 'Network Activate %s', 'plugin' ), $plugin_data['Name'] ) ), - __( 'Network Activate' ) - ); + if ( $compatible_php && $compatible_wp ) { + $actions['activate'] = sprintf( + '%s', + wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ) . '&plugin_status=' . $context . '&paged=' . $page . '&s=' . $s, 'activate-plugin_' . $plugin_file ), + esc_attr( $plugin_id_attr ), + /* translators: %s: Plugin name. */ + esc_attr( sprintf( _x( 'Network Activate %s', 'plugin' ), $plugin_data['Name'] ) ), + __( 'Network Activate' ) + ); + } else { + $actions['activate'] = sprintf( + '%s', + _x( 'Cannot Activate', 'plugin' ) + ); + } } if ( current_user_can( 'delete_plugins' ) && ! is_plugin_active( $plugin_file ) ) { @@ -846,14 +859,21 @@ } } else { if ( current_user_can( 'activate_plugin', $plugin_file ) ) { - $actions['activate'] = sprintf( - '%s', - wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ) . '&plugin_status=' . $context . '&paged=' . $page . '&s=' . $s, 'activate-plugin_' . $plugin_file ), - esc_attr( $plugin_id_attr ), - /* translators: %s: Plugin name. */ - esc_attr( sprintf( _x( 'Activate %s', 'plugin' ), $plugin_data['Name'] ) ), - __( 'Activate' ) - ); + if ( $compatible_php && $compatible_wp ) { + $actions['activate'] = sprintf( + '%s', + wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ) . '&plugin_status=' . $context . '&paged=' . $page . '&s=' . $s, 'activate-plugin_' . $plugin_file ), + esc_attr( $plugin_id_attr ), + /* translators: %s: Plugin name. */ + esc_attr( sprintf( _x( 'Activate %s', 'plugin' ), $plugin_data['Name'] ) ), + __( 'Activate' ) + ); + } else { + $actions['activate'] = sprintf( + '%s', + _x( 'Cannot Activate', 'plugin' ) + ); + } } if ( ! is_multisite() && current_user_can( 'delete_plugins' ) ) { @@ -879,12 +899,15 @@ * * @since 3.1.0 * - * @param string[] $actions An array of plugin action links. By default this can include 'activate', - * 'deactivate', and 'delete'. + * @param string[] $actions An array of plugin action links. By default this can include + * 'activate', 'deactivate', and 'delete'. * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. See `get_plugin_data()`. - * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive', - * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. + * @param string $context The plugin context. By default this can include 'all', + * 'active', 'inactive', 'recently_activated', 'upgrade', + * 'mustuse', 'dropins', and 'search'. */ $actions = apply_filters( 'network_admin_plugin_action_links', $actions, $plugin_file, $plugin_data, $context ); @@ -896,12 +919,15 @@ * * @since 3.1.0 * - * @param string[] $actions An array of plugin action links. By default this can include 'activate', - * 'deactivate', and 'delete'. + * @param string[] $actions An array of plugin action links. By default this can include + * 'activate', 'deactivate', and 'delete'. * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. See `get_plugin_data()`. - * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive', - * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. + * @param string $context The plugin context. By default this can include 'all', + * 'active', 'inactive', 'recently_activated', 'upgrade', + * 'mustuse', 'dropins', and 'search'. */ $actions = apply_filters( "network_admin_plugin_action_links_{$plugin_file}", $actions, $plugin_file, $plugin_data, $context ); @@ -914,13 +940,16 @@ * @since 2.6.0 The `$context` parameter was added. * @since 4.9.0 The 'Edit' link was removed from the list of action links. * - * @param string[] $actions An array of plugin action links. By default this can include 'activate', - * 'deactivate', and 'delete'. With Multisite active this can also include - * 'network_active' and 'network_only' items. + * @param string[] $actions An array of plugin action links. By default this can include + * 'activate', 'deactivate', and 'delete'. With Multisite active + * this can also include 'network_active' and 'network_only' items. * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. See `get_plugin_data()`. - * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive', - * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. + * @param string $context The plugin context. By default this can include 'all', + * 'active', 'inactive', 'recently_activated', 'upgrade', + * 'mustuse', 'dropins', and 'search'. */ $actions = apply_filters( 'plugin_action_links', $actions, $plugin_file, $plugin_data, $context ); @@ -933,22 +962,23 @@ * @since 2.7.0 * @since 4.9.0 The 'Edit' link was removed from the list of action links. * - * @param string[] $actions An array of plugin action links. By default this can include 'activate', - * 'deactivate', and 'delete'. With Multisite active this can also include - * 'network_active' and 'network_only' items. + * @param string[] $actions An array of plugin action links. By default this can include + * 'activate', 'deactivate', and 'delete'. With Multisite active + * this can also include 'network_active' and 'network_only' items. * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. See `get_plugin_data()`. - * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive', - * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. + * @param string $context The plugin context. By default this can include 'all', + * 'active', 'inactive', 'recently_activated', 'upgrade', + * 'mustuse', 'dropins', and 'search'. */ $actions = apply_filters( "plugin_action_links_{$plugin_file}", $actions, $plugin_file, $plugin_data, $context ); } - $requires_php = isset( $plugin_data['requires_php'] ) ? $plugin_data['requires_php'] : null; - $compatible_php = is_php_version_compatible( $requires_php ); - $class = $is_active ? 'active' : 'inactive'; - $checkbox_id = 'checkbox_' . md5( $plugin_file ); + $class = $is_active ? 'active' : 'inactive'; + $checkbox_id = 'checkbox_' . md5( $plugin_file ); if ( $restrict_network_active || $restrict_network_only || in_array( $status, array( 'mustuse', 'dropins' ), true ) || ! $compatible_php ) { $checkbox = ''; @@ -968,7 +998,9 @@ $plugin_name = $plugin_data['Name']; } - if ( ! empty( $totals['upgrade'] ) && ! empty( $plugin_data['update'] ) ) { + if ( ! empty( $totals['upgrade'] ) && ! empty( $plugin_data['update'] ) + || ! $compatible_php || ! $compatible_wp + ) { $class .= ' update'; } @@ -1046,9 +1078,13 @@ __( 'View details' ) ); } elseif ( ! empty( $plugin_data['PluginURI'] ) ) { + /* translators: %s: Plugin name. */ + $aria_label = sprintf( __( 'Visit plugin site for %s' ), $plugin_name ); + $plugin_meta[] = sprintf( - '%s', + '%s', esc_url( $plugin_data['PluginURI'] ), + esc_attr( $aria_label ), __( 'Visit plugin site' ) ); } @@ -1061,7 +1097,39 @@ * @param string[] $plugin_meta An array of the plugin's metadata, including * the version, author, author URI, and plugin URI. * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. + * @param array $plugin_data { + * An array of plugin data. + * + * @type string $id Plugin ID, e.g. `w.org/plugins/[plugin-name]`. + * @type string $slug Plugin slug. + * @type string $plugin Plugin basename. + * @type string $new_version New plugin version. + * @type string $url Plugin URL. + * @type string $package Plugin update package URL. + * @type string[] $icons An array of plugin icon URLs. + * @type string[] $banners An array of plugin banner URLs. + * @type string[] $banners_rtl An array of plugin RTL banner URLs. + * @type string $requires The version of WordPress which the plugin requires. + * @type string $tested The version of WordPress the plugin is tested against. + * @type string $requires_php The version of PHP which the plugin requires. + * @type string $upgrade_notice The upgrade notice for the new plugin version. + * @type bool $update-supported Whether the plugin supports updates. + * @type string $Name The human-readable name of the plugin. + * @type string $PluginURI Plugin URI. + * @type string $Version Plugin version. + * @type string $Description Plugin description. + * @type string $Author Plugin author. + * @type string $AuthorURI Plugin author URI. + * @type string $TextDomain Plugin textdomain. + * @type string $DomainPath Relative path to the plugin's .mo file(s). + * @type bool $Network Whether the plugin can only be activated network-wide. + * @type string $RequiresWP The version of WordPress which the plugin requires. + * @type string $RequiresPHP The version of PHP which the plugin requires. + * @type string $UpdateURI ID of the plugin for update purposes, should be a URI. + * @type string $Title The human-readable title of the plugin. + * @type string $AuthorName Plugin author's name. + * @type bool $update Whether there's an available update. Default null. + * } * @param string $status Status filter currently applied to the plugin list. Possible * values are: 'all', 'active', 'inactive', 'recently_activated', * 'upgrade', 'mustuse', 'dropins', 'search', 'paused', @@ -1157,10 +1225,13 @@ * * @since 5.5.0 * - * @param string $html The HTML of the plugin's auto-update column content, including - * toggle auto-update action links and time to next update. + * @param string $html The HTML of the plugin's auto-update column content, + * including toggle auto-update action links and + * time to next update. * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. */ echo apply_filters( 'plugin_auto_update_setting_html', $html, $plugin_file, $plugin_data ); @@ -1180,7 +1251,9 @@ * * @param string $column_name Name of the column. * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. */ do_action( 'manage_plugins_custom_column', $column_name, $plugin_file, $plugin_data ); @@ -1190,18 +1263,77 @@ echo ''; + if ( ! $compatible_php || ! $compatible_wp ) { + printf( + '' . + '' . + '

', + esc_attr( $this->get_column_count() ) + ); + + if ( ! $compatible_php && ! $compatible_wp ) { + _e( 'This plugin does not work with your versions of WordPress and PHP.' ); + if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) { + printf( + /* translators: 1: URL to WordPress Updates screen, 2: URL to Update PHP page. */ + ' ' . __( 'Please update WordPress, and then learn more about updating PHP.' ), + self_admin_url( 'update-core.php' ), + esc_url( wp_get_update_php_url() ) + ); + wp_update_php_annotation( '

', '' ); + } elseif ( current_user_can( 'update_core' ) ) { + printf( + /* translators: %s: URL to WordPress Updates screen. */ + ' ' . __( 'Please update WordPress.' ), + self_admin_url( 'update-core.php' ) + ); + } elseif ( current_user_can( 'update_php' ) ) { + printf( + /* translators: %s: URL to Update PHP page. */ + ' ' . __( 'Learn more about updating PHP.' ), + esc_url( wp_get_update_php_url() ) + ); + wp_update_php_annotation( '

', '' ); + } + } elseif ( ! $compatible_wp ) { + _e( 'This plugin does not work with your version of WordPress.' ); + if ( current_user_can( 'update_core' ) ) { + printf( + /* translators: %s: URL to WordPress Updates screen. */ + ' ' . __( 'Please update WordPress.' ), + self_admin_url( 'update-core.php' ) + ); + } + } elseif ( ! $compatible_php ) { + _e( 'This plugin does not work with your version of PHP.' ); + if ( current_user_can( 'update_php' ) ) { + printf( + /* translators: %s: URL to Update PHP page. */ + ' ' . __( 'Learn more about updating PHP.' ), + esc_url( wp_get_update_php_url() ) + ); + wp_update_php_annotation( '

', '' ); + } + } + + echo '

'; + } + /** * Fires after each row in the Plugins list table. * * @since 2.3.0 - * @since 5.5.0 Added 'auto-update-enabled' and 'auto-update-disabled' to possible values for `$status`. + * @since 5.5.0 Added 'auto-update-enabled' and 'auto-update-disabled' + * to possible values for `$status`. * * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. - * @param string $status Status filter currently applied to the plugin list. Possible - * values are: 'all', 'active', 'inactive', 'recently_activated', - * 'upgrade', 'mustuse', 'dropins', 'search', 'paused', - * 'auto-update-enabled', 'auto-update-disabled'. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. + * @param string $status Status filter currently applied to the plugin list. + * Possible values are: 'all', 'active', 'inactive', + * 'recently_activated', 'upgrade', 'mustuse', 'dropins', + * 'search', 'paused', 'auto-update-enabled', 'auto-update-disabled'. */ do_action( 'after_plugin_row', $plugin_file, $plugin_data, $status ); @@ -1212,14 +1344,17 @@ * to the plugin file, relative to the plugins directory. * * @since 2.7.0 - * @since 5.5.0 Added 'auto-update-enabled' and 'auto-update-disabled' to possible values for `$status`. + * @since 5.5.0 Added 'auto-update-enabled' and 'auto-update-disabled' + * to possible values for `$status`. * * @param string $plugin_file Path to the plugin file relative to the plugins directory. - * @param array $plugin_data An array of plugin data. - * @param string $status Status filter currently applied to the plugin list. Possible - * values are: 'all', 'active', 'inactive', 'recently_activated', - * 'upgrade', 'mustuse', 'dropins', 'search', 'paused', - * 'auto-update-enabled', 'auto-update-disabled'. + * @param array $plugin_data An array of plugin data. See `get_plugin_data()` + * and the {@see 'plugin_row_meta'} filter for the list + * of possible values. + * @param string $status Status filter currently applied to the plugin list. + * Possible values are: 'all', 'active', 'inactive', + * 'recently_activated', 'upgrade', 'mustuse', 'dropins', + * 'search', 'paused', 'auto-update-enabled', 'auto-update-disabled'. */ do_action( "after_plugin_row_{$plugin_file}", $plugin_file, $plugin_data, $status ); }