3.x/Toon laatste berichten extern

Uit phpBB.nl Wiki
Ga naar: navigatie, zoeken

phpBB3

Het kan handig zijn om de laatste onderwerpen/berichten extern te tonen, bijvoorbeeld op de homepage van je website. Dit is vrij gemakkelijk te realiseren door gebruik te maken van functies in phpBB. In deze uitleg gaan we werken met een pagina die we "home.php" noemen, en geven we deze voorbeelden:

  • Laatste topics weergeven (uit bepaalde forums)
  • Het eerste bericht van het laatste topic weergeven (uit bepaalde forums)
  • De laatste berichten uit bepaalde topics weergeven
  • De laatste berichten van het hele forum weergeven


Bij het weergeven van de berichten wordt rekening gehouden met de permissies.

Header

Allereerst maken we een bestand genaamd home.php en voegen we daaraan de standaard "header information" van phpBB toe. De $phpbb_root_path variabele moet je in jouw geval misschien aanpassen. Als het je het bestand "home.php" in dezelfde map op je server gaat plaatsen als de map waarin je forum staat, dan is het $phpbb_root_path './' en hoef je hem dus niet aan te passen.

Als je phpBB installatie in een andere map op je server staat (bijvoorbeeld http://www.voorbeeld.nl/forum) en je wil het home.php bestand in de root van je website (bijvoorbeeld http://www.voorbeeld.nl/home.php), dan moet je $phpbb_root_path veranderen in:

$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './forum/';

De standaard phpBB header is als volgt:

<?php
/*
* home.php 
* Description: example file for displaying latest posts and topics
* by battye (for phpBB.com MOD Team)
* September 29, 2009
*/

define('IN_PHPBB', true);
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
include($phpbb_root_path . 'common.' . $phpEx);
include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);

// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup('viewforum');

We includen hier ook 'bbcode.php' omdat die nodig kan zijn bij het ophalen van berichten van je forum.

Functies

Het is handig om functies te gebruiken tijdens het ophalen van berichten of topics uit verschillende forums/topics.

<?php
/* create_where_clauses( int[] gen_id, String type )
* This function outputs an SQL WHERE statement for use when grabbing 
* posts and topics */

function create_where_clauses($gen_id, $type)
{
global $db, $auth;

    $size_gen_id = sizeof($gen_id);

        switch($type)
        {
            case 'forum':
                $type = 'forum_id';
                break;
            case 'topic':
                $type = 'topic_id';
                break;
            default:
                trigger_error('No type defined');
        }

    // Set $out_where to nothing, this will be used of the gen_id
    // size is empty, in other words "grab from anywhere" with
    // no restrictions
    $out_where = '';

    if( $size_gen_id > 0 )
    {
    // Get a list of all forums the user has permissions to read
    $auth_f_read = array_keys($auth->acl_getf('f_read', true));

        if( $type == 'topic_id' )
        {
            $sql     = 'SELECT topic_id FROM ' . TOPICS_TABLE . '
                        WHERE ' .  $db->sql_in_set('topic_id', $gen_id) . '
                        AND ' .  $db->sql_in_set('forum_id', $auth_f_read);

            $result     = $db->sql_query($sql);

                while( $row = $db->sql_fetchrow($result) )
                {
                        // Create an array with all acceptable topic ids
                        $topic_id_list[] = $row['topic_id'];
                }

            unset($gen_id);

            $gen_id = $topic_id_list;
            $size_gen_id = sizeof($gen_id);
        }

    $j = 0;    

        for( $i = 0; $i < $size_gen_id; $i++ )
        {
        $id_check = (int) $gen_id[$i];

            // If the type is topic, all checks have been made and the query can start to be built
            if( $type == 'topic_id' )
            {
                $out_where .= ($j == 0) ? 'WHERE ' . $type . ' = ' . $id_check . ' ' : 'OR ' . $type . ' = ' . $id_check . ' ';
            }

            // If the type is forum, do the check to make sure the user has read permissions
            else if( $type == 'forum_id' && $auth->acl_get('f_read', $id_check) )
            {
                $out_where .= ($j == 0) ? 'WHERE ' . $type . ' = ' . $id_check . ' ' : 'OR ' . $type . ' = ' . $id_check . ' ';
            }    

        $j++;
        }
    }

    if( $out_where == '' && $size_gen_id > 0 )
    {
        trigger_error('A list of topics/forums has not been created');
    }

    return $out_where;
}

Forum en topic informatie

We includen nu forum en topic ID's die we zullen gebruiken in de rest van het script. $forum_id en $topic_id zijn allebei arrays die je de mogelijkheid geven om informatie vanuit meerdere bronnen op te halen. De $forum_id_where en $topic_id_where variabelen roepen beide een nieuwe functie aan, create_where_clauses, welke de database queries makkelijker maakt.

$search_limit is het aantal rijen dat je wil ophalem. Dus als je de laatste 5 topics wil ophalen uit de database, moet je $search_limit op 5 zetten.

Als je $forum_id leeg laat, betekent dat dat hij alle posts/topics van het hele forum ophaald in plaats van alleen een bepaald forum. De voorbeelden 3 en 4 laten zien hoe je de laatste berichten van bepaalde forums ophaald en van het hele forum.

