From 71ac1e2da2b72dadc92f4b771062444fbee61ae7 Mon Sep 17 00:00:00 2001 From: Anton Ukhanev Date: Tue, 27 Apr 2021 12:02:39 +0200 Subject: [PATCH 1/4] Move default string assignment to constructor This allows the default strings to be overridden via configuration after instantiation but before they are used. TGMPA/TGM-Plugin-Activation#804 --- class-tgm-plugin-activation.php | 150 ++++++++++++++++---------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/class-tgm-plugin-activation.php b/class-tgm-plugin-activation.php index 6ae71d3c..7f70bad9 100755 --- a/class-tgm-plugin-activation.php +++ b/class-tgm-plugin-activation.php @@ -261,6 +261,81 @@ public function __construct() { // Set the current WordPress version. $this->wp_version = $GLOBALS['wp_version']; + // Load class strings. + $this->strings = array( + 'page_title' => __( 'Install Required Plugins', 'tgmpa' ), + 'menu_title' => __( 'Install Plugins', 'tgmpa' ), + /* translators: %s: plugin name. */ + 'installing' => __( 'Installing Plugin: %s', 'tgmpa' ), + /* translators: %s: plugin name. */ + 'updating' => __( 'Updating Plugin: %s', 'tgmpa' ), + 'oops' => __( 'Something went wrong with the plugin API.', 'tgmpa' ), + /* translators: 1: plugin name(s). */ + 'notice_can_install_required' => _n_noop( + 'This theme requires the following plugin: %1$s.', + 'This theme requires the following plugins: %1$s.', + 'tgmpa' + ), + /* translators: 1: plugin name(s). */ + 'notice_can_install_recommended' => _n_noop( + 'This theme recommends the following plugin: %1$s.', + 'This theme recommends the following plugins: %1$s.', + 'tgmpa' + ), + /* translators: 1: plugin name(s). */ + 'notice_ask_to_update' => _n_noop( + 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.', + 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.', + 'tgmpa' + ), + /* translators: 1: plugin name(s). */ + 'notice_ask_to_update_maybe' => _n_noop( + 'There is an update available for: %1$s.', + 'There are updates available for the following plugins: %1$s.', + 'tgmpa' + ), + /* translators: 1: plugin name(s). */ + 'notice_can_activate_required' => _n_noop( + 'The following required plugin is currently inactive: %1$s.', + 'The following required plugins are currently inactive: %1$s.', + 'tgmpa' + ), + /* translators: 1: plugin name(s). */ + 'notice_can_activate_recommended' => _n_noop( + 'The following recommended plugin is currently inactive: %1$s.', + 'The following recommended plugins are currently inactive: %1$s.', + 'tgmpa' + ), + 'install_link' => _n_noop( + 'Begin installing plugin', + 'Begin installing plugins', + 'tgmpa' + ), + 'update_link' => _n_noop( + 'Begin updating plugin', + 'Begin updating plugins', + 'tgmpa' + ), + 'activate_link' => _n_noop( + 'Begin activating plugin', + 'Begin activating plugins', + 'tgmpa' + ), + 'return' => __( 'Return to Required Plugins Installer', 'tgmpa' ), + 'dashboard' => __( 'Return to the Dashboard', 'tgmpa' ), + 'plugin_activated' => __( 'Plugin activated successfully.', 'tgmpa' ), + 'activated_successfully' => __( 'The following plugin was activated successfully:', 'tgmpa' ), + /* translators: 1: plugin name. */ + 'plugin_already_active' => __( 'No action taken. Plugin %1$s was already active.', 'tgmpa' ), + /* translators: 1: plugin name. */ + 'plugin_needs_higher_version' => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'tgmpa' ), + /* translators: 1: dashboard link. */ + 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ), + 'dismiss' => __( 'Dismiss this notice', 'tgmpa' ), + 'notice_cannot_install_activate' => __( 'There are one or more required or recommended plugins to install, update or activate.', 'tgmpa' ), + 'contact_admin' => __( 'Please contact the administrator of this site for help.', 'tgmpa' ), + ); + // Announce that the class is ready, and pass the object (for advanced use). do_action_ref_array( 'tgmpa_init', array( $this ) ); @@ -335,81 +410,6 @@ public function init() { return; } - // Load class strings. - $this->strings = array( - 'page_title' => __( 'Install Required Plugins', 'tgmpa' ), - 'menu_title' => __( 'Install Plugins', 'tgmpa' ), - /* translators: %s: plugin name. */ - 'installing' => __( 'Installing Plugin: %s', 'tgmpa' ), - /* translators: %s: plugin name. */ - 'updating' => __( 'Updating Plugin: %s', 'tgmpa' ), - 'oops' => __( 'Something went wrong with the plugin API.', 'tgmpa' ), - /* translators: 1: plugin name(s). */ - 'notice_can_install_required' => _n_noop( - 'This theme requires the following plugin: %1$s.', - 'This theme requires the following plugins: %1$s.', - 'tgmpa' - ), - /* translators: 1: plugin name(s). */ - 'notice_can_install_recommended' => _n_noop( - 'This theme recommends the following plugin: %1$s.', - 'This theme recommends the following plugins: %1$s.', - 'tgmpa' - ), - /* translators: 1: plugin name(s). */ - 'notice_ask_to_update' => _n_noop( - 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with this theme: %1$s.', - 'The following plugins need to be updated to their latest version to ensure maximum compatibility with this theme: %1$s.', - 'tgmpa' - ), - /* translators: 1: plugin name(s). */ - 'notice_ask_to_update_maybe' => _n_noop( - 'There is an update available for: %1$s.', - 'There are updates available for the following plugins: %1$s.', - 'tgmpa' - ), - /* translators: 1: plugin name(s). */ - 'notice_can_activate_required' => _n_noop( - 'The following required plugin is currently inactive: %1$s.', - 'The following required plugins are currently inactive: %1$s.', - 'tgmpa' - ), - /* translators: 1: plugin name(s). */ - 'notice_can_activate_recommended' => _n_noop( - 'The following recommended plugin is currently inactive: %1$s.', - 'The following recommended plugins are currently inactive: %1$s.', - 'tgmpa' - ), - 'install_link' => _n_noop( - 'Begin installing plugin', - 'Begin installing plugins', - 'tgmpa' - ), - 'update_link' => _n_noop( - 'Begin updating plugin', - 'Begin updating plugins', - 'tgmpa' - ), - 'activate_link' => _n_noop( - 'Begin activating plugin', - 'Begin activating plugins', - 'tgmpa' - ), - 'return' => __( 'Return to Required Plugins Installer', 'tgmpa' ), - 'dashboard' => __( 'Return to the Dashboard', 'tgmpa' ), - 'plugin_activated' => __( 'Plugin activated successfully.', 'tgmpa' ), - 'activated_successfully' => __( 'The following plugin was activated successfully:', 'tgmpa' ), - /* translators: 1: plugin name. */ - 'plugin_already_active' => __( 'No action taken. Plugin %1$s was already active.', 'tgmpa' ), - /* translators: 1: plugin name. */ - 'plugin_needs_higher_version' => __( 'Plugin not activated. A higher version of %s is needed for this theme. Please update the plugin.', 'tgmpa' ), - /* translators: 1: dashboard link. */ - 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ), - 'dismiss' => __( 'Dismiss this notice', 'tgmpa' ), - 'notice_cannot_install_activate' => __( 'There are one or more required or recommended plugins to install, update or activate.', 'tgmpa' ), - 'contact_admin' => __( 'Please contact the administrator of this site for help.', 'tgmpa' ), - ); - do_action( 'tgmpa_register' ); /* After this point, the plugins should be registered and the configuration set. */ From 989ab79f9171fc73cdfd74c61ebb84c30e6834a7 Mon Sep 17 00:00:00 2001 From: Anton Ukhanev Date: Tue, 27 Apr 2021 12:05:58 +0200 Subject: [PATCH 2/4] Inject TGM_Plugin_Activation into TGMPA_List_Table This allows each list to use its corresponding TGMPA instance, instead of all lists using the same global instance. TGMPA/TGM-Plugin-Activation#804 --- class-tgm-plugin-activation.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/class-tgm-plugin-activation.php b/class-tgm-plugin-activation.php index 7f70bad9..644971f8 100755 --- a/class-tgm-plugin-activation.php +++ b/class-tgm-plugin-activation.php @@ -755,7 +755,7 @@ protected function add_admin_menu( array $args ) { */ public function install_plugins_page() { // Store new instance of plugin table in object. - $plugin_table = new TGMPA_List_Table(); + $plugin_table = new TGMPA_List_Table($this); // Return early if processing a plugin installation action. if ( ( ( 'tgmpa-bulk-install' === $plugin_table->current_action() || 'tgmpa-bulk-update' === $plugin_table->current_action() ) && $plugin_table->process_bulk_actions() ) || $this->do_plugin_install() ) { @@ -2271,10 +2271,12 @@ class TGMPA_List_Table extends WP_List_Table { /** * References parent constructor and sets defaults for class. * + * @param TGM_Plugin_Activation $tgmpa The TGMPA instance to be used by this list. + * * @since 2.2.0 */ - public function __construct() { - $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); + public function __construct($tgmpa) { + $this->tgmpa = $tgmpa; parent::__construct( array( From 5f46fa63d423254a7629656a7b219a459811ae00 Mon Sep 17 00:00:00 2001 From: Anton Ukhanev Date: Tue, 27 Apr 2021 14:09:10 +0200 Subject: [PATCH 3/4] Inject TGM_Plugin_Activation into TGMPA_Bulk_Installer This allows each bulk installer to use its corresponding TGMPA instance, instead of all installers using the same global instance. TGMPA/TGM-Plugin-Activation#804 --- class-tgm-plugin-activation.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/class-tgm-plugin-activation.php b/class-tgm-plugin-activation.php index 644971f8..91203e0c 100755 --- a/class-tgm-plugin-activation.php +++ b/class-tgm-plugin-activation.php @@ -3018,6 +3018,7 @@ public function process_bulk_actions() { // Create a new instance of TGMPA_Bulk_Installer. $installer = new TGMPA_Bulk_Installer( + $this->tgmpa, new TGMPA_Bulk_Installer_Skin( array( 'url' => esc_url_raw( $this->tgmpa->get_tgmpa_url() ), @@ -3284,14 +3285,14 @@ class TGMPA_Bulk_Installer extends Plugin_Upgrader { * * @since 2.2.0 * + * @param TGM_Plugin_Activation $tgmpa The TGMPA instance to be used by this class. * @param \Bulk_Upgrader_Skin|null $skin Installer skin. */ - public function __construct( $skin = null ) { - // Get TGMPA class instance. - $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - + public function __construct( $tgmpa, $skin = null ) { parent::__construct( $skin ); + $this->tgmpa = $tgmpa; + if ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) { $this->clear_destination = true; } From 7480014e5703de492179534976878d20738999d6 Mon Sep 17 00:00:00 2001 From: Anton Ukhanev Date: Tue, 27 Apr 2021 14:16:01 +0200 Subject: [PATCH 4/4] TGMPA_Bulk_Installer and TGMPA_Bulk_Installer_Skin now declared unconditionally Classes should be available for use by whatever needs them, on any page. Simply declaring them if they don't already exist facilitates that capability. WordPress will not try to include it again, because it is done with `require_once`: https://github.com/WordPress/WordPress/blob/270f2011f8ec7265c3f4ddce39c77ef5b496ed1c/wp-admin/includes/class-wp-upgrader.php#L953 TGMPA/TGM-Plugin-Activation#804 --- class-tgm-plugin-activation.php | 1032 +++++++++++++++---------------- 1 file changed, 497 insertions(+), 535 deletions(-) diff --git a/class-tgm-plugin-activation.php b/class-tgm-plugin-activation.php index 91203e0c..cbf63c9d 100755 --- a/class-tgm-plugin-activation.php +++ b/class-tgm-plugin-activation.php @@ -3196,603 +3196,565 @@ class TGM_Bulk_Installer_Skin { } } -/** - * The WP_Upgrader file isn't always available. If it isn't available, - * we load it here. - * - * We check to make sure no action or activation keys are set so that WordPress - * does not try to re-include the class when processing upgrades or installs outside - * of the class. - * - * @since 2.2.0 - */ -add_action( 'admin_init', 'tgmpa_load_bulk_installer' ); -if ( ! function_exists( 'tgmpa_load_bulk_installer' ) ) { +if ( ! class_exists( 'TGMPA_Bulk_Installer' ) ) { + + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + /** - * Load bulk installer + * Installer class to handle bulk plugin installations. + * + * Extends WP_Upgrader and customizes to suit the installation of multiple + * plugins. + * + * @since 2.2.0 + * + * {@internal Since 2.5.0 the class is an extension of Plugin_Upgrader rather than WP_Upgrader.}} + * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer to TGMPA_Bulk_Installer. + * This was done to prevent backward compatibility issues with v2.3.6.}} + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones */ - function tgmpa_load_bulk_installer() { - // Silently fail if 2.5+ is loaded *after* an older version. - if ( ! isset( $GLOBALS['tgmpa'] ) ) { - return; - } + class TGMPA_Bulk_Installer extends Plugin_Upgrader { + /** + * Holds result of bulk plugin installation. + * + * @since 2.2.0 + * + * @var string + */ + public $result; - // Get TGMPA class instance. - $tgmpa_instance = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); + /** + * Flag to check if bulk installation is occurring or not. + * + * @since 2.2.0 + * + * @var boolean + */ + public $bulk = false; - if ( isset( $_GET['page'] ) && $tgmpa_instance->menu === $_GET['page'] ) { - if ( ! class_exists( 'Plugin_Upgrader', false ) ) { - require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + /** + * TGMPA instance + * + * @since 2.5.0 + * + * @var object + */ + protected $tgmpa; + + /** + * Whether or not the destination directory needs to be cleared ( = on update). + * + * @since 2.5.0 + * + * @var bool + */ + protected $clear_destination = false; + + /** + * References parent constructor and sets defaults for class. + * + * @since 2.2.0 + * + * @param TGM_Plugin_Activation $tgmpa The TGMPA instance to be used by this class. + * @param \Bulk_Upgrader_Skin|null $skin Installer skin. + */ + public function __construct( $tgmpa, $skin = null ) { + parent::__construct( $skin ); + + $this->tgmpa = $tgmpa; + + if ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) { + $this->clear_destination = true; } - if ( ! class_exists( 'TGMPA_Bulk_Installer' ) ) { + if ( $this->tgmpa->is_automatic ) { + $this->activate_strings(); + } - /** - * Installer class to handle bulk plugin installations. - * - * Extends WP_Upgrader and customizes to suit the installation of multiple - * plugins. - * - * @since 2.2.0 - * - * {@internal Since 2.5.0 the class is an extension of Plugin_Upgrader rather than WP_Upgrader.}} - * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer to TGMPA_Bulk_Installer. - * This was done to prevent backward compatibility issues with v2.3.6.}} - * - * @package TGM-Plugin-Activation - * @author Thomas Griffin - * @author Gary Jones - */ - class TGMPA_Bulk_Installer extends Plugin_Upgrader { - /** - * Holds result of bulk plugin installation. - * - * @since 2.2.0 - * - * @var string - */ - public $result; - - /** - * Flag to check if bulk installation is occurring or not. - * - * @since 2.2.0 - * - * @var boolean - */ - public $bulk = false; - - /** - * TGMPA instance - * - * @since 2.5.0 - * - * @var object - */ - protected $tgmpa; - - /** - * Whether or not the destination directory needs to be cleared ( = on update). - * - * @since 2.5.0 - * - * @var bool - */ - protected $clear_destination = false; - - /** - * References parent constructor and sets defaults for class. - * - * @since 2.2.0 - * - * @param TGM_Plugin_Activation $tgmpa The TGMPA instance to be used by this class. - * @param \Bulk_Upgrader_Skin|null $skin Installer skin. - */ - public function __construct( $tgmpa, $skin = null ) { - parent::__construct( $skin ); - - $this->tgmpa = $tgmpa; - - if ( isset( $this->skin->options['install_type'] ) && 'update' === $this->skin->options['install_type'] ) { - $this->clear_destination = true; - } + add_action( 'upgrader_process_complete', array( $this->tgmpa, 'populate_file_path' ) ); + } - if ( $this->tgmpa->is_automatic ) { - $this->activate_strings(); - } + /** + * Sets the correct activation strings for the installer skin to use. + * + * @since 2.2.0 + */ + public function activate_strings() { + $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'tgmpa' ); + $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' ); + } - add_action( 'upgrader_process_complete', array( $this->tgmpa, 'populate_file_path' ) ); - } + /** + * Performs the actual installation of each plugin. + * + * @since 2.2.0 + * + * @see WP_Upgrader::run() + * + * @param array $options The installation config options. + * @return null|array Return early if error, array of installation data on success. + */ + public function run( $options ) { + $result = parent::run( $options ); - /** - * Sets the correct activation strings for the installer skin to use. - * - * @since 2.2.0 - */ - public function activate_strings() { - $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'tgmpa' ); - $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' ); - } + // Reset the strings in case we changed one during automatic activation. + if ( $this->tgmpa->is_automatic ) { + if ( 'update' === $this->skin->options['install_type'] ) { + $this->upgrade_strings(); + } else { + $this->install_strings(); + } + } - /** - * Performs the actual installation of each plugin. - * - * @since 2.2.0 - * - * @see WP_Upgrader::run() - * - * @param array $options The installation config options. - * @return null|array Return early if error, array of installation data on success. - */ - public function run( $options ) { - $result = parent::run( $options ); - - // Reset the strings in case we changed one during automatic activation. - if ( $this->tgmpa->is_automatic ) { - if ( 'update' === $this->skin->options['install_type'] ) { - $this->upgrade_strings(); - } else { - $this->install_strings(); - } - } + return $result; + } - return $result; - } + /** + * Processes the bulk installation of plugins. + * + * @since 2.2.0 + * + * {@internal This is basically a near identical copy of the WP Core + * Plugin_Upgrader::bulk_upgrade() method, with minor adjustments to deal with + * new installs instead of upgrades. + * For ease of future synchronizations, the adjustments are clearly commented, but no other + * comments are added. Code style has been made to comply.}} + * + * @see Plugin_Upgrader::bulk_upgrade() + * @see https://core.trac.wordpress.org/browser/tags/4.2.1/src/wp-admin/includes/class-wp-upgrader.php#L838 + * (@internal Last synced: Dec 31st 2015 against https://core.trac.wordpress.org/browser/trunk?rev=36134}} + * + * @param array $plugins The plugin sources needed for installation. + * @param array $args Arbitrary passed extra arguments. + * @return array|false Install confirmation messages on success, false on failure. + */ + public function bulk_install( $plugins, $args = array() ) { + // [TGMPA + ] Hook auto-activation in. + add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - /** - * Processes the bulk installation of plugins. - * - * @since 2.2.0 - * - * {@internal This is basically a near identical copy of the WP Core - * Plugin_Upgrader::bulk_upgrade() method, with minor adjustments to deal with - * new installs instead of upgrades. - * For ease of future synchronizations, the adjustments are clearly commented, but no other - * comments are added. Code style has been made to comply.}} - * - * @see Plugin_Upgrader::bulk_upgrade() - * @see https://core.trac.wordpress.org/browser/tags/4.2.1/src/wp-admin/includes/class-wp-upgrader.php#L838 - * (@internal Last synced: Dec 31st 2015 against https://core.trac.wordpress.org/browser/trunk?rev=36134}} - * - * @param array $plugins The plugin sources needed for installation. - * @param array $args Arbitrary passed extra arguments. - * @return array|false Install confirmation messages on success, false on failure. - */ - public function bulk_install( $plugins, $args = array() ) { - // [TGMPA + ] Hook auto-activation in. - add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - - $defaults = array( - 'clear_update_cache' => true, - ); - $parsed_args = wp_parse_args( $args, $defaults ); + $defaults = array( + 'clear_update_cache' => true, + ); + $parsed_args = wp_parse_args( $args, $defaults ); - $this->init(); - $this->bulk = true; + $this->init(); + $this->bulk = true; - $this->install_strings(); // [TGMPA + ] adjusted. + $this->install_strings(); // [TGMPA + ] adjusted. - /* [TGMPA - ] $current = get_site_transient( 'update_plugins' ); */ + /* [TGMPA - ] $current = get_site_transient( 'update_plugins' ); */ - /* [TGMPA - ] add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4); */ + /* [TGMPA - ] add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4); */ - $this->skin->header(); + $this->skin->header(); - // Connect to the Filesystem first. - $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) ); - if ( ! $res ) { - $this->skin->footer(); - return false; - } + // Connect to the Filesystem first. + $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) ); + if ( ! $res ) { + $this->skin->footer(); + return false; + } - $this->skin->bulk_header(); - - /* - * Only start maintenance mode if: - * - running Multisite and there are one or more plugins specified, OR - * - a plugin with an update available is currently active. - * @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible. - */ - $maintenance = ( is_multisite() && ! empty( $plugins ) ); - - /* - [TGMPA - ] - foreach ( $plugins as $plugin ) - $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) ); - */ - if ( $maintenance ) { - $this->maintenance_mode( true ); - } + $this->skin->bulk_header(); - $results = array(); + /* + * Only start maintenance mode if: + * - running Multisite and there are one or more plugins specified, OR + * - a plugin with an update available is currently active. + * @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible. + */ + $maintenance = ( is_multisite() && ! empty( $plugins ) ); - $this->update_count = count( $plugins ); - $this->update_current = 0; - foreach ( $plugins as $plugin ) { - $this->update_current++; + /* + [TGMPA - ] + foreach ( $plugins as $plugin ) + $maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) ); + */ + if ( $maintenance ) { + $this->maintenance_mode( true ); + } - /* - [TGMPA - ] - $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true); + $results = array(); - if ( !isset( $current->response[ $plugin ] ) ) { - $this->skin->set_result('up_to_date'); - $this->skin->before(); - $this->skin->feedback('up_to_date'); - $this->skin->after(); - $results[$plugin] = true; - continue; - } + $this->update_count = count( $plugins ); + $this->update_current = 0; + foreach ( $plugins as $plugin ) { + $this->update_current++; - // Get the URL to the zip file. - $r = $current->response[ $plugin ]; + /* + [TGMPA - ] + $this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true); + + if ( !isset( $current->response[ $plugin ] ) ) { + $this->skin->set_result('up_to_date'); + $this->skin->before(); + $this->skin->feedback('up_to_date'); + $this->skin->after(); + $results[$plugin] = true; + continue; + } - $this->skin->plugin_active = is_plugin_active($plugin); - */ + // Get the URL to the zip file. + $r = $current->response[ $plugin ]; - $result = $this->run( - array( - 'package' => $plugin, // [TGMPA + ] adjusted. - 'destination' => WP_PLUGIN_DIR, - 'clear_destination' => false, // [TGMPA + ] adjusted. - 'clear_working' => true, - 'is_multi' => true, - 'hook_extra' => array( + $this->skin->plugin_active = is_plugin_active($plugin); + */ + + $result = $this->run( + array( + 'package' => $plugin, // [TGMPA + ] adjusted. + 'destination' => WP_PLUGIN_DIR, + 'clear_destination' => false, // [TGMPA + ] adjusted. + 'clear_working' => true, + 'is_multi' => true, + 'hook_extra' => array( 'plugin' => $plugin, - ), - ) - ); + ), + ) + ); - $results[ $plugin ] = $this->result; + $results[ $plugin ] = $this->result; - // Prevent credentials auth screen from displaying multiple times. - if ( false === $result ) { - break; - } - } + // Prevent credentials auth screen from displaying multiple times. + if ( false === $result ) { + break; + } + } //end foreach $plugins - $this->maintenance_mode( false ); - - /** - * Fires when the bulk upgrader process is complete. - * - * @since WP 3.6.0 / TGMPA 2.5.0 - * - * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might - * be a Theme_Upgrader or Core_Upgrade instance. - * @param array $data { - * Array of bulk item update data. - * - * @type string $action Type of action. Default 'update'. - * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. - * @type bool $bulk Whether the update process is a bulk update. Default true. - * @type array $packages Array of plugin, theme, or core packages to update. - * } - */ - do_action( - // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Using WP core hook. - 'upgrader_process_complete', - $this, - array( - 'action' => 'install', // [TGMPA + ] adjusted. - 'type' => 'plugin', - 'bulk' => true, - 'plugins' => $plugins, - ) - ); + $this->maintenance_mode( false ); - $this->skin->bulk_footer(); + /** + * Fires when the bulk upgrader process is complete. + * + * @since WP 3.6.0 / TGMPA 2.5.0 + * + * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might + * be a Theme_Upgrader or Core_Upgrade instance. + * @param array $data { + * Array of bulk item update data. + * + * @type string $action Type of action. Default 'update'. + * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'. + * @type bool $bulk Whether the update process is a bulk update. Default true. + * @type array $packages Array of plugin, theme, or core packages to update. + * } + */ + do_action( 'upgrader_process_complete', $this, array( + 'action' => 'install', // [TGMPA + ] adjusted. + 'type' => 'plugin', + 'bulk' => true, + 'plugins' => $plugins, + ) ); - $this->skin->footer(); + $this->skin->bulk_footer(); - // Cleanup our hooks, in case something else does a upgrade on this connection. - /* [TGMPA - ] remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin')); */ + $this->skin->footer(); - // [TGMPA + ] Remove our auto-activation hook. - remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); + // Cleanup our hooks, in case something else does a upgrade on this connection. + /* [TGMPA - ] remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin')); */ - // Force refresh of plugin update information. - wp_clean_plugins_cache( $parsed_args['clear_update_cache'] ); + // [TGMPA + ] Remove our auto-activation hook. + remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - return $results; - } + // Force refresh of plugin update information. + wp_clean_plugins_cache( $parsed_args['clear_update_cache'] ); + + return $results; + } - /** - * Handle a bulk upgrade request. - * - * @since 2.5.0 - * - * @see Plugin_Upgrader::bulk_upgrade() - * - * @param array $plugins The local WP file_path's of the plugins which should be upgraded. - * @param array $args Arbitrary passed extra arguments. - * @return string|bool Install confirmation messages on success, false on failure. - */ - public function bulk_upgrade( $plugins, $args = array() ) { + /** + * Handle a bulk upgrade request. + * + * @since 2.5.0 + * + * @see Plugin_Upgrader::bulk_upgrade() + * + * @param array $plugins The local WP file_path's of the plugins which should be upgraded. + * @param array $args Arbitrary passed extra arguments. + * @return string|bool Install confirmation messages on success, false on failure. + */ + public function bulk_upgrade( $plugins, $args = array() ) { - add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); + add_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - $result = parent::bulk_upgrade( $plugins, $args ); + $result = parent::bulk_upgrade( $plugins, $args ); - remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); + remove_filter( 'upgrader_post_install', array( $this, 'auto_activate' ), 10 ); - return $result; - } + return $result; + } - /** - * Abuse a filter to auto-activate plugins after installation. - * - * Hooked into the 'upgrader_post_install' filter hook. - * - * @since 2.5.0 - * - * @param bool $bool The value we need to give back (true). - * @return bool - */ - public function auto_activate( $bool ) { - // Only process the activation of installed plugins if the automatic flag is set to true. - if ( $this->tgmpa->is_automatic ) { - // Flush plugins cache so the headers of the newly installed plugins will be read correctly. - wp_clean_plugins_cache(); - - // Get the installed plugin file. - $plugin_info = $this->plugin_info(); - - // Don't try to activate on upgrade of active plugin as WP will do this already. - if ( ! is_plugin_active( $plugin_info ) ) { - $activate = activate_plugin( $plugin_info ); - - // Adjust the success string based on the activation result. - $this->strings['process_success'] = $this->strings['process_success'] . "
\n"; - - if ( is_wp_error( $activate ) ) { - $this->skin->error( $activate ); - $this->strings['process_success'] .= $this->strings['activation_failed']; - } else { - $this->strings['process_success'] .= $this->strings['activation_success']; - } - } - } + /** + * Abuse a filter to auto-activate plugins after installation. + * + * Hooked into the 'upgrader_post_install' filter hook. + * + * @since 2.5.0 + * + * @param bool $bool The value we need to give back (true). + * @return bool + */ + public function auto_activate( $bool ) { + // Only process the activation of installed plugins if the automatic flag is set to true. + if ( $this->tgmpa->is_automatic ) { + // Flush plugins cache so the headers of the newly installed plugins will be read correctly. + wp_clean_plugins_cache(); + + // Get the installed plugin file. + $plugin_info = $this->plugin_info(); - return $bool; + // Don't try to activate on upgrade of active plugin as WP will do this already. + if ( ! is_plugin_active( $plugin_info ) ) { + $activate = activate_plugin( $plugin_info ); + + // Adjust the success string based on the activation result. + $this->strings['process_success'] = $this->strings['process_success'] . "
\n"; + + if ( is_wp_error( $activate ) ) { + $this->skin->error( $activate ); + $this->strings['process_success'] .= $this->strings['activation_failed']; + } else { + $this->strings['process_success'] .= $this->strings['activation_success']; } } } - if ( ! class_exists( 'TGMPA_Bulk_Installer_Skin' ) ) { - - /** - * Installer skin to set strings for the bulk plugin installations.. - * - * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple - * plugins. - * - * @since 2.2.0 - * - * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer_Skin to - * TGMPA_Bulk_Installer_Skin. - * This was done to prevent backward compatibility issues with v2.3.6.}} - * - * @see https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/class-wp-upgrader-skins.php - * - * @package TGM-Plugin-Activation - * @author Thomas Griffin - * @author Gary Jones - */ - class TGMPA_Bulk_Installer_Skin extends Bulk_Upgrader_Skin { - /** - * Holds plugin info for each individual plugin installation. - * - * @since 2.2.0 - * - * @var array - */ - public $plugin_info = array(); - - /** - * Holds names of plugins that are undergoing bulk installations. - * - * @since 2.2.0 - * - * @var array - */ - public $plugin_names = array(); - - /** - * Integer to use for iteration through each plugin installation. - * - * @since 2.2.0 - * - * @var integer - */ - public $i = 0; - - /** - * TGMPA instance - * - * @since 2.5.0 - * - * @var object - */ - protected $tgmpa; - - /** - * Constructor. Parses default args with new ones and extracts them for use. - * - * @since 2.2.0 - * - * @param array $args Arguments to pass for use within the class. - */ - public function __construct( $args = array() ) { - // Get TGMPA class instance. - $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - - // Parse default and new args. - $defaults = array( - 'url' => '', - 'nonce' => '', - 'names' => array(), - 'install_type' => 'install', - ); - $args = wp_parse_args( $args, $defaults ); + return $bool; + } + } +} - // Set plugin names to $this->plugin_names property. - $this->plugin_names = $args['names']; +if ( ! class_exists( 'TGMPA_Bulk_Installer_Skin' ) ) { - // Extract the new args. - parent::__construct( $args ); - } + require_once ABSPATH . 'wp-admin/includes/class-bulk-upgrader-skin.php'; - /** - * Sets install skin strings for each individual plugin. - * - * Checks to see if the automatic activation flag is set and uses the - * the proper strings accordingly. - * - * @since 2.2.0 - */ - public function add_strings() { - if ( 'update' === $this->options['install_type'] ) { - parent::add_strings(); - /* translators: 1: plugin name, 2: action number 3: total number of actions. */ - $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); - } else { - /* translators: 1: plugin name, 2: error message. */ - $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s.', 'tgmpa' ); - /* translators: 1: plugin name. */ - $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'tgmpa' ); - - if ( $this->tgmpa->is_automatic ) { - // Automatic activation strings. - $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); - /* translators: 1: plugin name. */ - $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'tgmpa' ); - $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'tgmpa' ); - /* translators: 1: plugin name, 2: action number 3: total number of actions. */ - $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); - } else { - // Default installation strings. - $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); - /* translators: 1: plugin name. */ - $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed successfully.', 'tgmpa' ); - $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'tgmpa' ); - /* translators: 1: plugin name, 2: action number 3: total number of actions. */ - $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); - } + /** + * Installer skin to set strings for the bulk plugin installations.. + * + * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple + * plugins. + * + * @since 2.2.0 + * + * {@internal Since 2.5.2 the class has been renamed from TGM_Bulk_Installer_Skin to + * TGMPA_Bulk_Installer_Skin. + * This was done to prevent backward compatibility issues with v2.3.6.}} + * + * @see https://core.trac.wordpress.org/browser/trunk/src/wp-admin/includes/class-wp-upgrader-skins.php + * + * @package TGM-Plugin-Activation + * @author Thomas Griffin + * @author Gary Jones + */ + class TGMPA_Bulk_Installer_Skin extends Bulk_Upgrader_Skin { + /** + * Holds plugin info for each individual plugin installation. + * + * @since 2.2.0 + * + * @var array + */ + public $plugin_info = array(); - // Add "read more" link only for WP < 4.8. - if ( version_compare( $this->tgmpa->wp_version, '4.8', '<' ) ) { - $this->upgrader->strings['skin_update_successful'] .= ' ' . esc_html__( 'Show Details', 'tgmpa' ) . '.'; - } - } - } + /** + * Holds names of plugins that are undergoing bulk installations. + * + * @since 2.2.0 + * + * @var array + */ + public $plugin_names = array(); - /** - * Outputs the header strings and necessary JS before each plugin installation. - * - * @since 2.2.0 - * - * @param string $title Unused in this implementation. - */ - public function before( $title = '' ) { - if ( empty( $title ) ) { - $title = esc_html( $this->plugin_names[ $this->i ] ); - } - parent::before( $title ); - } + /** + * Integer to use for iteration through each plugin installation. + * + * @since 2.2.0 + * + * @var integer + */ + public $i = 0; - /** - * Outputs the footer strings and necessary JS after each plugin installation. - * - * Checks for any errors and outputs them if they exist, else output - * success strings. - * - * @since 2.2.0 - * - * @param string $title Unused in this implementation. - */ - public function after( $title = '' ) { - if ( empty( $title ) ) { - $title = esc_html( $this->plugin_names[ $this->i ] ); - } - parent::after( $title ); + /** + * TGMPA instance + * + * @since 2.5.0 + * + * @var object + */ + protected $tgmpa; - $this->i++; - } + /** + * Constructor. Parses default args with new ones and extracts them for use. + * + * @since 2.2.0 + * + * @param array $args Arguments to pass for use within the class. + */ + public function __construct( $args = array() ) { + // Get TGMPA class instance. + $this->tgmpa = call_user_func( array( get_class( $GLOBALS['tgmpa'] ), 'get_instance' ) ); - /** - * Outputs links after bulk plugin installation is complete. - * - * @since 2.2.0 - */ - public function bulk_footer() { - // Serve up the string to say installations (and possibly activations) are complete. - parent::bulk_footer(); - - // Flush plugins cache so we can make sure that the installed plugins list is always up to date. - wp_clean_plugins_cache(); - - $this->tgmpa->show_tgmpa_version(); - - // Display message based on if all plugins are now active or not. - $update_actions = array(); - - if ( $this->tgmpa->is_tgmpa_complete() ) { - // All plugins are active, so we display the complete string and hide the menu to protect users. - echo ''; - $update_actions['dashboard'] = sprintf( - esc_html( $this->tgmpa->strings['complete'] ), - '' . esc_html( $this->tgmpa->strings['dashboard'] ) . '' - ); - } else { - $update_actions['tgmpa_page'] = '' . esc_html( $this->tgmpa->strings['return'] ) . ''; - } + // Parse default and new args. + $defaults = array( + 'url' => '', + 'nonce' => '', + 'names' => array(), + 'install_type' => 'install', + ); + $args = wp_parse_args( $args, $defaults ); - /** - * Filter the list of action links available following bulk plugin installs/updates. - * - * @since 2.5.0 - * - * @param array $update_actions Array of plugin action links. - * @param array $plugin_info Array of information for the last-handled plugin. - */ - $update_actions = apply_filters( 'tgmpa_update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info ); - - if ( ! empty( $update_actions ) ) { - $this->feedback( implode( ' | ', (array) $update_actions ) ); - } - } + // Set plugin names to $this->plugin_names property. + $this->plugin_names = $args['names']; - /* *********** DEPRECATED METHODS *********** */ - - /** - * Flush header output buffer. - * - * @since 2.2.0 - * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead - * @see Bulk_Upgrader_Skin::flush_output() - */ - public function before_flush_output() { - _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); - $this->flush_output(); - } + // Extract the new args. + parent::__construct( $args ); + } - /** - * Flush footer output buffer and iterate $this->i to make sure the - * installation strings reference the correct plugin. - * - * @since 2.2.0 - * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead - * @see Bulk_Upgrader_Skin::flush_output() - */ - public function after_flush_output() { - _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); - $this->flush_output(); - $this->i++; - } + /** + * Sets install skin strings for each individual plugin. + * + * Checks to see if the automatic activation flag is set and uses the + * the proper strings accordingly. + * + * @since 2.2.0 + */ + public function add_strings() { + if ( 'update' === $this->options['install_type'] ) { + parent::add_strings(); + /* translators: 1: plugin name, 2: action number 3: total number of actions. */ + $this->upgrader->strings['skin_before_update_header'] = __( 'Updating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); + } else { + /* translators: 1: plugin name, 2: error message. */ + $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s.', 'tgmpa' ); + /* translators: 1: plugin name. */ + $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'tgmpa' ); + + if ( $this->tgmpa->is_automatic ) { + // Automatic activation strings. + $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); + /* translators: 1: plugin name. */ + $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'tgmpa' ) . ' ' . esc_html__( 'Show Details', 'tgmpa' ) . '.'; + $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'tgmpa' ); + /* translators: 1: plugin name, 2: action number 3: total number of actions. */ + $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); + } else { + // Default installation strings. + $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); + /* translators: 1: plugin name. */ + $this->upgrader->strings['skin_update_successful'] = esc_html__( '%1$s installed successfully.', 'tgmpa' ) . ' ' . esc_html__( 'Show Details', 'tgmpa' ) . '.'; + $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'tgmpa' ); + /* translators: 1: plugin name, 2: action number 3: total number of actions. */ + $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); } } } + + /** + * Outputs the header strings and necessary JS before each plugin installation. + * + * @since 2.2.0 + * + * @param string $title Unused in this implementation. + */ + public function before( $title = '' ) { + if ( empty( $title ) ) { + $title = esc_html( $this->plugin_names[ $this->i ] ); + } + parent::before( $title ); + } + + /** + * Outputs the footer strings and necessary JS after each plugin installation. + * + * Checks for any errors and outputs them if they exist, else output + * success strings. + * + * @since 2.2.0 + * + * @param string $title Unused in this implementation. + */ + public function after( $title = '' ) { + if ( empty( $title ) ) { + $title = esc_html( $this->plugin_names[ $this->i ] ); + } + parent::after( $title ); + + $this->i++; + } + + /** + * Outputs links after bulk plugin installation is complete. + * + * @since 2.2.0 + */ + public function bulk_footer() { + // Serve up the string to say installations (and possibly activations) are complete. + parent::bulk_footer(); + + // Flush plugins cache so we can make sure that the installed plugins list is always up to date. + wp_clean_plugins_cache(); + + $this->tgmpa->show_tgmpa_version(); + + // Display message based on if all plugins are now active or not. + $update_actions = array(); + + if ( $this->tgmpa->is_tgmpa_complete() ) { + // All plugins are active, so we display the complete string and hide the menu to protect users. + echo ''; + $update_actions['dashboard'] = sprintf( + esc_html( $this->tgmpa->strings['complete'] ), + '' . esc_html__( 'Return to the Dashboard', 'tgmpa' ) . '' + ); + } else { + $update_actions['tgmpa_page'] = '' . esc_html( $this->tgmpa->strings['return'] ) . ''; + } + + /** + * Filter the list of action links available following bulk plugin installs/updates. + * + * @since 2.5.0 + * + * @param array $update_actions Array of plugin action links. + * @param array $plugin_info Array of information for the last-handled plugin. + */ + $update_actions = apply_filters( 'tgmpa_update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info ); + + if ( ! empty( $update_actions ) ) { + $this->feedback( implode( ' | ', (array) $update_actions ) ); + } + } + + /* *********** DEPRECATED METHODS *********** */ + + /** + * Flush header output buffer. + * + * @since 2.2.0 + * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead + * @see Bulk_Upgrader_Skin::flush_output() + */ + public function before_flush_output() { + _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); + $this->flush_output(); + } + + /** + * Flush footer output buffer and iterate $this->i to make sure the + * installation strings reference the correct plugin. + * + * @since 2.2.0 + * @deprecated 2.5.0 use {@see Bulk_Upgrader_Skin::flush_output()} instead + * @see Bulk_Upgrader_Skin::flush_output() + */ + public function after_flush_output() { + _deprecated_function( __FUNCTION__, 'TGMPA 2.5.0', 'Bulk_Upgrader_Skin::flush_output()' ); + $this->flush_output(); + $this->i++; + } } }