How to make a news module in punFramework that uses Topics/Posts?
Concept:
- We specify ID of a forum
- Topics from that forum became news
- Replyes became comments
- Only staff (users you want) can "Post Topics" in that forum (Admin Panel - Forums management)
Topics are stored in PREFIXtopics table. Look at it structure in phpMyAdmin and/or see docs/dev.html for more details.
The last column - "forum_id" - has the forum ID in which the topic is located,
"posted" column stores the date od the topic creation (when the news was added ?).
We will use that data in the query.
- Create Controller called punnews and save it as punnews.php:
<?PHP
class punnews extends punController
{
public function index()
{
$news = punnews::load_model('news');
$query = $news->get_latest_news();
IF(isset($query[0]['id']))
{
$content = '';
foreach($query as $new)
{
$content .= punnews::load_view('latestNews', $new);
}
}
return punnews::render_template('Latest News', $content);
}
}
- We have a simple controller with the default index method. We load "news" model (which we will create in a moment),
then we call "get_latest_news()" method which as the name says will return latest news. Next we check if there is some data and
if we have some date we display it in a foreach. For each news we load a view called "latestNews" and add the result to $content
( .= appends like $foo = $foo.'something news';) and at the end we display the result in a pun default box (render_template)
- Create model news and save it as news.php:
<?PHP
class news extends punRoot
{
public function get_latest_news()
{
return news::query("SELECT * FROM ".$this->db->prefix."topics WHERE forum_id = '1' ORDER BY posted DESC LIMIT 10");
}
}
We have here a SELECT from the topics table. $this->db->prefix is the prefix we specified during the installation. "forum_id = '1'" means that
we will use topics from forum ID 1 as our news. You can change that to other ID (of an existing forum).
"ORDER BY posted DESC LIMIT 10" we order by the posted time descending - newer news at the begening and limit the query to 10 results.
The ::query wrapper returns an associative array with the results
- Create view latestNews.php with the code:
<h1 style="font-size:20px;"><?PHP echo $data['subject']; ?></h1>
<b>Added at:</b>: <?PHP echo date('Y-m-d', $data['posted']); ?>, <b>by</b> <?PHP echo $data['poster']; ?>.
<?PHP
IF($data['num_replies'] > 0)
{
echo $data['num_replies'].' comment/s.';
}
else
{
echo 'No comments yet.';
}
?>
<br /><br />
We just display some data from the table. Our news listing is working now, check mvc.php?c=punnews and you should see a list of our "news"
As you noticed - there is no content as punBB stores topic content in the posts table. We need to modify our query (or make another one).
To select data from two tables "with dependencies" we need to use JOINs.
- Modify query in the model to:
return news::query("SELECT * FROM ".$this->db->prefix."topics AS t LEFT JOIN ".$this->db->prefix."posts AS p ON t.id = p.topic_id WHERE t.forum_id = '1' GROUP BY t.id ORDER BY t.posted DESC LIMIT 10");
We Joined two tables - topics and posts tables, where from the posts table we take only entries that match - "ON t.id = p.topic_id" posts from topic that we selected.
Now if you would "print_r($query);" in the controller you would see that topics have now also data from their first posts - content also.
Modify the view to:
<h1 style="font-size:20px;"><?PHP echo $data['subject']; ?></h1>
<?PHP echo $data['message']; ?>
<br /><b>Added at:</b>: <?PHP echo date('Y-m-d', $data['posted']); ?>, <b>by</b> <?PHP echo $data['poster']; ?>.
<?PHP
IF($data['num_replies'] > 0)
{
echo $data['num_replies'].' comment/s.';
}
else
{
echo 'No comments yet.';
}
?>
<br /><br />
And done - latest 10 news is done... the basics :)
A NOTE: our example code is MySQL specific, it may not work on PostgreSQL or SQLite. punBB solves this having 3 queries ready for each DB type.
It uses $db_type variable to determinate used backend (mysqli, mysql, sqlite, pgsql). Open some punBB files and you will find it for some queries.
In punFramework $db_type is available under $this->db->db_type
visit /mvc.php?c=punnews (if you don't have forum ID 1 then edit the model :))
Other Eample: mvc.php?c=avatarGalery - if you use MySQL and have some users with avatars you will see a list of avatars and basic user data |