Marking posts as read - solution looking for improvements

I wanted a system for a simple forum that shows which topics contain unread posts for the logged in user (same as most other forums).

I spent a loooong time on this. I have it working but wondered if anyone had inprovements or a better way of implementing this.

My original approach was to use relations in the model to join this with my topics table but I struggled with joining across the topic and topic_read tables with a logged in user as a condition. I also was concerned with the size of any joined table. Another approach was to add the topic_read data to the topics data to display in the view but again, couldn’t work that out.

So working solution is put the topics a user has read into the session…

ATM I have a table tbl_topic_read with columns read_user_id read_topic_id read_forum_id read_time

TopicController inserts the user, topic, forum ID’s and time into the topic_read table when a topic is viewed so the system knows the last time a user looked at that topic.

Now the dodgy bit… I wanted the session to contain an array of topic_ids (key) and dates (value) so came up with possibly mad way of achieving this:

View action in ForumController




...

		$criteria = new CDbCriteria;

		$criteria->select = 'read_topic_id, read_time';

		$criteria->condition = 'read_forum_id=:forum_id AND read_user_id=:user_id';

		$criteria->params = array(

		       'forum_id'=>intval($_GET['id']),

			   'user_id'=>Yii::app()->user->getId(),

			   );

		$model = Yii::app()->db->commandBuilder;

		$readtopics = $model->createFindCommand('tbl_topic_read', $criteria)->queryAll();

		

		function array_function($mdArray){

		  if(!$mdArray||!is_array($mdArray))return '';

		  foreach($mdArray as $k=>$a){

		  	foreach($a as $k=>$v){

				if($k=='read_topic_id') $topicKey = $v;

				if($k=='read_time') $topicKeyTime[$topicKey] = $v;	

		  	}

		  }

		  return $topicKeyTime;

		}


		Yii::app()->session['readTopics'] = array_function($readtopics);

...



and then in the _topics partial I check if the current topic has an entry set and if so if the time is before the latest post time in that topic




if (isset(Yii::app()->session['readTopics'][$data->topic_id]) && Yii::app()->session['readTopics'][$data->topic_id] >= $data->topic_last_post_time){echo "no new posts";}



‘no new posts’ will be a pretty icon in the finished code.

I don’t know about this, but I’ll give you another idea.

In phpbb2 you have column last_visit in the users table, where you record the time of the last visit of the user.

When the user come in the forum, you set all of the posts, that are wrote after his last visit, in a cookie. (serialize).

To mark all posts as read - you need just to delete the cookie :)

ah, that’s useful for ‘topics with new posts since last visit’. My solution shows topics that have unread posts in the current visit as the user moves around the forum.