xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Пишем модуль утверждения комментариев в один клик. Часть 2

В первой части был написан модуль, для одобрения анонимных комментариев в один клик. В этой части добавим к нему AJAX функции.

В папке модуля создаём файл ajax_publish.js со следующим содержанием:

Drupal.behaviors.ajax_publish = function(){
 
    $('li.ajax_publish_publish a').click(function(){
 
        var $a = $(this);
 
        // при клике показываем pre-loader после ссылки
        var $preloader = $('<span>').css({
            'display': 'inline-block',
            'width': '20px',
            'height': '12px',
            'vertical-align': 'middle',
            'background': 'url(/misc/throbber.gif) no-repeat right -21px'
        }).appendTo($a.parent());
 
        // посылаем ajax запрос на публикацю комментария
        $.get($a.attr('href'), function(response){
 
            responseObject = Drupal.parseJson(response);
 
            if (responseObject.status)
            {
                $a.parents('.comment-unpublished').removeClass('comment-unpublished').addClass('comment-published');
                $a.parent().remove();
            }
 
            $preloader.remove();
 
        });
 
        return false;
 
    });
 
}

Подключаем его с помощью функции drupal_add_js и хука hook_nodeapi — в файл ajax_publish.module добавляем:

/**
 * Реализация hook_nodeapi()
 */
function ajax_publish_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL)
{
    if ($op == 'view' && $a3 == false)
    {
        drupal_add_js(drupal_get_path('module', 'ajax_publish') .'/ajax_publish.js');
    }
}

Теперь при клике на ссылке опубликовать, запрос на сервер будет отправлен с помощью AJAX, без перезагрузки страницы.

Модифицируем функцию ajax_publish_publish таким образом, чтобы при AJAX запросе, вместо редиректа, возвращался статус операции в JSON формате:

/**
 * Menu callback для url "comment/publish"
 * Публикация комментария
 */
function ajax_publish_publish($cid = 0)
{
    if (!$cid) return false;
 
    $operations = comment_operations('publish');
    db_query($operations['publish'][1], $cid);
 
    if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
    {
        drupal_json(array('status' => true));
    }
    else
    {
        drupal_set_message('Комментарий #' . $cid . ' опубликован');
        drupal_goto(referer_uri(), null, 'comment-' . $cid);
    }
}

Окончательная версия модуля.

Похожие записи

Комментарии RSS

Спасибо огромное, облегчили работу

Спасибо огромное. Побольше бы таких разработчиков.
Не сразу, но примерно начал понимать как делать формы друпала ajax'овыми.
Пишите еще.

для ajax-овых форм лучше использовать AHAH

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

Я что-то неправильно отдаю ему скорее всего. Если отдавать пустую друпаловскую страницу с формой, то выдает какой то страшный алерт с полным html ответа. Если завершать php после drupal_get_form(""), то есть выдавать только html формы, то видимо какой то неправильный html отдается и javascript выдает ошибку.

Ладно разберусь. Понятно куда копать если что.

Обнаружилась бага =(
Если я аноним и печатаю 1ый коммент в ноде - при публикации посредством этого модуля из ноды админом, не обновляется счетчик комментов почему-то, сейчас сам залезу в код и посмотрю что там к чему. То есть он появляется, а счетчик как был на 0 так и есть ... Только после добавления коммента админом самолично - счетчик нормализуется и выводит 2 коммента.

при публикации комментария можно обновлять статистику ноды с помощью функции _comment_update_node_statistics($nid);

надеюсь, как узнать $nid по $cid, разберётесь самостоятельно

добавил в модуль из API функцию

function ajax_publish_comment_update_node_statistics($nid) {
  $count = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE nid = %d AND status = %d', $nid, COMMENT_PUBLISHED));
 
  // comments exist
  if ($count > 0) {
    $last_reply = db_fetch_object(db_query_range('SELECT cid, name, timestamp, uid FROM {comments} WHERE nid = %d AND status = %d ORDER BY cid DESC', $nid, COMMENT_PUBLISHED, 0, 1));
    db_query("UPDATE {node_comment_statistics} SET comment_count = %d, last_comment_timestamp = %d, last_comment_name = '%s', last_comment_uid = %d WHERE nid = %d", $count, $last_reply->timestamp, $last_reply->uid ? '' : $last_reply->name, $last_reply->uid, $nid);
  }
 
  // no comments
  else {
    $node = db_fetch_object(db_query("SELECT uid, created FROM {node} WHERE nid = %d", $nid));
    db_query("UPDATE {node_comment_statistics} SET comment_count = 0, last_comment_timestamp = %d, last_comment_name = '', last_comment_uid = %d WHERE nid = %d", $node->created, $node->uid, $nid);
  }
}

0ль эмоций ... конкретнее подскажите пжалуйста, не рылся так глубоко =)

_comment_update_node_statistics это функция а не хук, её надо вызвать в ajax_publish_publish, предварительно узнав nid с помощью _comment_load

Спасибо, разобрался! Поможем будущим искателям, надо добавить 2 строчки:

$comment = _comment_load($cid);
	_comment_update_node_statistics($comment->nid);

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании