Finally, A Solution to the UNBEARABLE Torture of Installing WordPress Plugins

Cleanshot 2025 04 10 at 08.45.53@2x optimised.png

Ever found yourself weeping uncontrollably at the thought of having to install another WordPress plugin? Do your fingers cramp at the mere idea of clicking “Upload Plugin” for the FIFTH time in one day? Does your mouse hand tremble with repetitive stress injury from the grueling marathon of plugin installations?

Plugins. Add New Plugin. Upload Plugin. Choose File. Select. Install Now. Activate Plugin. REPEAT! Add New Plugin. Upload Plugin. Choose File. Select. Install Now. Activate Plugin.Add New Plugin. Upload Plugin. Choose File. Select. Install Now. Activate Plugin. REPEAT! Add New Plugin. Upload Plugin. Choose File. Select. Install Now. Activate Plugin.Add New Plugin. Upload Plugin. Choose File. Select. Install Now. Activate Plugin. REPEAT! Add New Plugin. Upload Plugin. Choose File. Select. Install Now. Activate Plugin. AHHHHHHHHHHHHH!!!!!!

INSTALLATION: Copy this code into a new PHP file in your wp-content/plugins directory, or use the “Code Snippets” plugin if you’re one of those fancy developers who’s too good for proper plugin files (hopefully you are). Activate it and access via either the Tools or Plugins menu. Remember: this one-time setup will save you SECONDS of work later!

What it does…

The Bulk Plugin Upload tool does what the WordPress gods cruelly decided wasn’t important enough to include in core: it lets you upload a bundle of plugins in a single ZIP file and installs them all at once. You can even have it automatically activate these plugins and enable auto-updates, because apparently clicking two more buttons is just too much to ask of a human being in 2025. The tool adds itself to both your Tools and Plugins menus so you can access this life-saving functionality from whichever sacred location you prefer to perform your plugin ritual sacrifices.

Why it does it…

Let’s be honest – installing WordPress plugins one by one is basically an outright suck of your soul. The mind-numbing tedium of clicking “Upload Plugin,” selecting a file, clicking “Install Now,” and then either activating or not activating each plugin is enough to drive any developer to consider a career change to something less traumatic, like professional alligator wrestling. This plugin saves precious seconds of your life that you’ll never get back, and prevents the carpal tunnel syndrome that inevitably comes from excessive upload button clicking.

How it does it…

    • The class WP_Bulk_Plugin_Upload creates a menu item in both the Tools and Plugins sections (because making you look in just ONE place would be too easy)

    • It uses ZipArchive to extract your uploaded ZIP file into a temporary directory, because apparently WordPress developers have nothing better to do than write temporary file management code

    • The tool intelligently searches for plugin folders and nested ZIP files within your uploaded bundle, because organizing your plugins logically is apparently too much to ask

    • It handles all the boring stuff like checking for existing plugins, copying files, and activating plugins, saving you from the existential dread of doing it manually

    • The tool even gives you a detailed report of what happened, as if you care about anything besides the fact that you didn’t have to click “Upload” 27 separate times

See the code…

<?php

/*
 * Plugin Name: Bulk Plugin Upload
 * Description: Upload multiple WordPress plugins at once using a single ZIP file or several.
 * Excerpt: Improve native WordPress plugin uploading with this Bulk Plugin Uploader which allows you to upload multiple WordPress plugins at once. You can select several individual ZIP files for upload, or choose a single ZIP that contains multiple plugins—either as separate folders or nested ZIPs. This user-friendly tool simplifies plugin management, making it quick and easy to install, activate, and set up auto-updates for your plugins. Perfect for novice users looking to streamline their WordPress site management!
 * Version: 2.3.0
 * Author: brandonjp.com
 * License: GPL v2 or later
 * Text Domain: bulk-plugin-upload
 *
 * The Blog Post or CSCloud URLs will probably have the latest version.
 * Blog Post URL: https://snipsnip.pro/s/868
 * CSCloud URL: https://codesnippets.cloud/snippet/brandonjp/WP-Bulk-563
 * GitHub URL: https://github.com/brandonjp/wp-bulk-plugin-uploader
 * Gist URL:
 *
 */

