Здравствуйте!
На моем небольшом сайте проблема со спамом стоит не особо критично, поэтому любой незарегистрированный пользователь может оставить свой комментарий. Для удобства, последние комментарии выводятся блоком со снипетом "Прямой эфир". К сожалению этот снипет не подхватывает имя введенное анонимом и выводит стандартное имя для всех незарегистрированных пользователей. Периодически, в ветках с подобными сниппетами, люди задаются двнным вопросом, но ответ так и не появился. Если кто-то знает ответ и может поделится решением, а еще лучше с этапами размышлений — такая информация будет полезна многим.
Код прямого эфира:
<?php
$number=10;
$result = db_query_range(db_rewrite_sql(
"SELECT n.type,n.title,n.nid,cm.cid,u.uid,u.name,cm.cnt,cc.timestamp, cc.comment
FROM {node_comment_statistics} nc JOIN {node} n ON nc.comment_count > 0 AND n.nid=nc.nid
INNER JOIN (SELECT max(c.cid) as cid ,c.nid,count(c.cid) as cnt FROM {comments} c GROUP by c.nid ) cm
ON cm.nid=n.nid
INNER JOIN {comments} cc ON cc.cid=cm.cid
INNER JOIN {users} u ON u.uid=cc.uid
ORDER BY nc.last_comment_timestamp DESC"),0,$number);
$items=array();
while($comment=db_fetch_object($result)){
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.theme('username',user_load($comment->uid)).
'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.
$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
if(count($items)){
print theme('item_list',$items);
}
?>
Комментарии
проблема вот тут: theme('username',user_load($comment->uid))При отображении комментов данный объект ($user) содержит информацию о смотрящем, а не авторе коммента.
Надо создавать объект $comuser, к примеру, и набивать его данными из query и затем его отдавать для темизации.
Необходимо заполнить:
$comuser->uid
$comuser->name
$comuser->homepage
Сорри. Плохо читал. Буду читать еще.
В запросе возвращаются uid и name из таблицы пользователей, а не из комментария.
PS
А чем стандартный блок последних комментариев не устраивает?
Данный сниппет, в отличие от стандартного блока, выводит в начале имя пользователя, затем заголовок, а затем сам коммент. Все это легко темизируется, поэтому и предпочитаю этот сниппет.
Как сделать, чтобы возвращался name из комментария?
У данного снипета query "каличный" как по мне. Проще всего вставить слегка измененный код из comment_get_recent():
<?php
$nids = array();
$comments = array();
$items=array();
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.theme('username',user_load($comment->uid)).
$number=10;
// Select the $number nodes (visible to the current user) with the most
// recent comments. This is efficient due to the index on
// last_comment_timestamp.
$result = db_query_range(db_rewrite_sql("SELECT nc.nid FROM {node_comment_statistics} nc WHERE nc.comment_count > 0 ORDER BY nc.last_comment_timestamp DESC", 'nc'), 0, $number);
while ($row = db_fetch_object($result)) {
$nids[] = $row->nid;
}
if (!empty($nids)) {
// From among the comments on the nodes selected in the first query,
// find the $number most recent comments.
$result = db_query_range('SELECT c.uid, c.name, c.nid, c.subject, c.cid, c.timestamp FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.nid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.cid DESC', COMMENT_PUBLISHED, 0, $number);
while($comment=db_fetch_object($result)){
'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.
$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
if(count($items)){
print theme('item_list',$items);
}
?>
Ключевые изменения стандартного кода во втором СЕЛЕКТЕ:
SELECT c.uid, c.name, ...
Parse error: syntax error, unexpected $end in /home/цццццц/цццццц.ru/includes/common.inc(1685) : eval()'d code on line 30
Не идет ((( Кстати, что значит каличный?
В экран все не влезло
Второй запрос к БД можно взять из http://api.drupal.org/api/function/comment_get_recent
Хотя вот он двумя строчками с изменениями:
<?php$result = db_query_range('SELECT c.uid, c.name, c.nid, c.subject, c.cid, c.timestamp FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid
WHERE c.nid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.cid DESC', COMMENT_PUBLISHED, 0, $number);
?>
Почему каличный? Непонятно зачем для такой простой задачи делать столько вложенных селектов - они ресурсы жрут неподецки
Можно это одним кодом оформить? А я пока, за вашу помошь, пойду по кликаю гугл эдс на сайте однофамильцев )))
я одну { забыл
<?php
$nids = array();
$comments = array();
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.theme('username',user_load($comment->uid)).
$number=10;
// Select the $number nodes (visible to the current user) with the most
// recent comments. This is efficient due to the index on
// last_comment_timestamp.
$result = db_query_range(db_rewrite_sql("SELECT nc.nid FROM {node_comment_statistics} nc WHERE nc.comment_count > 0 ORDER BY nc.last_comment_timestamp DESC", 'nc'), 0, $number);
while ($row = db_fetch_object($result)) {
$nids[] = $row->nid;
}
if (!empty($nids)) {
// From among the comments on the nodes selected in the first query,
// find the $number most recent comments.
$result = db_query_range('SELECT c.uid, c.name, c.nid, c.subject, c.cid, c.timestamp FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid
WHERE c.nid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.cid DESC', COMMENT_PUBLISHED, 0, $number);
}
$items=array();
while($comment=db_fetch_object($result)){
'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.
$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
if(count($items)){
print theme('item_list',$items);
}
?>
Не работает. Можно все же сохранить начальный снипет, просто сделать так, чтобы имя выбиралось из таблицы comment?
Не работает, потому что надо мануалы читать нам обоим
http://api.drupal.org/api/function/theme_username - смотрите самый первый "if" - если $user->uid = 0, то сама тема ставит по определению анонима.
значит для гостей надо уходить от этой темы и ссылку на профиль пользователя лепить самому. Ниже один из вариантов решения:
<?php
$nids = array();
$comments = array();
$number=10;
// Select the $number nodes (visible to the current user) with the most
// recent comments. This is efficient due to the index on
// last_comment_timestamp.
$result = db_query_range(db_rewrite_sql("SELECT nc.nid FROM {node_comment_statistics} nc WHERE nc.comment_count > 0 ORDER BY nc.last_comment_timestamp DESC", 'nc'), 0, $number);
while ($row = db_fetch_object($result)) {
$nids[] = $row->nid;
}
if (!empty($nids)) {
// From among the comments on the nodes selected in the first query,
// find the $number most recent comments.
$result = db_query_range('SELECT c.uid, c.name, c.nid, c.subject as title, c.cid, c.timestamp FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.nid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.cid DESC', COMMENT_PUBLISHED, 0, $number);
}
$items=array();
while($comment=db_fetch_object($result)){
if ($comment->uid) {
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.theme('username',$comment).'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
else {
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.$comment->name.'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
}
if(count($items)){
print theme('item_list',$items);
}?>
Я ничего не делал с выводом количества комментариев, но ИМХО он здесь лишен смысла.
Все работает, но вывод как у стандартного модуля ((( Нужно чтобы выводилось как в сниппете - имя пользователя, затем заголовок СТАТЬИ, а затем сам коммент. Т.е. этот снипет абсолютно рабочий, кроме того, что не подхватывает имя незарегенного пользователя.
<?php
$nids = array();
$comments = array();
$number=10;
// Select the $number nodes (visible to the current user) with the most
// recent comments. This is efficient due to the index on
// last_comment_timestamp.
$result = db_query_range(db_rewrite_sql("SELECT nc.nid FROM {node_comment_statistics} nc WHERE nc.comment_count > 0 ORDER BY nc.last_comment_timestamp DESC", 'nc'), 0, $number);
while ($row = db_fetch_object($result)) {
$nids[] = $row->nid;
}
if (!empty($nids)) {
// From among the comments on the nodes selected in the first query,
// find the $number most recent comments.
$result = db_query_range('SELECT c.uid, c.name, c.nid, c.subject, n.title, c.cid, c.timestamp, c.comment FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.nid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.cid DESC', COMMENT_PUBLISHED, 0, $number);
}
$items=array();
while($comment=db_fetch_object($result)){
if ($comment->uid) {
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.theme('username',$comment).'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
else {
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.$comment->name.'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
}
if(count($items)){
print theme('item_list',$items);
}?>
Илья, вы просто молодец! Остальсь только решить как ограничить количество символов в сообщении и еще одна такая тонкость - из статьи должно публиковаться толкьо последнее сообщение, иначе получается, что если в статье ведется бурное обсуждение, то весь блок будет забит этими комментами.
А с длинной разобрался, просто стало два вывода )))
<?php
$number=10;
$nids = array();
$comments = array();
//Limit for comment's teaser in chars
$com_limit = 50;
// Select the $number nodes (visible to the current user) with the most
// recent comments. This is efficient due to the index on
// last_comment_timestamp.
$result = db_query_range("SELECT nc.nid, max(c.cid) AS cid FROM {node_comment_statistics} nc INNER JOIN {comments} c ON c.nid = nc.nid WHERE nc.comment_count > 0 GROUP BY nc.nid ORDER BY nc.last_comment_timestamp DESC", 0, $number);
while ($row = db_fetch_object($result)) {
$nids[] = $row->cid;
}
if (!empty($nids)) {
// From among the comments on the nodes selected in the first query,
// find the $number most recent comments.
$result = db_query_range('SELECT c.uid, c.name, c.nid, c.subject, n.title, c.cid, c.timestamp, c.comment FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.cid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.cid DESC', COMMENT_PUBLISHED, 0, $number);
}
$items=array();
while($comment=db_fetch_object($result)){
$comment->comment = trim($comment->comment, " \t\n\r\0");
if (mb_strlen($comment->comment) > $com_limit) {
$comment->comment = mb_substr($comment->comment, 0, $com_limit - 3). '...';
}
if (
$comment->uid) {$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.theme('username',$comment).'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
else {
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.$comment->name.'→</strong> '. l($comment->title.' ('.$comment->cnt.')', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
}
if(count($items)){
print theme('item_list',$items);
}?>
Код получился вполне рабочий. Потестил на сайте. В английской версии все хорошо, ва вот в русской версии вылазит вопрос � в конце вывода комментария, там где обрезается текст.
забыл про multibyte
надо сделать замены:
strlen -> mb_strlen
substr -> mb_substr
PS
Вот взяли бы и отменили у нас кириллицу, как казахи сделали в свое время - столько компутерных проблем отпало бы
Работает! Сделали большое дело и надеюсь не только для меня.
С введением зоны "ру" такие проблемы проблемы будут толкьо сниться ))) Стандартное сегментирование рынка, когда уже трудно что-то разделить. Когда идет речь о деньгах, то людские проблемы уже никого не интересуют.
Вы хотели сказать, что старые проблемы покажутся детским лепетом?
Я не живу в России и для меня эта доменная зона "xn--p1ag" пока выглядит чей-то злой шуткой.
Сайтами русскими пользуетесь? Кстати, Украина - моя вторая родина, так что знаю, что и там может все случиться )))
Я сейчас живу в Шанхае, страшно представить, что китайцы то же захотят национализировать свой веб и будет что-то вроде "。中国" в добавок к ".com.cn". Сейчас и так невозможно нормально работать, тк все сайты заточены под ИЕ, но от обилия используемых скриптов он то же отказывается работать.
у наших борзости не хватит такое ломить пока северный сосед не обкатает
Если меня память не подводит, то как раз китайцы и были застрельщиками идеи использовать национальные алфавиты в адресах.
А это здесь к чему? Разработчики сайтов все равно будут косячить независимо от используемых алфавитов.
а как внизу сделать ссылку на список всех комментариев? либо слайдер вправо влево через аякс?
Нет в Китае алфавита, поэтому и страшно, поэтому и застрелили )))
всех всех всех комментариев? Ссылка на ноду покажет в т.ч. и все комментарии к ней.
сделать ссылку всех комментариев не к отдельной ноде.. а ко всем, как? то есть чтобы можно было посмотреть не только последние 10 комментов а вообще все...
кстати, приеложенный сниппет неправильно отрабатывает, неправильно в том смысле, что выводит не все подряд последний комментарии, некоторые пропускает просто!!! У меня было селан через стандарнтый views так все нолмально было, попробывал этот сниппт и ужаснулся!!!! Поэтоу не используейте его!!!!
кстати топикстартер "зарезал" такой вариант выше - ему надо ссылки на последние откомментированные ноды. А Вам подойдет вариант из этого коммента
хорошо, подошел код, а вот как можно сделайть листалку в блоке комментов последних... вправо-влево??? через аякс?
а можно сделать темизацию пейджером, что бы внизу списка шли страницы 1, 2, 3...
Но имхо оба варианта излишние для блока кроме расположенного внизу содержимого.
Аяксовая листалка, только через свой модуль
Уважаемый Илья!
Нашел еще один баг. При выводе заголовка не формируется ссылка на ноду, а просто стоит на главную страницу.
Странно.
А тут формируется все нормально - http://d6.reznik.kiev.ua
И на Вашем сайте спокойно перешел на последний комментарий
Соррри, моя ошибка. Код не правильно правил.
Как убрать скобки?
А вот так:
<?php if ($comment->uid) {
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.theme('username',$comment).'→</strong> '. l($comment->title.'', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}
else {
$items[] = '<span style="color: red; font-family: arial;"> ♫ </span>'.'<strong>'.$comment->name.'→</strong> '. l($comment->title.'', 'node/'.$comment->nid, array('fragment' => 'comment-'. $comment->cid)) . "→ " . substr($comment->comment, 0, 555);
}?>
Какие скобки Вы хотите убрать?
Надо, что бы все комментаторы выводились как гости? Тогда все равно проверка на $user->uid останется, так как по гостям data берем из таблицы комментов, а по зарегистрированным юзерам - из таблицы юзеров.
Скобки выводятся после темы. Не айс. В сообщшении выше убрал )))
нашел статью вывод данных с постраничной разбивкой: ссылка
Вопрос, как прикрутить пейджер к этому коду?