[РЕШЕНО] Вызов имени незарегистрированного пользователя в "прямом эфире"

Главные вкладки

Аватар пользователя Dimanic Dimanic 25 февраля 2010 в 8:44

Здравствуйте!

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

Код прямого эфира:

<?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->comment0555);
 }
 if(
count($items)){
  print 
theme('item_list',$items);
 }
?>

Комментарии

Аватар пользователя elia elia 25 февраля 2010 в 10:30

проблема вот тут: theme('username',user_load($comment->uid))
При отображении комментов данный объект ($user) содержит информацию о смотрящем, а не авторе коммента.
Надо создавать объект $comuser, к примеру, и набивать его данными из query и затем его отдавать для темизации.
Необходимо заполнить:
$comuser->uid
$comuser->name
$comuser->homepage

Сорри. Плохо читал. Буду читать еще.

Аватар пользователя elia elia 25 февраля 2010 в 10:36

В запросе возвращаются uid и name из таблицы пользователей, а не из комментария.

PS
А чем стандартный блок последних комментариев не устраивает?

Аватар пользователя Dimanic Dimanic 25 февраля 2010 в 11:25

"elia" wrote:
А чем стандартный блок последних комментариев не устраивает?

Данный сниппет, в отличие от стандартного блока, выводит в начале имя пользователя, затем заголовок, а затем сам коммент. Все это легко темизируется, поэтому и предпочитаю этот сниппет.
Как сделать, чтобы возвращался name из комментария?

Аватар пользователя elia elia 25 февраля 2010 в 11:38

У данного снипета query "каличный" как по мне. Проще всего вставить слегка измененный код из comment_get_recent():

<?php
 $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);

  

$nids = array();
  while (
$row db_fetch_object($result)) {
    
$nids[] = $row->nid;
  }

  

$comments = array();
  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_PUBLISHED0$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->comment0555);
 }
 if(
count($items)){
  print 
theme('item_list',$items);
 }
?>

Ключевые изменения стандартного кода во втором СЕЛЕКТЕ:

SELECT c.uid, c.name, ...

Аватар пользователя Dimanic Dimanic 25 февраля 2010 в 11:49

Parse error: syntax error, unexpected $end in /home/цццццц/цццццц.ru/includes/common.inc(1685) : eval()'d code on line 30
Не идет ((( Кстати, что значит каличный?

Аватар пользователя elia elia 25 февраля 2010 в 12:29

В экран все не влезло Smile
Второй запрос к БД можно взять из 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);
?>

Почему каличный? Непонятно зачем для такой простой задачи делать столько вложенных селектов - они ресурсы жрут неподецки

Аватар пользователя Dimanic Dimanic 25 февраля 2010 в 14:50

Можно это одним кодом оформить? А я пока, за вашу помошь, пойду по кликаю гугл эдс на сайте однофамильцев )))

Аватар пользователя elia elia 25 февраля 2010 в 15:37

ROFL
я одну { забыл

<?php
 $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);

  

$nids = array();
  while (
$row db_fetch_object($result)) {
    
$nids[] = $row->nid;
  }

  

$comments = array();
  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_PUBLISHED0$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->comment0555);
 }
 if(
count($items)){
  print 
theme('item_list',$items);
 }
?>
Аватар пользователя Dimanic Dimanic 25 февраля 2010 в 21:25

Не работает. Можно все же сохранить начальный снипет, просто сделать так, чтобы имя выбиралось из таблицы comment?

Аватар пользователя elia elia 26 февраля 2010 в 10:24

Не работает, потому что надо мануалы читать нам обоим Smile
http://api.drupal.org/api/function/theme_username - смотрите самый первый "if" - если $user->uid = 0, то сама тема ставит по определению анонима.
значит для гостей надо уходить от этой темы и ссылку на профиль пользователя лепить самому. Ниже один из вариантов решения:

<?php
 $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);

  

