Call activation hook multiple times

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:

Leave a Comment