3

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.

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?

1 Answer 1

2

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:

7
  • Namespaces and lambda functions at once, welcome to 2013!
    – brasofilo
    Commented May 31, 2013 at 8:09
  • 1
    @brasofilo Actually, these are features from 2009.
    – fuxia
    Commented May 31, 2013 at 8:13
  • @brasofilo Welcome to WordPress 4.6! Commented May 31, 2013 at 11:37
  • @StephenHarris, it arrived earlier than expected :) toscho, on the other hand, took longer than expected :P
    – brasofilo
    Commented May 31, 2013 at 12:52
  • Great!! Thank you so much for your help. That's beyond my capabilities so I'm going to digest your code carefully and learn from it.
    – ahnkee
    Commented May 31, 2013 at 19:16

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.