+/**
+ * Check whether the plugin is active by checking the active_plugins list.
+ *
+ * @since 2.5.0
+ *
+ * @param string $plugin Base plugin path from plugins directory.
+ * @return bool True, if in the active plugins list. False, not in the list.
+ */
+function is_plugin_active($plugin) {
+ return in_array( $plugin, apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) );
+}
+
+/**
+ * Attempts activation of plugin in a "sandbox" and redirects on success.
+ *
+ * A plugin that is already activated will not attempt to be activated again.
+ *
+ * The way it works is by setting the redirection to the error before trying to
+ * include the plugin file. If the plugin fails, then the redirection will not
+ * be overwritten with the success message. Also, the options will not be
+ * updated and the activation hook will not be called on plugin error.
+ *
+ * It should be noted that in no way the below code will actually prevent errors
+ * within the file. The code should not be used elsewhere to replicate the
+ * "sandbox", which uses redirection to work.
+ * {@source 13 1}
+ *
+ * If any errors are found or text is outputted, then it will be captured to
+ * ensure that the success redirection will update the error redirection.
+ *
+ * @since unknown
+ *
+ * @param string $plugin Plugin path to main plugin file with plugin data.
+ * @param string $redirect Optional. URL to redirect to.
+ * @return WP_Error|null WP_Error on invalid file or null on success.
+ */
+function activate_plugin($plugin, $redirect = '') {
+ $current = get_option('active_plugins');
+ $plugin = plugin_basename(trim($plugin));
+
+ $valid = validate_plugin($plugin);
+ if ( is_wp_error($valid) )
+ return $valid;
+
+ if ( !in_array($plugin, $current) ) {
+ if ( !empty($redirect) )
+ wp_redirect(add_query_arg('_error_nonce', wp_create_nonce('plugin-activation-error_' . $plugin), $redirect)); // we'll override this later if the plugin can be included without fatal error
+ ob_start();
+ @include(WP_PLUGIN_DIR . '/' . $plugin);
+ $current[] = $plugin;
+ sort($current);
+ do_action( 'activate_plugin', trim( $plugin) );
+ update_option('active_plugins', $current);
+ do_action( 'activate_' . trim( $plugin ) );
+ do_action( 'activated_plugin', trim( $plugin) );
+ ob_end_clean();
+ }
+
+ return null;
+}
+
+/**
+ * Deactivate a single plugin or multiple plugins.
+ *
+ * The deactivation hook is disabled by the plugin upgrader by using the $silent
+ * parameter.
+ *
+ * @since unknown
+ *
+ * @param string|array $plugins Single plugin or list of plugins to deactivate.
+ * @param bool $silent Optional, default is false. Prevent calling deactivate hook.
+ */
+function deactivate_plugins($plugins, $silent= false) {
+ $current = get_option('active_plugins');
+
+ if ( !is_array($plugins) )
+ $plugins = array($plugins);
+
+ foreach ( $plugins as $plugin ) {
+ $plugin = plugin_basename($plugin);
+ if( ! is_plugin_active($plugin) )
+ continue;
+ if ( ! $silent )
+ do_action( 'deactivate_plugin', trim( $plugin ) );
+
+ $key = array_search( $plugin, (array) $current );
+
+ if ( false !== $key )
+ array_splice( $current, $key, 1 );
+
+ //Used by Plugin updater to internally deactivate plugin, however, not to notify plugins of the fact to prevent plugin output.
+ if ( ! $silent ) {
+ do_action( 'deactivate_' . trim( $plugin ) );
+ do_action( 'deactivated_plugin', trim( $plugin ) );
+ }
+ }
+
+ update_option('active_plugins', $current);
+}
+
+/**
+ * Activate multiple plugins.
+ *
+ * When WP_Error is returned, it does not mean that one of the plugins had
+ * errors. It means that one or more of the plugins file path was invalid.
+ *
+ * The execution will be halted as soon as one of the plugins has an error.
+ *
+ * @since unknown
+ *
+ * @param string|array $plugins
+ * @param string $redirect Redirect to page after successful activation.
+ * @return bool|WP_Error True when finished or WP_Error if there were errors during a plugin activation.
+ */
+function activate_plugins($plugins, $redirect = '') {
+ if ( !is_array($plugins) )
+ $plugins = array($plugins);
+
+ $errors = array();
+ foreach ( (array) $plugins as $plugin ) {
+ if ( !empty($redirect) )
+ $redirect = add_query_arg('plugin', $plugin, $redirect);
+ $result = activate_plugin($plugin, $redirect);
+ if ( is_wp_error($result) )
+ $errors[$plugin] = $result;
+ }
+
+ if ( !empty($errors) )
+ return new WP_Error('plugins_invalid', __('One of the plugins is invalid.'), $errors);
+
+ return true;
+}
+
+/**
+ * Remove directory and files of a plugin for a single or list of plugin(s).
+ *
+ * If the plugins parameter list is empty, false will be returned. True when
+ * completed.
+ *
+ * @since unknown
+ *
+ * @param array $plugins List of plugin
+ * @param string $redirect Redirect to page when complete.
+ * @return mixed
+ */
+function delete_plugins($plugins, $redirect = '' ) {
+ global $wp_filesystem;
+
+ if( empty($plugins) )
+ return false;
+
+ $checked = array();
+ foreach( $plugins as $plugin )
+ $checked[] = 'checked[]=' . $plugin;
+
+ ob_start();
+ $url = wp_nonce_url('plugins.php?action=delete-selected&verify-delete=1&' . implode('&', $checked), 'bulk-manage-plugins');
+ if ( false === ($credentials = request_filesystem_credentials($url)) ) {
+ $data = ob_get_contents();
+ ob_end_clean();
+ if( ! empty($data) ){
+ include_once( ABSPATH . 'wp-admin/admin-header.php');
+ echo $data;
+ include( ABSPATH . 'wp-admin/admin-footer.php');
+ exit;
+ }
+ return;
+ }
+
+ if ( ! WP_Filesystem($credentials) ) {
+ request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again
+ $data = ob_get_contents();
+ ob_end_clean();
+ if( ! empty($data) ){
+ include_once( ABSPATH . 'wp-admin/admin-header.php');
+ echo $data;
+ include( ABSPATH . 'wp-admin/admin-footer.php');
+ exit;
+ }
+ return;
+ }
+
+ if ( ! is_object($wp_filesystem) )
+ return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
+
+ if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
+ return new WP_Error('fs_error', __('Filesystem error'), $wp_filesystem->errors);
+
+ //Get the base plugin folder
+ $plugins_dir = $wp_filesystem->wp_plugins_dir();
+ if ( empty($plugins_dir) )
+ return new WP_Error('fs_no_plugins_dir', __('Unable to locate WordPress Plugin directory.'));
+
+ $plugins_dir = trailingslashit( $plugins_dir );
+
+ $errors = array();
+
+ foreach( $plugins as $plugin_file ) {
+ // Run Uninstall hook
+ if ( is_uninstallable_plugin( $plugin_file ) )
+ uninstall_plugin($plugin_file);
+
+ $this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin_file) );
+ // If plugin is in its own directory, recursively delete the directory.
+ if ( strpos($plugin_file, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory seperator AND that its not the root plugin folder
+ $deleted = $wp_filesystem->delete($this_plugin_dir, true);
+ else
+ $deleted = $wp_filesystem->delete($plugins_dir . $plugin_file);
+
+ if ( ! $deleted )
+ $errors[] = $plugin_file;
+ }
+
+ if ( ! empty($errors) )
+ return new WP_Error('could_not_remove_plugin', sprintf(__('Could not fully remove the plugin(s) %s'), implode(', ', $errors)) );
+
+ // Force refresh of plugin update information
+ if ( $current = get_transient('update_plugins') ) {
+ unset( $current->response[ $plugin_file ] );
+ set_transient('update_plugins', $current);
+ }
+
+ return true;
+}
+
+function validate_active_plugins() {
+ $check_plugins = apply_filters( 'active_plugins', get_option('active_plugins') );
+
+ // Sanity check. If the active plugin list is not an array, make it an
+ // empty array.
+ if ( !is_array($check_plugins) ) {
+ update_option('active_plugins', array());
+ return;
+ }
+
+ //Invalid is any plugin that is deactivated due to error.
+ $invalid = array();
+
+ // If a plugin file does not exist, remove it from the list of active
+ // plugins.
+ foreach ( $check_plugins as $check_plugin ) {
+ $result = validate_plugin($check_plugin);
+ if ( is_wp_error( $result ) ) {
+ $invalid[$check_plugin] = $result;
+ deactivate_plugins( $check_plugin, true);
+ }
+ }
+ return $invalid;
+}
+
+/**
+ * Validate the plugin path.
+ *
+ * Checks that the file exists and {@link validate_file() is valid file}.
+ *
+ * @since unknown
+ *
+ * @param string $plugin Plugin Path
+ * @return WP_Error|int 0 on success, WP_Error on failure.
+ */
+function validate_plugin($plugin) {
+ if ( validate_file($plugin) )
+ return new WP_Error('plugin_invalid', __('Invalid plugin path.'));
+ if ( ! file_exists(WP_PLUGIN_DIR . '/' . $plugin) )
+ return new WP_Error('plugin_not_found', __('Plugin file does not exist.'));
+
+ $installed_plugins = get_plugins();
+ if ( ! isset($installed_plugins[$plugin]) )
+ return new WP_Error('no_plugin_header', __('The plugin does not have a valid header.'));
+ return 0;
+}
+
+/**
+ * Whether the plugin can be uninstalled.
+ *
+ * @since 2.7.0
+ *
+ * @param string $plugin Plugin path to check.
+ * @return bool Whether plugin can be uninstalled.
+ */
+function is_uninstallable_plugin($plugin) {
+ $file = plugin_basename($plugin);
+
+ $uninstallable_plugins = (array) get_option('uninstall_plugins');
+ if ( isset( $uninstallable_plugins[$file] ) || file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) )
+ return true;
+
+ return false;
+}
+
+/**
+ * Uninstall a single plugin.
+ *
+ * Calls the uninstall hook, if it is available.
+ *
+ * @since 2.7.0
+ *
+ * @param string $plugin Relative plugin path from Plugin Directory.
+ */
+function uninstall_plugin($plugin) {
+ $file = plugin_basename($plugin);
+
+ $uninstallable_plugins = (array) get_option('uninstall_plugins');
+ if ( file_exists( WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php' ) ) {
+ if ( isset( $uninstallable_plugins[$file] ) ) {
+ unset($uninstallable_plugins[$file]);
+ update_option('uninstall_plugins', $uninstallable_plugins);
+ }
+ unset($uninstallable_plugins);
+
+ define('WP_UNINSTALL_PLUGIN', $file);
+ include WP_PLUGIN_DIR . '/' . dirname($file) . '/uninstall.php';
+
+ return true;
+ }
+
+ if ( isset( $uninstallable_plugins[$file] ) ) {
+ $callable = $uninstallable_plugins[$file];
+ unset($uninstallable_plugins[$file]);
+ update_option('uninstall_plugins', $uninstallable_plugins);
+ unset($uninstallable_plugins);
+
+ include WP_PLUGIN_DIR . '/' . $file;
+
+ add_action( 'uninstall_' . $file, $callable );
+ do_action( 'uninstall_' . $file );
+ }
+}
+