2.8. Displaying Forums and Posts

Both add_forum.php and add_post.php redirect the user to view.php after saving their data to the database. There are three different displays this file can generate: a list of all forums, a list of message threads that make up a particular forum and finally the contents of the messages. By passing parameters in the URL and analyzing them, you are able to determine which display should be generated. Briefly consider these examples:

  • view.php displays the list of all available forums.

  • view.php?fid=1 displays the threads in whatever forum has a primary key 1 in the database.

  • view.php?fid=1&mid2 displays the actual messages that make up thread 2 in forum 1.

Both fid and mid should be validated with each page call, but the database queries can also retrieve information at the same time, such as the forum name and how to construct back-links, if the parameters are valid to show to the user.

$forum_id = (isset($_GET['fid'])) ? (int)$_GET['fid'] : 0;
$msg_id = (isset($_GET['mid'])) ? (int)$_GET['mid'] : 0;

if ($forum_id)
{
    $query = sprintf('SELECT FORUM_NAME FROM %sFORUM WHERE FORUM_ID = %d',
        DB_TBL_PREFIX, $forum_id);
    $result = mysql_query($query, $GLOBALS['DB']);

    if (!mysql_num_rows($result))
    {
        die('<p>Invalid forum id.</p>'),
    }
    $row = mysql_fetch_assoc($result);
    echo '<h1>' . htmlspecialchars($row['FORUM_NAME']) . '</h1>';
    mysql_free_result($result);

    if ($msg_id)
    {
        $query = sprintf('SELECT MESSAGE_ID FROM %sFORUM_MESSAGE ' .
            'WHERE MESSAGE_ID = %d', DB_TBL_PREFIX, $msg_id);
        $result = mysql_query($query, $GLOBALS['DB']);

        if (!mysql_num_rows($result))
        {
            mysql_free_result($result);
            die('<p>Invalid forum id.</p>'),
        }
        mysql_free_result($result);

        // link back to thread view
        echo '<p><a href="view.php?fid=' . $forum_id . '">Back to forum ' .
            'threads.</a></p>';
    }

else
    {
        // link back to forum list
        echo '<p><a href="view.php">Back to forum list.</a></p>';
    }
}
else
{
    echo '<h1>Forums</h1>';
}

The $_SESSION array can be checked to see if a user has logged on, and if so then a link to add_post.php should be provided so he or she can add new messages. Additionally, the user's permissions can be tested to see if the User::CREATE_FORUM permission bit is set. If he or she is allowed to create new forums, then a link to add_forum.php should also be generated.

if (isset($_SESSION['access']))
{
    echo '<p><a href="add_post.php?fid=' . $forum_id . '">Post new ' .
        'message.</a></p>';
}

if (isset($_SESSION['userId']))
{
    $user = User::getById($_SESSION['userId']);
    if ($user->permission & User::CREATE_FORUM)
    {
        echo '<p><a href="add_forum.php">Create new forum.</a></p>';
    }
}

However you decide to style the display is your decision, but ultimately, generating the forum view is as simple as displaying a list of all available forums and their descriptions as links to the user.

$query = sprintf('SELECT FORUM_ID, FORUM_NAME, DESCRIPTION FROM %sFORUM ' .
        'ORDER BY FORUM_NAME ASC, FORUM_ID ASC', DB_TBL_PREFIX);
$result = mysql_query($query, $GLOBALS['DB']);

echo '<ul>';
while ($row = mysql_fetch_assoc($result))
{
    echo '<li><a href="' . htmlspecialchars($_SERVER['PHP_SELF']);
    echo '?fid=' . $row['FORUM_ID'] . '">';
    echo htmlspecialchars($row['FORUM_NAME']) . ': ';
    echo htmlspecialchars($row['DESCRIPTION']) . '</li>';
}
echo '</ul>';
mysql_free_result($result);

Similarly, the thread view should retrieve a list of messages whose record has a PARENT_MESSAGE_ID of 0 for the selected forum.

$query = sprintf('SELECT MESSAGE_ID, SUBJECT, ' .
    'UNIX_TIMESTAMP(MESSAGE_DATE) AS MESSAGE_DATE FROM %sFORUM_MESSAGE ' .
    'WHERE PARENT_MESSAGE_ID = 0 AND FORUM_ID = %d ORDER BY ' .
    'MESSAGE_DATE DESC', DB_TBL_PREFIX, $forum_id);
