Drupal → Создаём форму в виде таблицы. Drupal 7 создание таблицы
Database API Drupal 7, hook_schema и создание таблицы в Drupal 7. Часть 1 | Видеоуроки и статьи по изучению Drupal 7
По многим просьбам мы распишем как правильно управляться с Базой Данных в Друпал 7.В этой статье мы познакомимся с самой первой основной Database API, а именно мы создадим таблицу в БД Друпал.
Написание модуля
Про написание модуля для Drupal 7 уже не раз описывалось на данном сайте. Если у Вас есть проблемы с этим, тогда рекомендуем прочитать статью Пишем модуль, Form API в Drupal 7 (уровень 2.1) часть 1 или же видео Пишем модуль Drupal 7, hook_menu.Стоит обратить внимание на то, что нам необходимо создать только 2 файла, это .info и .module.
Создадим папку с модулем, назвем ее “my_database”, также создадим файлик в середине папки с названием my_database.info.Содержимое файла стандартное и имеет следующий вид:
name = My database description = Module for example of use Database API in Drupal. core = 7.x version = 7.x-1.x-dev
Пишем таблицу
Вот мы уже подошли к тому самому моменту, когда нужно работать с Database API в Drupal 7.Мы будем писать hook_schema для того что бы создать таблицу.Стоит запомнить один нюанс, что данный хук необходимо писать в файле “.install”, таким образом, при включении модуля в Друпал, данный файл будет запускаться в первую очередь. hook_schema отвечает за создание таблицы в БД Друпала.
Создадим файл my_database.install, содержимое будет следующее:
<?php /*** @file* Installation file for My database module.*/Файл у нас есть, теперь давайте создадим таблицу с полям:- id - первичный ключ + автоинкремент;- number - целые числа;- teaser - текст до 150 символов, следовательно тип будет varchar;- text - тип текст.Таблица будет иметь название my_table.
hook_schema будет выглядеть следующим образом:
-
/**
-
* Implements hook_schema().
-
*/
-
function my_database_schema() {
-
$schema['my_table'] = array(
-
'description' => 'Custom table from My database module.',
-
'fields' => array(
-
'id' => array(
-
'description' => 'The primary identifier for a record.',
-
'type' => 'serial',
-
'unsigned' => TRUE,
-
'not null' => TRUE,
-
),
-
'number' => array(
-
'description' => 'Field for integer number.',
-
'type' => 'int',
-
'unsigned' => TRUE,
-
'not null' => TRUE,
-
'default' => 0,
-
),
-
'teaser' => array(
-
'description' => 'Teaser field.',
-
'type' => 'varchar',
-
'length' => 150,
-
'not null' => TRUE,
-
'default' => '',
-
),
-
'text' => array(
-
'description' => 'Text field.',
-
'type' => 'text',
-
'not null' => FALSE,
-
),
-
),
-
'primary key' => array('id'),
-
);
-
return $schema;
-
}
Давайте разберем строчки кода.Строчка 5 создает переменную с ключом массива 'my_table', здесь необходимо прописывать название таблицы.Следующая, 6 строчка, добавляет описание к таблице. Описание таблицы не есть обязательным, но желательным. Обратите внимание, что здесь текст не нужно оборачивать в функцию t, иначе будет ошибка.В строчках 7-33 описываются поля таблицы. Здесь думаю что все понятно, что ключом каждого поля это и есть его название, в каждом поле есть обязательное значение как 'type', в нем мы описываем тип поля. Еще, поля могут иметь дополнительные параметры, такие как 'description', 'unsigned', 'not null', 'default' и многие другие. Список всех типов вы можете посмотреть в официальной документации, а именно на этой странице.34 строчка задает первичный ключ для поля 'id'.И в 36 строчке возвращается массив.
Если вы уверены в том, что у вас создан файл .info, .module и .install, тогда можете смело включать модуль.Во время включения, Друпал увидит файл .install, за счет того, что он имеет одинаковое название вместе с файлом .info. Потом он увидит задействованный hook_schema. Относительно выстроенных параметров сформируется необходимый SQL-запрос, который будет применен к базе данных, на которой установлен Друпал.
После включение модуля проверьте, появилась ли новая таблица в БД Друпала.
Работа над ошибками
Иногда бывает проблемы с установкой таблицы, например вы включили модуль, а таблицы нет.В таких случаях необходимо попробовать еще раз установить модуль.В нашем случаи мы имеем дело с Базой Данных, поэтому если мы выключим модуль, тогда он еще останется в реестре сайта. Следовательно если вы выключите модуль Views а потом снова включите, тогда все его настройки никуда не пропадут. Но если зайти на страницу “/admin/modules/uninstall” (ссылка указана относительная), тогда вы увидите список выключенных модулей которые можно удалить. Только после полного удаления, модуль сотрет все свои следы пребывания в БД, также, во время удаления модуля задействован hook_uninstall (прописывать в .install файле), где можно прописать действия, которые будут сделаны во время удаления..
Получается следующее, если у Вас проблемы с модулем, вы нашли ошибку в уже созданой таблице, тогда выключите его, удалите и тогда снова включите.
Также, если у вас уже есть созданная таблица в ней есть данные, тогда ее удаление не есть уместно, поскольку мы потеряем информацию. В таких случаях необходимо прописать hook_update_N.
Для сверки, в конце статьи прикреплен архив с модулем.
Итог
В это статье мы познакомились с hook_schema, проанализировали как правильно создавать таблицы в БД Друпала.В следующей части статьи мы познакомимся с написанием запросов используя Database API Drupal 7.
drupalguide.ru
Drupal: Создаём форму в виде таблицы
Формы в виде таблиц, где нужно выбрать несколько записей, довольно распространены в шестом друпале, но процесс их создания очень не простой :(
Код, создающий по адресу example.com/form-table простую таблицу со списком нод и возможностью выбрать несколько из них:
А вот код который делает тоже самое, но с пагинацией и возможностью сортировки:
/** * Описание формы mymodule_form_table */ function mymodule_form_table() { // описание заголовков $form['header'] = array( '#type' => 'value', '#value' => array( theme('table_select_header_cell'), array('data' => 'Заголовок', 'field' => 'title'), array('data' => 'Дата создания', 'field' => 'created', 'sort' => 'asc'), ), ); // получаем список нод $nodes = pager_query("SELECT nid, title, created FROM {node}" . tablesort_sql($form['header']['#value']), 10); while ($node = db_fetch_object($nodes)) { $options[$node->nid] = ''; // заголовок ноды в виде ссылки $form['title'][$node->nid] = array('#value' => l($node->title, 'node/' . $node->nid)); // дата создания ноды $form['created'][$node->nid] = array('#value' => format_date($node->created)); } $form['nid'] = array( '#type' => 'checkboxes', '#options' => isset($options) ? $options : array(), ); $form['pager'] = array( '#value' => theme('pager', null, 10) ); $form['submit'] = array( '#type' => 'submit', '#value' => 'Удалить', ); return $form; }xandeadx.ru
Drupal: Создание табличной формы | xandeadx.ru
Пример создания таблицы со списком материалов, в которой можно редактировать заголовки и устанавливать статус ноды:
Небольшая вводная информация — при создании любых табличных форм, я обычно применяю принцип прогрессивного улучшения. Т.е. первым делом создаю форму как если бы я ничего не знал о темизации, но форма при этом должна быть полностью рабочая и понятно выглядеть. Например вот так выглядит наша табличная форма без использования темизации:
Ну а вторым шагом, с помощью темизации, придаю ей необходимый вид:
Если следовать такому принципу, то достаточно легко создавать формы любой сложности.
Итак, код с комментариями:
/** * Form builder. */ function modulename_massedit_form($form, &$form_state) { $form['nodes'] = array( '#tree' => TRUE, '#theme' => 'table_form', // Функция, с помощью которой мы будем придавать форме табличный вид ); $nodes = db_query("SELECT nid, title, created, status FROM {node}"); foreach ($nodes as $node) { $form['nodes'][$node->nid]['created'] = array( '#type' => 'item', '#title' => 'Дата создания', '#markup' => format_date($node->created, 'small'), ); $form['nodes'][$node->nid]['title'] = array( '#type' => 'textfield', '#title' => 'Заголовок', '#default_value' => $node->title, '#required' => TRUE, ); $form['nodes'][$node->nid]['status'] = array( '#type' => 'checkbox', '#title' => 'Статус', '#default_value' => $node->status, ); } $form['submit'] = array( '#type' => 'submit', '#value' => 'Сохранить', ); return $form; } /** * Implements hook_theme(). */ function modulename_theme() { return array( 'table_form' => array( 'render element' => 'form', ), ); } /** * Format form as table. */ function theme_table_form($vars) { $form = $vars['form']; $header = isset($vars['#header']) ? $vars['#header'] : array(); $header_created = (bool)$header; $rows = array(); foreach (element_children($form) as $key) { foreach (element_children($form[$key]) as $name) { // Create header if (!$header_created) { $header[] = $form[$key][$name]['#title']; } // Hide title $form[$key][$name]['#title_display'] = 'invisible'; // Cell data $cell = array('data' => drupal_render($form[$key][$name])); if (isset($form[$key][$name]['#td_attributes'])) { $cell += $form[$key][$name]['#td_attributes']; } $rows[$key]['data'][] = $cell; } $header_created = TRUE; if (isset($form[$key]['#attributes'])) { $rows[$key] += $form[$key]['#attributes']; } } return theme('table', array( 'rows' => $rows, 'header' => $header, 'attributes' => isset($form['#attributes']) ? $form['#attributes'] : array(), 'caption' => isset($form['#caption']) ? $form['#caption'] : NULL, 'colgroups' => isset($form['#colgroups']) ? $form['#colgroups'] : NULL, 'sticky' => isset($form['#sticky']) ? $form['#sticky'] : NULL, 'empty' => isset($form['#empty']) ? $form['#empty'] : NULL, )); }Рабочий пример можно посмотреть в демо-модуле.
Написанное актуально для Drupal 7 Похожие записиxandeadx.ru
Drupal: Работа с базой данных в Drupal 7
Выборка с условием:
// Drupal 6 $nodes = db_query(" SELECT nid, title FROM {node} WHERE type = '%s' AND uid = %d ", 'page', 1); // Drupal 7, static query $nodes = db_query(" SELECT nid, title FROM {node} WHERE type = :type AND uid = :uid ", array(':type' => 'page', ':uid' => 1))->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->condition('n.type', 'page') ->condition('n.uid', 1) ->execute() ->fetchAll();Выборка из двух таблиц соединённых с помощью INNER JOIN:
// Drupal 6 $nodes = db_query(" SELECT n.title, u.name FROM {node} n INNER JOIN {users} u ON n.uid = u.uid "); // Drupal 7, static query $nodes = db_query(" SELECT n.title, u.name FROM {node} n INNER JOIN {users} u ON n.uid = u.uid ")->fetchAll(); // Drupal 7, dynamic query $query = db_select('node', 'n'); $query->innerJoin('users', 'u', 'n.uid = u.uid'); $query->fields('n', array('title')); $query->fields('u', array('name')); $nodes = $query->execute()->fetchAll();Следует помнить, что некоторые методы (например джоины) не возвращают объект SelectQuery, и поэтому их нельзя использовать в цепочке вызовов вроде db_select()->method1()->innerJoin()->method2().
Получить значение поля у единственной записи:
// Drupal 6 $title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", 123)); // Drupal 7, static query $title = db_query("SELECT title FROM {node} WHERE nid = :nid", array(':nid' => 123))->fetchField(); // Drupal 7, dynamic query $title = db_select('node', 'n') ->fields('n', array('title')) ->condition('n.nid', 123) ->execute() ->fetchField();Получить объект по его id:
// Drupal 6 $node = db_fetch_object(db_query("SELECT * FROM {node} WHERE nid = %d", 123)); // Drupal 7, static query $node = db_query("SELECT * FROM {node} WHERE nid = :nid", array(':nid' => 123))->fetchObject(); // Drupal 7, dynamic query $node = db_select('node', 'n') ->fields('n') ->condition('n.nid', 123) ->execute() ->fetchObject();Посчитать число записей:
// Drupal 6 $count = db_result(db_query("SELECT COUNT(*) FROM {node} n WHERE n.uid = 1")); // Drupal 7, static query $count = db_query("SELECT COUNT(*) FROM {node} n WHERE n.uid = 1")->fetchField(); // Drupal 7, dynamic query, вариант 1 $count = db_select('node', 'n') ->condition('n.uid', 1) ->countQuery() ->execute() ->fetchField(); // Drupal 7, dynamic query, вариант 2 $query = db_select('node'); $query->addExpression('COUNT(*)'); $count = $query->execute()->fetchField();Найти минимальное значение:
// Drupal 6 $min = db_result(db_query("SELECT MIN(fieldname) FROM {table}")); // Drupal 7, static query $min = db_query("SELECT MIN(fieldname) FROM {table}")->fetchField(); // Drupal 7, dynamic query $query = db_select('table'); $query->addExpression('MIN(fieldname)'); $min = $query->execute()->fetchField();Выбрать определённое количество записей:
// Drupal 6 $nodes = db_query("SELECT * FROM {node} LIMIT 0, 10"); // Drupal 7, static query $nodes = db_query("SELECT * FROM {node} LIMIT 0, 10")->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n') ->range(0, 10) ->execute() ->fetchAll();Обойти записи:
// Drupal 6 $nodes = db_query("SELECT * FROM {node}"); while ($node = db_fetch_object($nodes)) { $items[] = $node->title; } // Drupal 7, static query $result = db_query("SELECT * FROM {node}"); foreach ($result as $node) { $items[] = $node->title; } // Drupal 7, dynamic query $result = db_select('node', 'n')->fields('n')->execute(); foreach ($result as $node) { $items[] = $node->title; }Обновление записи:
// Drupal 6 db_query("UPDATE {node} SET status = %d WHERE nid = %d", 1, 123); // Drupal 7, static query db_query("UPDATE {node} SET status = :status WHERE nid = :nid", array(':status' => 1, ':nid' => 123)); // Drupal 7, dynamic query db_update('node') ->fields(array('status' => 1)) ->condition('nid', 123) ->execute();Инкремент значения поля:
// Drupal 6 db_query("UPDATE {node_counter} SET totalcount = totalcount + 1 WHERE nid = %d", 123); // Drupal 7, static query db_query("UPDATE {node_counter} SET totalcount = totalcount + 1 WHERE nid = :nid", array(':nid' => 123)); // Drupal 7, dynamic query db_update('node_counter') ->expression('totalcount', 'totalcount + 1') ->condition('nid', 123) ->execute();Удаление записи:
// Drupal 6 db_query("DELETE FROM {node} WHERE uid = %d AND created < %d", 1, time() - 3600); // Drupal 7, static query db_query("DELETE FROM {node} WHERE uid = :uid AND created < :created", array(':uid' => 1, ':created' => time() - 3600)); // Drupal 7, dynamic query db_delete('node') ->condition('uid', 1) ->condition('created', time() - 3600, '<') ->execute();Очистка таблицы (удаление всех данных из таблицы):
// Drupal 6, Drupal 7 static query db_query("TRUNCATE {node}"); // Drupal 7, dynamic query db_truncate('node')->execute();Добавление записи:
// Drupal 6 db_query("INSERT INTO {mytable} (intvar, stringvar, floatvar) VALUES (%d, '%s', %f)", 5, 'hello world', 3.14); $id = db_last_insert_id(); // Drupal 7, dynamic query $id = db_insert('mytable') ->fields(array( 'intvar' => 5, 'stringvar' => 'hello world', 'floatvar' => 3.14, )) ->execute();Для добавления данных можно по прежнему пользоваться drupal_write_record()
Использование логического оператора OR в условии:
// Drupal 6 $nodes = db_query("SELECT * FROM {node} WHERE uid = %d OR status = %d", 1, 0); // Drupal 7, static query $nodes = db_query("SELECT * FROM {node} WHERE uid = :uid OR status = :status", array(':uid' => 1, ':status' => 0))->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n') ->condition( db_or() ->condition('uid', 1) ->condition('status', 0) ) ->execute() ->fetchAll();Использование оператора IN в условии:
$nids = array(1, 2, 3); // Drupal 6 $nodes = db_query("SELECT * FROM {node} WHERE nid IN (" . db_placeholders($nids) . ")", $nids); // Drupal 7, static query $nodes = db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' => $nids))->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n') ->condition('n.nid', $nids, 'IN') ->execute() ->fetchAll();Использование оператора LIKE в условии:
// Drupal 6 $nodes = db_query("SELECT * FROM {node} WHERE title LIKE '%%%s%%'", 'substring'); // Drupal 7, static query $nodes = db_query("SELECT * FROM {node} WHERE title LIKE :title", array(':title' => '%' . db_like('substring') . '%'))->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n') ->condition('n.title', '%' . db_like('substring') . '%', 'LIKE') ->execute() ->fetchAll();Использование оператора BETWEEN в условии:
// Drupal 6 $nodes = db_query("SELECT * FROM {node} WHERE nid BETWEEN %d AND %d", 123, 456); // Drupal 7, static query $nodes = db_query("SELECT * FROM {node} WHERE nid BETWEEN :nid1 AND :nid2", array(':nid1' => 123, ':nid2' => 456))->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n') ->condition('n.nid', array(123, 456), 'BETWEEN') ->execute() ->fetchAll();Проверка значения на NULL:
// Drupal 6, Drupal 7 static query $result = db_query("SELECT * FROM {table} WHERE field IS NULL"); // Drupal 7, dynamic query, вариант 1 $result = db_select('table', 't') ->fields('t') ->condition('t.field', NULL, 'IS NULL') ->execute(); // Drupal 7, dynamic query, вариант 2 $result = db_select('table', 't') ->fields('t') ->isNull('t.field') ->execute();Сложные условия в WHERE:
// Drupal 6 $nodes = db_query("SELECT * FROM {node} WHERE YEAR(FROM_UNIXTIME(created)) = %d", 2011); // Drupal 7, static query $nodes = db_query("SELECT * FROM {node} WHERE YEAR(FROM_UNIXTIME(created)) = :created", array(':created' => 2011))->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n') ->where('YEAR(FROM_UNIXTIME(n.created)) = :created', array(':created' => 2011)) ->execute() ->fetchAll();Сортировка:
// Drupal 6 $nodes = db_query("SELECT * FROM {node} ORDER BY created DESC, title ASC"); // Drupal 7, static query $nodes = db_query("SELECT * FROM {node} ORDER BY created DESC, title ASC")->fetchAll(); // Drupal 7, dynamic query $nodes = db_select('node', 'n') ->fields('n') ->orderBy('n.created', 'DESC') ->orderBy('n.title', 'ASC') ->execute() ->fetchAll();Получить результаты запроса в виде двумерного ассоциативного массива:
// Drupal 6 $result = db_query("SELECT nid, title, created FROM {node}"); $nodes = array(); while ($row = db_fetch_object($result)) { $nodes[$row->nid] = $row; } // Drupal 7, static query $nids = db_query("SELECT nid, title, created FROM {node}")->fetchAllAssoc('nid'); // Drupal 7, dynamic query $nids = db_select('node', 'n') ->fields('n', array('nid', 'title', 'created')) ->execute() ->fetchAllAssoc('nid');Получить одну колонку из таблицы в виде простого одномерного массива:
// Drupal 6 $result = db_query("SELECT nid FROM {node}"); $nids = array(); while ($row = db_fetch_object($result)) { $nids[] = $row->nid; } // Drupal 7, static query $nids = db_query("SELECT nid FROM {node}")->fetchCol(); // Drupal 7, dynamic query $nids = db_select('node', 'n') ->fields('n', array('nid')) ->execute() ->fetchCol();Получить одномерный ассоциативный массив, где ключами будет первая колонка запроса, а значениями — вторая:
// Drupal 6 $result = db_query("SELECT nid, title FROM {node}"); $titles = array(); while ($row = db_fetch_object($result)) { $nids[$row->nid] = $row->title; } // Drupal 7, static query $titles = db_query("SELECT nid, title FROM {node}")->fetchAllKeyed(); // Drupal 7, dynamic query $titles = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->execute() ->fetchAllKeyed();Полный мануал с кучей примеров есть на официальном сайте — Database API.
Добавлено 09/07/2011
Видео с DrupalCamp Kyiv 2011:
Написанное актуально для Drupal 7 Похожие записиxandeadx.ru