/** * Processes bulk installation and activation actions. * * The bulk installation process looks for the $_POST information and passes that * through if a user has to use WP_Filesystem to enter their credentials. * * @since 2.2.0 */ public function process_bulk_actions() { // Bulk installation process. if ('tgmpa-bulk-install' === $this->current_action() || 'tgmpa-bulk-update' === $this->current_action()) { check_admin_referer('bulk-' . $this->_args['plural']); $install_type = 'install'; if ('tgmpa-bulk-update' === $this->current_action()) { $install_type = 'update'; } $plugins_to_install = array(); // Did user actually select any plugins to install/update ? if (empty($_POST['plugin'])) { if ('install' === $install_type) { $message = __('No plugins were selected to be installed. No action taken.', 'sociallyviral'); } else { $message = __('No plugins were selected to be updated. No action taken.', 'sociallyviral'); } echo '<div id="message" class="error"><p>', esc_html($message), '</p></div>'; return false; } if (is_array($_POST['plugin'])) { $plugins_to_install = (array) $_POST['plugin']; } elseif (is_string($_POST['plugin'])) { // Received via Filesystem page - un-flatten array (WP bug #19643). $plugins_to_install = explode(',', $_POST['plugin']); } // Sanitize the received input. $plugins_to_install = array_map('urldecode', $plugins_to_install); $plugins_to_install = array_map(array($this->tgmpa, 'sanitize_key'), $plugins_to_install); // Validate the received input. foreach ($plugins_to_install as $key => $slug) { // Check if the plugin was registered with TGMPA and remove if not. if (!isset($this->tgmpa->plugins[$slug])) { unset($plugins_to_install[$key]); continue; } // For updates: make sure this is a plugin we *can* update (update available and WP version ok). if ('update' === $install_type && ($this->tgmpa->is_plugin_installed($slug) && (false === $this->tgmpa->does_plugin_have_update($slug) || !$this->tgmpa->can_plugin_update($slug)))) { unset($plugins_to_install[$key]); } } // No need to proceed further if we have no plugins to handle. if (empty($plugins_to_install)) { if ('install' === $install_type) { $message = __('No plugins are available to be installed at this time.', 'sociallyviral'); } else { $message = __('No plugins are available to be updated at this time.', 'sociallyviral'); } echo '<div id="message" class="error"><p>', esc_html($message), '</p></div>'; return false; } // Pass all necessary information if WP_Filesystem is needed. $url = wp_nonce_url($this->tgmpa->get_tgmpa_url(), 'bulk-' . $this->_args['plural']); // Give validated data back to $_POST which is the only place the filesystem looks for extra fields. $_POST['plugin'] = implode(',', $plugins_to_install); // Work around for WP bug #19643. $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. $fields = array_keys($_POST); // Extra fields to pass to WP_Filesystem. if (false === ($creds = request_filesystem_credentials(esc_url_raw($url), $method, false, false, $fields))) { return true; // Stop the normal page form from displaying, credential request form will be shown. } // Now we have some credentials, setup WP_Filesystem. if (!WP_Filesystem($creds)) { // Our credentials were no good, ask the user for them again. request_filesystem_credentials(esc_url_raw($url), $method, true, false, $fields); return true; } /* If we arrive here, we have the filesystem */ // Store all information in arrays since we are processing a bulk installation. $names = array(); $sources = array(); // Needed for installs. $file_paths = array(); // Needed for upgrades. $to_inject = array(); // Information to inject into the update_plugins transient. // Prepare the data for validated plugins for the install/upgrade. foreach ($plugins_to_install as $slug) { $name = $this->tgmpa->plugins[$slug]['name']; $source = $this->tgmpa->get_download_url($slug); if (!empty($name) && !empty($source)) { $names[] = $name; switch ($install_type) { case 'install': $sources[] = $source; break; case 'update': $file_paths[] = $this->tgmpa->plugins[$slug]['file_path']; $to_inject[$slug] = $this->tgmpa->plugins[$slug]; $to_inject[$slug]['source'] = $source; break; } } } unset($slug, $name, $source); // Create a new instance of TGMPA_Bulk_Installer. $installer = new TGMPA_Bulk_Installer(new TGMPA_Bulk_Installer_Skin(array('url' => esc_url_raw($this->tgmpa->get_tgmpa_url()), 'nonce' => 'bulk-' . $this->_args['plural'], 'names' => $names, 'install_type' => $install_type))); // Wrap the install process with the appropriate HTML. echo '<div class="tgmpa wrap">', '<h2>', esc_html(get_admin_page_title()), '</h2>'; // Process the bulk installation submissions. add_filter('upgrader_source_selection', array($this->tgmpa, 'maybe_adjust_source_dir'), 1, 3); if ('tgmpa-bulk-update' === $this->current_action()) { // Inject our info into the update transient. $this->tgmpa->inject_update_info($to_inject); $installer->bulk_upgrade($file_paths); } else { $installer->bulk_install($sources); } remove_filter('upgrader_source_selection', array($this->tgmpa, 'maybe_adjust_source_dir'), 1, 3); echo '</div>'; return true; } // Bulk activation process. if ('tgmpa-bulk-activate' === $this->current_action()) { check_admin_referer('bulk-' . $this->_args['plural']); // Did user actually select any plugins to activate ? if (empty($_POST['plugin'])) { echo '<div id="message" class="error"><p>', esc_html__('No plugins were selected to be activated. No action taken.', 'sociallyviral'), '</p></div>'; return false; } // Grab plugin data from $_POST. $plugins = array(); if (isset($_POST['plugin'])) { $plugins = array_map('urldecode', (array) $_POST['plugin']); $plugins = array_map(array($this->tgmpa, 'sanitize_key'), $plugins); } $plugins_to_activate = array(); $plugin_names = array(); // Grab the file paths for the selected & inactive plugins from the registration array. foreach ($plugins as $slug) { if ($this->tgmpa->can_plugin_activate($slug)) { $plugins_to_activate[] = $this->tgmpa->plugins[$slug]['file_path']; $plugin_names[] = $this->tgmpa->plugins[$slug]['name']; } } unset($slug); // Return early if there are no plugins to activate. if (empty($plugins_to_activate)) { echo '<div id="message" class="error"><p>', esc_html__('No plugins are available to be activated at this time.', 'sociallyviral'), '</p></div>'; return false; } // Now we are good to go - let's start activating plugins. $activate = activate_plugins($plugins_to_activate); if (is_wp_error($activate)) { echo '<div id="message" class="error"><p>', wp_kses_post($activate->get_error_message()), '</p></div>'; } else { $count = count($plugin_names); // Count so we can use _n function. $plugin_names = array_map(array('TGMPA_Utils', 'wrap_in_strong'), $plugin_names); $last_plugin = array_pop($plugin_names); // Pop off last name to prep for readability. $imploded = empty($plugin_names) ? $last_plugin : implode(', ', $plugin_names) . ' ' . esc_html_x('and', 'plugin A *and* plugin B', 'sociallyviral') . ' ' . $last_plugin; printf('<div id="message" class="updated"><p>%1$s %2$s.</p></div>', esc_html(_n('The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'sociallyviral')), $imploded); // Update recently activated plugins option. $recent = (array) get_option('recently_activated'); foreach ($plugins_to_activate as $plugin => $time) { if (isset($recent[$plugin])) { unset($recent[$plugin]); } } update_option('recently_activated', $recent); } unset($_POST); // Reset the $_POST variable in case user wants to perform one action after another. return true; } return false; }