<?php
$search_limit = 5;

    $forum_id = array(2, 5);
    $forum_id_where = create_where_clauses($forum_id, 'forum');

    $topic_id = array(20, 50);
    $topic_id_where = create_where_clauses($topic_id, 'topic');

Ophalen van gegevens uit de database

Nu gaan we beginnen met het daadwerkelijk ophalen van gegevens uit de database.

Voorbeeld 1

Het eerste voorbeeld laat zien hoe je de 5 laatste berichten van de bovengenoemde forum(s) ophaald. Een voorbeeld hiervan vindt je op http://www.bilvardsforum.se/ (in het Zweeds).

Laat laatste berichten zien uit bepaalde forums

<?php
$topics = 'SELECT * FROM ' . TOPICS_TABLE . '
            ' . $forum_id_where . '
              AND topic_status <> ' . ITEM_MOVED . '
              AND topic_approved = 1
            ORDER BY topic_id DESC';

   $topics_result = $db->sql_query_limit($topics, $search_limit);

      while( $topics_row = $db->sql_fetchrow($topics_result) )
      {
         $topic_title       = $topics_row['topic_title'];
         $topic_author       = get_username_string('full', $topics_row['topic_poster'], $topics_row['topic_first_poster_name'], $topics_row['topic_first_poster_colour']);
         $topic_date       = $user->format_date($topics_row['topic_time']);
         $topic_last_post    = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topics_row['forum_id'] . '&amp;t=' . $topics_row['topic_id'] . '&amp;p=' . $topics_row['topic_last_post_id']) . '#p' . $topics_row['topic_last_post_id'];
         $topic_last_author    = get_username_string('full', $topics_row['topic_last_poster_id'], $topics_row['topic_last_poster_name'], $topics_row['topic_last_poster_colour']);
         $topic_link       = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topics_row['forum_id'] . '&amp;t=' . $topics_row['topic_id']);

         $template->assign_block_vars('announcements', array(
         'TOPIC_TITLE'       => censor_text($topic_title),
         'TOPIC_AUTHOR'       => $topic_author,
         'TOPIC_DATE'       => $topic_date,
         'TOPIC_LAST_POST'    => $topic_last_post,
         'TOPIC_LAST_AUTHOR' => $topic_last_author,
         'TOPIC_LINK'       => $topic_link,
         ));
      }

Voorbeeld 2

In het volgende voorbeeld wordt het eerste bericht uit de elk van de vijf laatste geposte topics weergegeven. De code is vrijwel hetzelfde, behalve dat deze code ook de tekst (met BBCode) uit het topic ophaald. Een voorbeeld hiervan vind je op http://www.cricketmix.com (in het Engels).

Laat eerste bericht uit de laatste 5 topics

<?php
   $posts_ary = array(
        'SELECT'    => 'p.*, t.*',
    
        'FROM'      => array(
            POSTS_TABLE     => 'p',
        ),
    
        'LEFT_JOIN' => array(
            array(
                'FROM'  => array(TOPICS_TABLE => 't'),
                'ON'    => 't.topic_first_post_id = p.post_id'
            )
        ),
    
        'WHERE'     => str_replace( array('WHERE ', 'forum_id'), array('', 't.forum_id'), $forum_id_where) . '
                        AND t.topic_status <> ' . ITEM_MOVED . '
                        AND t.topic_approved = 1',
    
        'ORDER_BY'  => 'p.post_id DESC',
    );
    
    $posts = $db->sql_build_query('SELECT', $posts_ary);

   $posts_result = $db->sql_query_limit($posts, $search_limit);

      while( $posts_row = $db->sql_fetchrow($posts_result) )
      {
         $topic_title       = $posts_row['topic_title'];
         $topic_author       = get_username_string('full', $posts_row['topic_poster'], $posts_row['topic_first_poster_name'], $posts_row['topic_first_poster_colour']);
         $topic_date       = $user->format_date($posts_row['topic_time']);
         $topic_link       = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $posts_row['forum_id'] . '&amp;t=' . $posts_row['topic_id']);

         $post_text = nl2br($posts_row['post_text']);

         $bbcode = new bbcode(base64_encode($bbcode_bitfield));         
         $bbcode->bbcode_second_pass($post_text, $posts_row['bbcode_uid'], $posts_row['bbcode_bitfield']);

         $post_text = smiley_text($post_text);

         $template->assign_block_vars('announcements', array(
         'TOPIC_TITLE'       => censor_text($topic_title),
         'TOPIC_AUTHOR'       => $topic_author,
         'TOPIC_DATE'       => $topic_date,
         'TOPIC_LINK'       => $topic_link,
         'POST_TEXT'         => censor_text($post_text),
         ));
      }


Voorbeeld 3

Dit derde voorbeeld laat zien hoe je de laatste berichten uit bepaalde topics kan ophalen. Een voorbeeld hiervan is te vinden op http://www.tokiohotelfans.se (in het Zweeds).

Berichten uit bepaalde topics ophalen

