web-dev-qa-db-fra.com

register_activation_hook n'ajoute pas de table à la base de données

J'ai lancé mon premier plugin et j'ai besoin de stocker les valeurs renvoyées par un appel API vers une base de données. Mais avant cela, je dois pouvoir créer une table de base de données. J'ai le code suivant dans un fichier qui est requis du fichier de plugin principal:

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

J'ai réinstallé le plugin et l'activé, mais rien ne s'est passé.

Pour une raison quelconque, la table n'est pas en cours de création. Qu'est-ce qui pourrait arrêter ça?

1
ExcellentSP

Notez que le $file dans register_activation_hook( $file, $callback ), devrait être égal au chemin du fichier de plugin principal, mais quand vous l'avez dans un sous-fichier en tant que __FILE__, alors ce n'est pas le même! Cela signifie que votre rappel n'est jamais appelé.

Je recommanderais également de préfixer le nom de la fonction pour éviter une éventuelle collision de noms ou utiliser des espaces de noms.

Plus dans le Codex ici .

Update

Il est instructif de jeter un coup d'œil dans la définition de la fonction:

/**
 * 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);
}

et il s’agit de l’appel do_action correspondant pour l’activation du plug-in dans la fonction activate_plugin() :

/**
 * 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 );

Exemple

Passons en revue cela avec un vrai plugin.

Alors prenons par exemple le WooCommerce plugin, qui contient le fichier de plugin principal:

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

où il définit :

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

$file est __FILE__ ou

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

Puis la ligne:

$file = plugin_basename( $file );

devient:

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

ça donne:

$file = 'woocommerce/woocommerce.php';

Puis le crochet dynamique:

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

génère:

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

Donc, si WooCommerce placerait le crochet d’activation de l’enregistrement dans un fichier spécial sous, par exemple.

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

alors ce serait la valeur de __FILE__ et nous enregistrerions l'action suivante:

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

mais il n'y a pas d'appel do_action() pour celui-là.

Au lieu de cela, ils pourraient stocker le chemin du fichier du plugin principal, pour l'utiliser ailleurs, comme ils le font déjà dans le fichier du plugin principal ici :

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

J'espère que ça aide!

5
birgire