1
Cozzie
Change recent comments block to show each article only once
  • 2008/1/9 9:11

  • Cozzie

  • Not too shy to talk

  • Posts: 133

  • Since: 2007/7/13


Hi there,

My recent comments block often features several comments about the same article, I'd like it to show only the most recent comment for any given article.

Is it possible to change the recent comments block so that it does not repeat comments about the same article?

So just like the 'most recent forum posts' block in newbb will only show the most recent post for any given topic, can this be done on the recent comments block?

Thanks a lot!

2
mboyden
Re: Change recent comments block to show each article only once
  • 2008/1/9 15:39

  • mboyden

  • Moderator

  • Posts: 484

  • Since: 2005/3/9 1


This would likely be a good enhancement to the recent comments block. There are likely a few methods you could use to do this.

For instance, you could change the php for the block so that it keeps track of whether or not a specific module item has already displayed a comment for it or not before it gets added to the displayed comments. You'd need to initialize an array for this purpose, then in the foreach loop check to see if a comment already exists for this item or not and if so skip it, and if not then add it to the comments and then add the info (probably moduleID and then itemID) to the array for the next time to check. This would be done in the /modules/system/blocks/system_blocks.php in the function b_system_comments_show.

For example, this code MIGHT work (I haven't tested it, but it should be close). Replace:
foreach (array_keys($comments) as $i) {
  
$mid $comments[$i]->getVar('com_modid');
  
$com['module'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/">'.$modules[$mid]->getVar('name').'';
  if (!isset(
$comment_config[$mid])) {
    
$comment_config[$mid] = $modules[$mid]->getInfo('comments');
  }
  
$com['id'] = $i;
  
$com['title'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/'.$comment_config[$mid]['pageName'].'?'.$comment_config[$mid]['itemName'].'='.$comments[$i]->getVar('com_itemid').'&com_id='.$i.'&com_rootid='.$comments[$i]->getVar('com_rootid').'&'.htmlspecialchars($comments[$i]->getVar('com_exparams')).'#comment'.$i.'">'.$comments[$i]->getVar('com_title').'';
  
$com['icon'] = htmlspecialchars$comments[$i]->getVar('com_icon'), ENT_QUOTES );
  
$com['icon'] = ($com['icon'] != '') ? $com['icon'] : 'icon1.gif';
  
$com['time'] = formatTimestamp($comments[$i]->getVar('com_created'),'m');
  if (
$comments[$i]->getVar('com_uid') > 0) {
    
$poster =& $member_handler->getUser($comments[$i]->getVar('com_uid'));
    if (
is_object($poster)) {
      
$com['poster'] = '.XOOPS_URL.'/userinfo.php?uid='.$comments[$i]->getVar('com_uid').'">'.$poster->getVar('uname').'';
    } else {
      
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
    }
  } else {
    
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
  }
  
$block['comments'][] =& $com;
  unset(
$com);
}
with:
$trackedItems = array();
foreach (
array_keys($comments) as $i) {
  
$mid $comments[$i]->getVar('com_modid');
  
$com['module'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/">'.$modules[$mid]->getVar('name').'';
  if (!isset(
$comment_config[$mid])) {
    
$comment_config[$mid] = $modules[$mid]->getInfo('comments');
  }
  
$com['id'] = $i;
  
$com['title'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/'.$comment_config[$mid]['pageName'].'?'.$comment_config[$mid]['itemName'].'='.$comments[$i]->getVar('com_itemid').'&com_id='.$i.'&com_rootid='.$comments[$i]->getVar('com_rootid').'&'.htmlspecialchars($comments[$i]->getVar('com_exparams')).'#comment'.$i.'">'.$comments[$i]->getVar('com_title').'';
  
$com['icon'] = htmlspecialchars$comments[$i]->getVar('com_icon'), ENT_QUOTES );
  
$com['icon'] = ($com['icon'] != '') ? $com['icon'] : 'icon1.gif';
  
$com['time'] = formatTimestamp($comments[$i]->getVar('com_created'),'m');
  if (
$comments[$i]->getVar('com_uid') > 0) {
    
$poster =& $member_handler->getUser($comments[$i]->getVar('com_uid'));
    if (
is_object($poster)) {
      
$com['poster'] = '.XOOPS_URL.'/userinfo.php?uid='.$comments[$i]->getVar('com_uid').'">'.$poster->getVar('uname').'';
    } else {
      
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
    }
  } else {
    
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
  }
  if (
count($trackedItems) > 0) {
    
$itemMatch false;
    foreach (
array_keys($trackedItems) as $j) {
      if (
$comments[$i]->getVar('com_modid') == $trackedItems[$j]['modid'] && $comments[$i]->getVar('com_itemid') == $trackedItems[$j]['itemid']) {
          
$itemMatch true;
      }
    }
    if (
$itemMatch) {
      
$block['comments'][] =& $com;
      
$trackedItems[] = array('modid' => $comments[$i]->getVar('com_modid'), 'itemid' => $comments[$i]->getVar('com_itemid') );
    }
  } else {
    
$block['comments'][] =& $com;
    
$trackedItems[] = array('modid' => $comments[$i]->getVar('com_modid'), 'itemid' => $comments[$i]->getVar('com_itemid') );
  }
  unset(
$com);
}
BTW, I'm sure the code can be made more elegant, and as presented above, it may not work, but this hack should get you closer.
Pessimists see difficulty in opportunity; Optimists see opportunity in difficulty. --W Churchill

XOOPS: Latest | Debug | Hosting and Web Development

3
Cozzie
Re: Change recent comments block to show each article only once
  • 2008/1/10 4:04

  • Cozzie

  • Not too shy to talk

  • Posts: 133

  • Since: 2007/7/13


Thanks a lot mboyden

I tried that but the result is that only one comment is shown, its the most recent comment and as far as I can figure its the only comment that has received no replies (so, recent comments are not showing for articles that have mutiple comments)

I've tried to figure the solution but can't see it

Any ideas

Thanks a lot!!!

4
trabis
Re: Change recent comments block to show each article only once
  • 2008/1/10 14:03

  • trabis

  • Core Developer

  • Posts: 2269

  • Since: 2006/9/1 1


Try:
if (!$itemMatch) {

5
Cozzie
Re: Change recent comments block to show each article only once
  • 2008/1/11 6:30

  • Cozzie

  • Not too shy to talk

  • Posts: 133

  • Since: 2007/7/13


Hi Trabis

Thanks a lot! That did it

But there is one small problem remaining, not sure if there is a simple solution.

In the block of course you must state the number of comments you want to be shown (for me its 10) but after the above change the number of comments shown varies. The system is checking the 10 most recent comments and only displaying 6 because the other 4 are previous comments from one of those articles

Any solution (this is way beyond me)

Thanks again!

6
trabis
Re: Change recent comments block to show each article only once
  • 2008/1/11 14:07

  • trabis

  • Core Developer

  • Posts: 2269

  • Since: 2006/9/1 1


I see, try to replace the entire function with this one:

function b_system_comments_show($options)
{
    
$block = array();
    include_once 
XOOPS_ROOT_PATH.'/include/comment_constants.php';
    
$comment_handler =& xoops_gethandler('comment');
    
$criteria = new CriteriaCompo(new Criteria('com_status'XOOPS_COMMENT_ACTIVE));
    
$criteria->setLimit(intval($options[0] * 10));
    
$criteria->setSort('com_created');
    
$criteria->setOrder('DESC');
    
$comments $comment_handler->getObjects($criteriatrue);
    
$member_handler =& xoops_gethandler('member');
    
$module_handler =& xoops_gethandler('module');
    
$modules $module_handler->getObjects(new Criteria('hascomments'1), true);
    
$comment_config = array();

    
$trackedItems = array();
    
$count 0;
    foreach (
array_keys($comments) as $i) {
        if ( 
$count == $options[0])  continue;
        
$mid $comments[$i]->getVar('com_modid');
        
$com['module'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/">'.$modules[$mid]->getVar('name').'';
        if (!isset(
$comment_config[$mid])) {
            
$comment_config[$mid] = $modules[$mid]->getInfo('comments');
        }
        
$com['id'] = $i;
        
$com['title'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/'.$comment_config[$mid]['pageName'].'?'.$comment_config[$mid]['itemName'].'='.$comments[$i]->getVar('com_itemid').'&com_id='.$i.'&com_rootid='.$comments[$i]->getVar('com_rootid').'&'.htmlspecialchars($comments[$i]->getVar('com_exparams')).'#comment'.$i.'">'.$comments[$i]->getVar('com_title').'';
        
$com['icon'] = htmlspecialchars$comments[$i]->getVar('com_icon'), ENT_QUOTES );
        
$com['icon'] = ($com['icon'] != '') ? $com['icon'] : 'icon1.gif';
        
$com['time'] = formatTimestamp($comments[$i]->getVar('com_created'),'m');
        if (
$comments[$i]->getVar('com_uid') > 0) {
            
$poster =& $member_handler->getUser($comments[$i]->getVar('com_uid'));
            if (
is_object($poster)) {
                
$com['poster'] = '.XOOPS_URL.'/userinfo.php?uid='.$comments[$i]->getVar('com_uid').'">'.$poster->getVar('uname').'';
            } else {
                
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
            }
        } else {
            
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
        }
        if (
count($trackedItems) > 0) {
            
$itemMatch false;
            foreach (
array_keys($trackedItems) as $j) {
                if (
$comments[$i]->getVar('com_modid') == $trackedItems[$j]['modid'] && $comments[$i]->getVar('com_itemid') == $trackedItems[$j]['itemid']) {
                    
$itemMatch true;
                }
            }
            if (!
$itemMatch) {
                
$block['comments'][] =& $com;
                
$trackedItems[] = array('modid' => $comments[$i]->getVar('com_modid'), 'itemid' => $comments[$i]->getVar('com_itemid') );
                
$count++;
            }
        } else {
            
$block['comments'][] =& $com;
            
$trackedItems[] = array('modid' => $comments[$i]->getVar('com_modid'), 'itemid' => $comments[$i]->getVar('com_itemid') );
            
$count++;
        }
        unset(
$com);
    }
    return 
$block;
}

7
migoe
Re: Change recent comments block to show each article only once
  • 2008/4/29 19:23

  • migoe

  • Just popping in

  • Posts: 68

  • Since: 2003/4/2 9


Thank you guys for this very useful hack. Is it posible to hide the comments to users who have no rights to a module?

migoe
whttp://www.liedermacher-forum.de | German Singers and Songwriters

http://www.weltladen-rothenburg.de | German Site about Fair trade Project

8
trabis
Re: Change recent comments block to show each article only once
  • 2008/4/29 20:18

  • trabis

  • Core Developer

  • Posts: 2269

  • Since: 2006/9/1 1


Hum, try this way:
function b_system_comments_show($options)
{
    global 
$xoopsUser;
    include_once 
XOOPS_ROOT_PATH.'/include/comment_constants.php';
    
$limit 10// If you  are not getting suficient results, please increase a little more this number
    
$block $comment_config $trackedItems = array();

    
$comment_handler =& xoops_gethandler('comment');
    
$moduleperm_handler =& xoops_gethandler('groupperm');
    
$member_handler =& xoops_gethandler('member');
    
$module_handler =& xoops_gethandler('module');

    
$criteria = new CriteriaCompo(new Criteria('com_status'XOOPS_COMMENT_ACTIVE));
    
$criteria->setLimit(intval($options[0] * $limit));
    
$criteria->setSort('com_created');
    
$criteria->setOrder('DESC');

    
$comments $comment_handler->getObjects($criteriatrue);
    
$modules $module_handler->getObjects(new Criteria('hascomments'1), true);
    
    
$count 0;
    foreach (
array_keys($comments) as $i) {
        if ( 
$count == $options[0])  continue;
        
$mid $comments[$i]->getVar('com_modid');

        if (
$xoopsUser) {
            if (!
$moduleperm_handler->checkRight('module_read'$mid$xoopsUser->getGroups())) {
                continue;
            }
        } else {
            if (!
$moduleperm_handler->checkRight('module_read'$midXOOPS_GROUP_ANONYMOUS)) {
                continue;
            }
        }
        
        
$com['module'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/">'.$modules[$mid]->getVar('name').'';
        if (!isset(
$comment_config[$mid])) {
            
$comment_config[$mid] = $modules[$mid]->getInfo('comments');
        }
        
$com['id'] = $i;
        
$com['title'] = '.XOOPS_URL.'/modules/'.$modules[$mid]->getVar('dirname').'/'.$comment_config[$mid]['pageName'].'?'.$comment_config[$mid]['itemName'].'='.$comments[$i]->getVar('com_itemid').'&com_id='.$i.'&com_rootid='.$comments[$i]->getVar('com_rootid').'&'.htmlspecialchars($comments[$i]->getVar('com_exparams')).'#comment'.$i.'">'.$comments[$i]->getVar('com_title').'';
        
$com['icon'] = htmlspecialchars$comments[$i]->getVar('com_icon'), ENT_QUOTES );
        
$com['icon'] = ($com['icon'] != '') ? $com['icon'] : 'icon1.gif';
        
$com['time'] = formatTimestamp($comments[$i]->getVar('com_created'),'m');
        if (
$comments[$i]->getVar('com_uid') > 0) {
            
$poster =& $member_handler->getUser($comments[$i]->getVar('com_uid'));
            if (
is_object($poster)) {
                
$com['poster'] = '.XOOPS_URL.'/userinfo.php?uid='.$comments[$i]->getVar('com_uid').'">'.$poster->getVar('uname').'';
            } else {
                
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
            }
        } else {
            
$com['poster'] = $GLOBALS['xoopsConfig']['anonymous'];
        }
        if (
count($trackedItems) > 0) {
            
$itemMatch false;
            foreach (
array_keys($trackedItems) as $j) {
                if (
$comments[$i]->getVar('com_modid') == $trackedItems[$j]['modid'] && $comments[$i]->getVar('com_itemid') == $trackedItems[$j]['itemid']) {
                    
$itemMatch true;
                }
            }
            if (!
$itemMatch) {
                
$block['comments'][] =& $com;
                
$trackedItems[] = array('modid' => $comments[$i]->getVar('com_modid'), 'itemid' => $comments[$i]->getVar('com_itemid') );
                
$count++;
            }
        } else {
            
$block['comments'][] =& $com;
            
$trackedItems[] = array('modid' => $comments[$i]->getVar('com_modid'), 'itemid' => $comments[$i]->getVar('com_itemid') );
            
$count++;
        }
        unset(
$com);
    }
    return 
$block;
}


I did not tested it so please, be kind to report the results.
Thanks.

9
migoe
Re: Change recent comments block to show each article only once
  • 2008/4/29 21:36

  • migoe

  • Just popping in

  • Posts: 68

  • Since: 2003/4/2 9


trabis,

this works very well, thank you. Just one bad thing: the anonymous can see every comment, but when you login, you see only the comments, you have rights for.

migoe
whttp://www.liedermacher-forum.de | German Singers and Songwriters

http://www.weltladen-rothenburg.de | German Site about Fair trade Project

10
trabis
Re: Change recent comments block to show each article only once
  • 2008/4/29 22:05

  • trabis

  • Core Developer

  • Posts: 2269

  • Since: 2006/9/1 1


Are you sure,?
I mean, have you tried to click on the comment as anonym?
If yes, did you get a "NO PERMISSION".
I´m saying this because anonyms may have permissons set and you did not realised.
Please try this.
Thanks.

Login

Who's Online

408 user(s) are online (293 user(s) are browsing Support Forums)


Members: 0


Guests: 408


more...

Donat-O-Meter

Stats
Goal: $100.00
Due Date: Nov 30
Gross Amount: $0.00
Net Balance: $0.00
Left to go: $100.00
Make donations with PayPal!

Latest GitHub Commits