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

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

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

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

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

<?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);
 }
?>

Комментарии

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

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

25 февраля 2010 в 10:30

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

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

25 февраля 2010 в 10:36

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

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

25 февраля 2010 в 11:25

У данного снипета 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, ...

25 февраля 2010 в 11:38

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

25 февраля 2010 в 11:49

В экран все не влезло 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);
?>

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

25 февраля 2010 в 12:29

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

25 февраля 2010 в 14:50

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);
 }
?>
25 февраля 2010 в 15:37

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

25 февраля 2010 в 21:25

Не работает, потому что надо мануалы читать нам обоим 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);
 }
?>

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

26 февраля 2010 в 10:24

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

26 февраля 2010 в 12:22
<?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);
 }
?>
26 февраля 2010 в 12:46

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

26 февраля 2010 в 13:05
<?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);
 }
?>
26 февраля 2010 в 19:11

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

26 февраля 2010 в 16:55

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

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

26 февраля 2010 в 18:24

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

26 февраля 2010 в 19:00

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

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

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

26 февраля 2010 в 19:09

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

27 февраля 2010 в 10:09

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

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

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

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

27 февраля 2010 в 10:32

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

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

27 февраля 2010 в 11:53

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

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

27 февраля 2010 в 13:44

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

27 февраля 2010 в 14:59

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

28 февраля 2010 в 14:39

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

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

28 февраля 2010 в 18:44

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

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

28 февраля 2010 в 19:59

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

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

28 февраля 2010 в 20:11

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

2 марта 2010 в 6:33

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

<?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);
}
?>
2 марта 2010 в 20:12

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

2 марта 2010 в 21:40