多次调用激活钩子

时间:2013-05-30 作者:ahnkee

我有一个插件,它使用register_activation_hook 从其调用__construct().

此后,我扩展了插件,为其添加了功能。为了便于组织,我将扩展函数移到了它自己的类中。我需要创建一个表来处理这个新类特有的数据。

我的新类是从我的主插件的构造中实例化的。从construct 我想给我的新班级打电话register_activation_hook 第二次创建我的表。毫不奇怪,这似乎不起作用。(我已经在其他地方测试了我的db创建代码,它确实有效)。

有什么方法可以让我register_activation_hook 从我的新类,以确保数据库是在激活时创建的,或者甚至可能以某种方式背驮到父类,以确保数据库是创建的?

1 个回复
最合适的回答,由SO网友:fuxia 整理而成

使用某种控制器,并将对两个类的调用组合在每个操作的一个回调中。控制器应该负责将业务逻辑真正分配给事件(操作),而不是类之外的代码<基本要点是:插件控制器不应更改数据,只有模型才能更改数据。

以下示例显示了如何创建一个表(我在这里使用一个选项来保持简单)和一个选项:

<?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 );
    }
}
您可以使用第二个插件测试是否成功:

add_action( \'admin_footer\', function() {

    $db     = get_option( \'wpse_db\', \'missing\' );
    $option = get_option( \'wpse_option\', \'missing\' );

    print "<code>\\$db = $db, \\$option = $option</code>";
});
以下链接供进一步阅读:

结束