0

i have a class to activate the plugins when i set my theme to active but the class auto activate all plugins , how i can modify to activate only the plugins that i choose.

if ( ! class_exists( __NAMESPACE__ . '\Auto_Activate' ) ) {
    class Auto_Activate extends Plugin {
        protected $plugins = [];

        public function __construct() {
            parent::__construct();

            $this->plugins = [
            'woocommerce/woocommerce.php',
            'ayyash-studio/ayyash-studio.php',
            'other-plugin/main-file.php',
            //...
        ];
        }

        protected function get_plugins() {
            $plugins = $this->plugins;
            $plugin  = plugin_basename( self::get( 'file' ) );
            if ( isset( $plugins[ $plugin ] ) ) unset( $plugins[ $plugin ] );
            return apply_filters( self::get( 'slug' ), $plugins );
        }

        public function action_after_setup_theme() {
            foreach( $this->get_plugins() as $plugin => $data )
                if ( in_array( $plugin, array_keys( $this->plugins ) ) )
                    if ( is_wp_error( $result = activate_plugin( $plugin, ! empty( $data['Network'] ) ) ) )
                        error_log( self::get( 'slug' ) . ': ' . $result->get_error_message() );
        }

        public function filter_network_admin_plugin_action_links( $actions, $plugin ) {
            if ( plugin_basename( self::get( 'file' ) ) !== $plugin &&
                 array_key_exists( 'deactivate', $actions ) &&
                 array_key_exists( $plugin, $this->get_plugins() ) )
                unset( $actions['deactivate'] );

            return $actions;
        }

        public function filter_plugin_action_links( $actions, $plugin ) {
            if ( plugin_basename( self::get( 'file' ) ) !== $plugin &&
                 array_key_exists( 'deactivate', $actions ) &&
                 array_key_exists( $plugin, $this->get_plugins() ) )
                unset( $actions['deactivate'] );

            return $actions;
        }
    }
}

1 Answer 1

0

get_plugins() this function return all installed plugins. so when your calling activate_plugin() in the loop it just activate all available (installed plugin). Just list your necessary plugin like below.

NB: It doesn't install or download the plugins listed in the plugins array. It only activates them.

class Auto_Activate extends Plugin {
    protected $plugins = [];

    public function __construct() {
        parent::__construct();

        $this->plugins = [
            'woocommerce/woocommerce.php',
            'ayyash-studio/ayyash-studio.php',
            'other-plugin/main-file.php',
            //...
        ];
    }
    public function action_after_setup_theme() {
        foreach( $this->plugins as $plugin ) {
            if ( ! is_plugin_active( $plugin ) ) {
                $activate = activate_plugin( $plugin, '', false, false );
                if ( is_wp_error( $activate ) ) {
                    error_log( $plugin . ': ' . $activate->get_error_message() );
                }
            }
        }
    }
}

Also it's not recommended to activate a bunch of plugin like this. most of the time this would end with timeout or memory exhaustion error, instead this one-by-one with AJAX request form the browser.

Edit:

I clearly missed the deactivation link part from your question. Below class should do all you need. Code below had necessary documentation and hints that will help you farther.

<?php
/**
 *
 * Required Plugins Activator.
 *
 * This auto activates required plugins and remove deactivation links from plugins page.
 *
 * @package Pixelhive\PluginActivator
 * @version 1.0.0
 * @license GPL-3.0-or-later
 */

if ( ! defined( 'ABSPATH' ) ) {
    die();
}

class RequiredPluginActivator {

    /**
     * Singleton Instance Placeholder.
     *
     * @var self
     */
    protected static $instance;

    /**
     * Array of required plugin.
     * Plugin needs to be listed as slug/main-file.php format.
     *
     * @var string[]
     */
    protected $required_plugins;

    /**
     * Create and returns singleton instance.
     *
     * @return self
     */
    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * Protected constructor, enforces singleton.
     *
     * @return void
     */
    protected function __construct() {
        // Add the required plugins.
        $this->required_plugins = [
            'woocommerce/woocommerce.php',
            'ayyash-studio/ayyash-studio.php',
            'other-plugin/main-file.php',
            //...
        ];

        // if the theme doesn't dependes on the required plugin much for initial setup, it's safe to increase the priority.
        add_action( 'after_setup_theme', [ $this, 'install_plugins' ], 1 );

        // Filter plugin action links.
        foreach ( $this->required_plugins as $plugin ) {
            add_filter( 'plugin_action_links_' . $plugin, [ $this, 'plugin_action_links' ] );
        }
    }

    /**
     * Install Required Plugins.
     *
     * This doesn't download the plugins itself, just activate already downloaded (installed) plugin
     * if it's not activated already.
     *
     * To download the plugin see the ajax function below for some idea.
     * @see wp_ajax_install_plugin()
     *
     * @return void
     */
    public function install_plugins() {
        // After theme setup initializes even in frontend, but plugins install should only be handled from the backend.
        if ( ! is_admin() ) {
            return;
        }

        if ( ! function_exists( 'is_plugin_active' ) ) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        foreach( $this->required_plugins as $plugin ) {
            if ( is_plugin_active( $plugin ) ) {
                continue;
            }
            $activate = activate_plugin( $plugin, '', false, false );
            if ( is_wp_error( $activate ) && defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                error_log( $plugin . ': ' . $activate->get_error_message() );
            }
        }
    }

    /**
     * Filters Plugin Action Links.
     *
     * @param array $links Action links.
     *
     * @return array
     */
    public function plugin_action_links( $links = [] ) {
        if ( isset( $links['deactivate'] ) ) {
            // Removes deactivation link.
            unset( $links['deactivate'] );
        }

        return $links;
    }
}

// Initialize auto activator.
RequiredPluginActivator::get_instance();

PS: From you code it seems you used some kind of boilerplate, but i could not figure which, so i put necessary action and filter in the constructor.

3
  • Thank you for your answer , it helped me , i edited the code and removed get plugins function , but how i can unset the deactivate action for this plugins? Commented Aug 29, 2022 at 18:48
  • @CrashPoint i have updated the answer for your comment. Check if it helps. Commented Aug 29, 2022 at 20:26
  • ,Thank you so much Commented Aug 29, 2022 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.