$result = mysql_query($query, $GLOBALS['DB']);

if (mysql_num_rows($result))
{
    echo '<ul>';
    while ($row = mysql_fetch_assoc($result))
    {
        echo '<li><a href="view.php?fid=' . $forum_id . '&mid=' .
            $row['MESSAGE_ID'] . '">';
        echo date('m/d/Y', $row['MESSAGE_DATE']) . ': ';
        echo htmlspecialchars($row['SUBJECT']) . '</li>';
    }
    echo '</ul>';
}
else
{
    echo '<p>This forum contains no messages.</p>';
}
mysql_free_result($result);

The message view shows all the messages that make up a particular thread. The query is a bit more complex than those used in the other views because it contains a JOIN clause to join the WROX_USER table to retrieve the message's author information as well.

$query = sprintf('
SELECT
    USERNAME, FORUM_ID, MESSAGE_ID, PARENT_MESSAGE_ID,
    SUBJECT, MESSAGE_TEXT, UNIX_TIMESTAMP(MESSAGE_DATE) AS MESSAGE_DATE
FROM
    %sFORUM_MESSAGE M JOIN %sUSER U
        ON M.USER_ID = U.USER_ID
WHERE
    MESSAGE_ID = %d OR
    PARENT_MESSAGE_ID = %d
ORDER BY
    MESSAGE_DATE ASC',
    DB_TBL_PREFIX,
    DB_TBL_PREFIX,
    $msg_id,
    $msg_id);

$result = mysql_query($query, $GLOBALS['DB']);

echo '<table border=1>';

