'Unread Posts' question

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

'Unread Posts' question

Post 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!
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Post 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...
timclaason
Forum Commoner
Posts: 77
Joined: Tue Dec 16, 2003 9:06 am
Location: WI

Quickest way

Post 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.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Quickest way

Post 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.
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post 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.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Post 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?
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post 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.
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Post 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']}" );
	}
Post Reply