$nids = array();
  while (
$row db_fetch_object($result)) {
    
$nids[] = $row->nid;
  }

  

$comments = array();
  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_PUBLISHED0$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->comment0555);
}
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->comment0555);
}
 }
 if(
count($items)){
  print 
theme('item_list',$items);
 }
?>

Я ничего не делал с выводом количества комментариев, но ИМХО он здесь лишен смысла.

Аватар пользователя Dimanic Dimanic 26 февраля 2010 в 12:22

Все работает, но вывод как у стандартного модуля ((( Нужно чтобы выводилось как в сниппете - имя пользователя, затем заголовок СТАТЬИ, а затем сам коммент. Т.е. этот снипет абсолютно рабочий, кроме того, что не подхватывает имя незарегенного пользователя.

Аватар пользователя elia elia 26 февраля 2010 в 12:46
<?php
 $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);

  

$nids = array();
  while (
$row db_fetch_object($result)) {
    
$nids[] = $row->nid;
  }

  

$comments = array();
  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_PUBLISHED0$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->comment0555);
}
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->comment0555);
}
 }
 if(
count($items)){
  print 
theme('item_list',$items);
 }
?>
Аватар пользователя Dimanic Dimanic 26 февраля 2010 в 13:05

Илья, вы просто молодец! Остальсь только решить как ограничить количество символов в сообщении и еще одна такая тонкость - из статьи должно публиковаться толкьо последнее сообщение, иначе получается, что если в статье ведется бурное обсуждение, то весь блок будет забит этими комментами.

Аватар пользователя elia elia 26 февраля 2010 в 19:11
<?php
//Limit for comment's teaser in chars
$com_limit 50;

 

$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("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);

  

$nids = array();
  while (
$row db_fetch_object($result)) {
    
$nids[] = $row->cid;
  }

  

$comments = array();
  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_PUBLISHED0$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->comment0$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->comment0555);
}
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->comment0555);
}
 }
 if(
count($items)){
  print 
theme('item_list',$items);
 }
?>
Аватар пользователя Dimanic Dimanic 26 февраля 2010 в 16:55

Код получился вполне рабочий. Потестил на сайте. В английской версии все хорошо, ва вот в русской версии вылазит вопрос � в конце вывода комментария, там где обрезается текст.

Аватар пользователя elia elia 26 февраля 2010 в 18:24

забыл про multibyte
надо сделать замены:
strlen -> mb_strlen
substr -> mb_substr

PS
Вот взяли бы и отменили у нас кириллицу, как казахи сделали в свое время - столько компутерных проблем отпало бы Biggrin

Аватар пользователя Dimanic Dimanic 26 февраля 2010 в 19:00

Работает! Сделали большое дело и надеюсь не только для меня.
С введением зоны "ру" такие проблемы проблемы будут толкьо сниться ))) Стандартное сегментирование рынка, когда уже трудно что-то разделить. Когда идет речь о деньгах, то людские проблемы уже никого не интересуют.

Аватар пользователя elia elia 26 февраля 2010 в 19:09

"Dimanic" wrote:
С введением зоны "ру" такие проблемы проблемы будут толкьо сниться )))

Вы хотели сказать, что старые проблемы покажутся детским лепетом?

Я не живу в России и для меня эта доменная зона "xn--p1ag" пока выглядит чей-то злой шуткой. Wink

Аватар пользователя Dimanic Dimanic 27 февраля 2010 в 10:09

Сайтами русскими пользуетесь? Кстати, Украина - моя вторая родина, так что знаю, что и там может все случиться )))
Я сейчас живу в Шанхае, страшно представить, что китайцы то же захотят национализировать свой веб и будет что-то вроде "。中国" в добавок к ".com.cn". Сейчас и так невозможно нормально работать, тк все сайты заточены под ИЕ, но от обилия используемых скриптов он то же отказывается работать.

Аватар пользователя elia elia 27 февраля 2010 в 10:32

"Dimanic" wrote:
Сайтами русскими пользуетесь? Кстати, Украина - моя вторая родина, так что знаю, что и там может все случиться )))

у наших борзости не хватит такое ломить пока северный сосед не обкатает Smile
"Dimanic" wrote:
сейчас живу в Шанхае, страшно представить, что китайцы то же захотят национализировать свой веб и будет что-то вроде "。中国" в добавок к ".com.cn".

Если меня память не подводит, то как раз китайцы и были застрельщиками идеи использовать национальные алфавиты в адресах.
"Dimanic" wrote:
Сейчас и так невозможно нормально работать, тк все сайты заточены под ИЕ, но от обилия используемых скриптов он то же отказывается работать.

А это здесь к чему? Разработчики сайтов все равно будут косячить независимо от используемых алфавитов.

Аватар пользователя Dimanic Dimanic 27 февраля 2010 в 11:53

"elia" wrote:
Разработчики сайтов все равно будут косячить независимо от используемых алфавитов.

Нет в Китае алфавита, поэтому и страшно, поэтому и застрелили )))

Аватар пользователя elia elia 27 февраля 2010 в 13:44

"<a href="mailto:gothica@drupal.org">gothica@drupal.org</a>" wrote:
а как внизу сделать ссылку на список всех комментариев? либо слайдер вправо влево через аякс?

всех всех всех комментариев? Ссылка на ноду покажет в т.ч. и все комментарии к ней.

Аватар пользователя gothica@drupal.org gothica@drupal.org 27 февраля 2010 в 14:59

сделать ссылку всех комментариев не к отдельной ноде.. а ко всем, как? то есть чтобы можно было посмотреть не только последние 10 комментов а вообще все...

Аватар пользователя gothica@drupal.org gothica@drupal.org 28 февраля 2010 в 14:39

кстати, приеложенный сниппет неправильно отрабатывает, неправильно в том смысле, что выводит не все подряд последний комментарии, некоторые пропускает просто!!! У меня было селан через стандарнтый views так все нолмально было, попробывал этот сниппт и ужаснулся!!!! Поэтоу не используейте его!!!!

Аватар пользователя elia elia 28 февраля 2010 в 18:44

"<a href="mailto:gothica@drupal.org">gothica@drupal.org</a>" wrote:
кстати, приеложенный сниппет неправильно отрабатывает, неправильно в том смысле, что выводит не все подряд последний комментарии, некоторые пропускает просто!!!

кстати топикстартер "зарезал" такой вариант выше - ему надо ссылки на последние откомментированные ноды. А Вам подойдет вариант из этого коммента

Аватар пользователя elia elia 28 февраля 2010 в 19:59

а можно сделать темизацию пейджером, что бы внизу списка шли страницы 1, 2, 3...

Но имхо оба варианта излишние для блока кроме расположенного внизу содержимого.

Аватар пользователя Виктор Степаньков ака RxB Виктор Степаньк... 28 февраля 2010 в 20:11

"elia" wrote:
хорошо, подошел код, а вот как можно сделайть листалку в блоке комментов последних... вправо-влево??? через аякс?

Аяксовая листалка, только через свой модуль

Аватар пользователя Dimanic Dimanic 2 марта 2010 в 6:33

Уважаемый Илья!
Нашел еще один баг. При выводе заголовка не формируется ссылка на ноду, а просто стоит на главную страницу.

Аватар пользователя Dimanic Dimanic 2 марта 2010 в 20:12

Соррри, моя ошибка. Код не правильно правил.
Как убрать скобки?
А вот так:

<?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->comment0555);
}
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->comment0555);
}
?>
Аватар пользователя elia elia 2 марта 2010 в 21:40

Какие скобки Вы хотите убрать?
Надо, что бы все комментаторы выводились как гости? Тогда все равно проверка на $user->uid останется, так как по гостям data берем из таблицы комментов, а по зарегистрированным юзерам - из таблицы юзеров.