I'm using the View module's "Node: Has New Content" filter to display a list of nodes that a particular user has not yet read. However, I'm having trouble finding a way to display a *count* of these unread nodes (e.g., on the user's front page).

I'm curious to hear how are other people are displaying counts of unread nodes.

Comments

radarkyle’s picture

I found a discussion at #347819: How count results of one view ? that describes a way to execute a view and count the number of results it returns.


//specify the view
$view = views_get_view( 'VIEW_TO_EXECUTE' );

//execute the query, storing the result in $view->result array
$view->execute();

//print the number of entries in the result
print count( $view->result );

This seems like an acceptable solution, but are there any other ways? I was thinking it might be possible to reduce the overhead of executing the query every time.

whitekeys’s picture

I have a similar need, but using views and views calc it is still not possible to come up with a value of the number of UPDATED nodes separate from the number of NEW nodes. It would additionally be helpful to return a value for the number of nodes with new comments.

radarkyle’s picture

True, whitekeys. According to #262954: "Node: Has new content" filter broken., the "Node: Has New Content" filter is Boolean by design.

It would be great to be able to separate:

  • # New Posts
  • # Updated Posts
  • # New Comments

Is anyone doing this now?

radarkyle’s picture

You might be able to use comment.module's function comment_num_new($nid, $timestamp = 0) to return the number of new comments on a node for the current user.

Unfortunately, I still don't have a good way to differentiate between the number of new posts and the number of updated posts.

Here's a thought... The DB query that the comment module uses is:


$result = db_result(db_query('SELECT COUNT(c.cid) FROM {node} n INNER JOIN {comments} c ON n.nid = c.nid WHERE n.nid = %d AND timestamp > %d AND c.status = %d', $nid, $timestamp, COMMENT_PUBLISHED));

and if no timestamp is specified, it uses the value from:


  $timestamp = node_last_viewed($nid);

Could we possibly modify this query to find new/updated nodes (rather than comments)?

whitekeys’s picture

I did eventually find a solution to return a value for the number of new nodes, updated nodes, and new comments. The following code counts nodes of type "request".

global $user;
$new = array();
$query = db_query('SELECT n.nid FROM node n LEFT OUTER JOIN history h ON n.nid = h.nid AND h.uid = ' . $user->uid . ' WHERE h.nid IS NULL AND n.type = "request"');
while ($row = db_result($query)) {
	array_push($new, $row);
}

This query returns an array ($new) containing the NIDs of all nodes that have never been viewed by the current user. One might replace 'SELECT n.nid FROM...' with 'SELECT COUNT(n.nid) FROM...' for just the number of nodes, but the above code may be used in conjunction with the Views PHP Filter module to create a view of only new nodes as it produces an array of NIDs which can be returned directly into the views filter.

$changed = array();
$query = db_query('SELECT n.nid FROM node n INNER JOIN history h ON n.nid = h.nid WHERE h.timestamp < n.changed AND h.uid = ' . $user->uid . ' AND n.uid != ' . $user->uid . ' AND n.type = "request"');
while ($row = db_result($query)) {
	array_push($changed, $row);
}

This query returns an array ($changed) containing the NIDs of all nodes that are not new, but have been changed since the last time the current user viewed any of them.

$comments = array();
$query = db_query('SELECT c.nid FROM comments c INNER JOIN history h ON c.nid = h.nid WHERE h.timestamp < c.timestamp AND h.uid = ' . $user->uid . ' AND c.uid != ' . $user->uid);
while ($row = db_result($query)) {
	array_push($comments, $row);
}
$query = db_query('SELECT c.nid FROM comments c LEFT OUTER JOIN history h ON c.nid = h.nid AND h.uid = ' . $user->uid . ' WHERE h.nid IS NULL');
while ($row = db_result($query)) {
	array_push($comments, $row);
}

This code returns an array ($comments) containing the NIDs of all nodes containing new comments. There are two queries here because, effectively, the number of new comments needs to be added to the number of changed comments to produce a count of all nodes with 'unread' comments.

Naturally, the number of nodes may be found by using the php count() function.