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

Дальше создадим файл my_database.module. Содержимое файла будет следующее:

<?php /*** @file* Contains base function for module.*/

 

Пишем таблицу

Вот мы уже подошли к тому самому моменту, когда нужно работать с 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 будет выглядеть следующим образом:

  1. /**

  2.  * Implements hook_schema().

  3.  */

  4. function my_database_schema() {

  5.   $schema['my_table'] = array(

  6.     'description' => 'Custom table from My database module.',

  7.     'fields' => array(

  8.       'id' => array(

  9.         'description' => 'The primary identifier for a record.',

  10.         'type' => 'serial',

  11.         'unsigned' => TRUE,

  12.         'not null' => TRUE,

  13.       ),

  14.       'number' => array(

  15.         'description' => 'Field for integer number.',

  16.         'type' => 'int',

  17.         'unsigned' => TRUE,

  18.         'not null' => TRUE,

  19.         'default' => 0,

  20.       ),

  21.       'teaser' => array(

  22.         'description' => 'Teaser field.',

  23.         'type' => 'varchar',

  24.         'length' => 150,

  25.         'not null' => TRUE,

  26.         'default' => '',

  27.       ),

  28.       'text' => array(

  29.         'description' => 'Text field.',

  30.         'type' => 'text',

  31.         'not null' => FALSE,

  32.       ),

  33.     ),

  34.     'primary key' => array('id'),

  35.   );

  36.   return $schema;

  37. }

Давайте разберем строчки кода.Строчка 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 простую таблицу со списком нод и возможностью выбрать несколько из них:

/** * Реализация hook_menu() * Регистрируем адрес example.com/form-table и функцию которая будет генерировать по этому адресу контент */ function mymodule_menu() { $items = array();   $items['form-table'] = array( 'title' => 'Form-Table', 'page callback' => 'drupal_get_form', 'page arguments' => array('mymodule_form_table'), 'access arguments' => array('administer nodes'), 'type' => MENU_CALLBACK, );   return $items; }   /** * Реализация hook_theme() * Регистрируем функцию темизации формы mymodule_form_table */ function mymodule_theme() { return array( 'mymodule_form_table' => array( 'arguments' => array('form' => NULL), ), ); }   /** * Описание формы mymodule_form_table */ function mymodule_form_table() { // описание заголовков $form['header'] = array( '#type' => 'value', '#value' => array( theme('table_select_header_cell'), 'Заголовок', 'Дата создания', ), );   // получаем список нод $nodes = db_query("SELECT nid, title, created FROM {node} ORDER BY created");   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['submit'] = array( '#type' => 'submit', '#value' => 'Удалить', );   return $form; }     /** * Темизация формы mymodule_form_table * Создаём ту самую таблицу */ function theme_mymodule_form_table($form) { $rows = array(); foreach (element_children($form['nid']) as $key) { $rows[] = array( drupal_render($form['nid'][$key]), // чекбокс drupal_render($form['title'][$key]), // заголовок drupal_render($form['created'][$key]), // дата создания ); }   $output = theme('table', $form['header']['#value'], $rows); // выводим таблицу $output .= drupal_render($form); // выводим остальную часть формы   return $output; }   /** * Сабмит формы mymodule_form_table * Выводим в сообщении список выбранных нод */ function mymodule_form_table_submit($form, &$form_state) { $nids = array(); foreach ($form_state['values']['nid'] as $nid) { if ($nid) { $nids[] = $nid; } }   drupal_set_message('Выбраны ноды ' . implode(', ', $nids)); }

Код в работе Сабмит формы

А вот код который делает тоже самое, но с пагинацией и возможностью сортировки:

/** * Описание формы 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; }

Форма-таблица с пагинатором и сортировкой

Написанное актуально для Drupal 6 Похожие записи

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, )); }

Я уже писал про то, как создавать формы в виде таблицы, на примере формы удаления нод, но этот способ более универсальный — здесь темизируется только часть формы ($form['nodes']) и функция theme_table_form() генерирует колонки автоматически.

Рабочий пример можно посмотреть в демо-модуле.

Написанное актуально для 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


Prostoy-Site | Все права защищены © 2018 | Карта сайта