<?php
     $posts_ary = array(
        'SELECT'    => 'p.*, t.*, u.username, u.user_colour',
    
        'FROM'      => array(
            POSTS_TABLE     => 'p',
        ),
    
        'LEFT_JOIN' => array(
            array(
                'FROM'  => array(USERS_TABLE => 'u'),
                'ON'    => 'u.user_id = p.poster_id'
            ),
            array(
                'FROM'  => array(TOPICS_TABLE => 't'),
                'ON'    => 'p.topic_id = t.topic_id'
            ),
        ),
    
        'WHERE'     =>  str_replace( array('WHERE ', 'topic_id'), array('', 't.topic_id'), $topic_id_where) . '
                        AND t.topic_status <> ' . ITEM_MOVED . '
                         AND t.topic_approved = 1',
    
        'ORDER_BY'  => 'p.post_id DESC',
    );
    
    $posts = $db->sql_build_query('SELECT', $posts_ary);

   $posts_result = $db->sql_query_limit($posts, $search_limit);

      while( $posts_row = $db->sql_fetchrow($posts_result) )
      {
         $topic_title       = $posts_row['topic_title'];
         $post_author       = get_username_string('full', $posts_row['poster_id'], $posts_row['username'], $posts_row['user_colour']);
         $post_date          = $user->format_date($posts_row['post_time']);
         $post_link       = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $posts_row['forum_id'] . '&amp;t=' . $posts_row['topic_id'] . '&amp;p=' . $posts_row['post_id']) . '#p' . $posts_row['post_id'];

         $post_text = nl2br($posts_row['post_text']);

         $bbcode = new bbcode(base64_encode($bbcode_bitfield));         
         $bbcode->bbcode_second_pass($post_text, $posts_row['bbcode_uid'], $posts_row['bbcode_bitfield']);

         $post_text = smiley_text($post_text);

         $template->assign_block_vars('announcements', array(
         'TOPIC_TITLE'       => censor_text($topic_title),
         'POST_AUTHOR'       => $post_author,
         'POST_DATE'       => $post_date,
         'POST_LINK'       => $post_link,
         'POST_TEXT'         => censor_text($post_text),
         ));
      }


Voorbeeld 4

Als laatste voorbeeld, het ophalen van de laatste berichten uit het hele forum, zonder beperkingen. Een voorbeeld hiervan is te zien op http://www.rmcgirr83.org/ (in het Engels).

Laatste berichten uit het hele forum ophalen

<?php
     $posts_ary = array(
        'SELECT'    => 'p.*, t.*, u.username, u.user_colour',
    
        'FROM'      => array(
            POSTS_TABLE     => 'p',
        ),
    
        'LEFT_JOIN' => array(
            array(
                'FROM'  => array(USERS_TABLE => 'u'),
                'ON'    => 'u.user_id = p.poster_id'
            ),
            array(
                'FROM'  => array(TOPICS_TABLE => 't'),
                'ON'    => 'p.topic_id = t.topic_id'
            ),
        ),
    
        'WHERE'     => $db->sql_in_set('t.forum_id', array_keys($auth->acl_getf('f_read', true))) . '
                        AND t.topic_status <> ' . ITEM_MOVED . '
                         AND t.topic_approved = 1',
    
        'ORDER_BY'  => 'p.post_id DESC',
    );
    
    $posts = $db->sql_build_query('SELECT', $posts_ary);

   $posts_result = $db->sql_query_limit($posts, $search_limit);

      while( $posts_row = $db->sql_fetchrow($posts_result) )
      {
         $topic_title       = $posts_row['topic_title'];
         $post_author       = get_username_string('full', $posts_row['poster_id'], $posts_row['username'], $posts_row['user_colour']);
         $post_date          = $user->format_date($posts_row['post_time']);
         $post_link       = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $posts_row['forum_id'] . '&amp;t=' . $posts_row['topic_id'] . '&amp;p=' . $posts_row['post_id']) . '#p' . $posts_row['post_id'];

         $post_text = nl2br($posts_row['post_text']);

         $bbcode = new bbcode(base64_encode($bbcode_bitfield));         
         $bbcode->bbcode_second_pass($post_text, $posts_row['bbcode_uid'], $posts_row['bbcode_bitfield']);

         $post_text = smiley_text($post_text);

         $template->assign_block_vars('announcements', array(
         'TOPIC_TITLE'       => censor_text($topic_title),
         'POST_AUTHOR'       => $post_author,
         'POST_DATE'       => $post_date,
         'POST_LINK'       => $post_link,
         'POST_TEXT'         => censor_text($post_text),
         ));
      }

Footer en conclusie

Door de SQL query aan te passen kan eigenlijk alles doen omtrent het ophalen van berichten en topics uit je database en ze tonen op pagina's buiten je forum.

Dit is de standaard footer van phpBB, waar je het bestand dus mee afsluit.

<?php
    page_header('External page');

    $template->set_filenames(array(
        'body' => 'external_body.html'
    ));

    page_footer();

Bron

Het orginele (Engelstalige) artikel is hier te vinden: http://wiki.phpbb.com/display/MODDOCS/Practical.Displaying+posts+and+topics+on+external+pages