News:

Want to get involved in developing SMF, then why not lend a hand on our github!

Main Menu

How to mark MOVED topic as read

Started by floydpink, June 09, 2010, 12:32:42 AM

Previous topic - Next topic

floydpink

SMF 1.1.11
Whenever a topic is moved the MOVED post that is created in the original board gets marked as unread by all members. It therefore appears in everyone's unread posts list which is silly as they don't want to read the standard MOVED message at all.

How can the newly created MOVED message be marked as read by all users when it is created? I'm guessing it can be done in MoveTopic.php, but not quite sure how. When the MOVED post gets created using subs_post.php [createpos()] the post is set as read for the person doing the post only. Can it be done using the this part of the MoveTopic function? // Move over the mark_read data. (because it may be read and now not by some!)
$SaveAServer = max(0, $modSettings['maxMsgID'] - 50000);
$request = db_query("
SELECT lmr.ID_MEMBER, lmr.ID_MSG, t.ID_TOPIC
FROM ({$db_prefix}topics AS t, {$db_prefix}log_mark_read AS lmr)
LEFT JOIN {$db_prefix}log_topics AS lt ON (lt.ID_TOPIC = t.ID_TOPIC AND lt.ID_MEMBER = lmr.ID_MEMBER)
WHERE t.ID_TOPIC $condition
AND lmr.ID_BOARD = t.ID_BOARD
AND lmr.ID_MSG > t.ID_FIRST_MSG
AND lmr.ID_MSG > $SaveAServer
AND lmr.ID_MSG > IFNULL(lt.ID_MSG, 0)", __FILE__, __LINE__);
$log_topics = array();
while ($row = mysql_fetch_assoc($request))
{
$log_topics[] = '(' . $row['ID_TOPIC'] . ', ' . $row['ID_MEMBER'] . ', ' . $row['ID_MSG'] . ')';

// Prevent queries from getting too big. Taking some steam off.
if (count($log_topics) > 500)
{
db_query("
REPLACE INTO {$db_prefix}log_topics
(ID_TOPIC, ID_MEMBER, ID_MSG)
VALUES " . implode(',
', $log_topics), __FILE__, __LINE__);
$log_topics = array();
}
}
mysql_free_result($request);

// Now that we have all the topics that *should* be marked read, and by which members...
if (!empty($log_topics))
{
// Insert that information into the database!
db_query("
REPLACE INTO {$db_prefix}log_topics
(ID_TOPIC, ID_MEMBER, ID_MSG)
VALUES " . implode(',
', $log_topics), __FILE__, __LINE__);
}


Any help much appreciated.

Arantor

How many members in your forum? 100? 1000?

For *every* *single* *member*, that's a row that has to be added to the log_topics table. Which means for 100 members, that's 100 rows. You'll also have to do another query to actually get every single member id too.

floydpink

350
Won't those rows get created anyway over time as each member views the post?

Arantor

Sure they will. Assuming everyone actually reads it - which not everyone will.

But there's a difference in suddenly throwing 350 rows into a table every time you move a topic, and it being added gradually over time, especially since it'll actually disappear out of the unread list soon enough anyway (unless they go for 'all unread')

I'd point out that even the above doesn't move the entire read history, only part of it, deliberately for performance reasons.


If you're really determined to do this, the bit of code you're doing it in is actually not the right part of the file.

Code (find) Select
createPost($msgOptions, $topicOptions, $posterOptions);

Code (after it, add) Select

$query = db_query("SELECT ID_MEMBER FROM {$db_prefix}members", __FILE__, __LINE__);
$force_read_members = array();
while ($row = mysql_fetch_row($query))
$force_read_members[] = '(' . $topicOptions['id'] . ',' . $row[0] . ',' . $msgOptions['id'] . ')';
mysql_free_result($query);

db_query("
REPLACE INTO {$db_prefix}log_topics
(ID_TOPIC, ID_MEMBER, ID_MSG)
VALUES " . implode(',
', $force_read_members), __FILE__, __LINE__);

floydpink

Many thanks for the detailed and full response.
Maybe it would be better then to leave the MOVED messages as unread, but change recent.php to not include them in the list of recent posts (filtering for the subject text starting with  'MOVED:'). They'd still appear as unread in the Boards, but would eventually dissapear anyway. It a bit hackish for the programmer in me and I'd originally assumed that would be less efficient than a database update, but maybe its the better solution for the users. What do you think?

Arantor

There are better ways of doing it than searching on the MOVED text, instead searching on the message icon (since that way it's language independent)

In that situation it's probably worse if you have a lot of people using the unread/unreadreplies because filtering on a textual column is slow, and on an already slow piece of code, it's just going to be slower. Probably slower than the above hack is really, if a decent proportion of your 350 users regularly uses Recent.php-powered code.

Advertisement: