';
+ if ( $has_dependents ) {
+ $this->add_dependents_to_dependency_plugin_row( $plugin_file );
+ }
+
+ if ( WP_Plugin_Dependencies::has_dependencies( $plugin_file ) ) {
+ $this->add_dependencies_to_dependent_plugin_row( $plugin_file );
+ }
+
+ /**
+ * Fires after plugin row meta.
+ *
+ * @since 6.5.0
+ *
+ * @param string $plugin_file Refer to {@see 'plugin_row_meta'} filter.
+ * @param array $plugin_data Refer to {@see 'plugin_row_meta'} filter.
+ */
+ do_action( 'after_plugin_row_meta', $plugin_file, $plugin_data );
+
if ( $paused ) {
$notice_text = __( 'This plugin failed to load properly and is paused during recovery mode.' );
@@ -1156,7 +1291,7 @@
echo '';
break;
case 'auto-updates':
- if ( ! $this->show_autoupdates ) {
+ if ( ! $this->show_autoupdates || in_array( $status, array( 'mustuse', 'dropins' ), true ) ) {
break;
}
@@ -1229,13 +1364,20 @@
* 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. See `get_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 );
- echo '
';
+ wp_admin_notice(
+ '',
+ array(
+ 'type' => 'error',
+ 'additional_classes' => array( 'notice-alt', 'inline', 'hidden' ),
+ )
+ );
+
echo '';
break;
@@ -1251,7 +1393,7 @@
*
* @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. See `get_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.
*/
@@ -1265,58 +1407,65 @@
if ( ! $compatible_php || ! $compatible_wp ) {
printf(
- '
' .
- '
' .
- '
',
+ '
',
esc_attr( $this->get_column_count() )
);
+ $incompatible_message = '';
if ( ! $compatible_php && ! $compatible_wp ) {
- _e( 'This plugin does not work with your versions of WordPress and PHP.' );
+ $incompatible_message .= __( 'This plugin does not work with your versions of WordPress and PHP.' );
if ( current_user_can( 'update_core' ) && current_user_can( 'update_php' ) ) {
- printf(
+ $incompatible_message .= sprintf(
/* 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( '
', '', false );
}
} elseif ( ! $compatible_wp ) {
- _e( 'This plugin does not work with your version of WordPress.' );
+ $incompatible_message .= __( 'This plugin does not work with your version of WordPress.' );
if ( current_user_can( 'update_core' ) ) {
- printf(
+ $incompatible_message .= sprintf(
/* 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.' );
+ $incompatible_message .= __( 'This plugin does not work with your version of PHP.' );
if ( current_user_can( 'update_php' ) ) {
- printf(
+ $incompatible_message .= sprintf(
/* translators: %s: URL to Update PHP page. */
' ' . __( 'Learn more about updating PHP.' ),
esc_url( wp_get_update_php_url() )
);
- wp_update_php_annotation( '
';
}
/**
@@ -1327,7 +1476,7 @@
* 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. See `get_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.
* @param string $status Status filter currently applied to the plugin list.
@@ -1348,7 +1497,7 @@
* 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. See `get_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.
* @param string $status Status filter currently applied to the plugin list.
@@ -1369,4 +1518,140 @@
protected function get_primary_column_name() {
return 'name';
}
+
+ /**
+ * Prints a list of other plugins that depend on the plugin.
+ *
+ * @since 6.5.0
+ *
+ * @param string $dependency The dependency's filepath, relative to the plugins directory.
+ */
+ protected function add_dependents_to_dependency_plugin_row( $dependency ) {
+ $dependent_names = WP_Plugin_Dependencies::get_dependent_names( $dependency );
+
+ if ( empty( $dependent_names ) ) {
+ return;
+ }
+
+ $dependency_note = __( 'Note: This plugin cannot be deactivated or deleted until the plugins that require it are deactivated or deleted.' );
+
+ $comma = wp_get_list_item_separator();
+ $required_by = sprintf(
+ /* translators: %s: List of dependencies. */
+ __( 'Required by: %s' ),
+ implode( $comma, $dependent_names )
+ );
+
+ printf(
+ '
%1$s
%2$s
',
+ $required_by,
+ $dependency_note
+ );
+ }
+
+ /**
+ * Prints a list of other plugins that the plugin depends on.
+ *
+ * @since 6.5.0
+ *
+ * @param string $dependent The dependent plugin's filepath, relative to the plugins directory.
+ */
+ protected function add_dependencies_to_dependent_plugin_row( $dependent ) {
+ $dependency_names = WP_Plugin_Dependencies::get_dependency_names( $dependent );
+
+ if ( array() === $dependency_names ) {
+ return;
+ }
+
+ $links = array();
+ foreach ( $dependency_names as $slug => $name ) {
+ $links[] = $this->get_dependency_view_details_link( $name, $slug );
+ }
+
+ $is_active = is_multisite() ? is_plugin_active_for_network( $dependent ) : is_plugin_active( $dependent );
+ $comma = wp_get_list_item_separator();
+ $requires = sprintf(
+ /* translators: %s: List of dependency names. */
+ __( 'Requires: %s' ),
+ implode( $comma, $links )
+ );
+
+ $notice = '';
+ $error_message = '';
+ if ( WP_Plugin_Dependencies::has_unmet_dependencies( $dependent ) ) {
+ if ( $is_active ) {
+ $error_message = __( 'This plugin is active but may not function correctly because required plugins are missing or inactive.' );
+ } else {
+ $error_message = __( 'This plugin cannot be activated because required plugins are missing or inactive.' );
+ }
+ $notice = wp_get_admin_notice(
+ $error_message,
+ array(
+ 'type' => 'error',
+ 'additional_classes' => array( 'inline', 'notice-alt' ),
+ )
+ );
+ }
+
+ printf(
+ '
%1$s
%2$s
',
+ $requires,
+ $notice
+ );
+ }
+
+ /**
+ * Returns a 'View details' like link for a dependency.
+ *
+ * @since 6.5.0
+ *
+ * @param string $name The dependency's name.
+ * @param string $slug The dependency's slug.
+ * @return string A 'View details' link for the dependency.
+ */
+ protected function get_dependency_view_details_link( $name, $slug ) {
+ $dependency_data = WP_Plugin_Dependencies::get_dependency_data( $slug );
+
+ if ( false === $dependency_data
+ || $name === $slug
+ || $name !== $dependency_data['name']
+ || empty( $dependency_data['version'] )
+ ) {
+ return $name;
+ }
+
+ return $this->get_view_details_link( $name, $slug );
+ }
+
+ /**
+ * Returns a 'View details' link for the plugin.
+ *
+ * @since 6.5.0
+ *
+ * @param string $name The plugin's name.
+ * @param string $slug The plugin's slug.
+ * @return string A 'View details' link for the plugin.
+ */
+ protected function get_view_details_link( $name, $slug ) {
+ $url = add_query_arg(
+ array(
+ 'tab' => 'plugin-information',
+ 'plugin' => $slug,
+ 'TB_iframe' => 'true',
+ 'width' => '600',
+ 'height' => '550',
+ ),
+ network_admin_url( 'plugin-install.php' )
+ );
+
+ $name_attr = esc_attr( $name );
+ return sprintf(
+ "%s",
+ esc_url( $url ),
+ /* translators: %s: Plugin name. */
+ sprintf( __( 'More information about %s' ), $name_attr ),
+ $name_attr,
+ esc_html( $name )
+ );
+ }
}