Page 1 of 3

Ignoring a topic

Posted: Wed Feb 07, 2007 6:13 pm
by RMcGirr83
I have developed a mod that will allow a user to mark a topic as ignored (when the topic is clicked and the topic is ignored a message box shows to ask the user if they would like to ignore the topic and then refreshes back to the topic).

What I am now trying to do is get the topic to show as ignored in search.php as well as when "View new posts since last visit" and where ever else it needs to be included. (Search on author, viewforum, etc.)?

I have stored in a seperate table the topic id as well as the user id. So the question arises how to pull that information when performing a search....possibly inserting [ignored] next to the topic title?

Any advice is greatly appreciated or am I biting off more than I can chew.

TIA

Posted: Wed Feb 07, 2007 6:45 pm
by Joe Belmaati
Well, what I would do would be to query once in search.php:

Build a query that gets the topic_id's from your new table where the user_id = $userdata['user_id']. Make sure you are not querying inside a loop.

Use that resultset to fill an array of ignored topic_id's.

Inside the existing loop that traverses over the returned topics that match the search criteria you can add whatever you want, fx prepend the topic-title with [IGNORED] or whatnot. You would simply do that by adding a little control structure:

Code: Select all

if(in_array($topic_id, $ingnored_topics))
{
  whatever you want to do...
}
I hope that makes some sense. This may seem like a tedious procedure, but for this kind of excersice you really want to pay attention to things like not querying inside loops.

Posted: Wed Feb 07, 2007 6:48 pm
by Brf
How about taking your array and putting it in the initial SQL select...

Code: Select all

'and topic_id not in (' . implode(',',$ignored_topics) . ')'

Posted: Wed Feb 07, 2007 7:01 pm
by RMcGirr83
Thanks for the replies guys.

BRF, correct me if i am wrong but will that not also cause the topics that are ignored to not display?

FWIW here is the code that I have been messing with

Code: Select all

//
// Get ignored topics
//
if ( $userdata['session_logged_in'] )
{
	$sql = "SELECT ignore_topic_id
		FROM " . IGNORETOPIC_TABLE . " 
		WHERE user_id = " . $userdata['user_id'];
	if ( !$result = $db->sql_query($sql) )
	{
		message_die(GENERAL_ERROR, 'Error getting ignore listing', '', __LINE__, __FILE__, $sql);
	}
	$ignoredtopic_ids = array();
	$ignoredtopic_sql = '';
	while( $row = $db->sql_fetchrow($result) )
	{
		$ignoredtopic_ids[$row['ignored_topic_id']] = true;
		$ignoredtopic_sql .= ' , ' . $row['ignored_topic_id'];
	}

    if ( $ignoredtopic_sql != '' )
    {
        $ignoredtopic_sql = ' AND topic_id NOT IN (' . substr($ignoredtopic_sql, 2) . ' )';
    }
}
Thoughts?

Posted: Wed Feb 07, 2007 7:03 pm
by Brf
RMcGirr83 wrote: BRF, correct me if i am wrong but will that not also cause the topics that are ignored to not display?


Yeah. Isnt that what "ignore" means? 8)

I see your loop is trying to do the same thing that implode() already does.

Posted: Wed Feb 07, 2007 7:22 pm
by Joe Belmaati
Personally, I would return those rows becuase you can always ommit them if you decide you don't want them with a simple continue; statement.

Posted: Wed Feb 07, 2007 7:24 pm
by RMcGirr83
:lol:

"Battle of the modders" You both bring up good points ;)

Brf, would you mind expounding on the implode part a bit more?

What would the code then look like? I'm having a tough time, for whatever reason, in seeing it....plus in all actuality I am a php nOOb.

Joe is the code I posted above similar to what you were thinking?

Posted: Wed Feb 07, 2007 7:27 pm
by Brf
Well... that works fine as long as you do not have pagination.

Search only returns like 20 at a time, and if you are skipping some, you might end up with short pages, or some pages with nothing at all on them.

