web-dev-qa-db-ja.com

register_activation_hookはDBにテーブルを追加していません

最初のプラグインを始めました。API呼び出しから返された値をデータベースに格納する必要があります。しかしそれをする前に、データベーステーブルを作ることができる必要があります。メインプラグインファイルに必要なファイルに次のコードがあります。

register_activation_hook(__FILE__, 'PLUGIN_activation');
function PLUGIN_activation() {
    //setup DB Tables
    global $wpdb;

    $table_name = $wpdb->prefix . "table_name";//insert actual tablename here

    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
      id mediumint(9) NOT NULL AUTO_INCREMENT,
      event_id text NOT NULL,
      event_date mediumint(8) DEFAULT '00000000' NOT NULL,
      event_unique mediumint(13) NOT NULL,
      name tinytext NOT NULL,
      PRIMARY KEY  (id)
    ) $charset_collate;";

    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    dbDelta( $sql );
}

プラグインを再インストールしてアクティブ化しましたが、何も起こりませんでした。

何らかの理由で、テーブルが作成されていません。これを止めることができるものは何ですか?

1
ExcellentSP

register_activation_hook( $file, $callback )$fileは、メインプラグインファイルへのパスと同じであるべきですが、サブファイルで__FILE__として持っている場合は同じではありません。つまり、コールバックは呼び出されません。

名前の衝突を避けるため、または名前空間を使用するために、関数の名前をプレフィックスとして付けることをお勧めします。

もっとコーデックス ここ

更新

関数の定義を覗いてみるのは有益です。

/**
 * Set the activation hook for a plugin.
 *
 * When a plugin is activated, the action 'activate_PLUGINNAME' hook is
 * called. In the name of this hook, PLUGINNAME is replaced with the name
 * of the plugin, including the optional subdirectory. For example, when the
 * plugin is located in wp-content/plugins/sampleplugin/sample.php, then
 * the name of this hook will become 'activate_sampleplugin/sample.php'.
 *
 * When the plugin consists of only one file and is (as by default) located at
 * wp-content/plugins/sample.php the name of this hook will be
 * 'activate_sample.php'.
 *
 * @since 2.0.0
 *
 * @param string   $file     The filename of the plugin including the path.
 * @param callable $function The function hooked to the 'activate_PLUGIN' action.
 */
function register_activation_hook($file, $function) {
    $file = plugin_basename($file);
    add_action('activate_' . $file, $function);
}

これは、 activate_plugin() 関数のプラグイン起動の対応するdo_action呼び出しです。

/**
 * Fires as a specific plugin is being activated.
 *
 * This hook is the "activation" hook used internally by register_activation_hook().
 * The dynamic portion of the hook name, `$plugin`, refers to the plugin basename.
 *
 * If a plugin is silently activated (such as during an update), this hook does not fire.
 *
 * @since 2.0.0
 *
 * @param bool $network_wide Whether to enable the plugin for all sites in the network
 *                           or just the current site. Multisite only. Default is false.
 */
  do_action( "activate_{$plugin}", $network_wide );

本物のプラグインを使ってこれを見ていきましょう。

たとえば、WooCommerceプラグインを取ります。これにはメインのプラグインファイルがあります。

/full/path/to/wp-content/woocommerce/woocommerce.php 

ここで を定義します。

register_activation_hook( __FILE__, array( 'WC_Install', 'install' ) );

$file__FILE__または

/full/path/to/wp-content/woocommerce/woocommerce.php 

それから行:

$file = plugin_basename( $file );

になります:

$file = plugin_basename( '/full/path/to/wp-content/woocommerce/woocommerce.php' );

それは与えます:

$file = 'woocommerce/woocommerce.php';

それから動的なフック:

add_action('activate_' . $file, $function);

生成されます:

add_action('activate_woocommerce/woocommerce.php', $function);

そのため、WooCommerceが登録アクティベーションフックを特別なファイル(たとえば、.

/full/path/to/wp-content/woocommerce/include/activation.php

これが__FILE__の値になり、次のアクションを登録します。

add_action('activate_woocommerce/include/activation.php', $function);

しかし、それに対するdo_action()呼び出しはありません。

代わりに、メインプラグインファイルのパスを保存して、他の場所で使用することができます。これは、メインプラグインファイル で既に行われているように です。

$this->define( 'WC_PLUGIN_FILE', __FILE__ );

それが役に立てば幸い!

5
birgire