Page 1 of 1

'Unread Posts' question

Posted: Mon Dec 04, 2006 1:33 pm
by kaisellgren
Hi,

You guys know the 'unread posts' feature in IPB, SMF, etc... so the board remembers which threads you have not read. I am asking how to do this? I know couple of methods to do this but what could be the fastest one?

If I have 5000 topics and 5000 members... you understand that simply making rows of each new unread messages would make my dabatase big...

Help thanks!

Posted: Mon Dec 04, 2006 1:37 pm
by feyd
Fastest in which way?

Typically I'd use a separate table. I'd store which threads have been read and when they were read. The only records that would be in the table are topics since the user last visited. All previous records would be removed when they log in.

Posted: Mon Dec 04, 2006 2:31 pm
by kaisellgren
Thank you for your great help!

By fastest I mean a method that uses as less time as possible. Also as less database as possible.

Do you mean something like this?

read_topics

id | topic id | user id | last read
1 15 46 2353474
etc...

Hm...

Quickest way

Posted: Mon Dec 04, 2006 2:32 pm
by timclaason
$_SESSION or cookies would work well, I think. It wouldn't be explicitly permanent the way a db entry is, but it would be reasonably close to achieving what you're looking for. Then that way, it's more client-side.

Re: Quickest way

Posted: Mon Dec 04, 2006 2:34 pm
by kaisellgren
timclaason wrote:$_SESSION or cookies would work well, I think. It wouldn't be explicitly permanent the way a db entry is, but it would be reasonably close to achieving what you're looking for. Then that way, it's more client-side.
Thanks for the idea, but I think I'll stick around with the databases as they are used to store data permanently.

Posted: Mon Dec 04, 2006 2:34 pm
by Burrito
using this method has its pitfalls as well. Look at phpBB for example: It uses this method and as soon as the size of the cookie gets too large, all kinds of funky things start happening.

Posted: Mon Dec 04, 2006 2:36 pm
by kaisellgren
IPB does the job perfectly, but it's just that the code in IPB is too hard to read for me - my coding style is so different and I am not used to IPB in any other way as well...

Does someone know how IPB really do the unread thing?

Posted: Mon Dec 04, 2006 6:51 pm
by RobertGonzalez
Can you post the section of their code that handles this? You might not be able to because of licensing issues, which is understandable, but if you can, post it and maybe we can translate it.

Posted: Tue Dec 05, 2006 6:05 am
by kaisellgren
Any help?

I found this from my friend's ipb script:

Code: Select all

function get_new_posts()
 	{
		if ( ! $this->ipsclass->member['id'] and ! $this->ipsclass->input['active'] )
		{
			$this->ipsclass->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_results' ) );
		}
		
		//-----------------------------------------
		// Do we have flood control enabled?
		//-----------------------------------------
		
		if ($this->ipsclass->member['g_search_flood'] > 0)
		{
			$flood_time = time() - $this->ipsclass->member['g_search_flood'];
			
			// Get any old search results..
			
			$this->ipsclass->DB->simple_construct( array( 'select' => 'id',
										 				  'from'   => 'search_results',
										 				  'where'  => "(member_id='".$this->ipsclass->member['id']."' OR ip_address='".$this->ipsclass->input['IP_ADDRESS']."') AND search_date > '$flood_time'" ) );
			$this->ipsclass->DB->simple_exec();
			
			if ( $this->ipsclass->DB->get_num_rows() )
			{
				$this->ipsclass->Error( array( 'LEVEL' => 1, 'MSG' => 'search_flood', 'EXTRA' => $this->ipsclass->member['g_search_flood']) );
			}
		}
		
		$last_time = $this->ipsclass->member['last_visit'];
		
		if ( $this->ipsclass->member['members_markers']['board'] > $last_time )
		{
			$last_time = $this->ipsclass->member['members_markers']['board'];
		}
		
		//-----------------------------------------
		// Are we getting 'active topics'?
		//-----------------------------------------
		
		if ( $this->ipsclass->input['active'] )
		{
			if ( $this->ipsclass->input['lastdate'] )
			{
				$last_time = time() - intval($this->ipsclass->input['lastdate']);
			}
			else
			{
				$last_time = time() - 86400;
			}
		}
		
		$this->ipsclass->input['forums'] = 'all';
		$this->ipsclass->input['nav']    = 'lv';
		
		$forums = $this->get_searchable_forums();
		
		//-----------------------------------------
		// Do we have any forums to search in?
		//-----------------------------------------
		
		if ($forums == "")
		{
			$this->ipsclass->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_forum') );
		}
		
		//-----------------------------------------
		// Get the topic ID's to serialize and store into
		// the database
		//-----------------------------------------
		
		$this->ipsclass->DB->simple_construct( array( 'select' => 'count(*) as count', 'from' => 'topics', 'where' => "approved=1 AND state != 'link' AND forum_id IN($forums) AND last_post > '".$last_time."'" ) );
		$this->ipsclass->DB->simple_exec();
		
		$row = $this->ipsclass->DB->fetch_row();
		
		$results = intval($row['count']);
		
		//-----------------------------------------
		// Do we have any results?
		//-----------------------------------------
		
		if ( ! $results )
		{
			//$this->ipsclass->Error( array( 'LEVEL' => 1, 'MSG' => 'no_search_results' ) );
		}
		
		//-----------------------------------------
		// Cache query
		//-----------------------------------------
		
		$this->ipsclass->DB->simple_construct( array( 'select' => 't.*, t.title as topic_title',
													  'from'   => 'topics t',
													  'where'  => "t.approved=1 AND t.state != 'link' AND t.forum_id IN($forums) AND t.last_post > {$last_time}",
													  'order'  => "t.last_post DESC" ) );
		
		
		$query_to_cache = $this->ipsclass->DB->cur_query;
		$this->ipsclass->DB->flush_query();
		
		//-----------------------------------------
		// If we are still here, store the data into the database...
		//-----------------------------------------
		
		$unique_id = md5(uniqid(microtime(),1));
		
		$this->ipsclass->DB->do_insert( 'search_results', array (
												 'id'          => $unique_id,
												 'search_date' => time(),
												 'post_max'    => $results,
												 'sort_key'    => $this->sort_key,
												 'sort_order'  => $this->sort_order,
												 'member_id'   => $this->ipsclass->member['id'],
												 'ip_address'  => $this->ipsclass->input['IP_ADDRESS'],
												 'query_cache' => $query_to_cache
										)        );
		
		$this->ipsclass->boink_it( $this->ipsclass->base_url."act=Search&nav=lv&CODE=show&searchid=$unique_id&search_in=topics&result_type=topics&lastdate={$this->ipsclass->input['lastdate']}" );
	}