Skip to content

Commit

Permalink
Merge branch 'develop' into trunk
Browse files Browse the repository at this point in the history
  • Loading branch information
afragen committed Jul 11, 2023
2 parents 79b2dcd + 633f800 commit c254079
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 78 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
[unreleased]

#### 1.13.0 / 2023-07-10
* update version check
* simplify plugin card notice

#### 1.12.1 / 2023-07-01
* extra life to 6.4-beta1

Expand Down
7 changes: 5 additions & 2 deletions plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Plugin URI: https://wordpress.org/plugins/wp-plugin-dependencies
* Description: Parses 'Requires Plugins' header, add plugin install dependencies tab, and information about dependencies.
* Author: Andy Fragen, Colin Stewart, Paul Biron
* Version: 1.12.1
* Version: 1.13.0
* License: MIT
* Network: true
* Requires at least: 6.0
Expand All @@ -40,7 +40,7 @@
}

// TODO: update with correct version.
if ( version_compare( get_bloginfo( 'version' ), '6.4-beta-1', '>=' ) ) {
if ( version_compare( get_bloginfo( 'version' ), '6.5-beta-1', '>=' ) ) {
define( 'WP_PLUGIN_DEPENDENCIES2_COMMITTED', true );
} else {
define( 'WP_PLUGIN_DEPENDENCIES2_COMMITTED', false );
Expand Down Expand Up @@ -79,6 +79,9 @@ static function( $class_name ) {
}
);

// Switch to simple plugin card.
add_filter( 'pd_simple_card', '__return_true' );

if ( ! WP_PLUGIN_DEPENDENCIES1_COMMITTED ) {
require_once __DIR__ . '/wp-admin/includes/class-wp-plugin-dependencies.php';

Expand Down
6 changes: 5 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Network: true
Requires at least: 6.0
Requires PHP: 5.6
Tested up to: 6.3
Stable tag: 1.12.1
Stable tag: 1.13.0

## Description

Expand Down Expand Up @@ -48,6 +48,10 @@ PRs should be made against the `develop` branch.

## Changelog

#### 1.13.0 / 2023-07-10
* update version check
* simplify plugin card notice

#### 1.12.1 / 2023-07-01
* extra life to 6.4-beta1

Expand Down
124 changes: 63 additions & 61 deletions wp-admin/includes/class-wp-plugin-dependencies.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* @package WordPress
* @subpackage Administration
* @since 6.3.0
* @since 6.4.0
*/

/**
Expand Down Expand Up @@ -64,6 +64,13 @@ final class WP_Plugin_Dependencies {
*/
private $plugin_dirnames_cache = array();

/**
* Holds data for plugin card.
*
* @var array
*/
private static $plugin_card_data = array();

/**
* Constructor.
*/
Expand All @@ -83,6 +90,7 @@ public function start() {
add_filter( 'plugins_api_result', array( $this, 'empty_plugins_api_result' ), 10, 3 );
add_filter( 'plugin_install_description', array( $this, 'plugin_install_description_installed' ), 10, 2 );
add_filter( 'plugin_install_description', array( $this, 'plugin_install_description_uninstalled' ), 10, 2 );
add_filter( 'plugin_install_description', array( $this, 'set_plugin_card_data' ), 10, 1 );
add_filter( 'plugin_install_action_links', array( $this, 'modify_plugin_install_action_links' ), 10, 2 );
add_filter( 'plugin_install_action_links', array( $this, 'empty_package_remove_install_button' ), 10, 2 );

Expand Down Expand Up @@ -481,12 +489,16 @@ public function modify_plugin_install_action_links( $action_links, $plugin ) {
public function empty_package_remove_install_button( $action_links, $plugin ) {
global $pagenow;

// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$tab = isset( $_GET['tab'] ) ? sanitize_title_with_dashes( wp_unslash( $_GET['tab'] ) ) : '';

if ( 'plugin-install.php' !== $pagenow
|| ! isset( $_GET['tab'] ) || 'dependencies' !== $_GET['tab'] // phpcs:ignore WordPress.Security.NonceVerification
|| 'dependencies' !== $tab
|| ! empty( $plugin['download_link'] ) || ! str_contains( $action_links[0], 'install-now' )
) {
return $action_links;
}

$action_links[0] = str_replace( __( 'Network Install' ), __( 'Install' ), $action_links[0] );
$action_links[0] = str_replace( __( 'Install Now' ), _x( 'Cannot Install', 'plugin' ), $action_links[0] );
$action_links[0] .= '<span class="screen-reader-text">' . __( 'Cannot install due to empty package' ) . '</span>';
Expand All @@ -503,24 +515,33 @@ public function empty_package_remove_install_button( $action_links, $plugin ) {
* @return string
*/
public function plugin_install_description_installed( $description, $plugin ) {
$required = '';
if ( in_array( $plugin['slug'], array_keys( $this->plugin_data ), true ) ) {
$dependents = $this->get_dependency_sources( $plugin );
$required = '<strong>' . __( 'Required by:' ) . '</strong> ' . $dependents;
$description = $description . '<p>' . $required . '</p>';
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$tab = isset( $_GET['tab'] ) ? sanitize_title_with_dashes( wp_unslash( $_GET['tab'] ) ) : '';
if ( 'dependencies' !== $tab ) {
return $description;
}

if ( ! isset( $this->plugin_dirnames[ $plugin['slug'] ] ) ) {
return $description;
$required = array();
$requires = array();
if ( ! isset( $plugin['requires_plugins'] ) ) {
$plugin['requires_plugins'] = array();
}
if ( in_array( $plugin['slug'], array_keys( $this->plugin_data ), true ) ) {
$dependents = $this->get_dependency_sources( $plugin );
$dependents = explode( ', ', $dependents );
$required[] = '<strong>' . __( 'Required by:' ) . '</strong>';
$required = array_merge( $required, $dependents );
}

$file = $this->plugin_dirnames[ $plugin['slug'] ];
if ( in_array( $file, array_keys( $this->requires_plugins ), true ) ) {
$require_names = $this->get_requires_plugins_names( $file );
$requires = '<strong>' . __( 'Requires:' ) . '</strong> ' . $require_names;
$description = $description . '<p>' . $requires . '</p>';
foreach ( (array) $plugin['requires_plugins']as $slug ) {
if ( isset( $this->plugin_data[ $slug ] ) ) {
$require_names = $this->plugin_data[ $slug ]['name'];
$requires[] = $require_names;
}
}

self::$plugin_card_data = array_merge( self::$plugin_card_data, $requires, $required );

return $description;
}

Expand All @@ -532,9 +553,6 @@ public function plugin_install_description_installed( $description, $plugin ) {
* @return string
*/
public function plugin_install_description_uninstalled( $description, $plugin ) {
if ( str_contains( $description, 'Required by:' ) || str_contains( $description, 'Requires:' ) ) {
return $description;
}
if ( empty( $plugin['requires_plugins'] ) ) {
return $description;
}
Expand Down Expand Up @@ -569,7 +587,6 @@ public function plugin_install_description_uninstalled( $description, $plugin )
set_site_transient( 'wp_plugin_dependencies_plugin_api_data', $this->plugin_api_data, WEEK_IN_SECONDS );
}

$required_names = array();
foreach ( $plugin['requires_plugins'] as $slug ) {
$plugin_data = $this->plugin_api_data[ $slug ];
$url = network_admin_url( 'plugin-install.php' );
Expand All @@ -584,58 +601,42 @@ public function plugin_install_description_uninstalled( $description, $plugin )
$url
);

// Check if plugin dependency is installed and active.
$plugin_is_active = 'plugin-dependency-incompatible';
$active_plugins = get_option( 'active_plugins' );
foreach ( $active_plugins as $plugin_file ) {
if ( str_contains( $plugin_file, '/' ) && explode( '/', $plugin_file )[0] === $slug ) {
$plugin_is_active = 'plugin-dependency-compatible';
break;
}
}

if ( isset( $plugin_data['name'] ) && ! empty( $plugin_data['version'] ) ) {
$plugin_dependency_name = sprintf(
'<span class="plugin-dependency-name %1$s">%2$s</span>',
esc_attr( $plugin_is_active ),
esc_html( $plugin_data['name'] )
);

$more_details_link = sprintf(
'<a href="%1$s" class="thickbox open-plugin-details-modal" aria-label="%2$s" data-title="%3$s">%4$s</a>',
$more_details_link[ $slug ] = sprintf(
'<a href="%1$s" class="alignright thickbox open-plugin-details-modal" aria-label="%2$s" data-title="%3$s">%3$s</a>',
esc_url( $url ),
/* translators: %s: Plugin name. */
esc_attr( sprintf( __( 'More information about %s' ), $plugin_data['name'] ) ),
esc_attr( $plugin_data['name'] ),
__( 'More details' )
);

$requires_php = isset( $plugin_data['requires_php'] ) ? $plugin_data['requires_php'] : '';
$requires_wp = isset( $plugin_data['requires'] ) ? $plugin_data['requires'] : '';

$compatible_php = is_php_version_compatible( $requires_php );
$compatible_wp = is_wp_version_compatible( $requires_wp );

$button = wp_get_plugin_action_button( $plugin_data['name'], $plugin_data, $compatible_php, $compatible_wp );

$required_names[] = '<div class="plugin-dependency plugin-card-' . esc_attr( $slug ) . '">' . $plugin_dependency_name . ' ' . $button . ' ' . $more_details_link . '</div>';
} else {
$required_names[] = $slug;
$more_details_link[ $slug ] = esc_attr( $plugin_data['name'] ) . '&nbsp' . $more_details_link[ $slug ];
}
}

$requires = '<strong>' . __( 'Additional plugins are required' ) . '</strong><br>';
$requires .= __( 'The following plugins must also be installed and activated. This plugin will be deactivated if any of the required plugins is deactivated or deleted.' ) . '<br>';
$header = '<strong>' . __( 'Additional plugins are required' ) . '</strong>';
array_unshift( self::$plugin_card_data, $header );
self::$plugin_card_data = array_merge( self::$plugin_card_data, $more_details_link );

$required_names_count = count( $required_names );
for ( $i = 0; $i < $required_names_count; ++$i ) {
$requires .= $required_names[ $i ];
if ( $i !== $required_names_count ) {
$requires . '<br>';
}
return $description;
}

/**
* Display plugin card data.
*
* @param string $description Plugin card description.
* @return string
*/
public function set_plugin_card_data( $description ) {
if ( ! empty( self::$plugin_card_data ) ) {
self::$plugin_card_data = array_filter( self::$plugin_card_data );
$data = implode( '<br>', self::$plugin_card_data );
$notice = '<div class="plugin-dependencies"><p class="plugin-dependencies-explainer-text">' . $data . '</p></div>';
$description = $description . $notice;
}

return $description . '<div class="plugin-dependencies"><p class="plugin-dependencies-explainer-text">' . $requires . '</p></div>';
self::$plugin_card_data = array();

return $description;
}

/**
Expand Down Expand Up @@ -766,9 +767,10 @@ public function admin_notices() {

// Only display on specific pages.
if ( in_array( $pagenow, array( 'plugin-install.php', 'plugins.php' ), true ) ) {

// Plugin deactivated if dependencies not met.
// Transient on a 10 second timeout.
/*
* Plugin deactivated if dependencies not met.
* Transient on a 10 second timeout.
*/
$deactivate_requires = get_site_transient( 'wp_plugin_dependencies_deactivate_plugins' );
if ( ! empty( $deactivate_requires ) ) {
foreach ( $deactivate_requires as $deactivated ) {
Expand Down
41 changes: 27 additions & 14 deletions wp-admin/includes/plugin-install.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,36 @@
* @return string $button The markup for the dependency row button.
*/
function wp_get_plugin_action_button( $name, $data, $compatible_php, $compatible_wp ) {
$button = '';
$data = (object) $data;
$status = install_plugin_install_status( $data );
$requires_plugins = isset( $data->requires_plugins ) ? $data->requires_plugins : array();
$plugin_dependency_met = true;
$button = '';
$data = (object) $data;
$status = install_plugin_install_status( $data );
$requires_plugins = isset( $data->requires_plugins ) ? $data->requires_plugins : array();

// Check if plugin dependency is installed and active.
// Determine the status of plugin dependencies.
$installed_plugins = get_plugins();
$active_plugins = get_option( 'active_plugins' );
$plugin_dependencies_count = count( $requires_plugins );
$installed_plugin_dependencies_count = 0;
$active_plugin_dependencies_count = 0;
foreach ( $requires_plugins as $dependency ) {
$plugin_dependency_met = false;
$active_plugins = get_option( 'active_plugins' );
foreach ( $active_plugins as $plugin_file ) {
if ( str_contains( $plugin_file, '/' ) && explode( '/', $plugin_file )[0] === $dependency ) {
$plugin_dependency_met = true;
break;
foreach ( array_keys( $installed_plugins ) as $installed_plugin_file ) {
if ( str_contains( $installed_plugin_file, '/' ) && explode( '/', $installed_plugin_file )[0] === $dependency ) {
++$installed_plugin_dependencies_count;
}
}

foreach ( $active_plugins as $active_plugin_file ) {
if ( str_contains( $active_plugin_file, '/' ) && explode( '/', $active_plugin_file )[0] === $dependency ) {
++$active_plugin_dependencies_count;
}
}
}
$all_plugin_dependencies_installed = $installed_plugin_dependencies_count === $plugin_dependencies_count;
$all_plugin_dependencies_active = $active_plugin_dependencies_count === $plugin_dependencies_count;

if ( apply_filters( 'pd_simple_card', false ) ) {
$plugin_dependency_met = true;
}

sprintf(
'<a class="install-now button" data-slug="%s" href="%s" aria-label="%s" data-name="%s">%s</a>',
Expand All @@ -59,7 +72,7 @@ function wp_get_plugin_action_button( $name, $data, $compatible_php, $compatible
switch ( $status['status'] ) {
case 'install':
if ( $status['url'] ) {
if ( $compatible_php && $compatible_wp && $plugin_dependency_met ) {
if ( $compatible_php && $compatible_wp && $all_plugin_dependencies_installed ) {
$button = sprintf(
'<a class="install-now button" data-slug="%s" href="%s" aria-label="%s" data-name="%s">%s</a>',
esc_attr( $data->slug ),
Expand Down Expand Up @@ -108,7 +121,7 @@ function wp_get_plugin_action_button( $name, $data, $compatible_php, $compatible
_x( 'Active', 'plugin' )
);
} elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) {
if ( $compatible_php && $compatible_wp ) {
if ( $compatible_php && $compatible_wp && $all_plugin_dependencies_active ) {
$button_text = __( 'Activate' );
/* translators: %s: Plugin name. */
$button_label = _x( 'Activate %s', 'plugin' );
Expand Down

0 comments on commit c254079

Please sign in to comment.