Posted: Wed Feb 07, 2007 7:30 pm
by Brf
Implode glues all your items together into a string.... so

Code: Select all

implode(',',$ignored_topics)
uses "," as the glue, so it returns a comma-delimited string, which is exactly what your loop is returning in $ignoredtopic_sql, without having to strip off the extra leading "," like you had to do.

Posted: Wed Feb 07, 2007 7:31 pm
by drathbun
There are many challenges with search. :)

The one that I believe you will be dealing with is the fact that search result sets can be based on posts or topics. Your ignore feature appears to be based on topics only. Yet if someone searches for posts by a particular user, you would probably still want to ignore (exclude) these topics, yes?

A word of advice, if you would like to consider it: instead of trying to remove the topics from the result set, simply hide the content and allow it to still exist. Adding "exclusion" logic to a query can really slow it down... exclusion logic like "and topic_id NOT IN (1, 2, 3)" is about the worst thing you can do for performance, especially if the list gets long. You can imagine a theoretical example where a user is ignoring 98% of the topics on a board... with 100 topics their exclude list would eliminate 98 of the 100 topics, but would read every single topic before doing so.

If you allow the results to come back but mask the topic title or post content with "you are ignoring me, aren't you?" instead ;-) it will make your life easier. It's just a suggestion; you may have a different goal in mind.

Posted: Wed Feb 07, 2007 7:34 pm
by Brf
drathbun wrote: Adding "exclusion" logic to a query can really slow it down... exclusion logic like "and topic_id NOT IN (1, 2, 3)" is about the worst thing you can do for performance, especially if the list gets long.


Definately!

I was assuming the user was only ignoring a handful or so topics, but if a large number were ignored, it would kill the performance of the query.

Posted: Wed Feb 07, 2007 7:35 pm
by RMcGirr83
Dave, that is exactly what I am trying to do.

Instead of removing the topic from the search just add a simple [ignored] (or whatever) to the end of the topic title....or replace the topic title altogether.

Really appreciate the input guys...thanks again.

Posted: Wed Feb 07, 2007 7:38 pm
by drathbun
Okay, then, I had a different understanding of your approach. I thought you were trying to eliminate the topics from the result set.

You have an array of topic_id values. When it comes time to output those values (there are two parts of the loop, depending on whether you want to output posts or topics) then simply check to see if the result row topic_id exists in your array. If so, replace the title (and post content) with your desired replacement string. That's quite easy; I have just finished doing that for a Post Approval MOD that I'm writing to keep spammer posts from showing up. Give me a sec and I'll post some code from that MOD for you to look at; it should be really close to what you need.

Posted: Wed Feb 07, 2007 7:46 pm
by drathbun
Okay, so in the code you posted you were building something called $ignore_topic_sql which I assumed meant you were going to try to eliminate values from the result set. That's why I posted what I did. Suppose you only use the $ignore_topic_ids array, where each entry uses the topic_id as the key and TRUE as the value. If you look in search.php you will find these lines of code:

Code: Select all

			$message = $searchset[$i]['post_text'];
			$topic_title = $searchset[$i]['topic_title'];
Just after that, simply check something like this:

Code: Select all

			if (isset($ignore_topid_ics[$search_set[$i]['topic_id]]))
			{
				$message = $ignore_message;
				$topic_title = $ignore_title;
			}
That checks to see if your array has an index value for the topic in question, and if so, replaces the message and topic title with some string that you should define. You don't even need your $ignore_topic_sql in this case, which should simplify matters quite a bit.

I think there are several places where $topic_title might be checked, so you might need to do this in more than one place.

Posted: Wed Feb 07, 2007 7:46 pm
by Joe Belmaati
Brf wrote: Well... that works fine as long as you do not have pagination.

Search only returns like 20 at a time, and if you are skipping some, you might end up with short pages, or some pages with nothing at all on them.
Yeah, that's true. You'd probably also end up with alternating row colors that don't alternate properly... did not think of that, but you're absolutely right.