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.