Call activation hook multiple times

I have a plugin that does some initialization stuff using register_activation_hook called from its __construct().

I’ve since extended my plugin to add functionality to it. For the sake of organization, I’ve moved the extended functions to it’s own class. I need to create a table that will deal with data unique to this new class.

Read More

My new class is instantiated from the construct of my main plugin. And from the construct of my new class, I am trying to call register_activation_hook a second time to create my table. Not surprisingly, this does not seem to work. (I have tested my db creation code elsewhere and it does work).

Is there a way that I can hook into the register_activation_hook from my new class to ensure the database is created at activation, or maybe even piggyback onto the parent class somehow to make sure the db is created?

Related posts

1 comment

  1. Use some kind of a Controller and combine the calls to both classes in one callback for each action. The controller should be responsible for the real assignation of business logic to an event (action), not some code outside of your classes.
    The basic point is: Your plugin controller should not alter data, only Models should do that.

    The following example shows how to create a table (I use an option here to keep things simple) and an option:

    <?php # -*- coding: utf-8 -*-
    namespace WPSE;
    /**
     * Plugin Name: Multiple De/Activation Objects
     */
    
    register_activation_hook(
        __FILE__,
        array ( Front_Controller::get_instance(), 'activate' )
    );
    
    register_deactivation_hook(
        __FILE__,
        array ( Front_Controller::get_instance(), 'deactivate' )
    );
    
    class Front_Controller
    {
        protected static $instance = NULL;
    
        protected $db_name     = 'wpse_db';
        protected $option_name = 'wpse_option';
    
        public static function get_instance()
        {
            if ( NULL === self::$instance )
                self::$instance = new self;
    
            return self::$instance;
        }
    
        public function activate()
        {
            $db = new Db( $this->db_name );
            $db->create_table();
    
            $option = new Option( $this->option_name );
            $option->add();
        }
    
        public function deactivate()
        {
            $db = new Db( $this->db_name );
            $db->delete_table();
    
            $option = new Option( $this->option_name );
            $option->remove();
        }
    }
    
    class Db
    {
        protected $db_name;
    
        public function __construct( $db_name )
        {
            $this->db_name = $db_name;
        }
    
        public function create_table()
        {
            // install table, for this demonstration, we use an option
            return add_option( $this->db_name, 'exists' );
        }
    
        public function delete_table()
        {
            // uninstall table
            return delete_option( $this->db_name );
        }
    }
    
    class Option
    {
        protected $option_name;
    
        public function __construct( $option_name )
        {
            $this->option_name = $option_name;
        }
    
        public function add()
        {
            // add option
            return add_option( $this->option_name, 'exists' );
        }
    
        public function remove()
        {
            // delete option
            return delete_option( $this->option_name );
        }
    }
    

    You can test the success with a second plugin:

    add_action( 'admin_footer', function() {
    
        $db     = get_option( 'wpse_db', 'missing' );
        $option = get_option( 'wpse_option', 'missing' );
    
        print "<code>$db = $db, $option = $option</code>";
    });
    

    Some links for further reading:

Comments are closed.