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

11.12.2009

В первой части был написан модуль, для одобрения анонимных комментариев в один клик. В этой части добавим к нему 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);
    }
}

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

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

Комментарии

Гость
04.03.2010, 17:37

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

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

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

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

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

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

Гость
04.05.2010, 21:48

при публикации комментария можно обновлять статистику ноды с помощью функции _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ль эмоций ... конкретнее подскажите пжалуйста, не рылся так глубоко =)

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

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

Добавить комментарий