02.10.2011 Ubercart - скрыть SKU и другие поля (модуль Ubercart Product Power Tools) | Drupal 6 26.09.2011 Пользовательские галереи и хранение файлов на сервере - Drupal 6 22.06.2011 Блок последних комментариев блога - DRUPAL 6 16.06.2011 Показывать блок в определенных типах материалов и на определенных страницах - Drupal 6 16.06.2011 Топ 10 блоггеров - Drupal 6 21.05.2011 Модуль переноса комментариев для Drupal 6 22.03.2011 Подсветка синтаксиса кода в Drupal 6 22.03.2011 Кнопки социальных сетей для Drupal
#105

Модуль переноса комментариев для Drupal 6

Как написать свой модуль для Drupal 6 или модуль переноса комментариев.

Часто задавался вопросом как расширить функциональные возможности существующих модулей Drupal 6 и решил узнать как это все-таки делается.
Данный вопрос, также, возник из-за отсутствия адекватного модуля переноса комментариев от ноды к ноде, поэтому решил совместить приятное с полезным и написать модуль, который расширит функционал модуля Comment и добавит возможность переноса комментариев к указанной ноде.

Данное решение является прототипом модуля и носит больше обучающий характер.

При написании данного решения НЕ учитывалось следующее:

  1. Не учитывалось взаимодействие с таблицей node_comment_statistics - из-за чего после переноса комментариев, их не видно в блоке последних комментариев, появляются после того, как в той ноде, к которой они были перенесены, появится новый комментарий. Также из-за этого отображается неверное кол-во комментариев у той ноды к которой сообщения были перенесены.
  2. Не учитывалось обновление места комментария в цепочке при переносе - что является также не совсем корректным. (поле thread в таблице comments - место комментария в цепочке).

Итак следует определить задачи, которые будет выполнять модуль и то как он будет их выполнять:

  1. Изменять NID комментария в таблице comments.
  2. Значение NID вводится в текстовое поле и выбираются комментарии из списка на странице admin/content/comment.
  3. После нажатия на кнопку значение NID меняется в таблице.
drupal таблица comments (модуль comment)
ПолеТипNullDefaultНазначение
cidint(11)НетAutoincrementПервичный ключ, уникальный идентификатор комментария
pidint(11)Нет0commens.cid, на который отвечает этот комментарий. 0 - без связи
nidint(11)Нет0node.nid, на который отвечает этот комментарий.
uidint(11)Нет0usewrs.nid автора комментария.
subjectvarchar(64)Нет''Заголовок комментария
сommentlongtextНетСодержание комментария
hostnamevarchar(128)Нет''Имя хоста автора
timestampint(11)Нет0Временная метка UNIX последнего обновления комментария.
statustityint(3) unsignedНет0Состояние публикации 0 - опубликован, 1 - нет
formatsmallint(6)Нет0filter_formats.format формат комментария
threadvarchar(255)Нет""Место комментария в цепочке
namevarchar(60)ДаNULLИмя автора users.name или введённое пользователем(для анонимов)
mailvarchar(64)ДаNULLemail автора или введённое пользователем (для анонимов, при включённой соответствующей настройке)
homepagevarchar(255)ДаNULLweb страница автора или введённое пользователем (для анонимов, при включённой соответствующей настройке)

Модули, используемые в Друпале, работают по принципу «хука» (англ. hook — крючок, ловушка). Хук — это PHP функция, которая имеет название module_name_hook_name(), где «module_name» — название модуля (имя файла module_name.module), а «hook_name» — название самого хука. Каждый хук имеет определенный набор параметров и типов результатов.. Подробнее о хуках.

Итак для начала надо создать директорию (с именем соответствующим названию модуля) в каталоге относительно корня сайта "/sites/all/modules", назовем наш модуль comment_transfer. 
Далее в этой директории требуется создать два файла: comment_transfer.info и comment_transfer.module (названия этих файлов должны соответствовать названию модуля).