// Prevent direct file access
if (!defined('ABSPATH')) {
    exit;
}

if (!class_exists('WP_Bulk_Plugin_Upload')) {
    class WP_Bulk_Plugin_Upload {
        /** @var WP_Bulk_Plugin_Upload Single instance of this class */
        private static $instance = null;

        /** @var array Stores results of plugin operations */
        private $results = [];

        /** @var array Plugin configuration */
        private $config = [];

        /** @var array Default configuration values */
        private static $default_config = [
            // Plugin info
            'version' => '2.3.0',
            'text_domain' => 'bulk-plugin-upload',

            // Menu configuration
            'menu_parent' => 'both', // 'tools', 'plugins', or 'both'
            'page_title' => 'Bulk Plugin Upload',
            'menu_title' => 'Bulk Plugin Upload',
            'capability' => 'manage_options',
            'menu_slug' => 'bulk-plugin-upload',

            // Form options defaults
            'default_replace_existing' => false,
            'default_activate_plugins' => false,
            'default_enable_updates' => false,

            // Interface text
            'upload_button_text' => 'Upload and Install Plugins',
            'replace_label' => 'Replace existing plugins',
            'replace_description' => 'If unchecked, will skip plugins that already exist',
            'activate_label' => 'Activate uploaded plugins',
            'activate_description' => 'Automatically activate plugins after installation',
            'updates_label' => 'Enable auto-updates',
            'updates_description' => 'Enable automatic updates for installed plugins',

            // Feature flags
            'allow_activation' => true,
            'allow_updates' => true,
            'show_instructions' => true
        ];

        /** @var array Deployment options with defaults */
        private $options = [
            'replace_existing' => false,
            'activate_plugins' => false,
            'enable_updates' => false
        ];

        /**
         * Returns single instance of this class
         *
         * @param array $config Optional configuration override
         * @return WP_Bulk_Plugin_Upload
         */
        public static function get_instance($config = []) {
            if (self::$instance === null) {
                self::$instance = new self($config);
            }
            return self::$instance;
        }

        /**
         * Constructor - Sets up actions and filters
         *
         * @param array $config Configuration override
         */
        private function __construct($config = []) {
            // Merge provided config with defaults
            $this->config = wp_parse_args($config, self::$default_config);

            add_action('admin_menu', [$this, 'add_admin_menus']);
            add_action('admin_init', [$this, 'handle_upload']);
            add_action('admin_notices', [$this, 'display_notices']);
            add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_styles']);
            add_action('admin_head', [$this, 'add_admin_buttons']);
        }

        /**
         * Enqueues admin styles
         */
        public function enqueue_admin_styles($hook) {
            // Only load on our plugin page
            if (strpos($hook, $this->config['menu_slug']) === false) {
                return;
            }

            // Add inline CSS for flex classes
            $custom_css = "
                [class*='bp-flex-'] {
                    width: 100%;
                    display: flex;
                    flex-wrap: nowrap;
                    align-content: center;
                    justify-content: center;
                    align-items: center;
                    gap: 0.9rem;
                }

                [class*='bp-flex-'][class*='-row'] {
                    flex-direction: row;
                }

                [class*='bp-flex-'][class*='-stack'] {
                    flex-direction: column;
                }

                [class*='bp-flex-'][class*='-wrap'] {
                    flex-wrap: wrap;
                }

                [class*='bp-flex-'][class*='-nowrap'] {
                    flex-wrap: nowrap;
                }

                [class*='bp-flex-'][class*='-center'] {
                    align-items: center;
                    align-content: center;
                    justify-content: center;
                }

                [class*='bp-flex-'][class*='-top'],
                [class*='bp-flex-'][class*='-left'],
                [class*='bp-flex-'][class*='-start'] {
                    align-items: flex-start;
                    align-content: flex-start;
                    justify-content: flex-start;
                }

                [class*='bp-flex-'][class*='-bottom'],
                [class*='bp-flex-'][class*='-right'],
                [class*='bp-flex-'][class*='-end'] {
                    align-items: flex-end;
                    align-content: flex-end;
                    justify-content: flex-end;
                }
            ";

            wp_add_inline_style('wp-admin', $custom_css);
        }

		/**
         * Adds menu items based on configuration
         */
        public function add_admin_menus() {
            $page_config = [
                'page_title' => $this->config['page_title'],
                'menu_title' => $this->config['menu_title'],
                'capability' => $this->config['capability'],
                'menu_slug'  => $this->config['menu_slug'],
                'callback'   => [$this, 'render_admin_page']
            ];

            // Add to Tools menu
            if (in_array($this->config['menu_parent'], ['tools', 'both'])) {
                add_management_page(...array_values($page_config));
            }

            // Add to Plugins menu
            if (in_array($this->config['menu_parent'], ['plugins', 'both'])) {
                add_plugins_page(...array_values($page_config));
            }
        }

        /**
         * Displays admin notices for operation results
         */
        public function display_notices() {
            if (empty($this->results)) {
                return;
            }

            $success_count = count(array_filter($this->results, fn($r) => $r['status'] === 'Success'));
            $total_count = count($this->results);

            if ($success_count > 0) {
                $message = sprintf(
                    '%d of %d plugins processed successfully. Check results table for details.',
                    $success_count,
                    $total_count
                );
                echo '<div class="notice notice-success is-dismissible"><p>' . esc_html($message) . '</p></div>';
            }

            if ($success_count < $total_count) {
                $message = sprintf(
                    '%d plugins failed to process. Check results table for details.',
                    $total_count - $success_count
                );
                echo '<div class="notice notice-error is-dismissible"><p>' . esc_html($message) . '</p></div>';
            }
        }

        /**
         * Renders the admin interface
         */
        public function render_admin_page() {
            if (!current_user_can($this->config['capability'])) {
                wp_die(__('You do not have sufficient permissions to access this page.'));
            }
            ?>
            <div class="wrap">
                <div>
                    <h1>
                        <?php echo esc_html($this->config['page_title']); ?>
                        <span style="font-size: 13px; color: #646970; font-weight: normal; margin-left: 10px;">
                            v<?php echo esc_html($this->config['version']); ?>
                        </span>
                    </h1>
                </div>

                <div class="bp-flex-row-top-wrap">
                    <?php if ($this->config['show_instructions']): ?>
                    <div class="card">
                        <h2>Instructions</h2>
                        <p style="margin-bottom: 0.5rem;">Upload a ZIP file containing WordPress plugins. The ZIP can contain:</p>
                        <ul style="list-style: square; padding-left: 1.6rem; line-height: 0.8rem; margin: 0.5rem 0 1rem;">
                            <li>Plugin folders directly</li>
                            <li>Plugin ZIP files</li>
                            <li>A mixture of both folders and ZIP files</li>
                            <li>Optional: All contents in a parent folder</li>
                        </ul>
                        <pre style="background: #f1f1f1; padding: 15px; border-radius: 5px;">
Example structure:
plugins.zip
├── my-plugin/              # Direct folder
├── another-plugin.zip      # Compressed plugin
└── parent-folder/          # Optional parent folder
    ├── plugin-three/       #   containing more plugins
    └── plugin-four.zip</pre>
                    </div>
                    <?php endif; ?>

                    <div class="card">
                        <h2>Upload Plugins</h2>
                        <form method="post" enctype="multipart/form-data">
                            <?php wp_nonce_field('bulk_plugin_upload', 'bulk_plugin_nonce'); ?>

                            <table class="form-table" role="presentation">
                                <tr>
                                    <th scope="row">
                                        <label for="plugins_zip">Select ZIP File</label>
                                    </th>
                                    <td>
                                        <input type="file"
                                               name="plugins_zip"
                                               id="plugins_zip"
                                               accept=".zip"
                                               required>
                                        <p class="description">
                                            Upload a ZIP file containing your plugins
                                        </p>
                                    </td>
                                </tr>
                                <tr>
                                    <th scope="row">Options</th>
                                    <td>
                                        <fieldset>
                                            <label>
                                                <input type="checkbox"
                                                       name="replace_existing"
                                                       value="1"
                                                       <?php checked($this->config['default_replace_existing']); ?>>
                                                <?php echo esc_html($this->config['replace_label']); ?>
                                            </label>
                                            <p class="description">
                                                <?php echo esc_html($this->config['replace_description']); ?>
                                            </p>
                                            <br><br>

                                            <?php if ($this->config['allow_activation']): ?>
                                            <label>
                                                <input type="checkbox"
                                                       name="activate_plugins"
                                                       value="1"
                                                       <?php checked($this->config['default_activate_plugins']); ?>>
                                                <?php echo esc_html($this->config['activate_label']); ?>
                                            </label>
                                            <p class="description">
                                                <?php echo esc_html($this->config['activate_description']); ?>
                                            </p>
                                            <br><br>
                                            <?php endif; ?>

                                            <?php if ($this->config['allow_updates']): ?>
                                            <label>
                                                <input type="checkbox"
                                                       name="enable_updates"
                                                       value="1"
                                                       <?php checked($this->config['default_enable_updates']); ?>>
                                                <?php echo esc_html($this->config['updates_label']); ?>
                                            </label>
                                            <p class="description">
                                                <?php echo esc_html($this->config['updates_description']); ?>
                                            </p>
                                            <?php endif; ?>
                                        </fieldset>
                                    </td>
                                </tr>
                            </table>

                            <?php submit_button($this->config['upload_button_text']); ?>
                        </form>
                    </div>
                </div>

                <?php if (!empty($this->results)): ?>
                <div class="card">
                    <h2>Results</h2>
                    <table class="widefat">
                        <thead>
                            <tr>
                                <th>Plugin Name</th>
                                <th>Version</th>
                                <th>Status</th>
                                <th>Details</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($this->results as $result): ?>
                            <tr>
                                <td><?php echo esc_html($result['name']); ?></td>
                                <td><?php echo esc_html($result['version']); ?></td>
                                <td><?php echo esc_html($result['status']); ?></td>
                                <td><?php echo esc_html($result['details']); ?></td>
                            </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
                <?php endif; ?>
            </div>
            <?php
        }

		/**
         * Handles the plugin upload and installation process
         */
        public function handle_upload() {
            if (!isset($_POST['bulk_plugin_nonce']) ||
                !wp_verify_nonce($_POST['bulk_plugin_nonce'], 'bulk_plugin_upload')) {
                return;
            }

            if (!current_user_can($this->config['capability'])) {
                return;
            }

            if (!isset($_FILES['plugins_zip'])) {
                return;
            }

            $zip_file = $_FILES['plugins_zip'];
            if ($zip_file['error'] !== UPLOAD_ERR_OK) {
                $this->add_result('Upload Error', '', 'Failed', 'File upload failed');
                return;
            }

            // Set processing options
            $this->options = [
                'replace_existing' => !empty($_POST['replace_existing']),
                'activate_plugins' => !empty($_POST['activate_plugins']),
                'enable_updates' => !empty($_POST['enable_updates'])
            ];

            // Process the uploaded ZIP
            $this->process_zip_file($zip_file['tmp_name']);
        }

        /**
         * Processes the uploaded ZIP file
         */
		private function process_zip_file($zip_path) {
		   $temp_dir = get_temp_dir() . 'bulk_plugin_upload_' . uniqid();
		   if (!wp_mkdir_p($temp_dir)) {
			   $this->add_result('System Error', '', 'Failed', 'Could not create temporary directory');
			   return;
		   }

		   $zip = new ZipArchive();
		   if ($zip->open($zip_path) !== true) {
			   $this->add_result('ZIP Error', '', 'Failed', 'Could not open ZIP file');
			   $this->cleanup_dir($temp_dir);
			   return;
		   }

		   $zip->extractTo($temp_dir);
		   $zip->close();

		   // Look for potential plugin files in root and single parent folder
		   $items = array_filter(
			   array_diff(scandir($temp_dir), ['.', '..']),
			   function($item) use ($temp_dir) {
				   $path = $temp_dir . '/' . $item;
				   // Keep only directories and zip files that might be plugins
				   return is_dir($path) || (is_file($path) && pathinfo($path, PATHINFO_EXTENSION) === 'zip');
			   }
		   );

		   // If single folder, look inside it
		   if (count($items) === 1 && is_dir($temp_dir . '/' . reset($items))) {
			   $parent_dir = $temp_dir . '/' . reset($items);

			   // Check if the parent directory itself is a valid plugin
			   if ($this->is_valid_plugin_directory($parent_dir)) {
				   $this->process_plugin_folder($parent_dir);
			   } else {
				   // Look for plugins inside the parent directory
				   $items = array_filter(
					   array_diff(scandir($parent_dir), ['.', '..']),
					   function($item) use ($parent_dir) {
						   $path = $parent_dir . '/' . $item;
						   // Keep only directories and zip files that might be plugins
						   return is_dir($path) || (is_file($path) && pathinfo($path, PATHINFO_EXTENSION) === 'zip');
					   }
				   );
				   $this->process_plugin_items($parent_dir, $items);
			   }
		   } else {
			   // Process items in root
			   $this->process_plugin_items($temp_dir, $items);
		   }

		   $this->cleanup_dir($temp_dir);
		}

        /**
         * Processes a collection of plugin items (folders or ZIPs)
         */
        private function process_plugin_items($base_path, $items) {
            foreach ($items as $item) {
                $path = $base_path . '/' . $item;
                if (is_dir($path)) {
                    // Check if this directory contains a valid plugin before processing it
                    if ($this->is_valid_plugin_directory($path)) {
                        $this->process_plugin_folder($path);
                    } else {
                        // Skip directories that don't contain valid plugins
                        $this->add_result(basename($path), '', 'Skipped', 'Not a valid plugin directory');
                    }
                } elseif (pathinfo($path, PATHINFO_EXTENSION) === 'zip') {
                    $this->process_plugin_zip($path);
                }
            }
        }

        /**
         * Checks if a directory contains a valid WordPress plugin
         */
        private function is_valid_plugin_directory($dir) {
            if (!is_dir($dir)) {
                return false;
            }

            // Check for a main plugin file with a valid header
            $main_file = $this->find_main_plugin_file($dir);
            if ($main_file) {
                return true;
            }

            // If no main plugin file found, check if this is a nested plugin structure
            // (like a plugin with src/vendor subdirectories)
            $php_files = glob($dir . '/*.php');
            foreach ($php_files as $file) {
                $content = file_get_contents($file);
                if (strpos($content, 'Plugin Name:') !== false) {
                    return true;
                }
            }

            return false;
        }

        /**
         * Processes a plugin folder
         */
        private function process_plugin_folder($folder_path) {
            // First check if this is a valid plugin directory
            if (!$this->is_valid_plugin_directory($folder_path)) {
                $this->add_result(basename($folder_path), '', 'Failed', 'Invalid plugin structure');
                return;
            }

            $plugin_data = $this->get_plugin_data($folder_path);
            if (!$plugin_data) {
                $this->add_result(basename($folder_path), '', 'Failed', 'Could not read plugin data');
                return;
            }

            $plugin_folder = basename($folder_path);
            $destination = WP_PLUGIN_DIR . '/' . $plugin_folder;

            // Check existing plugin
            $existing_version = '';
            if (is_dir($destination)) {
                $existing_data = $this->get_plugin_data($destination);
                if ($existing_data) {
                    $existing_version = $existing_data['Version'];
                    if (!$this->options['replace_existing']) {
                        $this->add_result(
                            $plugin_data['Name'],
                            $plugin_data['Version'],
                            'Skipped',
                            "Already installed (version $existing_version)"
                        );
                        return;
                    }
                }
            }

            // Copy plugin files
            if (!$this->copy_plugin($folder_path, $destination)) {
                $this->add_result(
                    $plugin_data['Name'],
                    $plugin_data['Version'],
                    'Failed',
                    'Could not copy plugin files'
                );
                return;
            }

            // Build result details
            $details = $existing_version ?
                "Replaced version $existing_version" :
                'Newly installed';

            // Handle activation
            if ($this->options['activate_plugins']) {
                $main_file = $this->find_main_plugin_file($destination);
                if ($main_file) {
                    $plugin_file = $plugin_folder . '/' . $main_file;
                    try {
                        activate_plugin($plugin_file);
                        $details .= ', Activated';
                    } catch (Exception $e) {
                        $details .= ', Activation failed';
                    }
                }
            }

            // Handle auto-updates
            if ($this->options['enable_updates']) {
                $main_file = $this->find_main_plugin_file($destination);
                if ($main_file) {
                    $plugin_file = $plugin_folder . '/' . $main_file;
                    $this->enable_plugin_auto_updates([$plugin_file]);
                    $details .= ', Auto-updates enabled';
                }
            }

            $this->add_result(
                $plugin_data['Name'],
                $plugin_data['Version'],
                'Success',
                $details
            );
        }

		/**
         * Processes a plugin ZIP file
         */
        private function process_plugin_zip($zip_path) {
            $temp_extract_dir = get_temp_dir() . 'plugin_zip_' . uniqid();
            if (!wp_mkdir_p($temp_extract_dir)) {
                $this->add_result(basename($zip_path), '', 'Failed', 'Could not create temporary directory');
                return;
            }

            $zip = new ZipArchive();
            if ($zip->open($zip_path) !== true) {
                $this->add_result(basename($zip_path), '', 'Failed', 'Could not open plugin ZIP');
                $this->cleanup_dir($temp_extract_dir);
                return;
            }

            $zip->extractTo($temp_extract_dir);
            $zip->close();

            // Find the actual plugin directory
            $items = array_diff(scandir($temp_extract_dir), ['.', '..']);
            if (count($items) === 1 && is_dir($temp_extract_dir . '/' . reset($items))) {
                $this->process_plugin_folder($temp_extract_dir . '/' . reset($items));
            } else {
                $this->add_result(basename($zip_path), '', 'Failed', 'Invalid plugin ZIP structure');
            }

            $this->cleanup_dir($temp_extract_dir);
        }

        /**
         * Gets plugin data from a plugin directory
         */
        private function get_plugin_data($plugin_dir) {
            $main_file = $this->find_main_plugin_file($plugin_dir);
            if (!$main_file) {
                return false;
            }

            return get_plugin_data($plugin_dir . '/' . $main_file, false, false);
        }

        /**
         * Finds the main plugin file in a directory
         */
        private function find_main_plugin_file($plugin_dir) {
            if (!is_dir($plugin_dir)) {
                return false;
            }

            $plugin_files = glob($plugin_dir . '/*.php');
            foreach ($plugin_files as $file) {
                $content = file_get_contents($file);
                if (strpos($content, 'Plugin Name:') !== false) {
                    return basename($file);
                }
            }
            return false;
        }

        /**
         * Copies a plugin directory to its destination
         */
        private function copy_plugin($source, $destination) {
            // Request filesystem credentials if needed
            if (false === ($creds = request_filesystem_credentials(wp_nonce_url('tools.php?page=bulk-plugin-upload', 'bulk_plugin_upload')))) {
                return false;
            }

            if (!WP_Filesystem($creds)) {
                request_filesystem_credentials(wp_nonce_url('tools.php?page=bulk-plugin-upload', 'bulk_plugin_upload'));
                return false;
            }

            global $wp_filesystem;

            // Remove existing directory if it exists
            if ($wp_filesystem->exists($destination)) {
                $wp_filesystem->delete($destination, true);
            }

            // Create the destination directory
            if (!$wp_filesystem->mkdir($destination)) {
                return false;
            }

            // Copy files
            return copy_dir($source, $destination);
        }

        /**
         * Cleans up a directory and its contents
         */
        private function cleanup_dir($dir) {
            if (!is_dir($dir)) {
                return;
            }

            $files = array_diff(scandir($dir), ['.', '..']);
            foreach ($files as $file) {
                $path = $dir . '/' . $file;
                is_dir($path) ? $this->cleanup_dir($path) : unlink($path);
            }
            rmdir($dir);
        }

        /**
         * Checks if a folder contains php files
         */
		private function directory_contains_php_files($dir) {
			if (!is_dir($dir)) {
				return false;
			}

			$php_files = glob($dir . '/*.php');
			foreach ($php_files as $file) {
				$content = file_get_contents($file);
				if (strpos($content, '<?php') !== false) {
					return true;
				}
			}
			return false;
		}

        /**
         * Adds a result to the results array
         */
        private function add_result($name, $version, $status, $details) {
            $this->results[] = [
                'name' => $name,
                'version' => $version,
                'status' => $status,
                'details' => $details
            ];
        }

        /**
         * Helper function to enable auto-updates for plugins
         */
		private function enable_plugin_auto_updates($plugins) {
			if (function_exists('wp_is_auto_update_enabled_for_type') && !wp_is_auto_update_enabled_for_type('plugin')) {
				return false;
			}

			if (function_exists('enable_plugins_auto_update')) {
				return enable_plugins_auto_update($plugins);
			}

			foreach ($plugins as $plugin) {
				$auto_updates = (array) get_site_option('auto_update_plugins', array());
				$auto_updates[] = $plugin;
				$auto_updates = array_unique($auto_updates);
				update_site_option('auto_update_plugins', $auto_updates);
			}

			return true;
		}

        /**
         * Adds buttons to the WordPress admin interface
         */
        public function add_admin_buttons() {
            // Only add buttons on specific admin pages
            $screen = get_current_screen();
            if (!$screen) {
                return;
            }

            $screen_id = $screen->id;

            // Add button to plugins.php page
            if ($screen_id === 'plugins') {
                ?>
                <script type="text/javascript">
                    jQuery(document).ready(function($) {
                        // Add button after the "Add New Plugin" button
                        $('.page-title-action').after('<a href="<?php echo esc_url(admin_url('tools.php?page=' . $this->config['menu_slug'])); ?>" class="page-title-action">Upload Multiple Plugins</a>');
                    });
                </script>
                <?php
            }

            // Add button to plugin-install.php page
            if ($screen_id === 'plugin-install') {
                ?>
                <script type="text/javascript">
                    jQuery(document).ready(function($) {
                        // Add button after the "Upload Plugin" button
                        $('.upload-view-toggle').after('<a href="<?php echo esc_url(admin_url('tools.php?page=' . $this->config['menu_slug'])); ?>" class="page-title-action">Upload Multiple Plugins</a>');
                    });
                </script>
                <?php
            }
        }
    }

    // Initialize the plugin with optional configuration
    WP_Bulk_Plugin_Upload::get_instance([
        // Example of overriding default configuration
        'menu_parent' => 'both',
        'page_title' => 'Bulk Plugin Upload',
        'menu_title' => 'Bulk Plugin Upload',
        // Add any other configuration overrides here
    ]);
}