web-dev-qa-db-ja.com

アクティベーションフックを複数回呼び出す

__construct()から呼び出されるregister_activation_hookを使って初期化を行うプラグインがあります。

私はそれ以来私はそれに機能を追加するために私のプラグインを拡張しました。編成のために、私は拡張機能をそれ自身のクラスに移しました。この新しいクラスに固有のデータを扱うテーブルを作成する必要があります。

私の新しいクラスは私のメインプラグインの構造からインスタンス化されています。そして私の新しいクラスのconstructから、私はテーブルを作成するためにもう一度register_activation_hookを呼び出そうとしています。当然のことながら、これはうまくいかないようです。 (私は自分のdb作成コードを他のところでテストしましたが、それはうまくいきます)。

アクティブ化時にデータベースが確実に作成されるようにするために新しいクラスからregister_activation_hookにフックできる方法はありますか。それとも、何らかの理由で親クラスに便乗してdbが確実に作成されるようにする方法もありますか。

3
ahnkee

ある種のControllerを使用して、各アクションに対してoneコールバックで両方のクラスへの呼び出しを組み合わせます。コントローラは、クラス外のコードではなく、イベント(アクション)へのビジネスロジックの実際の割り当てを担当する必要があります。
基本的なポイントは次のとおりです。あなたのプラグインコントローラはデータを変更するべきではなく、モデルだけがそれを行うべきです。

次の例は、テーブル(私は物事を単純にするためにオプションを使用します)とオプションを作成する方法を示します。

<?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 );
    }
}

2番目のプラグインを使って成功をテストできます。

add_action( 'admin_footer', function() {

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

    print "<code>\$db = $db, \$option = $option</code>";
});

さらに読むためのいくつかのリンク:

2
fuxia