Would like to learn how to add pagination to a SMF SSI function...

Here’s the SSI function. It’s designed fetch all recent topics:

[php]function ssi_recentTopics($num_recent = 8, $exclude_boards = null, $output_method = ‘echo’)
{
global $context, $settings, $scripturl, $txt, $db_prefix, $ID_MEMBER;
global $user_info, $modSettings, $func;

if ($exclude_boards === null && !empty($modSettings['recycle_enable']) && $modSettings['recycle_board'] > 0)
	$exclude_boards = array($modSettings['recycle_board']);
else
	$exclude_boards = empty($exclude_boards) ? array() : $exclude_boards;

$stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
$icon_sources = array();
foreach ($stable_icons as $icon)
	$icon_sources[$icon] = 'images_url';

	// Note that WHERE t.ID_LAST_MSG >= " . ($modSettings['maxMsgID'] - 35 * min($num_recent, 5)) . "

// was replaced with WHERE t.ID_LAST_MSG = m.ID_MSG because it kept cutting out older messages.
// Enjoy

// Find all the posts in distinct topics.  Newer ones will have higher IDs.
$request = db_query("
	SELECT
		m.posterTime, ms.subject, m.ID_TOPIC, m.ID_MEMBER, m.ID_MSG, b.ID_BOARD, b.name AS bName, t.numReplies, t.numViews,
		IFNULL(mem.realName, m.posterName) AS posterName, " . ($user_info['is_guest'] ? '1 AS isRead, 0 AS new_from' : '
		IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, 0)) >= m.ID_MSG_MODIFIED AS isRead,
		IFNULL(lt.ID_MSG, IFNULL(lmr.ID_MSG, -1)) + 1 AS new_from') . ", LEFT(m.body, 384) AS body, m.smileysEnabled, ms.icon
	FROM ({$db_prefix}messages AS m, {$db_prefix}boards AS b)
    INNER JOIN {$db_prefix}topics AS t ON (t.ID_LAST_MSG = m.ID_MSG)
    INNER JOIN {$db_prefix}messages AS ms ON (ms.ID_MSG = t.ID_FIRST_MSG)
		LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = m.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 = $ID_MEMBER)
		LEFT JOIN {$db_prefix}log_mark_read AS lmr ON (lmr.ID_BOARD = b.ID_BOARD AND lmr.ID_MEMBER = $ID_MEMBER)" : '') . "
        
	WHERE b.ID_BOARD = t.ID_BOARD" . (empty($exclude_boards) ? '' : "
		AND b.ID_BOARD NOT IN (" . implode(', ', $exclude_boards) . ")") . "
		AND $user_info[query_see_board]
	ORDER BY t.ID_LAST_MSG DESC
	LIMIT $num_recent", __FILE__, __LINE__);
