Drupal 7: адаптируем модуль от версии 6
Восьмая версия популярной CMS Drupal 8 набирает обороты, в разработке 9-я версия, а еще немало сайтов на 6-й версии. И причиной, порой тому является необходимость переписывать собственные модули, а это требует времени и знаний. Последними и хочу поделиться.
На странице https://www.drupal.org/update/modules/6/7 приведено около 250 изменений, рассказывающих об отличиях в коде 7-ки от 6-ки, но на английском. Я же расскажу про самые востребованные при конвертации модулей от 6-й версии в 7-ю. Но на русском.
Итак, поехали.
Свой модуль необходимо помещать в отдельную папку в папке sites/all/modules/custom при односайтовой конфигурации или в site_folder/modules/custom при мультисайтинге. Например: sites/all/modules/custom/mymodule.
Появилась удобная функция debug(variable, description)
позволяющая выводить в удобном виде переменную/объект/массив. Например: debug($node, 'Tish node in function mymodule_view')
.
Нет необходимости в файле module.install явно указывать выполнение схемы для создания/удаления таблиц в базе, это выполняется автоматически. Но необходимо помнить, что действия по удалению материалов или других данных из системных таблиц в случае необходимости лежит на вас и выполняется в хуке hook_uninstall через sql-запрос.
Функции для работы с БД тоже изменились, примеры смотрите здесь.
Тело статьи body теперь необходимо подключать в файле module.install в хуке hook_install. Пример:
function mymodule_install() { node_types_rebuild(); $types = node_type_get_types(); node_add_body_field($types['mymodule'], 'Type node description.'); // Загрузка определения экземпляра для тела типа контента. $body_instance = field_info_instance('node', 'body', 'mymodule'); // Настройка поля тела. $body_instance['type'] = 'text_summary_or_trimmed'; // Сохранение изменений в экземпляре поля тела. field_update_instance($body_instance); }
Соответственно, в хуке hook_form нет необходимости предусматривать вывод $node->body. К тому же $node->body теперь ассоциативный массив. Тело статьи будет выводиться автоматически. Если есть необходимость выводить body определенном образом в своем коде, то предварительно необходимо отключить его вывод в настройках типа материала в меню администрирования, причем отдельно для предпросмотра и полного просмотра. В настройках формы типа материала можно указать обязательность ввода значения в тело статьи.
Таблица node_revisions переименована в node_revision.
Хук hook_perm переименован в hook_permission.
В хуке hook_acces необходимо возвращать NODE_ACCESS_ALLOW.
Тело статьи из таблицы node_revision поля body переместилось в таблицу field_data_body в поле body_value.
Хук hook_link() больше не используется. Вместо этого ссылки под статьей указываем в hook_node_view(). Необходимо при этом проверять тип материала. Пример:
<?php function blog_node_view($node, $view_mode, $langcode) { if ($node->type == 'blog') { if (arg(0) != 'blog' || arg(1) != $node->uid) { $links['blog_usernames_blog'] = array( // Unrelated to the change where links are added, Drupal 7 also adds a // format_username() function. 'title' => t("!username's blog", array('!username' => format_username($node))), 'href' => "blog/$node->uid", 'attributes' => array('title' => t("Read !username's latest blog entries.", array('!username' =>format_username($node)))), ); $node->content['links']['blog'] = array( '#theme' => 'links__node__blog', '#links' => $links, '#attributes' => array('class' => array('links', 'inline')), ); } } } ?>
Если необходимо в ссылке указать дополнительные параметры, то они добавляются ассоциативным массовом в ключе 'query'. Пример:
$links['blog_usernames_blog'] = array( // Unrelated to the change where links are added, Drupal 7 also adds a // format_username() function. 'title' => t("!username's blog", array('!username' => format_username($node))), 'href' => "blog/$node->uid", 'query' => array('parent' => $node->nid), );
Примечание: после добавления hook_node_view() необходимо переподключить модуль в настройках.
Изменен вызов node_view. Теперь возвращается массив. Необходимо использовать drupal_render. Пример:
Drupal 6: <?php $node->build_mode = NODE_BUILD_NORMAL; $output = node_view($node, TRUE); ?> Drupal 7: <?php $content = node_view($node, 'teaser'); $output = drupal_render($content); ?>
Хук hook_view теперь объявляется так:hook_view($node, $view_mode, $langcode = NULL)
где $view_mode может быть full, teaser, rss и, возможно, другие, определенные в дополнительных модулях, значения.
Также, при объявлении функций theme ключ называется не value, а #markup. Затем необходимо ассоциативным массивом передать необходимые переменные и/или массивы. Пример:
$node->content['dgaldata'] = array( '#markup' => theme("mynode_view_chapter", array('state' => $node->state, 'image' => $node->image, 'body' => $node->body, 'nid' => $node->nid, 'pid' => $node->pid, 'file' => $node->file) ), '#weight' => 0, );
Вместо theme_table необходимо использовать theme('table', ...), к примеру:
theme('table', array('rows' => $tablarr)).
Изменилась работа с механизмом разбивки на страницы pager. Параметр $limit не используется, эта функция возложена на запрос к базе. Теперь при вызове theme('pager',...) используются только два параметра, где второй - ассоциативный массив и может быть опущен.
Drupal 6: <?php theme('pager', $tags, $limit, $element, $parameters, $quantity); ?> Drupal 7: <?php theme('pager', array('tags' => $tags, 'element' => $element, 'parameters' => $parameters, 'quantity' => $quantity)); ?>
Пример
$select = $select->fields('n', array('nid', 'title', 'created')) ->fields('p', array('active')) ->condition('n.status', 1) ->orderBy('n.created', 'DESC') ->groupBy('n.nid') ->groupBy('n.title') ->groupBy('p.active') ->groupBy('n.created') ->extend('PagerDefault') ->limit($polls_per_page) ->addTag('node_access'); ... $output .= theme('pager');
Если после включение какого-то из модулей сайт перестает отвечать, то найдите в базе в таблице system строку с именем модуля и полем type=module_name, и в поле status поменяйте 1 на 0. Если модуль на чисто установленном Drupal включается и работает нормально, то попробуйте сделать следующее. Поищите в тестовой базе и в рабочей все вхождения машинного имени модуля, найдите те таблицы, где модуль упоминается в рабочей базе, но не упоминается в тестовой (кроме таблиц, содержащих материалы, таких как node_revision, field_data_body и т.д.) и удалите эти записи в рабочей базе. Если модуль использует собственную таблицу в базе, переименуйте ее. Установите модуль. Если все прошло успешно, удалите вновь созданную установщиком модуля таблицу, а рабочую переименуйте обратно.
Это были основные моменты на которые необходимо обратить внимание при адаптации модуля Drupal 6 к версии Drupal 7.
Удачи!
- Блог пользователя - Byte
- Войдите, чтобы оставлять комментарии