punbb/extern.php
changeset 6 5e1f1e916419
parent 5 e3d7322305bf
child 7 98bbc533541c
equal deleted inserted replaced
5:e3d7322305bf 6:5e1f1e916419
     1 <?php
       
     2 /***********************************************************************
       
     3 
       
     4   Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
       
     5 
       
     6   This file is part of PunBB.
       
     7 
       
     8   PunBB is free software; you can redistribute it and/or modify it
       
     9   under the terms of the GNU General Public License as published
       
    10   by the Free Software Foundation; either version 2 of the License,
       
    11   or (at your option) any later version.
       
    12 
       
    13   PunBB is distributed in the hope that it will be useful, but
       
    14   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    16   GNU General Public License for more details.
       
    17 
       
    18   You should have received a copy of the GNU General Public License
       
    19   along with this program; if not, write to the Free Software
       
    20   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
       
    21   MA  02111-1307  USA
       
    22 
       
    23 ************************************************************************
       
    24 
       
    25 
       
    26   INSTRUCTIONS
       
    27 
       
    28   This script is used to include information about your board from
       
    29   pages outside the forums and to syndicate news about recent
       
    30   discussions via RSS. The script can display a list of recent
       
    31   discussions (sorted by post time or last post time), a list of
       
    32   active users or a collection of general board statistics. The
       
    33   script can be called directly via an URL (for RSS), from a PHP
       
    34   include command or through the use of Server Side Includes (SSI).
       
    35 
       
    36   The scripts behaviour is controlled via variables supplied in the
       
    37   URL to the script. The different variables are: action (what to
       
    38   output), show (how many topics to display), fid (the ID or ID's of
       
    39   the forum(s) to poll for topics), nfid (the ID or ID's of forums
       
    40   that should be excluded) and type (output as HTML or RSS). The
       
    41   only mandatory variable is action. Possible/default values are:
       
    42 
       
    43     action: active (show most recently active topics) (HTML or RSS)
       
    44             new (show newest topics) (HTML or RSS)
       
    45             online (show users online) (HTML)
       
    46             online_full (as above, but includes a full list) (HTML)
       
    47             stats (show board statistics) (HTML)
       
    48 
       
    49     show:   Any integer value between 1 and 50. This variables is
       
    50             ignored for RSS output. The default is 15.
       
    51 
       
    52     fid:    One or more forum ID's (comma-separated). If ignored,
       
    53             topics from all guest-readable forums will be polled.
       
    54 
       
    55     nfid:   One or more forum ID's (comma-separated) that are to be
       
    56             excluded. E.g. the ID of a a test forum.
       
    57 
       
    58     type:   RSS. Anything else means HTML output.
       
    59 
       
    60   Here are some examples using PHP include().
       
    61 
       
    62     Show the 15 most recently active topics from all forums:
       
    63     include('http://host.com/forums/extern.php?action=active');
       
    64 
       
    65     Show the 10 newest topics from forums with ID 5, 6 and 7:
       
    66     include('http://host.com/forums/extern.php?action=new&show=10&fid=5,6,7');
       
    67 
       
    68     Show users online:
       
    69     include('http://host.com/forums/extern.php?action=online');
       
    70 
       
    71     Show users online with full listing of users:
       
    72     include('http://host.com/forums/extern.php?action=online_full');
       
    73 
       
    74     Show board statistics:
       
    75     include('http://host.com/forums/extern.php?action=stats');
       
    76 
       
    77   Here are some examples using SSI.
       
    78 
       
    79     Show the 5 newest topics from forums with ID 11 and 22:
       
    80     <!--#include virtual="forums/extern.php?action=new&show=5&fid=11,22" -->
       
    81 
       
    82     Show board statistics:
       
    83     <!--#include virtual="forums/extern.php?action=stats" -->
       
    84 
       
    85   And finally some examples using extern.php to output an RSS 0.91
       
    86   feed.
       
    87 
       
    88     Output the 15 most recently active topics:
       
    89     http://host.com/extern.php?action=active&type=RSS
       
    90 
       
    91     Output the 15 newest topics from forum with ID=2:
       
    92     http://host.com/extern.php?action=active&type=RSS&fid=2
       
    93 
       
    94   Below you will find some variables you can edit to tailor the
       
    95   scripts behaviour to your needs.
       
    96 
       
    97 
       
    98 /***********************************************************************/
       
    99 
       
   100 // The maximum number of topics that will be displayed
       
   101 $show_max_topics = 60;
       
   102 
       
   103 // The length at which topic subjects will be truncated (for HTML output)
       
   104 $max_subject_length = 30;
       
   105 
       
   106 /***********************************************************************/
       
   107 
       
   108 // DO NOT EDIT ANYTHING BELOW THIS LINE! (unless you know what you are doing)
       
   109 
       
   110 
       
   111 define('PUN_ROOT', './');
       
   112 @include PUN_ROOT.'config.php';
       
   113 
       
   114 // If PUN isn't defined, config.php is missing or corrupt
       
   115 if (!defined('PUN'))
       
   116 	exit('The file \'config.php\' doesn\'t exist or is corrupt. Please run install.php to install PunBB first.');
       
   117 
       
   118 
       
   119 // Make sure PHP reports all errors except E_NOTICE
       
   120 error_reporting(E_ALL ^ E_NOTICE);
       
   121 
       
   122 // Turn off magic_quotes_runtime
       
   123 set_magic_quotes_runtime(0);
       
   124 
       
   125 
       
   126 // Load the functions script
       
   127 require PUN_ROOT.'include/functions.php';
       
   128 
       
   129 // Load DB abstraction layer and try to connect
       
   130 require PUN_ROOT.'include/dblayer/common_db.php';
       
   131 
       
   132 // Load cached config
       
   133 @include PUN_ROOT.'cache/cache_config.php';
       
   134 if (!defined('PUN_CONFIG_LOADED'))
       
   135 {
       
   136     require PUN_ROOT.'include/cache.php';
       
   137     generate_config_cache();
       
   138     require PUN_ROOT.'cache/cache_config.php';
       
   139 }
       
   140 
       
   141 // Make sure we (guests) have permission to read the forums
       
   142 $result = $pun_db->query('SELECT g_read_board FROM '.$pun_db->prefix.'groups WHERE g_id=3') or error('Unable to fetch group info', __FILE__, __LINE__, $pun_db->error());
       
   143 if ($pun_db->result($result) == '0')
       
   144 	exit('No permission');
       
   145 
       
   146 
       
   147 // Attempt to load the common language file
       
   148 @include PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/common.php';
       
   149 if (!isset($lang_common))
       
   150 	exit('There is no valid language pack \''.$pun_config['o_default_lang'].'\' installed. Please reinstall a language of that name.');
       
   151 
       
   152 // Check if we are to display a maintenance message
       
   153 if ($pun_config['o_maintenance'] && !defined('PUN_TURN_OFF_MAINT'))
       
   154 	maintenance_message();
       
   155 
       
   156 if (!isset($_GET['action']))
       
   157 	exit('No parameters supplied. See extern.php for instructions.');
       
   158 
       
   159 
       
   160 //
       
   161 // Converts the CDATA end sequence ]]> into ]]&gt;
       
   162 //
       
   163 function escape_cdata($str)
       
   164 {
       
   165 	return str_replace(']]>', ']]&gt;', $str);
       
   166 }
       
   167 
       
   168 
       
   169 //
       
   170 // Show recent discussions
       
   171 //
       
   172 if ($_GET['action'] == 'active' || $_GET['action'] == 'new')
       
   173 {
       
   174 	$order_by = ($_GET['action'] == 'active') ? 't.last_post' : 't.posted';
       
   175 	$forum_sql = '';
       
   176 
       
   177 	// Was any specific forum ID's supplied?
       
   178 	if (isset($_GET['fid']) && $_GET['fid'] != '')
       
   179 	{
       
   180 		$fids = explode(',', trim($_GET['fid']));
       
   181 		$fids = array_map('intval', $fids);
       
   182 
       
   183 		if (!empty($fids))
       
   184 			$forum_sql = ' AND f.id IN('.implode(',', $fids).')';
       
   185 	}
       
   186 
       
   187 	// Any forum ID's to exclude?
       
   188 	if (isset($_GET['nfid']) && $_GET['nfid'] != '')
       
   189 	{
       
   190 		$nfids = explode(',', trim($_GET['nfid']));
       
   191 		$nfids = array_map('intval', $nfids);
       
   192 
       
   193 		if (!empty($nfids))
       
   194 			$forum_sql = ' AND f.id NOT IN('.implode(',', $nfids).')';
       
   195 	}
       
   196 
       
   197 	// Should we output this as RSS?
       
   198 	if (isset($_GET['type']) && strtoupper($_GET['type']) == 'RSS')
       
   199 	{
       
   200 		$rss_description = ($_GET['action'] == 'active') ? $lang_common['RSS Desc Active'] : $lang_common['RSS Desc New'];
       
   201 		$url_action = ($_GET['action'] == 'active') ? '&amp;action=new' : '';
       
   202 
       
   203 		// Send XML/no cache headers
       
   204 		header('Content-Type: text/xml');
       
   205 		header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
       
   206 		header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
       
   207 		header('Pragma: public');
       
   208 
       
   209 		// It's time for some syndication!
       
   210 		echo '<?xml version="1.0" encoding="'.$lang_common['lang_encoding'].'"?>'."\r\n";
       
   211 		echo '<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">'."\r\n";
       
   212 		echo '<rss version="0.91">'."\r\n";
       
   213 		echo '<channel>'."\r\n";
       
   214 		echo "\t".'<title>'.pun_htmlspecialchars($pun_config['o_board_title']).'</title>'."\r\n";
       
   215 		echo "\t".'<link>'.$pun_config['o_base_url'].'/</link>'."\r\n";
       
   216 		echo "\t".'<description>'.pun_htmlspecialchars($rss_description.' '.$pun_config['o_board_title']).'</description>'."\r\n";
       
   217 		echo "\t".'<language>en-us</language>'."\r\n";
       
   218 
       
   219 		// Fetch 15 topics
       
   220 		$result = $pun_db->query('SELECT t.id, t.poster, t.subject, t.posted, t.last_post, f.id AS fid, f.forum_name FROM '.$pun_db->prefix.'topics AS t INNER JOIN '.$pun_db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$pun_db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.$order_by.' DESC LIMIT 15') or error('Unable to fetch topic list', __FILE__, __LINE__, $pun_db->error());
       
   221 
       
   222 		while ($cur_topic = $pun_db->fetch_assoc($result))
       
   223 		{
       
   224 			if ($pun_config['o_censoring'] == '1')
       
   225 				$cur_topic['subject'] = censor_words($cur_topic['subject']);
       
   226 
       
   227 			echo "\t".'<item>'."\r\n";
       
   228 			echo "\t\t".'<title>'.pun_htmlspecialchars($cur_topic['subject']).'</title>'."\r\n";
       
   229 			echo "\t\t".'<link>'.$pun_config['o_base_url'].'/viewtopic.php?id='.$cur_topic['id'].$url_action.'</link>'."\r\n";
       
   230 			echo "\t\t".'<description><![CDATA['.escape_cdata($lang_common['Forum'].': <a href="'.$pun_config['o_base_url'].'/viewforum.php?id='.$cur_topic['fid'].'">'.$cur_topic['forum_name'].'</a><br />'."\r\n".$lang_common['Author'].': '.$cur_topic['poster'].'<br />'."\r\n".$lang_common['Posted'].': '.date('r', $cur_topic['posted']).'<br />'."\r\n".$lang_common['Last post'].': '.date('r', $cur_topic['last_post'])).']]></description>'."\r\n";
       
   231 			echo "\t".'</item>'."\r\n";
       
   232 		}
       
   233 
       
   234 		echo '</channel>'."\r\n";
       
   235 		echo '</rss>';
       
   236 	}
       
   237 
       
   238 
       
   239 	// Output regular HTML
       
   240 	else
       
   241 	{
       
   242 		$show = isset($_GET['show']) ? intval($_GET['show']) : 15;
       
   243 		if ($show < 1 || $show > 50)
       
   244 			$show = 15;
       
   245 
       
   246 		// Fetch $show topics
       
   247 		$result = $pun_db->query('SELECT t.id, t.subject FROM '.$pun_db->prefix.'topics AS t INNER JOIN '.$pun_db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$pun_db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.$order_by.' DESC LIMIT '.$show) or error('Unable to fetch topic list', __FILE__, __LINE__, $pun_db->error());
       
   248 
       
   249 		while ($cur_topic = $pun_db->fetch_assoc($result))
       
   250 		{
       
   251 			if ($pun_config['o_censoring'] == '1')
       
   252 				$cur_topic['subject'] = censor_words($cur_topic['subject']);
       
   253 
       
   254 			if (pun_strlen($cur_topic['subject']) > $max_subject_length)
       
   255 				$subject_truncated = pun_htmlspecialchars(trim(substr($cur_topic['subject'], 0, ($max_subject_length-5)))).' &hellip;';
       
   256 			else
       
   257 				$subject_truncated = pun_htmlspecialchars($cur_topic['subject']);
       
   258 
       
   259 			echo '<li><a href="'.$pun_config['o_base_url'].'/viewtopic.php?id='.$cur_topic['id'].'&amp;action=new" title="'.pun_htmlspecialchars($cur_topic['subject']).'">'.$subject_truncated.'</a></li>'."\n";
       
   260 		}
       
   261 	}
       
   262 
       
   263 	return;
       
   264 }
       
   265 
       
   266 
       
   267 //
       
   268 // Show users online
       
   269 //
       
   270 else if ($_GET['action'] == 'online' || $_GET['action'] == 'online_full')
       
   271 {
       
   272 	// Load the index.php language file
       
   273 	require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php';
       
   274 	
       
   275 	// Fetch users online info and generate strings for output
       
   276 	$num_guests = $num_users = 0;
       
   277 	$users = array();
       
   278 	$result = $pun_db->query('SELECT user_id, ident FROM '.$pun_db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $pun_db->error());
       
   279 
       
   280 	while ($pun_user_online = $pun_db->fetch_assoc($result))
       
   281 	{
       
   282 		if ($pun_user_online['user_id'] > 1)
       
   283 		{
       
   284 			$users[] = '<a href="'.$pun_config['o_base_url'].'/profile.php?id='.$pun_user_online['user_id'].'">'.pun_htmlspecialchars($pun_user_online['ident']).'</a>';
       
   285 			++$num_users;
       
   286 		}
       
   287 		else
       
   288 			++$num_guests;
       
   289 	}
       
   290 
       
   291 	echo $lang_index['Guests online'].': '.$num_guests.'<br />';
       
   292 
       
   293 	if ($_GET['action'] == 'online_full')
       
   294 		echo $lang_index['Users online'].': '.implode(', ', $users).'<br />';
       
   295 	else
       
   296 		echo $lang_index['Users online'].': '.$num_users.'<br />';
       
   297 
       
   298 	return;
       
   299 }
       
   300 
       
   301 
       
   302 //
       
   303 // Show board statistics
       
   304 //
       
   305 else if ($_GET['action'] == 'stats')
       
   306 {
       
   307 	// Load the index.php language file
       
   308 	require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php';
       
   309 
       
   310 	// Collect some statistics from the database
       
   311 	$result = $pun_db->query('SELECT COUNT(id)-1 FROM '.$pun_db->prefix.'users') or error('Unable to fetch total user count', __FILE__, __LINE__, $pun_db->error());
       
   312 	$stats['total_users'] = $pun_db->result($result);
       
   313 
       
   314 	$result = $pun_db->query('SELECT id, username FROM '.$pun_db->prefix.'users ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $pun_db->error());
       
   315 	$stats['last_user'] = $pun_db->fetch_assoc($result);
       
   316 
       
   317 	$result = $pun_db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$pun_db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $pun_db->error());
       
   318 	list($stats['total_topics'], $stats['total_posts']) = $pun_db->fetch_row($result);
       
   319 
       
   320 	echo $lang_index['No of users'].': '.$stats['total_users'].'<br />';
       
   321 	echo $lang_index['Newest user'].': <a href="'.$pun_config['o_base_url'].'/profile.php?id='.$stats['last_user']['id'].'">'.pun_htmlspecialchars($stats['last_user']['username']).'</a><br />';
       
   322 	echo $lang_index['No of topics'].': '.$stats['total_topics'].'<br />';
       
   323 	echo $lang_index['No of posts'].': '.$stats['total_posts'];
       
   324 
       
   325 	return;
       
   326 }
       
   327 
       
   328 
       
   329 else
       
   330 	exit('Bad request');