Comment ajouter des valeurs par défaut à une table de base de données à l'aide de hook_install ()?

9

Je crée un module personnalisé avec son propre schéma de quelques tables. Ces tables doivent avoir des valeurs préremplies pour que le module fonctionne (emplacements par défaut, options de sélection, etc.).

Quelle est la meilleure façon d'insérer des valeurs par défaut dans ces tables pendant hook_install?

Étant donné que drupal_write_record n'est pas disponible, je peux utiliser db_query, mais je veux juste m'assurer que je n'enfreins aucune règle cardinale en le faisant.

oranges13
la source

Réponses:

7

La meilleure façon est de le faire dans hook_enable () ; au moment où le hook est invoqué, le module est déjà installé et le schéma de sa base de données est disponible pour Drupal et pour drupal_write_record(). Comme le hook est invoqué à chaque fois qu'un module est activé, et pas seulement lorsque le module est installé, l'implémentation du hook doit vérifier si elle n'a pas déjà ajouté ces lignes de base de données (par exemple, elle doit utiliser une variable Drupal contenant une valeur booléenne) .

Comme exemple de module qui utilise hook_enable()dans un but similaire, vous pouvez vérifier forum_enable () , ou php_enable () (qui ajoute le format d'entrée "code PHP").

function php_enable() {
  $format_exists = (bool) db_query_range('SELECT 1 FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'PHP code'))->fetchField();
  // Add a PHP code text format, if it does not exist. Do this only for the
  // first install (or if the format has been manually deleted) as there is no
  // reliable method to identify the format in an uninstall hook or in
  // subsequent clean installs.
  if (!$format_exists) {
    $php_format = array(
      'format' => 'php_code', 
      'name' => 'PHP code',
      // 'Plain text' format is installed with a weight of 10 by default. Use a
      // higher weight here to ensure that this format will not be the default
      // format for anyone. 
      'weight' => 11, 
      'filters' => array(
        // Enable the PHP evaluator filter.
        'php_code' => array(
          'weight' => 0, 
          'status' => 1,
        ),
      ),
    );
    $php_format = (object) $php_format;
    filter_format_save($php_format);

    drupal_set_message(t('A <a href="@php-code">PHP code</a> text format has been created.', array('@php-code' => url('admin/config/content/formats/' . $php_format->format))));
  }
}

Comme le montrent ces implémentations de hook, le code peut nécessairement avoir besoin d'être exécuté à chaque fois que le hook est exécuté; il peut également être nécessaire d'exécuter le code une seule fois, car dans le cas où les valeurs par défaut ajoutées à la base de données ne peuvent pas être modifiées par l'utilisateur, qui n'a pas d'interface utilisateur pour modifier / supprimer ces valeurs.

kiamlaluno
la source
Si je l'ai fait dans hook_enable (), cela signifie que les valeurs par défaut seraient réinitialisées à chaque fois que le module est activé et désactivé. Je pense que c'est assez courant, par opposition à une désinstallation et une réinstallation complètes (auquel cas il est prévu que la base de données soit réinitialisée).
oranges13
1
C'est pourquoi j'ai écrit: "l'implémentation du hook devrait vérifier si elle n'a pas déjà ajouté ces lignes de base de données." Cela signifie qu'il doit vérifier si les valeurs sont déjà dans la table de base de données, ou utiliser une variable Drupal pour vérifier s'il a déjà fait cette tâche. La vérification de la table de base de données serait effectuée si ces valeurs doivent nécessairement se trouver dans la base de données; par exemple, c'est le cas si les valeurs sont requises du module et que les utilisateurs ne sont pas autorisés à supprimer les valeurs par défaut.
kiamlaluno
Merci pour la clarification. Existe-t-il une différence entre le stockage de ces valeurs dans ma propre table personnalisée et le simple fait d'utiliser variable_set pour les stocker dans une variable persistante? Il s'agit simplement d'un tableau de valeurs pour les zones de sélection personnalisées.
oranges13
Toutes les valeurs définies avec variable_set(), qui ne sont pas supprimées avec variable_del(), sont chargées en mémoire lors du démarrage de Drupal et enregistrées dans une variable globale; cela signifie qu'ils sont en mémoire quel que soit le module qui utilise ces valeurs, ou non. À l'aide d'une table de base de données personnalisée, vous pouvez être sûr que ces valeurs ne sont chargées que lorsque le module en a vraiment besoin. Vous ne devez pas utiliser variable_set()si la variable Drupal contient un tableau auquel vous continuez d'ajouter un nouvel index de tableau à tout moment, par exemple.
kiamlaluno
En regardant le code (D7). Je ne vois que 2 lignes de code entre l'invocation de hook_install et hook_enable: une mise à jour d'une variable locale et un appel à watchdog. Ainsi, lors d'une véritable installation, il n'y a aucune différence entre ces 2 crochets sur ce qui est disponible et enregistré et ce qui ne l'est pas. La seule différence est de savoir s'il s'agit d'une première installation ou simplement de réactiver le module.
fietserwin
4

J'irais avec db_query/ db_insert(D6 / D7) dans hook_install ().

Ce n'est pas considéré comme une mauvaise pratique (et personne ne vous oblige à l'utiliser drupal_write_record()).

Il n'est pas rare que les gens désactivent et réactivent les modules, et dans ce cas, votre code hook_enable()se déclencherait à chaque fois. ce qui n'est pas sympa.

Bojan Zivanovic
la source