SMF Community Helpers > Mod Development
[MOD] Redirection/Clone Topic
nend:
Ok, lately I have been sharing my code that I have been working on with my websites. While I haven't had time or felt the need to make them into a mod yet, I feel the need to document the changes I am doing in my site if anyone wants to try.
A while back I was thinking of how to make a Topic appear in multiple boards. I couldn't think of anything at the time that didn't require allot of code editing or database strain. So I just backed off and put it in the bottom of my todo list.
Today though I had a breakthrough idea, why instead of creating the topic in multiple boards or using a set, just make a redirect to the original topic. SMF already does this when you move a topic, but not when you create a topic. So what we need is a way to select extra boards the post can show up in while making a post. I don't know how I want to go about this yet, so I am just thinking right now.
nend:
Ok, this is real primitive right now but it works.
SQL
--- Code: ---CREATE TABLE `smf_topic_clones` (
`id_topic` mediumint(8) unsigned NOT NULL,
`id_board` smallint(5) unsigned NOT NULL default '0',
KEY `id_board` (`id_board`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--- End code ---
In /Sources/MessageIndex.php
Find
--- Code: --- // Setup the default topic icons...
$stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless', 'clip');
$context['icon_sources'] = array();
foreach ($stable_icons as $icon)
$context['icon_sources'][$icon] = 'images_url';
$topic_ids = array();
$context['topics'] = array();
--- End code ---
Add After
--- Code: --- // Get the topic ids of clones
$request = $smcFunc['db_query']('', '
SELECT t.id_topic
FROM {db_prefix}topic_clones AS t
WHERE t.id_board = {int:current_board}',
array(
'current_board' => $board
)
);
$clone_topics = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
$clone_topics[] = $row['id_topic'];
--- End code ---
Find
--- Code: --- // Sequential pages are often not optimized, so we add an additional query. nend added a extra or in where
$pre_query = $start > 0;
if ($pre_query && $maxindex > 0)
{
$request = $smcFunc['db_query']('', '
SELECT t.id_topic
FROM {db_prefix}topics AS t' . ($context['sort_by'] === 'last_poster' ? '
INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)' : (in_array($context['sort_by'], array('starter', 'subject')) ? '
INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)' : '')) . ($context['sort_by'] === 'starter' ? '
LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' : '') . ($context['sort_by'] === 'last_poster' ? '
LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' : '') . '
WHERE t.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
' . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
--- End code ---
Add After
--- Code: ---'.($clone_topics ? 'OR t.id_topic IN ({array_int:clone_topics})' : '' ).'
--- End code ---
Find
--- Code: --- ORDER BY ' . (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC') . '
LIMIT {int:start}, {int:maxindex}',
array(
'current_board' => $board,
'current_member' => $user_info['id'],
--- End code ---
Add After
--- Code: --- 'clone_topics' => $clone_topics,
--- End code ---
Find
--- Code: --- // For search engine effectiveness we'll link guests differently.
$context['pageindex_multiplier'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) && !WIRELESS ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
$result = $smcFunc['db_query']('substring', '
SELECT
t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board,
' . ($user_info['is_guest'] ? '0' : 'IFNULL(lt.id_msg, IFNULL(lmr.id_msg, -1)) + 1') . ' AS new_from,
t.id_last_msg, t.approved, t.unapproved_posts, ml.poster_time AS last_poster_time,
ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon,
ml.poster_name AS last_member_name, ml.id_member AS last_id_member,
IFNULL(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg,
mf.poster_time AS first_poster_time, mf.subject AS first_subject, mf.icon AS first_icon,
mf.poster_name AS first_member_name, mf.id_member AS first_id_member,
IFNULL(memf.real_name, mf.poster_name) AS first_display_name, SUBSTRING(ml.body, 1, 385) AS last_body,
SUBSTRING(mf.body, 1, 385) AS first_body, ml.smileys_enabled AS last_smileys, mf.smileys_enabled AS first_smileys
FROM {db_prefix}topics AS t
INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)
LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' . ($user_info['is_guest'] ? '' : '
LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})'). '
WHERE ' . ($pre_query ? 't.id_topic IN ({array_int:topic_list})' : '(t.id_board = {int:current_board})') . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
--- End code ---
Add After
--- Code: ---'.($clone_topics ? 'OR t.id_topic IN ({array_int:clone_topics})' : '' ).'
--- End code ---
Find
--- Code: --- ORDER BY ' . ($pre_query ? 'FIND_IN_SET(t.id_topic, {string:find_set_topics})' : (!empty($modSettings['enableStickyTopics']) ? 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' : '') . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . '
LIMIT ' . ($pre_query ? '' : '{int:start}, ') . '{int:maxindex}',
array(
'current_board' => $board,
'current_member' => $user_info['id'],
'topic_list' => $topic_ids,
'is_approved' => 1,
'find_set_topics' => implode(',', $topic_ids),
--- End code ---
Add After
--- Code: --- 'clone_topics' => $clone_topics,
--- End code ---
Like I mentioned it is real primitive at this time. The only way you can redirect a topic right now is if you add it directly to the database in the "topic_clones" table. Where "id_topic" is the id of the topic you want to clone/redirect and board_id is the target board you want the clone/redirect to show in.
I know I said I was going to go a different route but it proved to be messy also.
Also the stats will not update within a board if you add a cloned/redirect topic.
nend:
Here is a little demo.
http://wrestletopia.2-si.net/n/wade-barrett/
http://wrestletopia.2-si.net/n/cm-punk/
If you look for the topic "Will Wade Barrett be the one to defeat CM Punk?", you will notice it is in both boards but when you click on it you end up in the same topic in the original board.
Labradoodle-360:
Very cool idea, I like it! You should hook up permissions to it and package it. Something new and innovative, not something done a million times already.
nend:
Ok, adding on to it.
In index.php
Find
--- Code: --- 'credits' => array('Who.php', 'Credits'),
'deletemsg' => array('RemoveTopic.php', 'DeleteMessage'),
--- End code ---
Add Before
--- Code: --- 'clonetopic' => array('CloneTopic.php', 'CloneTopic'),
'clonetopic2' => array('CloneTopic.php', 'CloneTopic2'),
--- End code ---
Upload CloneTopic.php to Sources
Upload CloneTopic.template.php to default theme folder.
If you notice allot of this code is borrowed from the movetopic portion of SMF. Allot easier to use something already there. :D
TODO
Make a way to delete topic clones.
I am thinking after you clone a topic, if you go back to clone the topic again it will show all the boards the topic is displayed in and you can remove them from the clone a topic page.
Navigation
[0] Message Index
[#] Next page
Go to full version