I needed to have a view which shows all unread posts of the forum for a logged in user. There are only blocks for "active posts" or "recent posts".

So I build up a custom view. It provides a list of topics, where a user has unread posts in it. A customized link jumps directly to the last page of the topic. Therefore comments have to be shown as flat list, ordered with oldest posts first (newest posts at the end).

I use advanced_forum with my site.

You will also need views and forum enabled, :)

(I have locked out anonymous users from the forums)

1. Build the view: (can be imported on the views section)

$view = new stdClass();
  $view->name = 'forumTracker';
  $view->description = 'Shows all new Forumposts';
  $view->access = array (
  0 => '2',
);
  $view->view_args_php = '';
  $view->page = TRUE;
  $view->page_title = 'Forum - New Posts';
  $view->page_header = 'To mark everything as read, use the "mark as read"-link on <a href="forum">Forums</a>!';
  $view->page_header_format = '1';
  $view->page_footer = '';
  $view->page_footer_format = '1';
  $view->page_empty = '';
  $view->page_empty_format = '1';
  $view->page_type = 'table';
  $view->url = 'forum/forumTracker';
  $view->use_pager = TRUE;
  $view->nodes_per_page = '25';
  $view->menu = TRUE;
  $view->menu_title = 'New Posts';
  $view->menu_tab = FALSE;
  $view->menu_tab_weight = '0';
  $view->menu_tab_default = FALSE;
  $view->menu_tab_default_parent = NULL;
  $view->menu_tab_default_parent_type = 'tab';
  $view->menu_parent_tab_weight = '0';
  $view->menu_parent_title = '';
  $view->sort = array (
    array (
      'tablename' => 'node_comment_statistics',
      'field' => 'last_comment_timestamp',
      'sortorder' => 'DESC',
      'options' => 'normal',
    ),
  );
  $view->argument = array (
  );
  $view->field = array (
    array (
      'tablename' => 'node',
      'field' => 'title',
      'label' => 'Title',
      'handler' => 'views_handler_field_nodelink_with_mark',
      'sortable' => '1',
      'options' => 'link',
    ),
    array (
      'tablename' => 'users',
      'field' => 'name',
      'label' => 'Author',
      'sortable' => '1',
    ),
    array (
      'tablename' => 'node_comment_statistics',
      'field' => 'comment_count',
      'label' => 'Answers',
      'handler' => 'views_handler_comments_with_new',
    ),
    array (
      'tablename' => 'node_comment_statistics',
      'field' => 'last_comment_timestamp',
      'label' => 'Last Post',
      'handler' => 'views_handler_field_since',
      'sortable' => '1',
      'defaultsort' => 'ASC',
    ),
  );
  $view->filter = array (
    array (
      'tablename' => 'node',
      'field' => 'status',
      'operator' => '=',
      'options' => '',
      'value' => '1',
    ),
    array (
      'tablename' => 'node',
      'field' => 'type',
      'operator' => 'OR',
      'options' => '',
      'value' => array (
  0 => 'forum',
),
    ),
    array (
      'tablename' => 'history',
      'field' => 'timestamp',
      'operator' => '0',
      'options' => '',
      'value' => array (
  0 => '0',
),
    ),
  );
  $view->exposed_filter = array (
  );
  $view->requires = array(node_comment_statistics, node, users, history);
  $views[$view->name] = $view;

2. Modify the template.php from your theme to get the "new"-Link jumping to the last page instead of the first one:
(from http://drupal.org/node/154084 )
therefore we modify the link to fit our needs.

function phptemplate_views_view_table_forumTracker($view, $nodes, $type) {
  $fields = _views_get_fields();
  $comments_per_page = _comment_get_display_setting('comments_per_page');

  foreach ($nodes as $node) {
    $row = array();
    foreach ($view->field as $field) {
      if ($fields[$field['id']]['visible'] !== FALSE) {
if($field['field'] == 'comment_count')
{
      $count = db_result(db_query('SELECT COUNT(c.cid) FROM {comments} c WHERE c.nid=%d', $node->nid));
    // Find the ending point. The pager URL is always 1 less than
    // the number being displayed because the first page is 0.
            $last_display_page = ceil($count / $comments_per_page);
            $last_pager_page = $last_display_page - 1;

    $cell['data'] = $node->node_comment_statistics_comment_count.'<br>'.l('new', 'node/'.$node->nid, array(), 'page='.$last_pager_page.'#new');
            $cell['class'] = "view-field ". views_css_safe('view-field-'. $field['queryname']);
            $row[] = $cell;
}
else
{
$cell['data'] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
                    $cell['class'] = "view-field ". views_css_safe('view-field-'. $field['queryname']);
                $row[] = $cell;
}
      }
    }
    $rows[] = $row;
  }
  return theme('table', $view->table_header, $rows);
}

Any improvements or hints are welcome! :)
(i.e. building a general solution for the fixed sort-order of comments)

Comments

Helldesigner’s picture

First of all, thanks for this tip - that's exactly what I needed. One thing didn't work as expected though - the "new" links in "Answers" column. No matter what, they were always pointing to the last page of comments (looking for "#new" anchor). But let's suppose I've got 10 comments per page, and a topic with - let's say - 65 unread replies. Your links would take me to the last page - which would be wrong (assuming my comments are sorted by date - oldest to newest). And I'd like to be taken to the oldest unread post.

This will work for Advanced Forum users only (it uses one of its functions), but I believe it's a better solution. In template.php, instead of:

$cell['data'] = $node->node_comment_statistics_comment_count.'<br>'.l('new', 'node/'.$node->nid, array(), 'page='.$last_pager_page.'#new');

do this:

$cell['data'] = $node->node_comment_statistics_comment_count.'<br />'.advanced_forum_first_new_post_link($node, $count);

An additional bonus would be having number of new comments in the link. Oh, and just for the record: I'm on Drupal 5.14, Views 5.x-1.6 and Advanced Forum 5.x-1.0-alpha16.

calexo’s picture

Hi !
In Drupal 6.x, I did this to create a link to the first unread message in a forum :
For a View2 named forum_answers, containing a field named new_comments, I created that template file on my theme : views-view-field--forum-answers--block-1--new-comments.tpl.php

Here's its content :

if ($row->node_new_comments>0) {
   $comments_per_page = 10;
   $count = db_result(db_query('SELECT COUNT(c.cid) FROM {comments} c WHERE c.nid=%d', $row->nid));
   // Find the ending point. The pager URL is always 1 less than
   // the number being displayed because the first page is 0.
   $poscmt=$count - $row->node_new_comments;
   if ($poscmt==0) $poscmt=1;
   $last_display_page = ceil( $poscmt / $comments_per_page );
   $last_pager_page = $last_display_page - 1;
   print l($row->node_new_comments.' non lu(s)', 'node/'.$row->nid, array( 'query'=>array('page'=>$last_pager_page), 'fragment'=>'new')  );
}

And it works ! (in work here : http://www.clubcanyon.com/ (fr) )

nimzie’s picture

I've implemented this view and template.php function. Thank you so much for this ...

One thing I noticed is that you make reference in your view to returning to the forum page to mark all as read, yet in my advanced forum, there is no mark all as unread link on the /forum page as the view header would suggest.

Have you got a script / process for doing this (mark all as read) in Drupal 5? This would be such a great asset to this particular website.

Thank you kindly for your time and response.
-adam