while ($row = mysql_fetch_assoc($result))
{
    echo '<tr>';
    echo '<td style="text-align:center; vertical-align:top; width:150px;">';
    if (file_exists('avatars/' . $row['USERNAME'] . 'jpg')
    {
        echo '<img src="avatars/' . $row['USERNAME'] . '.jpg" />';
    }
    else
    {
        echo '<img src="img/default_avatar.jpg" />';
    }
    echo '<br/><strong>' . $row['USERNAME'] . '</strong><br/>';
    echo date('m/d/Y<
/>H:i:s', $row['MESSAGE_DATE']) . '</td>';
    echo '<td style="vertical-align:top;">';
    echo '<div><strong>' . htmlspecialchars($row['SUBJECT']) .
        '</strong></div>';
    echo '<div>' . htmlspecialchars($row['MESSAGE_TEXT']) . '</div>';
    echo '<div style="text-align: right;">';
    echo '<a href="add_post.php?fid=' . $row['FORUM_ID'] . '&mid=' .
        (($row['PARENT_MESSAGE_ID'] != 0) ? $row['PARENT_MESSAGE_ID'] :
        $row['MESSAGE_ID']) . '">Reply</a></div></td>';
    echo '</tr>';
}
echo '</table>';
mysql_free_result($result);

Here is the complete code for view.php:

<?php
// include shared code
include '../lib/common.php';
include '../lib/db.php';
include '../lib/functions.php';
include '../lib/User.php';

// start or continue session
session_start();

// validate incoming values
$forum_id = (isset($_GET['fid'])) ? (int)$_GET['fid'] : 0;
$msg_id = (isset($_GET['mid'])) ? (int)$_GET['mid'] : 0;

ob_start();
if ($forum_id)
{
    // display forum name as header
    $query = sprintf('SELECT FORUM_NAME FROM %sFORUM WHERE FORUM_ID = %d',
        DB_TBL_PREFIX, $forum_id);
    $result = mysql_query($query, $GLOBALS['DB']);

    if (!mysql_num_rows($result))

{
        die('<p>Invalid forum id.</p>'),
    }
    $row = mysql_fetch_assoc($result);
    echo '<h1>' . htmlspecialchars($row['FORUM_NAME']) . '</h1>';
    mysql_free_result($result);

    if ($msg_id)
    {
        $query = sprintf('SELECT MESSAGE_ID FROM %sFORUM_MESSAGE ' .
            'WHERE MESSAGE_ID = %d', DB_TBL_PREFIX, $msg_id);
        $result = mysql_query($query, $GLOBALS['DB']);

        if (!mysql_num_rows($result))
        {
            mysql_free_result($result);
            die('<p>Invalid forum id.</p>'),
        }
        mysql_free_result($result);

        // link back to thread view
        echo '<p><a href="view.php?fid=' . $forum_id . '">Back to forum ' .
            'threads.</a></p>';
    }
    else
    {
        // link back to forum list
        echo '<p><a href="view.php">Back to forum list.</a></p>';

        // display option to add new post if user is logged in
        if (isset($_SESSION['access']))
        {
            echo '<p><a href="add_post.php?fid=' . $forum_id . '">Post new ' .
                'message.</a></p>';
        }
    }
}
else
{
    echo '<h1>Forums</h1>';
    if (isset($_SESSION['userId']))
    {
        // display link to create new forum if user has permissions to do so
        $user = User::getById($_SESSION['userId']);
        if ($user->permission & User::CREATE_FORUM)
        {
            echo '<p><a href="add_forum.php">Create new forum.</a></p>';
        }
    }
}

// generate message view

if ($forum_id && $msg_id)
{
    $query = sprintf('
SELECT
    USERNAME, FORUM_ID, MESSAGE_ID, PARENT_MESSAGE_ID,
    SUBJECT, MESSAGE_TEXT, UNIX_TIMESTAMP(MESSAGE_DATE) AS MESSAGE_DATE
FROM
    %sFORUM_MESSAGE M JOIN %sUSER U
        ON M.USER_ID = U.USER_ID
WHERE
    MESSAGE_ID = %d OR
    PARENT_MESSAGE_ID = %d
ORDER BY
    MESSAGE_DATE ASC',
    DB_TBL_PREFIX,
    DB_TBL_PREFIX,
    $msg_id,
    $msg_id);

    $result = mysql_query($query, $GLOBALS['DB']);

    echo '<table border=1>';
    while ($row = mysql_fetch_assoc($result))
    {
        echo '<tr>';
        echo '<td style="text-align:center; vertical-align:top; width:150px;">';
        if (file_exists('avatars/' . $row['USERNAME'] . 'jpg')
        {
            echo '<img src="avatars/' . $row['USERNAME'] . '.jpg" />';
        }
        else
        {
            echo '<img src="img/default_avatar.jpg" />';
        }
        echo '<br/><strong>' . $row['USERNAME'] . '</strong><br/>';
        echo date('m/d/Y<
/>H:i:s', $row['MESSAGE_DATE']) . '</td>';
        echo '<td style="vertical-align:top;">';
        echo '<div><strong>' . htmlspecialchars($row['SUBJECT']) .
            '</strong></div>';
        echo '<div>' . htmlspecialchars($row['MESSAGE_TEXT']) . '</div>';
        echo '<div style="text-align: right;">';
        echo '<a href="add_post.php?fid=' . $row['FORUM_ID'] . '&mid=' .
            (($row['PARENT_MESSAGE_ID'] != 0) ? $row['PARENT_MESSAGE_ID'] :
            $row['MESSAGE_ID']) . '">Reply</a></div></td>';
        echo '</tr>';
    }
    echo '</table>';
    mysql_free_result($result);
}

// generate thread view
else if ($forum_id)
{

    $query = sprintf('SELECT MESSAGE_ID, SUBJECT, ' .
        'UNIX_TIMESTAMP(MESSAGE_DATE) AS MESSAGE_DATE FROM %sFORUM_MESSAGE ' .
        'WHERE PARENT_MESSAGE_ID = 0 AND FORUM_ID = %d ORDER BY ' .
        'MESSAGE_DATE DESC', DB_TBL_PREFIX, $forum_id);
    $result = mysql_query($query, $GLOBALS['DB']);

    if (mysql_num_rows($result))
    {
        echo '<ul>';
        while ($row = mysql_fetch_assoc($result))
        {
            echo '<li><a href="view.php?fid=' . $forum_id . '&mid=' .
                $row['MESSAGE_ID'] . '">';
            echo date('m/d/Y', $row['MESSAGE_DATE']) . ': ';
            echo htmlspecialchars($row['SUBJECT']) . '</li>';
        }
        echo '</ul>';
    }
    else
    {
        echo '<p>This forum contains no messages.</p>';
    }
    mysql_free_result($result);
}
// generate forums view
else
{
    $query = sprintf('SELECT FORUM_ID, FORUM_NAME, DESCRIPTION FROM %sFORUM ' .
            'ORDER BY FORUM_NAME ASC, FORUM_ID ASC', DB_TBL_PREFIX);
    $result = mysql_query($query, $GLOBALS['DB']);

    echo '<ul>';
    while ($row = mysql_fetch_assoc($result))
    {
        echo '<li><a href="' . htmlspecialchars($_SERVER['PHP_SELF']);
        echo '?fid=' . $row['FORUM_ID'] . '">';
        echo htmlspecialchars($row['FORUM_NAME']) . ': ';
        echo htmlspecialchars($row['DESCRIPTION']) . '</li>';
    }
    echo '</ul>';
    mysql_free_result($result);
}
$GLOBALS['TEMPLATE']['content'] = ob_get_lean();

// display the page
include '../templates/template-page.php';
?>

Figure 2-2 shows the first view, a list of all available forums, Figure 2-3 shows the list of threads in a particular forum and Figure 2-4 shows the contents of the messages.

Figure 2-2. Figure 2-2

Figure 2-3. Figure 2-3

Figure 2-4. Figure 2-4

2.8.1. Pagination

Using the forum will become cumbersome as the number of threads and messages grows. To keep things manageable, you may want to implement some sort of pagination.

There are essentially two steps to add pagination. First, an additional parameter needs to be passed in the URL to identify the starting offset in the record set. Then links are generated, which allows the user to navigate to the next or previous pages. Either mysql_data_seek() can be used to move the result cursor to the appropriate offset, or a LIMIT clause can be appended to the SQL statement.

Most tutorials teach the LIMIT method, but keep in mind that 1) LIMIT is non-standard SQL and 2) if you choose to use LIMIT then you'll need to send a query to the database beforehand to determine the total number of records so you can create the appropriate links. I much prefer fetching the records, finding the total number of results using mysql_num_rows() and then moving to the appropriate offset with mysql_data_seek(), which saves me from making an additional query.

$display = 25;  // paginate showing 25 entries per page

$query = sprintf('SELECT MESSAGE_ID, SUBJECT, ' .
    'UNIX_TIMESTAMP(MESSAGE_DATE) AS MESSAGE_DATE FROM %sFORUM_MESSAGE ' .
    'WHERE PARENT_MESSAGE_ID = 0 AND FORUM_ID = %d ORDER BY ' .
    'MESSAGE_DATE DESC', DB_TBL_PREFIX, $forum_id);
$result = mysql_query($query, $GLOBALS['DB']);

if ($total = mysql_num_rows($result))

{
    // accept the display offset
    $start = (isset($_GET['start']) && ctype_digit($_GET['start']) &&
        $_GET['start'] <= $total) ? $_GET['start'] : 0;

    // move the data pointer to the appropriate starting record
    mysql_data_seek($start);

    // display entries
    echo '<ul>';
    $count = 0;
    while ($row = mysql_fetch_assoc($result) && $count++ < $display)
    {
        echo '<li><a href="view.php?fid=' . $forum_id . '&mid=' .
            $row['MESSAGE_ID'] . '">';
        echo date('m/d/Y', $row['MESSAGE_DATE']) . ': ';
        echo htmlspecialchars($row['SUBJECT']) . '</li>';
    }
    echo '</ul>';

    // Generate the paginiation menu.
    echo '<p>';
    if ($start > 0)
    {
        echo '<a href="view.php?fid=' . $form_id . '&start=0">' .
            'FIRST</a> ';
        echo '<a href="view.php?fid=' . $forum_id . '&start=' .
            ($start - $display) . '">&lt;PREV</a>';
    }
    if ($total > ($start + $display))
    {
        echo '<a href="view.php?fid=' . $forum_id . '&start=' .
            ($start + $display) . '">NEXT&gt;</a> ';
        echo '<a href="view.php?fid=' . $form_id . '&start=' .
            ($total - $display) . '">LAST</a>';
    }
    echo '</p>';
}
else
{
    echo '<p>This forum contains no messages.</p>';
}
mysql_free_result($result);

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.193.124