punbb/extern.php
changeset 7 98bbc533541c
equal deleted inserted replaced
6:5e1f1e916419 7:98bbc533541c
       
     1 <?php
       
     2 /***********************************************************************
       
     3 
       
     4   Copyright (C) 2002-2008  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   INSTRUCTIONS
       
    26 
       
    27   This script is used to include information about your board from
       
    28   pages outside the forums and to syndicate news about recent
       
    29   discussions via RSS/Atom/XML. The script can display a list of
       
    30   recent discussions, a list of active users or a collection of
       
    31   general board statistics. The script can be called directly via
       
    32   an URL, from a PHP include command or through the use of Server
       
    33   Side Includes (SSI).
       
    34 
       
    35   The scripts behaviour is controlled via variables supplied in the
       
    36   URL to the script. The different variables are: action (what to
       
    37   do), show (how many items to display), fid (the ID or ID's of
       
    38   the forum(s) to poll for topics), nfid (the ID or ID's of forums
       
    39   that should be excluded), tid (the ID of the topic from which to
       
    40   display posts) and type (output as HTML or RSS). The only
       
    41   mandatory variable is action. Possible/default values are:
       
    42 
       
    43     action: feed - show most recent topics/posts (HTML or RSS)
       
    44             online - show users online (HTML)
       
    45             online_full - as above, but includes a full list (HTML)
       
    46             stats - show board statistics (HTML)
       
    47 
       
    48     type:   rss - output as RSS 2.0
       
    49             atom - output as Atom 1.0
       
    50             xml - output as XML
       
    51             html - output as HTML (<li>'s)
       
    52 
       
    53     fid:    One or more forum ID's (comma-separated). If ignored,
       
    54             topics from all guest-readable forums will be pulled.
       
    55 
       
    56     nfid:   One or more forum ID's (comma-separated) that are to be
       
    57             excluded. E.g. the ID of a a test forum.
       
    58 
       
    59     tid:    A topic ID from which to show posts. If a tid is supplied,
       
    60             fid and nfid are ignored.
       
    61 
       
    62     show:   Any integer value between 1 and 50. This variables is
       
    63             ignored for RSS/Atom output. The default is 15.
       
    64 
       
    65 
       
    66 /***********************************************************************/
       
    67 
       
    68 // The length at which topic subjects will be truncated (for HTML output)
       
    69 define('MAX_SUBJECT_LENGTH', 30);
       
    70 
       
    71 
       
    72 // if (!defined('PUN_ROOT'))
       
    73 // 	define('PUN_ROOT', './');
       
    74 // require PUN_ROOT.'include/common.php';
       
    75 
       
    76 // import globals (I really hope this isn't dangerous)
       
    77 foreach ( $GLOBALS as $key => $_ )
       
    78 {
       
    79   $$key =& $GLOBALS[$key];
       
    80 }
       
    81 
       
    82 ($hook = get_hook('ex_start')) ? eval($hook) : null;
       
    83 
       
    84 if ($pun_user['g_read_board'] == '0')
       
    85 	exit($lang_common['No view']);
       
    86 
       
    87 
       
    88 //
       
    89 // Converts the CDATA end sequence ]]> into ]]&gt;
       
    90 //
       
    91 function escape_cdata($str)
       
    92 {
       
    93 	return str_replace(']]>', ']]&gt;', $str);
       
    94 }
       
    95 
       
    96 
       
    97 //
       
    98 // Output $feed as RSS 2.0
       
    99 //
       
   100 function output_rss($feed)
       
   101 {
       
   102 	global $lang_common, $pun_config;
       
   103 
       
   104 	// Send XML/no cache headers
       
   105 	header('Content-Type: text/xml; charset=utf-8');
       
   106 	header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
       
   107 	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
       
   108 	header('Pragma: public');
       
   109 
       
   110 	echo '<?xml version="1.0" encoding="utf-8"?>'."\r\n";
       
   111 	echo '<rss version="2.0">'."\r\n";
       
   112 	echo "\t".'<channel>'."\r\n";
       
   113 	echo "\t\t".'<title>'.htmlspecialchars($feed['title']).'</title>'."\r\n";
       
   114 	echo "\t\t".'<link>'.$feed['link'].'</link>'."\r\n";
       
   115 	echo "\t\t".'<description>'.htmlspecialchars($feed['description']).'</description>'."\r\n";
       
   116 	echo "\t\t".'<lastBuildDate>'.gmdate('r', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).'</lastBuildDate>'."\r\n";
       
   117 
       
   118 	if ($pun_config['o_show_version'] == '1')
       
   119 		echo "\t\t".'<generator>PunBB '.$pun_config['o_cur_version'].'</generator>'."\r\n";
       
   120 	else
       
   121 		echo "\t\t".'<generator>PunBB</generator>'."\r\n";
       
   122 
       
   123 	$num_items = count($feed['items']);
       
   124 	for ($i = 0; $i < $num_items; ++$i)
       
   125 	{
       
   126 		echo "\t\t".'<item>'."\r\n";
       
   127 		echo "\t\t\t".'<title>'.htmlspecialchars($feed['items'][$i]['title']).'</title>'."\r\n";
       
   128 		echo "\t\t\t".'<link>'.$feed['items'][$i]['link'].'</link>'."\r\n";
       
   129 		echo "\t\t\t".'<description>'.htmlspecialchars($feed['items'][$i]['description']).'</description>'."\r\n";
       
   130 		echo "\t\t\t".'<author>dummy@email.com ('.htmlspecialchars($feed['items'][$i]['author']).')</author>'."\r\n";
       
   131 		echo "\t\t\t".'<pubDate>'.gmdate('r', $feed['items'][$i]['pubdate']).'</pubDate>'."\r\n";
       
   132 		echo "\t\t\t".'<guid>'.$feed['items'][$i]['link'].'</guid>'."\r\n";
       
   133 		echo "\t\t".'</item>'."\r\n";
       
   134 	}
       
   135 
       
   136 	echo "\t".'</channel>'."\r\n";
       
   137 	echo '</rss>'."\r\n";
       
   138 }
       
   139 
       
   140 
       
   141 //
       
   142 // Output $feed as Atom 1.0
       
   143 //
       
   144 function output_atom($feed)
       
   145 {
       
   146 	global $lang_common, $pun_config;
       
   147 
       
   148 	// Send XML/no cache headers
       
   149 	header('Content-Type: text/xml; charset=utf-8');
       
   150 	header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
       
   151 	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
       
   152 	header('Pragma: public');
       
   153 
       
   154 	echo '<?xml version="1.0" encoding="utf-8"?>'."\r\n";
       
   155 	echo '<feed xmlns="http://www.w3.org/2005/Atom">'."\r\n";
       
   156 
       
   157 	echo "\t".'<title type="html">'.htmlspecialchars($feed['title']).'</title>'."\r\n";
       
   158 	echo "\t".'<link rel="self" href="'.htmlspecialchars($_SERVER['SCRIPT_NAME'].($_SERVER['QUERY_STRING'] != '' ? '?'.$_SERVER['QUERY_STRING'] :'')).'"/>'."\r\n";
       
   159 	echo "\t".'<updated>'.gmdate('Y-m-d\TH:i:s\Z', $feed['items'][0]['pubdate']).'</updated>'."\r\n";
       
   160 
       
   161 	if ($pun_config['o_show_version'] == '1')
       
   162 		echo "\t".'<generator version="'.$pun_config['o_cur_version'].'">PunBB</generator>'."\r\n";
       
   163 	else
       
   164 		echo "\t".'<generator>PunBB</generator>'."\r\n";
       
   165 
       
   166 	echo "\t".'<id>'.$feed['link'].'</id>'."\r\n";
       
   167 
       
   168 	$content_tag = ($feed['type'] == 'posts') ? 'content' : 'summary';
       
   169 
       
   170 	$num_items = count($feed['items']);
       
   171 	for ($i = 0; $i < $num_items; ++$i)
       
   172 	{
       
   173 		echo "\t\t".'<entry>'."\r\n";
       
   174 		echo "\t\t\t".'<title type="html">'.htmlspecialchars($feed['items'][$i]['title']).'</title>'."\r\n";
       
   175 		echo "\t\t\t".'<link rel="alternate" href="'.$feed['items'][$i]['link'].'"/>'."\r\n";
       
   176 		echo "\t\t\t".'<'.$content_tag.' type="html">'.htmlspecialchars($feed['items'][$i]['description']).'</'.$content_tag.'>'."\r\n";
       
   177 		echo "\t\t\t".'<author>'."\r\n";
       
   178 		echo "\t\t\t\t".'<name>'.htmlspecialchars($feed['items'][$i]['author']).'</name>'."\r\n";
       
   179 		echo "\t\t\t".'</author>'."\r\n";
       
   180 		echo "\t\t\t".'<updated>'.gmdate('Y-m-d\TH:i:s\Z', $feed['items'][$i]['pubdate']).'</updated>'."\r\n";
       
   181 		echo "\t\t\t".'<id>'.$feed['items'][$i]['link'].'</id>'."\r\n";
       
   182 		echo "\t\t".'</entry>'."\r\n";
       
   183 	}
       
   184 
       
   185 	echo '</feed>'."\r\n";
       
   186 }
       
   187 
       
   188 
       
   189 //
       
   190 // Output $feed as XML
       
   191 //
       
   192 function output_xml($feed)
       
   193 {
       
   194 	global $lang_common, $pun_config;
       
   195 
       
   196 	// Send XML/no cache headers
       
   197 	header('Content-Type: text/xml; charset=utf-8');
       
   198 	header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
       
   199 	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
       
   200 	header('Pragma: public');
       
   201 
       
   202 	echo '<?xml version="1.0" encoding="utf-8"?>'."\r\n";
       
   203 	echo '<source>'."\r\n";
       
   204 	echo "\t".'<url>'.$feed['link'].'</url>'."\r\n";
       
   205 
       
   206 	$pun_tag = ($feed['type'] == 'posts') ? 'post' : 'topic';
       
   207 
       
   208 	$num_items = count($feed['items']);
       
   209 	for ($i = 0; $i < $num_items; ++$i)
       
   210 	{
       
   211 		echo "\t".'<'.$pun_tag.' id="'.$feed['items'][$i]['id'].'">'."\r\n";
       
   212 
       
   213 		echo "\t\t".'<title>'.htmlspecialchars($feed['items'][$i]['title']).'</title>'."\r\n";
       
   214 		echo "\t\t".'<link>'.$feed['items'][$i]['link'].'</link>'."\r\n";
       
   215 		echo "\t\t".'<content>'.htmlspecialchars($feed['items'][$i]['description']).'</content>'."\r\n";
       
   216 		echo "\t\t".'<author>'.htmlspecialchars($feed['items'][$i]['author']).'</author>'."\r\n";
       
   217 		echo "\t\t".'<posted>'.gmdate('r', $feed['items'][$i]['pubdate']).'</posted>'."\r\n";
       
   218 
       
   219 		echo "\t".'</'.$pun_tag.'>'."\r\n";
       
   220 	}
       
   221 
       
   222 	echo '</source>'."\r\n";
       
   223 }
       
   224 
       
   225 
       
   226 //
       
   227 // Output $feed as HTML (using <li> tags)
       
   228 //
       
   229 function output_html($feed)
       
   230 {
       
   231 	global $pun_config;
       
   232 
       
   233 	$num_items = count($feed['items']);
       
   234 	for ($i = 0; $i < $num_items; ++$i)
       
   235 	{
       
   236 		if ($pun_config['o_censoring'] == '1')
       
   237 			$feed['items'][$i]['title'] = censor_words($feed['items'][$i]['title']);
       
   238 
       
   239 		if (pun_strlen($feed['items'][$i]['title']) > MAX_SUBJECT_LENGTH)
       
   240 			$subject_truncated = htmlspecialchars(trim(substr($feed['items'][$i]['title'], 0, (MAX_SUBJECT_LENGTH-5)))).' …';
       
   241 		else
       
   242 			$subject_truncated = htmlspecialchars($feed['items'][$i]['title']);
       
   243 
       
   244 		echo '<li><a href="'.$feed['items'][$i]['link'].'" title="'.htmlspecialchars($feed['items'][$i]['title']).'">'.$subject_truncated.'</a></li>'."\n";
       
   245 	}
       
   246 }
       
   247 
       
   248 
       
   249 //
       
   250 // Show recent discussions
       
   251 //
       
   252 if ($_GET['action'] == 'feed')
       
   253 {
       
   254 	// Determine what type of feed to output
       
   255 	$type = 'html';
       
   256 	if (isset($_GET['type']) && is_scalar($_GET['type']))
       
   257 	{
       
   258 		if (strtolower($_GET['type']) == 'rss')
       
   259 			$type = 'rss';
       
   260 		else if (strtolower($_GET['type']) == 'atom')
       
   261 			$type = 'atom';
       
   262 		else if (strtolower($_GET['type']) == 'xml')
       
   263 			$type = 'xml';
       
   264 	}
       
   265 
       
   266 	$forum_sql = '';
       
   267 
       
   268 	// Was a topic ID supplied?
       
   269 	if (isset($_GET['tid']))
       
   270 	{
       
   271 		$tid = intval($_GET['tid']);
       
   272 
       
   273 		// Fetch topic subject
       
   274 		$query = array(
       
   275 			'SELECT'	=> 't.subject, t.num_replies',
       
   276 			'FROM'		=> 'topics AS t',
       
   277 			'JOINS'		=> array(
       
   278 				array(
       
   279 					'LEFT JOIN'		=> 'forum_perms AS fp',
       
   280 					'ON'			=> '(fp.forum_id=t.forum_id AND fp.group_id=2)'
       
   281 				)
       
   282 			),
       
   283 			'WHERE'		=> '(fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL and t.id='.$tid
       
   284 		);
       
   285 
       
   286 		($hook = get_hook('ex_qr_get_topic_data')) ? eval($hook) : null;
       
   287 		$result = $pun_db->query_build($query) or error(__FILE__, __LINE__);
       
   288 		if (!$pun_db->num_rows($result))
       
   289 			exit('Bad request. The link you followed is incorrect or outdated.');
       
   290 
       
   291 		$cur_topic = $pun_db->fetch_assoc($result);
       
   292 
       
   293 		if ($pun_config['o_censoring'] == '1')
       
   294 			$cur_topic['subject'] = censor_words($cur_topic['subject']);
       
   295 
       
   296 		// Setup the feed
       
   297 		$feed = array(
       
   298 			'title' 		=>	$pun_config['o_board_title'].' - '.$cur_topic['subject'],
       
   299 			'link'			=>	pun_link($pun_url['topic'], $tid),
       
   300 			'description'	=>	sprintf($lang_common['RSS description topic'], $cur_topic['subject']),
       
   301 			'items'			=>	array(),
       
   302 			'type'			=>	'posts'
       
   303 		);
       
   304 
       
   305 		// Fetch 15 posts
       
   306 		$query = array(
       
   307 			'SELECT'	=> 'p.id, p.poster, p.message, p.posted',
       
   308 			'FROM'		=> 'posts AS p',
       
   309 			'WHERE'		=> 'p.topic_id='.$tid,
       
   310 			'ORDER BY'	=> 'p.posted DESC',
       
   311 			'LIMIT'		=> '15'
       
   312 		);
       
   313 
       
   314 		($hook = get_hook('ex_qr_get_posts')) ? eval($hook) : null;
       
   315 		$result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__);
       
   316 		while ($cur_post = $pun_db->fetch_assoc($result))
       
   317 		{
       
   318 			$feed['items'][] = array(
       
   319 				'id'			=>	$cur_post['id'],
       
   320 				'title'			=>	$lang_common['RSS reply'].$cur_topic['subject'],
       
   321 				'link'			=>	pun_link($pun_url['post'], $cur_post['id']),
       
   322 				'description'	=>	$cur_post['message'],
       
   323 				'author'		=>	$cur_post['poster'],
       
   324 				'pubdate'		=>	$cur_post['posted']
       
   325 			);
       
   326 		}
       
   327 
       
   328 		if (intval($cur_topic['num_replies']) <= 14)
       
   329 			$feed['items'][count($feed['items'])-1]['title'] = $cur_topic['subject'];
       
   330 
       
   331 		($hook = get_hook('ex_pre_topic_output')) ? eval($hook) : null;
       
   332 
       
   333 		$output_func = 'output_'.$type;
       
   334 		$output_func($feed);
       
   335 	}
       
   336 	else
       
   337 	{
       
   338 		// Was any specific forum ID's supplied?
       
   339 		if (isset($_GET['fid']) && is_scalar($_GET['fid']) && $_GET['fid'] != '')
       
   340 		{
       
   341 			$fids = explode(',', trim($_GET['fid']));
       
   342 			$fids = array_map('intval', $fids);
       
   343 
       
   344 			if (!empty($fids))
       
   345 				$forum_sql = ' AND f.id IN('.implode(',', $fids).')';
       
   346 		}
       
   347 
       
   348 		// Any forum ID's to exclude?
       
   349 		if (isset($_GET['nfid']) && is_scalar($_GET['nfid']) && $_GET['nfid'] != '')
       
   350 		{
       
   351 			$nfids = explode(',', trim($_GET['nfid']));
       
   352 			$nfids = array_map('intval', $nfids);
       
   353 
       
   354 			if (!empty($nfids))
       
   355 				$forum_sql = ' AND f.id NOT IN('.implode(',', $nfids).')';
       
   356 		}
       
   357 
       
   358 		// Setup the feed
       
   359 		$feed = array(
       
   360 			'title' 		=>	$pun_config['o_board_title'],
       
   361 			'link'			=>	pun_link($pun_url['index']),
       
   362 			'description'	=>	sprintf($lang_common['RSS description'], $pun_config['o_board_title']),
       
   363 			'items'			=>	array(),
       
   364 			'type'			=>	'topics'
       
   365 		);
       
   366 
       
   367 
       
   368 		if (isset($_GET['type']) && is_scalar($_GET['type']) && strtoupper($_GET['type']) == 'RSS')
       
   369 			$show = 15;
       
   370 		else
       
   371 		{
       
   372 			$show = isset($_GET['show']) ? intval($_GET['show']) : 15;
       
   373 			if ($show < 1 || $show > 50)
       
   374 				$show = 15;
       
   375 		}
       
   376 
       
   377 		// Fetch $show topics
       
   378 		$query = array(
       
   379 			'SELECT'	=> 't.id, t.poster, t.subject, t.last_post, t.last_poster, f.id AS fid, f.forum_name',
       
   380 			'FROM'		=> 'topics AS t',
       
   381 			'JOINS'		=> array(
       
   382 				array(
       
   383 					'INNER JOIN'	=> 'forums AS f',
       
   384 					'ON'			=> 'f.id=t.forum_id'
       
   385 				),
       
   386 				array(
       
   387 					'LEFT JOIN'		=> 'forum_perms AS fp',
       
   388 					'ON'			=> '(fp.forum_id=f.id AND fp.group_id=2)'
       
   389 				)
       
   390 			),
       
   391 			'WHERE'		=> '(fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL',
       
   392 			'ORDER BY'	=> 't.last_post DESC',
       
   393 			'LIMIT'		=> $show
       
   394 		);
       
   395 
       
   396 		if (isset($forum_sql))
       
   397 			$query['WHERE'] .= $forum_sql;
       
   398 
       
   399 		($hook = get_hook('ex_qr_get_topics')) ? eval($hook) : null;
       
   400 		$result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__);
       
   401 		while ($cur_topic = $pun_db->fetch_assoc($result))
       
   402 		{
       
   403 			if ($pun_config['o_censoring'] == '1')
       
   404 				$cur_topic['subject'] = censor_words($cur_topic['subject']);
       
   405 
       
   406 			$feed['items'][] = array(
       
   407 				'id'			=>	$cur_topic['id'],
       
   408 				'title'			=>	$cur_topic['subject'],
       
   409 				'link'			=>	pun_link($pun_url['topic_new_posts'], $cur_topic['id']),
       
   410 				'description'	=>	$lang_common['Forum'].': <a href="'.pun_link($pun_url['forum'], $cur_topic['fid']).'">'.$cur_topic['forum_name'].'</a>',
       
   411 				'author'		=>	$cur_topic['last_poster'],
       
   412 				'pubdate'		=>	$cur_topic['last_post']
       
   413 			);
       
   414 		}
       
   415 
       
   416 		($hook = get_hook('ex_pre_forum_output')) ? eval($hook) : null;
       
   417 
       
   418 		$output_func = 'output_'.$type;
       
   419 		$output_func($feed);
       
   420 	}
       
   421 
       
   422 	return;
       
   423 }
       
   424 
       
   425 
       
   426 //
       
   427 // Show users online
       
   428 //
       
   429 else if ($_GET['action'] == 'online' || $_GET['action'] == 'online_full')
       
   430 {
       
   431 	// Load the index.php language file
       
   432 	require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php';
       
   433 
       
   434 	// Fetch users online info and generate strings for output
       
   435 	$num_guests = $num_users = 0;
       
   436 	$users = array();
       
   437 
       
   438 	$query = array(
       
   439 		'SELECT'	=> 'o.user_id, o.ident',
       
   440 		'FROM'		=> 'online AS o',
       
   441 		'WHERE'		=> 'o.idle=0',
       
   442 		'ORDER BY'	=> 'o.ident'
       
   443 	);
       
   444 
       
   445 	($hook = get_hook('ex_qr_get_users_online')) ? eval($hook) : null;
       
   446 	$result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__);
       
   447 	while ($pun_user_online = $pun_db->fetch_assoc($result))
       
   448 	{
       
   449 		if ($pun_user_online['user_id'] > 1)
       
   450 		{
       
   451 			$users[] = '<a href="'.pun_link($pun_url['user'], $pun_user_online['user_id']).'">'.htmlspecialchars($pun_user_online['ident']).'</a>';
       
   452 			++$num_users;
       
   453 		}
       
   454 		else
       
   455 			++$num_guests;
       
   456 	}
       
   457 
       
   458 	echo $lang_index['Guests online'].': '.$num_guests.'<br />';
       
   459 
       
   460 	if ($_GET['action'] == 'online_full')
       
   461 		echo $lang_index['Users online'].': '.implode(', ', $users).'<br />';
       
   462 	else
       
   463 		echo $lang_index['Users online'].': '.$num_users.'<br />';
       
   464 
       
   465 	return;
       
   466 }
       
   467 
       
   468 
       
   469 //
       
   470 // Show board statistics
       
   471 //
       
   472 else if ($_GET['action'] == 'stats')
       
   473 {
       
   474 	// Load the index.php language file
       
   475 	require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php';
       
   476 
       
   477 	// Collect some statistics from the database
       
   478 	$query = array(
       
   479 		'SELECT'	=> 'COUNT(u.id)-1',
       
   480 		'FROM'		=> 'users AS u'
       
   481 	);
       
   482 
       
   483 	($hook = get_hook('ex_qr_get_user_count')) ? eval($hook) : null;
       
   484 	$result = $pun_db->query_build($query) or error(__FILE__, __LINE__);
       
   485 	$stats['total_users'] = $pun_db->result($result);
       
   486 
       
   487 	$query = array(
       
   488 		'SELECT'	=> 'u.id, u.username',
       
   489 		'FROM'		=> 'users AS u',
       
   490 		'ORDER BY'	=> 'u.registered DESC',
       
   491 		'LIMIT'		=> '1'
       
   492 	);
       
   493 
       
   494 	($hook = get_hook('ex_qr_get_newest_user')) ? eval($hook) : null;
       
   495 	$result = $pun_db->query_build($query) or error(__FILE__, __LINE__);
       
   496 	$stats['last_user'] = $pun_db->fetch_assoc($result);
       
   497 
       
   498 	$query = array(
       
   499 		'SELECT'	=> 'SUM(f.num_topics), SUM(f.num_posts)',
       
   500 		'FROM'		=> 'forums AS f'
       
   501 	);
       
   502 
       
   503 	($hook = get_hook('ex_qr_get_post_stats')) ? eval($hook) : null;
       
   504 	$result = $pun_db->query_build($query) or error(__FILE__, __LINE__);
       
   505 	list($stats['total_topics'], $stats['total_posts']) = $pun_db->fetch_row($result);
       
   506 
       
   507 	echo $lang_index['No of users'].': '.$stats['total_users'].'<br />';
       
   508 	echo $lang_index['Newest user'].': <a href="'.pun_link($pun_url['user'], $stats['last_user']['id']).'">'.htmlspecialchars($stats['last_user']['username']).'</a><br />';
       
   509 	echo $lang_index['No of topics'].': '.intval($stats['total_topics']).'<br />';
       
   510 	echo $lang_index['No of posts'].': '.intval($stats['total_posts']);
       
   511 
       
   512 	return;
       
   513 }
       
   514 
       
   515 
       
   516 ($hook = get_hook('ex_new_action')) ? eval($hook) : null;
       
   517 
       
   518 // If we end up here, the script was called with some wacky parameters
       
   519 exit($lang_common['Bad request']);