Есть такая больная мозоль у drupal — это модуль комментариев.
Ситуация как в анекдоте — прислали индусам из России танк. Как ни собирают — получается комбайн. Перечитывают инструкцию по сборке — «после сборки доработать напильником».
С комментариями в Drupal ситуация такая же. В 6ке — удаление комментариев пользователем без прав «администрирования комментариев» не предусмотрено! Казалось бы такая мелочь… Но проблема там в том, что удаляемый комментарий может иметь целый хвост из ответов, которые могут принадлежать другим пользователям, и удалять их нельзя. В некоторых социалках, где поддерживается иерархия ответов, поступают так — вместо удаленного коммента пишут, что «комментарий удален». А ответы остаются. Я же считаю что, если автор решил удалить коммент, то и ответы надо удалять, ибо что это за ответы на удаленный комментарий?
То как разрешить эту ситуацию — это дело вкуса. Нужно хотя бы преодолеть «правовые» установки, а там уж делать, что душе угодно.
Альтернативное удаление.
Мы разобрались, что штатно удалить свои записи в комментариях нельзя (если вы только не администратор комментов), значит нужно создать альтернативную версию страницы удаления. Добавим в hook_menu страничку:
1 2 3 4 5 6 7 8 |
//удаление комментариев $items['genius-comment/delete'] = array( 'title' => 'Delete comment', 'page callback' => '_SC_comment_delete', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, 'file' => 'comments.php', ); |
Пример из действующего проекта (гений места), не стал ничего придумывать. Код находится в отдельном файле модуля — comments.php. Там подправленная версия функции comment_delete из модуля comment. Выглядит она вот так.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/* удаление комментов */ function _SC_comment_delete($cid = NULL) { global $user; $comment = db_fetch_object(db_query('SELECT c.*, u.name AS registered_name, u.uid FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid WHERE c.cid = %d', $cid)); $comment->name = $comment->uid ? $comment->registered_name : $comment->name; $output = ''; //здесь меняем штатную логику - программируем, кто может удалять выбранный комментарий //в моем случае код написан от обратного - т.е. тех, кто не может удалять - отправляем //на страницу "доступ запрещен" (аноним и не автор, исключение - группа редакторов) if (!$user->uid || ($user->uid != $comment->uid && !in_array('редактор', $user->roles))) { drupal_access_denied(); return $output; } //иначе подключаем файл из модуля comment и выводим форму подтверждения удаления if (is_object($comment) && is_numeric($comment->cid) && $user->uid == $comment->uid) { require_once($_SERVER['DOCUMENT_ROOT'] . '/modules/comment/comment.admin.inc'); $output = drupal_get_form('comment_confirm_delete', $comment); } else { drupal_set_message(t('The comment no longer exists.')); } return $output; } |
А где же вариант с заменой drupal-овского удаления всей ветки?
Если же вам надо поменять логику работы встроенного удаления, то нужно скопировать и поправить еще пару функций из модуля comment. А именно ф-цию comment_confirm_delete — которая создаёт диалоговую форму подтверждения удаления, и comment_confirm_delete_submit, реализующую само удаление.
Тут уж все в ваших руках :).
Корректируем шаблон
Так как прав на администрирование комментариев мы не собираемся выдавать нашим пользователям, то и список ссылок в шаблоне комментариев не изменится, т.е. ссылка «удалить» волшебным образом не появится. Нужно скопировать в свою тему файл-шаблон comment.tpl.php из модуля comment, и немного его доработать напильником.
Вместо:
1 |
<?php print $links ?> |
Может получиться что то вроде:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<ul class="links"> <? if (($user->uid == $comment->uid && $user->uid > 0) || in_array('редактор', $user->roles)) { //можно дополнить условия проверкой ролей, чтобы, к примеру, дать права редакторам //править комментарии прямо с front-end сайта ?> <li class="comment_delete first"> <a href="/genius-comment/delete/<?=$comment->cid?>">удалить</a> </li> <li class="comment_edit"> <a href="/comment/edit/<?=$comment->cid?>">редактировать</a> </li> <li class="comment_reply last"> <a href="/comment/reply/<?=$comment->nid?>/<?=$comment->cid?>">ответить</a> </li> <? } else //ссылка ответить - для тех, кто авторизирован if ($user->uid > 0) { ?> <li class="comment_reply last"> <a href="/comment/reply/<?=$comment->nid?>/<?=$comment->cid?>">ответить</a> </li> <? } ?> </ul> |
Это не самый универсальный подход, так мы можем потерять модификации переменной $links, которые могут выполняться в других модулях. Если у вас дело обстоит именно так, тогда стоит пойти через использование hook_link_alter.