如何使用hook_install()将默认值添加到数据库表?


9

我正在创建一个带有几个表的自定义模块的自定义模块。这些表需要预先填充一些值才能使模块正常工作(默认位置,选择选项等)。

在hook_install期间将默认值插入这些表的最佳实践是什么?

由于drupal_write_record不可用,因此我可以使用db_query,但我只想确保这样做不会违反任何基本规则。

Answers:


7

更好的方法是在hook_enable()内部完成;在调用该挂钩时,该模块已经安装,并且它的数据库模式可用于Drupal和drupal_write_record()。由于挂钩始终在启用模块时(不仅是在安装模块时)被调用,挂钩实现应检查它是否尚未添加那些数据库行(例如,它应使用包含布尔值的Drupal变量) 。

作为hook_enable()用于类似目的的模块示例,您可以检查forum_enable()php_enable()(添加“ 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))));
  }
}

从这些挂钩实现中可以看出,代码在每次执行挂钩时都必须执行。也可能是代码只需要执行一次,因为在这种情况下,无法从用户那里更改添加到数据库的默认值,而用户没有用户界面来更改/删除这些值。


如果在hook_enable()中执行此操作,则意味着每次启用和禁用模块时都会重置默认值。我认为这是相当普遍的,与完全卸载并重新安装(此时数据库有望重置)相反。
oranges13 2011年

1
这就是为什么我写道:“挂钩实现应检查它是否还没有添加那些数据库行。” 这意味着它应该检查数据库表中是否已经存在这些值,或者使用Drupal变量来检查它是否已经完成了该任务。如果这些值必须在数据库中,则将检查数据库表;例如,如果从模块中需要这些值,并且不允许用户删除默认值,就是这种情况。
kiamlaluno

感谢您的澄清。将这些值存储在我自己的自定义表中与仅使用variable_set将它们存储在持久变量中有什么区别吗?它只是自定义选择框的值数组。
oranges13 2011年

在Drupal引导时,所有使用设置的值(variable_set()不会被删除)不会variable_del()被加载到内存中,并保存在全局变量中。这意味着无论模块是否使用这些值,它们都在内存中。使用自定义数据库表,可以确保仅在模块真正需要时才加载这些值。例如,variable_set()如果Drupal变量包含一个数组,并且一直向其添加新的数组索引,则不应使用该数组。
kiamlaluno

查看代码(D7)。在钩子安装和钩子启用之间,我仅看到两行代码:对局部变量的更新和对看门狗的调用。因此,在实际安装期间,这两个钩子之间关于可用和注册的内容以及未注册的内容之间没有任何区别。唯一的区别是这是第一次安装还是只是重新启用模块。
fietserwin 2012年

4

我会在hook_install()中使用db_query/ db_insert(D6 / D7)。

这不是坏习惯(也没有人强迫您使用drupal_write_record())。

人们禁用和重新启用模块的情况并不少见,在这种情况下,hook_enable()每次都会触发您的代码。不好

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.