Пишем модуль под Drupal. Часть 6. Хуки form_alter и nodeapi

вт, 13.04.2010 14:39 :: olk
Теперь нам надо позволить пользователям (с разрешением на закрепление ноды вверху трэкера и/или запрещением публикации ноды в трэкере) при редактировании материала как-то устанавливать данные признаки. В этом нам поможет хук form_alter.
Хук form_alter позволяет добавить либо изменить элементы формы еще до рендеринга этой самой формы, причем если это форма редактирования (добавления) ноды, то в элементе $form['#node'] будет присутствовать текущий объект ноды.

В нашем случае, мы проверяем, является ли объект нодой (причем тип материала должен быть включен в настройках нашего трэкера) и добавляем в отдельную область (fieldset) два чекбокса, которые будут отвечать за наши дополнительные параметры у ноды. Доступ к этим элементам зависит от прав пользователя, которые мы определили в предыдущей части (см. хук perm).

Шаг номер 14:

Данную функцию мы помещаем в основной файл модуля cctracker.module.
function cctracker_form_alter(&$form, &$form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) &&
    $form['type']['#value'] .'_node_form' == $form_id &&
    (in_array($form['type']['#value'], variable_get('cctracker_node_types', array()), TRUE) ||
     in_array($form['type']['#value'], variable_get('cctracker_tab_types', array()), TRUE))
     ) {
    $cctracker = db_fetch_object(db_query("SELECT cc_sticky,cc_not_public,cc_sticky_weight FROM {node_cctracker} WHERE nid = %d", $form['#node']->nid));
    $form['cctracker'] = array(
      '#type' => 'fieldset',
      '#title' => t('Cctracker settings'),
      '#collapsible' => TRUE,
      '#collapsed' => !($cctracker->cc_sticky || $cctracker->cc_not_public),
      '#access' => user_access('access not place cctracker') || user_access('access sticky cctracker'),
      '#weight' => 30,
    );
      $form['cctracker']['cc_sticky'] = array(
        '#type' => 'checkbox',
        '#title' => t('Sticky this node on top tracker'),
        '#access' => user_access('access sticky cctracker'),
        '#default_value' => $cctracker->cc_sticky,
      );
      $form['cctracker']['cc_sticky_weight'] = array(
      '#type' => 'weight',
      '#title' => t('Sticky Weight'),
      '#default_value' => $cctracker->cc_sticky_weight,
      '#access' => user_access('access sticky cctracker'),
      '#delta' => 10,
      '#description' => t('Optional. In the tracker, the heavier items will sink and the lighter items will be positioned nearer the top.'),
      );
      $form['cctracker']['cc_not_public'] = array(
        '#type' => 'checkbox',
        '#title' => t('Not public in cctracker'),
        '#access' => user_access('access not place cctracker'),
        '#default_value' => $cctracker->cc_not_public,
      );
  }
}
Теперь при редактировании ноды (если у нас есть соответствующие права и тип материала включен в настройках cctraker) у нас появляется возможность изменить соответствующие опции для нашей ноды.
Но нам еще надо как то сохранить эти опции в нашей таблице.
Прекрасное место где это можно сделать, хук nodeapi
Хук nodeapi позволяет модулям реагировать на действия, затрагивающие все типы узлов.
Как правило, хук nodeapi используется в сочетании с хук form_alter. Модули могут использовать хук form_alter, чтобы разместить дополнительные элементы в форме, а хук nodeapi для чтения и из базы данных и записи в базу дополнительных данных из добавленных полей формы.

Шаг номер 15:
Определяем хук nodeapi в нашем файле cctracker.module

В данном хуке нас интересуют только три действия
  • insert - запись новой ноды
  • update - изменение ноды
  • delete - удаление ноды

Что бы визуально не перегружать код функции, мы так-же написали вспомогательную функцию _cctracker_node_save, которая собственно и выполняет все действия с базой данных.

function cctracker_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if (in_array($node->type, variable_get('cctracker_node_types', array()), TRUE) ||
      in_array($node->type, variable_get('cctracker_tab_types', array()), TRUE)
     ) {
    switch ($op) {
    case 'insert':
    case 'update':
        _cctracker_node_save($node, 'update');
        break;
    case 'delete':
        _cctracker_node_save($node, 'delete');
        break;
    }
  }
}

function _cctracker_node_save($node, $op='update') {
  $is_existing = db_result(db_query("SELECT COUNT(*) FROM {node_cctracker} WHERE nid = %d", $node->nid));
  if ($is_existing ) {
    if ($op != 'delete') {
      db_query("UPDATE {node_cctracker} SET cc_sticky = %d, cc_not_public = %d, cc_sticky_weight = %d WHERE nid = %d", $node->cc_sticky, $node->cc_not_public, $node->cc_sticky_weight, $node->nid);
     }
    else {
      db_query("DELETE FROM {node_cctracker} WHERE nid = %d", $node->nid);
    }
  }
  else {
    if ($op != 'delete') {
      db_query("INSERT INTO {node_cctracker} (nid, cc_sticky, cc_not_public,cc_sticky_weight) VALUES(%d, %d, %d, %d)", $node->nid, $node->cc_sticky, $node->cc_sticky_weight, $node->cc_not_public);
     }
  }
}

Теперь данные из ноды, корректно сохраняются в базе данных (в нашей таблице {node_cctracker}), но пока ни как не воздействуют на вывод нашего трэкера. В следующей части мы как раз подправим вывод трэкера в соответствии с дополнительными данными сохраненными в ноде.
Добавить комментарий
« Добавить комментарий
» Добавить комментарий