| [ PHPXref.com ] | [ Generated: Thu Aug 19 03:35:06 2010 ] | [ FluxBB 1.4.2 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Copyright (C) 2008-2010 FluxBB 5 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB 6 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher 7 */ 8 9 /*----------------------------------------------------------------------------- 10 11 INSTRUCTIONS 12 13 This script is used to include information about your board from 14 pages outside the forums and to syndicate news about recent 15 discussions via RSS/Atom/XML. The script can display a list of 16 recent discussions, a list of active users or a collection of 17 general board statistics. The script can be called directly via 18 an URL, from a PHP include command or through the use of Server 19 Side Includes (SSI). 20 21 The scripts behaviour is controlled via variables supplied in the 22 URL to the script. The different variables are: action (what to 23 do), show (how many items to display), fid (the ID or IDs of 24 the forum(s) to poll for topics), nfid (the ID or IDs of forums 25 that should be excluded), tid (the ID of the topic from which to 26 display posts) and type (output as HTML or RSS). The only 27 mandatory variable is action. Possible/default values are: 28 29 action: feed - show most recent topics/posts (HTML or RSS) 30 online - show users online (HTML) 31 online_full - as above, but includes a full list (HTML) 32 stats - show board statistics (HTML) 33 34 type: rss - output as RSS 2.0 35 atom - output as Atom 1.0 36 xml - output as XML 37 html - output as HTML (<li>'s) 38 39 fid: One or more forum IDs (comma-separated). If ignored, 40 topics from all readable forums will be pulled. 41 42 nfid: One or more forum IDs (comma-separated) that are to be 43 excluded. E.g. the ID of a a test forum. 44 45 tid: A topic ID from which to show posts. If a tid is supplied, 46 fid and nfid are ignored. 47 48 show: Any integer value between 1 and 50. The default is 15. 49 50 order: last_post - show topics ordered by when they were last 51 posted in, giving information about the reply. 52 posted - show topics ordered by when they were first 53 posted, giving information about the original post. 54 55 -----------------------------------------------------------------------------*/ 56 57 define('PUN_QUIET_VISIT', 1); 58 59 if (!defined('PUN_ROOT')) 60 define('PUN_ROOT', './'); 61 require PUN_ROOT.'include/common.php'; 62 63 // The length at which topic subjects will be truncated (for HTML output) 64 if (!defined('FORUM_EXTERN_MAX_SUBJECT_LENGTH')) 65 define('FORUM_EXTERN_MAX_SUBJECT_LENGTH', 30); 66 67 // If we're a guest and we've sent a username/pass, we can try to authenticate using those details 68 if ($pun_user['is_guest'] && isset($_SERVER['PHP_AUTH_USER'])) 69 authenticate_user($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']); 70 71 if ($pun_user['g_read_board'] == '0') 72 { 73 http_authenticate_user(); 74 exit($lang_common['No view']); 75 } 76 77 $action = isset($_GET['action']) ? strtolower($_GET['action']) : 'feed'; 78 79 // Handle a couple old formats, from FluxBB 1.2 80 switch ($action) 81 { 82 case 'active': 83 $action = 'feed'; 84 $_GET['order'] = 'last_post'; 85 break; 86 87 case 'new': 88 $action = 'feed'; 89 $_GET['order'] = 'posted'; 90 break; 91 } 92 93 // 94 // Sends the proper headers for Basic HTTP Authentication 95 // 96 function http_authenticate_user() 97 { 98 global $pun_config, $pun_user; 99 100 if (!$pun_user['is_guest']) 101 return; 102 103 header('WWW-Authenticate: Basic realm="'.$pun_config['o_board_title'].' External Syndication"'); 104 header('HTTP/1.0 401 Unauthorized'); 105 } 106 107 108 // 109 // Output $feed as RSS 2.0 110 // 111 function output_rss($feed) 112 { 113 global $lang_common, $pun_config; 114 115 // Send XML/no cache headers 116 header('Content-Type: application/xml; charset=utf-8'); 117 header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); 118 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 119 header('Pragma: public'); 120 121 echo '<?xml version="1.0" encoding="utf-8"?>'."\n"; 122 echo '<rss version="2.0">'."\n"; 123 echo "\t".'<channel>'."\n"; 124 echo "\t\t".'<title><![CDATA['.escape_cdata($feed['title']).']]></title>'."\n"; 125 echo "\t\t".'<link>'.$feed['link'].'</link>'."\n"; 126 echo "\t\t".'<description><![CDATA['.escape_cdata($feed['description']).']]></description>'."\n"; 127 echo "\t\t".'<lastBuildDate>'.gmdate('r', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).'</lastBuildDate>'."\n"; 128 129 if ($pun_config['o_show_version'] == '1') 130 echo "\t\t".'<generator>FluxBB '.$pun_config['o_cur_version'].'</generator>'."\n"; 131 else 132 echo "\t\t".'<generator>FluxBB</generator>'."\n"; 133 134 foreach ($feed['items'] as $item) 135 { 136 echo "\t\t".'<item>'."\n"; 137 echo "\t\t\t".'<title><![CDATA['.escape_cdata($item['title']).']]></title>'."\n"; 138 echo "\t\t\t".'<link>'.$item['link'].'</link>'."\n"; 139 echo "\t\t\t".'<description><![CDATA['.escape_cdata($item['description']).']]></description>'."\n"; 140 echo "\t\t\t".'<author><![CDATA['.(isset($item['author']['email']) ? escape_cdata($item['author']['email']) : 'dummy@example.com').' ('.escape_cdata($item['author']['name']).')]]></author>'."\n"; 141 echo "\t\t\t".'<pubDate>'.gmdate('r', $item['pubdate']).'</pubDate>'."\n"; 142 echo "\t\t\t".'<guid>'.$item['link'].'</guid>'."\n"; 143 144 echo "\t\t".'</item>'."\n"; 145 } 146 147 echo "\t".'</channel>'."\n"; 148 echo '</rss>'."\n"; 149 } 150 151 152 // 153 // Output $feed as Atom 1.0 154 // 155 function output_atom($feed) 156 { 157 global $lang_common, $pun_config; 158 159 // Send XML/no cache headers 160 header('Content-Type: application/atom+xml; charset=utf-8'); 161 header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); 162 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 163 header('Pragma: public'); 164 165 echo '<?xml version="1.0" encoding="utf-8"?>'."\n"; 166 echo '<feed xmlns="http://www.w3.org/2005/Atom">'."\n"; 167 168 echo "\t".'<title type="html"><![CDATA['.escape_cdata($feed['title']).']]></title>'."\n"; 169 echo "\t".'<link rel="self" href="'.pun_htmlspecialchars(get_current_url()).'"/>'."\n"; 170 echo "\t".'<link href="'.$feed['link'].'"/>'."\n"; 171 echo "\t".'<updated>'.gmdate('Y-m-d\TH:i:s\Z', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).'</updated>'."\n"; 172 173 if ($pun_config['o_show_version'] == '1') 174 echo "\t".'<generator version="'.$pun_config['o_cur_version'].'">FluxBB</generator>'."\n"; 175 else 176 echo "\t".'<generator>FluxBB</generator>'."\n"; 177 178 echo "\t".'<id>'.$feed['link'].'</id>'."\n"; 179 180 $content_tag = ($feed['type'] == 'posts') ? 'content' : 'summary'; 181 182 foreach ($feed['items'] as $item) 183 { 184 echo "\t".'<entry>'."\n"; 185 echo "\t\t".'<title type="html"><![CDATA['.escape_cdata($item['title']).']]></title>'."\n"; 186 echo "\t\t".'<link rel="alternate" href="'.$item['link'].'"/>'."\n"; 187 echo "\t\t".'<'.$content_tag.' type="html"><![CDATA['.escape_cdata($item['description']).']]></'.$content_tag.'>'."\n"; 188 echo "\t\t".'<author>'."\n"; 189 echo "\t\t\t".'<name><![CDATA['.escape_cdata($item['author']['name']).']]></name>'."\n"; 190 191 if (isset($item['author']['email'])) 192 echo "\t\t\t".'<email><![CDATA['.escape_cdata($item['author']['email']).']]></email>'."\n"; 193 194 if (isset($item['author']['uri'])) 195 echo "\t\t\t".'<uri>'.$item['author']['uri'].'</uri>'."\n"; 196 197 echo "\t\t".'</author>'."\n"; 198 echo "\t\t".'<updated>'.gmdate('Y-m-d\TH:i:s\Z', $item['pubdate']).'</updated>'."\n"; 199 200 echo "\t\t".'<id>'.$item['link'].'</id>'."\n"; 201 echo "\t".'</entry>'."\n"; 202 } 203 204 echo '</feed>'."\n"; 205 } 206 207 208 // 209 // Output $feed as XML 210 // 211 function output_xml($feed) 212 { 213 global $lang_common, $pun_config; 214 215 // Send XML/no cache headers 216 header('Content-Type: application/xml; charset=utf-8'); 217 header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); 218 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 219 header('Pragma: public'); 220 221 echo '<?xml version="1.0" encoding="utf-8"?>'."\n"; 222 echo '<source>'."\n"; 223 echo "\t".'<url>'.$feed['link'].'</url>'."\n"; 224 225 $forum_tag = ($feed['type'] == 'posts') ? 'post' : 'topic'; 226 227 foreach ($feed['items'] as $item) 228 { 229 echo "\t".'<'.$forum_tag.' id="'.$item['id'].'">'."\n"; 230 231 echo "\t\t".'<title><![CDATA['.escape_cdata($item['title']).']]></title>'."\n"; 232 echo "\t\t".'<link>'.$item['link'].'</link>'."\n"; 233 echo "\t\t".'<content><![CDATA['.escape_cdata($item['description']).']]></content>'."\n"; 234 echo "\t\t".'<author>'."\n"; 235 echo "\t\t\t".'<name><![CDATA['.escape_cdata($item['author']['name']).']]></name>'."\n"; 236 237 if (isset($item['author']['email'])) 238 echo "\t\t\t".'<email><![CDATA['.escape_cdata($item['author']['email']).']]></email>'."\n"; 239 240 if (isset($item['author']['uri'])) 241 echo "\t\t\t".'<uri>'.$item['author']['uri'].'</uri>'."\n"; 242 243 echo "\t\t".'</author>'."\n"; 244 echo "\t\t".'<posted>'.gmdate('r', $item['pubdate']).'</posted>'."\n"; 245 246 echo "\t".'</'.$forum_tag.'>'."\n"; 247 } 248 249 echo '</source>'."\n"; 250 } 251 252 253 // 254 // Output $feed as HTML (using <li> tags) 255 // 256 function output_html($feed) 257 { 258 259 // Send the Content-type header in case the web server is setup to send something else 260 header('Content-type: text/html; charset=utf-8'); 261 header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); 262 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 263 header('Pragma: public'); 264 265 foreach ($feed['items'] as $item) 266 { 267 if (utf8_strlen($item['title']) > FORUM_EXTERN_MAX_SUBJECT_LENGTH) 268 $subject_truncated = pun_htmlspecialchars(pun_trim(utf8_substr($item['title'], 0, (FORUM_EXTERN_MAX_SUBJECT_LENGTH - 5)))).' …'; 269 else 270 $subject_truncated = pun_htmlspecialchars($item['title']); 271 272 echo '<li><a href="'.$item['link'].'" title="'.pun_htmlspecialchars($item['title']).'">'.$subject_truncated.'</a></li>'."\n"; 273 } 274 } 275 276 // Show recent discussions 277 if ($action == 'feed') 278 { 279 require PUN_ROOT.'include/parser.php'; 280 281 // Determine what type of feed to output 282 $type = isset($_GET['type']) ? strtolower($_GET['type']) : 'html'; 283 if (!in_array($type, array('html', 'rss', 'atom', 'xml'))) 284 $type = 'html'; 285 286 $show = isset($_GET['show']) ? intval($_GET['show']) : 15; 287 if ($show < 1 || $show > 50) 288 $show = 15; 289 290 // Was a topic ID supplied? 291 if (isset($_GET['tid'])) 292 { 293 $tid = intval($_GET['tid']); 294 295 // Fetch topic subject 296 $result = $db->query('SELECT t.subject, t.first_post_id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL AND t.id='.$tid) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); 297 if (!$db->num_rows($result)) 298 { 299 http_authenticate_user(); 300 exit($lang_common['Bad request']); 301 } 302 303 $cur_topic = $db->fetch_assoc($result); 304 305 if ($pun_config['o_censoring'] == '1') 306 $cur_topic['subject'] = censor_words($cur_topic['subject']); 307 308 // Setup the feed 309 $feed = array( 310 'title' => $pun_config['o_board_title'].$lang_common['Title separator'].$cur_topic['subject'], 311 'link' => $pun_config['o_base_url'].'/viewtopic.php?id='.$tid, 312 'description' => sprintf($lang_common['RSS description topic'], $cur_topic['subject']), 313 'items' => array(), 314 'type' => 'posts' 315 ); 316 317 // Fetch $show posts 318 $result = $db->query('SELECT p.id, p.poster, p.message, p.hide_smilies, p.posted, p.poster_id, u.email_setting, u.email, p.poster_email FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id WHERE p.topic_id='.$tid.' ORDER BY p.posted DESC LIMIT '.$show) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error()); 319 while ($cur_post = $db->fetch_assoc($result)) 320 { 321 $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); 322 323 $item = array( 324 'id' => $cur_post['id'], 325 'title' => $cur_topic['first_post_id'] == $cur_post['id'] ? $cur_topic['subject'] : $lang_common['RSS reply'].$cur_topic['subject'], 326 'link' => $pun_config['o_base_url'].'/viewtopic.php?pid='.$cur_post['id'].'#p'.$cur_post['id'], 327 'description' => $cur_post['message'], 328 'author' => array( 329 'name' => $cur_post['poster'], 330 ), 331 'pubdate' => $cur_post['posted'] 332 ); 333 334 if ($cur_post['poster_id'] > 1) 335 { 336 if ($cur_post['email_setting'] == '0' && !$pun_user['is_guest']) 337 $item['author']['email'] = $cur_post['email']; 338 339 $item['author']['uri'] = $pun_config['o_base_url'].'/profile.php?id='.$cur_post['poster_id']; 340 } 341 else if ($cur_post['poster_email'] != '' && !$pun_user['is_guest']) 342 $item['author']['email'] = $cur_post['poster_email']; 343 344 $feed['items'][] = $item; 345 } 346 347 $output_func = 'output_'.$type; 348 $output_func($feed); 349 } 350 else 351 { 352 $order_posted = isset($_GET['order']) && strtolower($_GET['order']) == 'posted'; 353 $forum_name = ''; 354 $forum_sql = ''; 355 356 // Were any forum IDs supplied? 357 if (isset($_GET['fid']) && is_scalar($_GET['fid']) && $_GET['fid'] != '') 358 { 359 $fids = explode(',', pun_trim($_GET['fid'])); 360 $fids = array_map('intval', $fids); 361 362 if (!empty($fids)) 363 $forum_sql .= ' AND t.forum_id IN('.implode(',', $fids).')'; 364 365 if (count($fids) == 1) 366 { 367 // Fetch forum name 368 $result = $db->query('SELECT f.forum_name FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fids[0]) or error('Unable to fetch forum name', __FILE__, __LINE__, $db->error()); 369 if ($db->num_rows($result)) 370 $forum_name = $lang_common['Title separator'].$db->result($result); 371 } 372 } 373 374 // Any forum IDs to exclude? 375 if (isset($_GET['nfid']) && is_scalar($_GET['nfid']) && $_GET['nfid'] != '') 376 { 377 $nfids = explode(',', pun_trim($_GET['nfid'])); 378 $nfids = array_map('intval', $nfids); 379 380 if (!empty($nfids)) 381 $forum_sql .= ' AND t.forum_id NOT IN('.implode(',', $nfids).')'; 382 } 383 384 // Setup the feed 385 $feed = array( 386 'title' => $pun_config['o_board_title'].$forum_name, 387 'link' => $pun_config['o_base_url'].'/index.php', 388 'description' => sprintf($lang_common['RSS description'], $pun_config['o_board_title']), 389 'items' => array(), 390 'type' => 'topics' 391 ); 392 393 // Fetch $show topics 394 $result = $db->query('SELECT t.id, t.poster, t.subject, t.posted, t.last_post, t.last_poster, p.message, p.hide_smilies, u.email_setting, u.email, p.poster_id, p.poster_email FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON p.id='.($order_posted ? 't.first_post_id' : 't.last_post_id').' INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.($order_posted ? 't.posted' : 't.last_post').' DESC LIMIT '.$show) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); 395 while ($cur_topic = $db->fetch_assoc($result)) 396 { 397 if ($pun_config['o_censoring'] == '1') 398 $cur_topic['subject'] = censor_words($cur_topic['subject']); 399 400 $cur_topic['message'] = parse_message($cur_topic['message'], $cur_topic['hide_smilies']); 401 402 $item = array( 403 'id' => $cur_topic['id'], 404 'title' => $cur_topic['subject'], 405 'link' => $pun_config['o_base_url'].($order_posted ? '/viewtopic.php?id='.$cur_topic['id'] : '/viewtopic.php?id='.$cur_topic['id'].'&action=new'), 406 'description' => $cur_topic['message'], 407 'author' => array( 408 'name' => $order_posted ? $cur_topic['poster'] : $cur_topic['last_poster'] 409 ), 410 'pubdate' => $order_posted ? $cur_topic['posted'] : $cur_topic['last_post'] 411 ); 412 413 if ($cur_topic['poster_id'] > 1) 414 { 415 if ($cur_topic['email_setting'] == '0' && !$pun_user['is_guest']) 416 $item['author']['email'] = $cur_topic['email']; 417 418 $item['author']['uri'] = $pun_config['o_base_url'].'/profile.php?id='.$cur_topic['poster_id']; 419 } 420 else if ($cur_topic['poster_email'] != '' && !$pun_user['is_guest']) 421 $item['author']['email'] = $cur_topic['poster_email']; 422 423 $feed['items'][] = $item; 424 } 425 426 $output_func = 'output_'.$type; 427 $output_func($feed); 428 } 429 430 exit; 431 } 432 433 // Show users online 434 else if ($action == 'online' || $action == 'online_full') 435 { 436 // Load the index.php language file 437 require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; 438 439 // Fetch users online info and generate strings for output 440 $num_guests = $num_users = 0; 441 $users = array(); 442 443 $result = $db->query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error()); 444 445 while ($pun_user_online = $db->fetch_assoc($result)) 446 { 447 if ($pun_user_online['user_id'] > 1) 448 { 449 $users[] = ($pun_user['g_view_users'] == '1') ? '<a href="'.$pun_config['o_base_url'].'/profile.php?id='.$pun_user_online['user_id'].'">'.pun_htmlspecialchars($pun_user_online['ident']).'</a>' : pun_htmlspecialchars($pun_user_online['ident']); 450 ++$num_users; 451 } 452 else 453 ++$num_guests; 454 } 455 456 // Send the Content-type header in case the web server is setup to send something else 457 header('Content-type: text/html; charset=utf-8'); 458 header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); 459 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 460 header('Pragma: public'); 461 462 echo sprintf($lang_index['Guests online'], forum_number_format($num_guests)).'<br />'."\n"; 463 464 if ($action == 'online_full' && !empty($users)) 465 echo sprintf($lang_index['Users online'], implode(', ', $users)).'<br />'."\n"; 466 else 467 echo sprintf($lang_index['Users online'], forum_number_format($num_users)).'<br />'."\n"; 468 469 exit; 470 } 471 472 // Show board statistics 473 else if ($action == 'stats') 474 { 475 // Load the index.php language file 476 require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; 477 478 // Collect some statistics from the database 479 $result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED) or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error()); 480 $stats['total_users'] = $db->result($result); 481 482 $result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE group_id!='.PUN_UNVERIFIED.' ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error()); 483 $stats['last_user'] = $db->fetch_assoc($result); 484 485 $result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error()); 486 list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result); 487 488 // Send the Content-type header in case the web server is setup to send something else 489 header('Content-type: text/html; charset=utf-8'); 490 header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); 491 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 492 header('Pragma: public'); 493 494 echo sprintf($lang_index['No of users'], forum_number_format($stats['total_users'])).'<br />'."\n"; 495 echo sprintf($lang_index['Newest user'], (($pun_user['g_view_users'] == '1') ? '<a href="'.$pun_config['o_base_url'].'/profile.php?id='.$stats['last_user']['id'].'">'.pun_htmlspecialchars($stats['last_user']['username']).'</a>' : pun_htmlspecialchars($stats['last_user']['username']))).'<br />'."\n"; 496 echo sprintf($lang_index['No of topics'], forum_number_format($stats['total_topics'])).'<br />'."\n"; 497 echo sprintf($lang_index['No of posts'], forum_number_format($stats['total_posts'])).'<br />'."\n"; 498 499 exit; 500 } 501 502 // If we end up here, the script was called with some wacky parameters 503 exit($lang_common['Bad request']);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |