Database API Drupal 7, обновляем (редактируем) данные с помощью db_update. Часть 4

Сложность: 
3

В статье Database API Drupal 7, выборка данных и их удаление. db_select, db_query и db_delete. Часть 3 мы полностью написали страницу с таблицей, где выводятся данные из нашей таблички и еще сделали функционал удаление записи из таблицы.
Здесь мы напишем форму для обновления записи используя db_update.

Написание формы

Конечно же нам нужно написать отдельную форму которая будет предназначена для обновления наших данных. Но для того что бы создать форму, нам необходимо объявить новую страницу в hook_menu. Код страницы будет следующий:

  1. $items['my_database/%/update'] = array(
  2.   'title callback' => 'my_database_update_page_title',
  3.   'title arguments' => array(1),
  4.   'page callback' => 'drupal_get_form',
  5.   'page arguments' => array('my_database_update_form', 1),
  6.   'access arguments' => array('administer site configuration'),
  7. );

По сути здесь нет ничего сложного. Если вы не знаете что значит каждая из опций, тогда обязательно почитайте про это в предыдущей статье, о которой мы уже вспоминали выше.

Опишем функцию которая указана в title callback, потому что пользователь, который будет пользоваться нашим функционалом должен понимать что он редактирует, а заголовок как раз даст отличную подсказку.
Функция 'my_database_update_page_title' будет иметь следующий вид:

  1. function my_database_update_page_title($id) {
  2.   $placeholders = array(':id' => $id);
  3.   $number = db_query("SELECT `number` FROM {my_table} WHERE `id` = :id", $placeholders)->fetchField();
  4.   if ($number) {
  5.     return t('Edit item with number "@num"', array('@num' => $number));
  6.   }
  7.   else {
  8.     return t('Id not found.');
  9.   }
  10. }

Здесь мы в 2-3 строчке получаем значения поля с номером нашей записи. Далее мы проверяем есть ли такая запись с указаным id, если есть, тогда выводим заголовок с использованием плейсхолдера (подмены по шаблону). К примеру, если мы будем редактировать запись с номером 12, тогда у нас будет такой заголовок: 'Edit item with number “12”'.
Если же у нас не будет записи в таблице (например пользователь руками ввел неправильный id), тогда он увидит соответственный текст.
Не бойтесь делать лишние проверки. Пользователи, как правило, очень любят делать неожиданные вещи, а такие небольшие проверки страхуют нас от всяких недоразумений и даже от поломки сайта.

Далее приступим к созданию формы, код ее такой:

  1. function my_database_update_form($form, $form_state) {
  2.   $form = array();
  3.   $id = $form_state['build_info']['args'][0];
  4.  
  5.   $data = db_select('my_table', 'm')
  6.     ->condition('m.id', $id)
  7.     ->fields('m')
  8.     ->execute()
  9.     ->fetchAssoc();
  10.  
  11.   if (empty($data) || empty($data['number'])) {
  12.     $placeholders = array(
  13.       '@id' => $id,
  14.       '!back' => l(t('Go back'), 'my_database'),
  15.     );
  16.     $form['text'] = array(
  17.       '#markup' => t('Undefined "@id" id. !back.', $placeholders),
  18.     );
  19.     return $form;
  20.   }
  21.  
  22.   $form['number'] = array(
  23.     '#title' => t('Number'),
  24.     '#type' => 'textfield',
  25.     '#maxlength' => 10,
  26.     '#description' => t('Only numbers'),
  27.     '#required' => TRUE,
  28.     '#default_value' => $data['number'],
  29.   );
  30.   $form['teaser'] = array(
  31.     '#title' => t('Teaser'),
  32.     '#type' => 'textfield',
  33.     '#maxlength' => 150,
  34.     '#required' => TRUE,
  35.     '#default_value' => $data['teaser'],
  36.   );
  37.   $form['text'] = array(
  38.     '#title' => t('Text'),
  39.     '#type' => 'textarea',
  40.     '#required' => TRUE,
  41.     '#default_value' => $data['text'],
  42.   );
  43.  
  44.   $form['actions'] = array('#type' => 'actions');
  45.   $form['actions']['submit'] = array(
  46.     '#type' => 'submit',
  47.     '#value' => t('Submit'),
  48.   );
  49.   $form['actions']['cancel'] = array(
  50.     '#markup' => l(t('Cancel'), 'my_database')
  51.   );
  52.  
  53.   $form['#validate'][] = 'my_database_insert_form_validate';
  54.  
  55.   return $form;
  56. }

Проанализируем новые нюансы в форме.
В строчке 5-9 выполняется запрос в БД где выводится значения всех столбцов в ассоциативном массиве.
Строчки 11-20 могут показаться сначала не понятными, но давайте внимательно посмотрим. Сначала мы видим условие (if), где проверяется существует ли у нас запись вообще, и есть ли в этой записи значения в колонке number. Если же это условие верно (то есть записи нет), тогда мы формируем необходимый текст в теле условия, присваиваем текст в элемент $form['text'] и сразу же выводим код (после return выполнения кода не продолжается). Таким образом, здесь, мы страхуем себя от случая, если пользователь попал на ошибочную страницу для обновления записи.
Строчки 22-42 почти аналогичны как и в форме создания записи, но здесь, в каждом элементе, есть новый ключ, это '#default_value'. Данный ключ задает значения в поле.
Очень часто новички в написании вместо '#default_value' используют ключ ‘#value’ или же ‘#input’. Запомните, эти ключи использовать здесь не уместно.
Стоит обратить внимание на строчку 44. Здесь мы создаем элемент типа 'actions'. Этот тип оборачивает дочерние элементы в тег div со специальным классом, который дает Друпал-у понимание что элементы, которые предназначены для действий.
В строках 45-51 мы формируем наши элементы с действиями, в данном случаи это кнопка с отправкой формы и ссылка отмены, которая ведет на таблицу с записями.
Строка 53 довольно интересная, посмотрите на нее внимательно. Здесь в ключ '#validate' мы добавляем как новым элементом простого массива уже существующую проверку в нашу форму для обновления данных. Напомню, что функция 'my_database_insert_form_validate' используется для валидации формы вставки данных. Таким образом мы уменьшили неуместное копирование кода. Конечно же, сюда можно добавить и несколько проверок.
Ну и конечно, в конце мы должны вернуть форму, как указано в строчке под номером 55.

Обновления данных

За обновления данных конечно же будет отвечать функция по отправке формы, вид ее будет следующий:

  1. function my_database_update_form_submit($form, &$form_state) {
  2.   $id = $form_state['build_info']['args'][0];
  3.   $values = $form_state['values'];
  4.  
  5.   $query = db_update('my_table')
  6.     ->fields(array(
  7.       'number' => $values['number'],
  8.       'teaser' => $values['teaser'],
  9.       'text' => $values['text'],
  10.     ))
  11.     ->condition('id', $id)
  12.     ->execute();
  13.  
  14.   if ($query) {
  15.     drupal_set_message(t('Data updated successfully'));
  16.   }
  17.   else {
  18.     drupal_set_message(t('Data is not updated'), 'warning');
  19.   }
  20.  
  21.   $form_state['redirect'] = 'my_database';
  22. }

С кода все должно быть понятно. Вот например в строчках 5-12 происходит обновление данных. Мы указываем какую таблицу будем обновлять, даем данные в метод fields, обязательно указываем условие (condition) какая именно запись должна быть обновлена и в конце выполняем запрос.
Далее происходит проверка. Если результат обновления возвращает нам значение 1, тогда это означает что запись обновлена и мы выводим соответственное сообщение. Если выводить 0, тогда это означает что запись не была обновлена или в ней не было что обновлять. Ну и в конце написан переход на страницу с таблицей.

Финальный штрих

В нашей таблице осталось только добавить ссылку на страницу редактирование записи. Строчка будет такая:

l(t('Update'), "my_database/{$value['id']}/update")

Уверен что вы сможете найти куда и как ее вставить, что бы она была в колонке ‘Actions’.
Конечно же, исходный код модуля вы можете скачать в конце статьи.

Итог

Вот и все, мы закончили написание модуля, который создает свою таблицу в БД Друпал-а, создали страницу для вставки данных, вывода их в таблице, обновления и удаление. Еще, мы достаточно хорошо познакомились с hook_menu, возможностями Form API, Database API в Друпал 7.
Благодарю всех за внимание и спасибо за то, что пользуетесь сайтом DrupalGuide.ru.

Рассказать друзьям: