УрокКак программно изменять информацию в ноде

Содержимое ноды можно менять программно при реализации в своём модуле хука hook_nodeapi (для Drupal 6) или хуков nodeapi (для Drupal 7). Для этого сначала надо создать info-файл модуля (mymodule.info) и поместить его в папку sites/all/modules/mymodule.

Для Drupal 6:

name = mymodule
description = module changes node CRUD behavior
core = 6.x

Для Drupal 7:

name = mymodule
description = module changes node CRUD behavior
core = 7.x

Теперь в этой же папке создаём файл mymodule.module, и в зависимости от версии Друпала пишем туда имплементацию хука nodeapi.

Содержимое mymodule.module для Drupal 6:

<?php
 
/**
 * Implementation of hook_nodeapi().
 */
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    // Выполняется при создании материала
    case 'insert':
      if ($node->type == 'blog') {
        // Если тип материала блог - то выставляю ему автором пользователя с uid = 1
        $node->uid = 1;
      }
      break;
    // Выполняется при обновлении материала
    case 'update':
      if ($node->moderate && user_access('access submission queue')) {
        drupal_set_message('Материал отправлен на рассмотрение модератора');
      }
      break;
    // Выполняется при просмотре материала
    case 'view':
      // Добавление поля к ноде
      $node->content['my_additional_field'] = array(
        '#value' => theme('mymodule_my_additional_field', $additional_field),
        '#weight' => 10,
      );
      break;
    // Выполняется при удалении материала
    case 'delete':
      // Если материал неопубликован
      if ($node->status == 0) {
        drupal_set_message('Вы удалили неопубликованный материал');
      }
  }
}

Здесь преведены только основные операции CRUD (create, read/view, update, delete). Но возможны и другие:

  • alter
  • deleterevision
  • load
  • prepare
  • preparetranslation
  • print
  • rssitem
  • searchresult
  • presave
  • updateindex
  • validate

Подробнее о них можно прочитать в разделе русской или английской документации по хуку nodeapi.

В Drupal 7, в отличие от шестого, каждая из возможных операций вынесена в отдельный хук. То есть, если раньше было так (Drupal 6):

/**
 * Implementation of hook_nodeapi().
 */
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    // Выполняется при создании материала
    case 'insert':
      if ($node->type == 'blog') {
        // Если тип материала блог - то выставляю ему автором пользователя с uid = 1
        $node->uid = 1;
      }
      break;
  }
}

То в седьмом Друпале это выглядит вот так:

/**
 * Implements hook_node_insert().
 */
function mymodule_node_insert($node) {
  if ($node->type == 'blog') {
    // Если тип материала блог - то выставляю ему автором пользователя с uid = 1
    $node->uid = 1;
  }
}

А в остальном различий для программной работы с нодами практически нет.

Отдельно прошу заметить, что в файле модуля mymodule.module нет закрывающей скобки ?>. Это связано с несколькими причинами:

  • Удаление ?> позволяет избежать ошибки "Заголовки уже отосланы" (headers already sent), вызываемая лишними пробелами после закрывающих символов.
  • Лишними пробелами также может вызываться ошибка валидации XHTML/XML и другие ошибки, отловить которые будет очень проблематично.
  • Закрывающие символы необязательны.
  • Неиспользование закрывающих символов считается хорошим тоном программирования на PHP.

Комментарии

Аватар пользователя AK47
AK47 написал:

Спасибо за материал.

29.08.2011 14:12
Аватар пользователя vegas
vegas написал:

Присоединяюсь к благодарностям! И тут же вопрос. Название модуля: есть ли правила для имени файлов?
Создаю папку "mynode" и в ней файлы mynode.info и mynode.module. Ну и сам хук mynode_node_view($node, $view_mode). Всё работает.
Но если везде поменять mynode на altnode, например, модуль в списке есть, но хук не срабатывает, даже после очистки кэша.
Вот и решил, что название имеет значение...

20.10.2011 18:00
Аватар пользователя Spleshka
Spleshka написал:

Название модуля играет большую роль. Если вы создали файл mynode.info, то все хуки должны начинаться только с mynode, и никак иначе. В Друпале все хуки обрабатываются по принципу имяМодуля_имяФункции().

20.10.2011 18:47
Аватар пользователя vegas
vegas написал:

Спасибо, наверное просто что-то не доглядел. На данный момент работает!

20.10.2011 21:32
Аватар пользователя vegas
vegas написал:

Большая просьба ткнуть меня носом туда, где можно изменить форму отправки комментариев (хочу поубирать всё лишнее, как на этом сайте, и текст поменять кое-где). Единственное, что нашел подходящее на api.drupal7 - это function hook_form($node, &$form_state).
Но есть сомнения :(

24.10.2011 18:13
Аватар пользователя Spleshka
Spleshka написал:

hook_form_FORM_ID_alter(). В твоём случае - hook_form_comment_form_alter().

24.10.2011 20:34
Аватар пользователя Dark
Dark написал:

А как внести изменения до сохранения ноды в 7 версии? hook_node_presave не срабатывает. Судя по https://api.drupal.org/api/drupal/modules%21node%21node.api.php/function/hook_node_presave/7

18.07.2014 13:37
Аватар пользователя Викa
Викa написал:

Здравствуйте! Как сделать так, что при создании ноды, имя менялось на заданное. Можно ли это реализовать с помощью хука hook_node_insert?

14.04.2015 01:18

Комментировать