Содержимое файла comment_transfer.info:

  1. ;; Идентификатор используемый СVS сервером сайта drupal.org для 
  2. ;; автоматической идентификации проекта при публикации модуля на 
  3. ;; данном ресурсе
  4. ; $Id$
  5.  
  6. ;; Наименовние модуля
  7. name = Comment transfer
  8.  
  9. ;; Описание модуля. (не обязательно)
  10. ;; Данное описание будет видно на странице admin/build/modules
  11. description = Admin`s comments transfer.
  12.  
  13. ;; Здесь можно указать зависимости модуля от других модулей.
  14. ;; Не обязательно, но лучше это сделать, т.к. наш модуль зависит
  15. ;; от модуля Comment укажем это.
  16. dependencies[] = comment
  17.  
  18. ;; Не обязательное поле - указывает на раздел в котором появится модуль
  19. ;; на странице модулей. Если оставить закомментированным то модуль
  20. ;; появится в разделе "Другое".
  21. ;; package = "My package"
  22.  
  23. ;; core - указывает на версию ядра Друпала 
  24. core = 6.x

Содержимое файла comment_transfer.module (следует учитывать что в конце файла не следует ставить закрывающий тег "?>"):
  1. <?php
  2. // $Id$
  3. /**
  4.   * @file
  5.   * Admin`s comments transfer.
  6.   */
  7.  
  8. // Используем для перехвата формы hook_FORM_ID_alter, и добавляем 
  9. // текстовое поле и дополнительную кнопку к форме. (название-модуля_id-формы_alter)
  10. // comment_transfer - название модуля
  11. // form_comment_admin_overview - id формы
  12. function comment_transfer_form_comment_admin_overview_alter(&$form, &$form_state) 
  13. {
  14.  
  15.   // Добавляем текстовое поле к массиву формы.
  16.   $form['node_id'] = array(
  17.     // Тип - (textfield, checkbox и т.п.).
  18.     // В нашем случае текстовое поле.
  19.     '#type' => 'textfield',
  20.     // Заголовок.
  21.     '#title' => 'ID ноды к которой отнести комментарий',
  22.     // Обязательно для заполнения?
  23.     '#required' => FALSE,
  24.     // Размер поля
  25.     '#size' => 30,
  26.     // Описание
  27.     '#description' => 'Для того чтобы перенести комментарий к другой ноде, впишите в это поле ID ноды.',
  28.   );
  29.   // Добавляем кнопку.
  30.   $form['nchange'] = array(
  31.     '#type' => 'submit',
  32.     '#value' => 'Переопределить ноду',
  33.     '#description' => 'Переопределить ноду у выделенных комментариев.',
  34.   // Указываем действие которое будет выполняться при нажатии
  35.     '#submit' => array('comment_transfer_nchange'),
  36.   );
  37.  
  38. }
  39.  
  40. function comment_transfer_nchange()
  41. {
  42.   // Получаем ID введенное в поле и приводим его к числовому значению
  43.     $nid = intval($_POST['node_id']);
  44.   // Если $nid не равно нулю (равно 0 когда вводятся буквы)
  45.     if(!empty($nid))
  46.     {
  47.   // Цикл обхода массива $_POST['comments'] где $key будет cid комментария.
  48. 	foreach($_POST['comments'] as $key)
  49. 	{
  50.   // Запрос на обновление данных в базе
  51. 	     db_query('UPDATE {comments} SET nid = %d WHERE cid = %d', $nid, $key);
  52. 	}
  53.   // Выводим сообщение об успешном завершении процедуры.
  54. 	drupal_set_message('Выбранные комментарии были перенесены к ноде #'.$_POST['node_id']);
  55.     }
  56.     else
  57.     {
  58.   // Если $nid равно нулю выводим сообщение об ошибке
  59. 	drupal_set_message('ID страницы не указан или указан не верно.', 'error');
  60.     }
  61. }

Для того, чтобы привязать действие к уже существующей в форме кнопке, вместо кода, который добавляет дополнительную кнопку "Переопределить ноду", нам следует написать код, который просто будет вызывать указанное действие:
  1. $form['#submit'] = array('comment_transfer_nchange');

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

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

перенос комментариев к другой ноде

НЕ РЕКОМЕНДУЕТСЯ ДЛЯ ИСПОЛЬЗОВАНИЯ НА РЕАЛЬНЫХ ПРОЕКТАХ!!!


29.03.2011 Пейджинг для Image Gallery (вперед, назад) - Drupal 6 22.03.2011 Форма входа вверху сайта - Drupal 6 22.03.2011 Сниппет поиска по товарам - Drupal 6 22.03.2011 Сниппет вывода самых популярных товаров - Drupal 6 22.03.2011 Сниппет вывода последних новостей в блоке - Drupal 6 03.03.2011 Денвер, Drupal7 19.03.2010 Индивидуальный шаблон для каждой страницы - Drupal 6 31.03.2010 Drupal 6 ошибка 0 /upload/js
О сайте