$posts = array();
while ($row = mysql_fetch_assoc($request))
{
	$row['body'] = strip_tags(strtr(parse_bbc($row['body'], $row['smileysEnabled'], $row['ID_MSG']), array('<br />' => '<br />')));
	if ($func['strlen']($row['body']) > 128)
		$row['body'] = $func['substr']($row['body'], 0, 128) . '...';

	// Censor the subject.
	censorText($row['subject']);
	censorText($row['body']);

	if (empty($modSettings['messageIconChecks_disable']) && !isset($icon_sources[$row['icon']]))
		$icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.gif') ? 'images_url' : 'default_images_url';

	// Build the array.
	$posts[] = array(
		'board' => array(
			'id' => $row['ID_BOARD'],
			'name' => $row['bName'],
			'href' => $scripturl . '?board=' . $row['ID_BOARD'] . '.0',
			'link' => '<a href="' . $scripturl . '?board=' . $row['ID_BOARD'] . '.0">' . $row['bName'] . '</a>'
		),
		'topic' => $row['ID_TOPIC'],
		'poster' => array(
			'id' => $row['ID_MEMBER'],
			'name' => $row['posterName'],
			'href' => empty($row['ID_MEMBER']) ? '' : $scripturl . '?action=profile;u=' . $row['ID_MEMBER'],
			'link' => empty($row['ID_MEMBER']) ? $row['posterName'] : '<a href="' . $scripturl . '?action=profile;u=' . $row['ID_MEMBER'] . '">' . $row['posterName'] . '</a>'
		),
		'subject' => $row['subject'],
		'short_subject' => shorten_subject($row['subject'], 65),
		'preview' => $row['body'],
		'time' => timeformat($row['posterTime']),
		'timestamp' => forum_time(true, $row['posterTime']),
		'href' => $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#new',
		'link' => '<a href="' . $scripturl . '?topic=' . $row['ID_TOPIC'] . '.msg' . $row['ID_MSG'] . '#new">' . shorten_subject($row['subject'], 65) . '</a>',
		'new' => !empty($row['isRead']),
		'new_from' => $row['new_from'],
		'replies' => $row['numReplies'],
		'views' => $row['numViews'],
		'icon' => '<img src="' . $settings[$icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.gif" align="middle" alt="' . $row['icon'] . '" border="0" />',
	);
}
mysql_free_result($request);

// Just return it.
if ($output_method != 'echo' || empty($posts))
	return $posts;

echo '
	<table border="0" class="ssi_table">';
foreach ($posts as $post)
	echo '
		<tr>
			<td align="right" valign="top" nowrap="nowrap">
				[', $post['board']['link'], ']
			</td>
			<td valign="top">
				<a href="', $post['href'], '">', $post['subject'], '</a>
				', $txt[525], ' ', $post['poster']['link'], '
				', $post['new'] ? '' : '<a href="' . $scripturl . '?topic=' . $post['topic'] . '.msg' . $post['new_from'] . ';topicseen#new"><img src="' . $settings['images_url'] . '/' . $context['user']['language'] . '/new.gif" alt="' . $txt[302] . '" border="0" /></a>', '
			</td>
			<td align="right" nowrap="nowrap">
				', $post['time'], '
			</td>
		</tr>';
echo '
	</table>';

}[/php]

How’d I do the whole pagination bit?

Well, without learning ALL of your code and doing the work for you, perhaps I can give you some ideas on how pagination is usually handled…

First, whenever you query a database and SELECT info for display, the returned results are usually ALL of the records you selected. There is a simple way to “limit” it to certain records and record counts. For instance, you can take the first 20 records, the 20 records starting at number 21 (next twenty) or whatever is needed. This is handled using a simple add on to the WHERE clause. Here is an example of the format of the query.

Old query: SELECT * FROM some-table WHERE some-condition…

New query: SELECT * FROM some-table WHERE some-condition LIMIT 20 (Selects first 20 records)

New query: SELECT * FROM some-table WHERE some-condition LIMIT 21, 20 (Selects second 20 records)

So, as you see it is very easy to query a number of records from a table starting at any number and for any count of records. You basically just have to add PREV and NEXT buttons and have the code for these alter the starting record number.

You create a variable, lets call it current_record. Then, set it to zero. ($current_record=0;)
In the code for the PREV button you substract 20 from the current value. ($current_record=$current_record-20;)
And, of course check to make sure you do not go below zero. (if($current_record==0)$current_record=0;)
For the NEXT button you add 20 to the current value. ($current_record=$current_record+20;)
And, of course check to make sure you are not over the max record count of the table. For this you query the number of records in the table and compare. (if($current_record=>$max_number)$current_record=$max_number-20;)

Also, in your display areas where you do the old query, SELECT * FROM, you have to add the limit at the end like SELECT * FROM some-table WHERE some-condition LIMIT $current_record, 20 …

So, that is one way to handle pagination. It is not very hard to implement, just have to think it out ahead. Once you get it in place, let us know if you have any problems. Good luck!

Sponsor our Newsletter | Privacy Policy | Terms of Service