[6] | 1 | <?php |
---|
| 2 | |
---|
| 3 | /** |
---|
| 4 | * Copyright (C) 2008-2011 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', dirname(__FILE__).'/'); |
---|
| 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" xmlns:atom="http://www.w3.org/2005/Atom">'."\n"; |
---|
| 123 | echo "\t".'<channel>'."\n"; |
---|
| 124 | echo "\t\t".'<atom:link href="'.pun_htmlspecialchars(get_current_url()).'" rel="self" type="application/rss+xml" />'."\n"; |
---|
| 125 | echo "\t\t".'<title><![CDATA['.escape_cdata($feed['title']).']]></title>'."\n"; |
---|
| 126 | echo "\t\t".'<link>'.pun_htmlspecialchars($feed['link']).'</link>'."\n"; |
---|
| 127 | echo "\t\t".'<description><![CDATA['.escape_cdata($feed['description']).']]></description>'."\n"; |
---|
| 128 | echo "\t\t".'<lastBuildDate>'.gmdate('r', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).'</lastBuildDate>'."\n"; |
---|
| 129 | |
---|
| 130 | if ($pun_config['o_show_version'] == '1') |
---|
| 131 | echo "\t\t".'<generator>FluxBB '.$pun_config['o_cur_version'].'</generator>'."\n"; |
---|
| 132 | else |
---|
| 133 | echo "\t\t".'<generator>FluxBB</generator>'."\n"; |
---|
| 134 | |
---|
| 135 | foreach ($feed['items'] as $item) |
---|
| 136 | { |
---|
| 137 | echo "\t\t".'<item>'."\n"; |
---|
| 138 | echo "\t\t\t".'<title><![CDATA['.escape_cdata($item['title']).']]></title>'."\n"; |
---|
| 139 | echo "\t\t\t".'<link>'.pun_htmlspecialchars($item['link']).'</link>'."\n"; |
---|
| 140 | echo "\t\t\t".'<description><![CDATA['.escape_cdata($item['description']).']]></description>'."\n"; |
---|
| 141 | 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"; |
---|
| 142 | echo "\t\t\t".'<pubDate>'.gmdate('r', $item['pubdate']).'</pubDate>'."\n"; |
---|
| 143 | echo "\t\t\t".'<guid>'.pun_htmlspecialchars($item['link']).'</guid>'."\n"; |
---|
| 144 | |
---|
| 145 | echo "\t\t".'</item>'."\n"; |
---|
| 146 | } |
---|
| 147 | |
---|
| 148 | echo "\t".'</channel>'."\n"; |
---|
| 149 | echo '</rss>'."\n"; |
---|
| 150 | } |
---|
| 151 | |
---|
| 152 | |
---|
| 153 | // |
---|
| 154 | // Output $feed as Atom 1.0 |
---|
| 155 | // |
---|
| 156 | function output_atom($feed) |
---|
| 157 | { |
---|
| 158 | global $lang_common, $pun_config; |
---|
| 159 | |
---|
| 160 | // Send XML/no cache headers |
---|
| 161 | header('Content-Type: application/atom+xml; charset=utf-8'); |
---|
| 162 | header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); |
---|
| 163 | header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); |
---|
| 164 | header('Pragma: public'); |
---|
| 165 | |
---|
| 166 | echo '<?xml version="1.0" encoding="utf-8"?>'."\n"; |
---|
| 167 | echo '<feed xmlns="http://www.w3.org/2005/Atom">'."\n"; |
---|
| 168 | |
---|
| 169 | echo "\t".'<title type="html"><![CDATA['.escape_cdata($feed['title']).']]></title>'."\n"; |
---|
| 170 | echo "\t".'<link rel="self" href="'.pun_htmlspecialchars(get_current_url()).'"/>'."\n"; |
---|
| 171 | echo "\t".'<link href="'.pun_htmlspecialchars($feed['link']).'"/>'."\n"; |
---|
| 172 | echo "\t".'<updated>'.gmdate('Y-m-d\TH:i:s\Z', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).'</updated>'."\n"; |
---|
| 173 | |
---|
| 174 | if ($pun_config['o_show_version'] == '1') |
---|
| 175 | echo "\t".'<generator version="'.$pun_config['o_cur_version'].'">FluxBB</generator>'."\n"; |
---|
| 176 | else |
---|
| 177 | echo "\t".'<generator>FluxBB</generator>'."\n"; |
---|
| 178 | |
---|
| 179 | echo "\t".'<id>'.pun_htmlspecialchars($feed['link']).'</id>'."\n"; |
---|
| 180 | |
---|
| 181 | $content_tag = ($feed['type'] == 'posts') ? 'content' : 'summary'; |
---|
| 182 | |
---|
| 183 | foreach ($feed['items'] as $item) |
---|
| 184 | { |
---|
| 185 | echo "\t".'<entry>'."\n"; |
---|
| 186 | echo "\t\t".'<title type="html"><![CDATA['.escape_cdata($item['title']).']]></title>'."\n"; |
---|
| 187 | echo "\t\t".'<link rel="alternate" href="'.pun_htmlspecialchars($item['link']).'"/>'."\n"; |
---|
| 188 | echo "\t\t".'<'.$content_tag.' type="html"><![CDATA['.escape_cdata($item['description']).']]></'.$content_tag.'>'."\n"; |
---|
| 189 | echo "\t\t".'<author>'."\n"; |
---|
| 190 | echo "\t\t\t".'<name><![CDATA['.escape_cdata($item['author']['name']).']]></name>'."\n"; |
---|
| 191 | |
---|
| 192 | if (isset($item['author']['email'])) |
---|
| 193 | echo "\t\t\t".'<email><![CDATA['.escape_cdata($item['author']['email']).']]></email>'."\n"; |
---|
| 194 | |
---|
| 195 | if (isset($item['author']['uri'])) |
---|
| 196 | echo "\t\t\t".'<uri>'.pun_htmlspecialchars($item['author']['uri']).'</uri>'."\n"; |
---|
| 197 | |
---|
| 198 | echo "\t\t".'</author>'."\n"; |
---|
| 199 | echo "\t\t".'<updated>'.gmdate('Y-m-d\TH:i:s\Z', $item['pubdate']).'</updated>'."\n"; |
---|
| 200 | |
---|
| 201 | echo "\t\t".'<id>'.pun_htmlspecialchars($item['link']).'</id>'."\n"; |
---|
| 202 | echo "\t".'</entry>'."\n"; |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | echo '</feed>'."\n"; |
---|
| 206 | } |
---|
| 207 | |
---|
| 208 | |
---|
| 209 | // |
---|
| 210 | // Output $feed as XML |
---|
| 211 | // |
---|
| 212 | function output_xml($feed) |
---|
| 213 | { |
---|
| 214 | global $lang_common, $pun_config; |
---|
| 215 | |
---|
| 216 | // Send XML/no cache headers |
---|
| 217 | header('Content-Type: application/xml; charset=utf-8'); |
---|
| 218 | header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); |
---|
| 219 | header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); |
---|
| 220 | header('Pragma: public'); |
---|
| 221 | |
---|
| 222 | echo '<?xml version="1.0" encoding="utf-8"?>'."\n"; |
---|
| 223 | echo '<source>'."\n"; |
---|
| 224 | echo "\t".'<url>'.pun_htmlspecialchars($feed['link']).'</url>'."\n"; |
---|
| 225 | |
---|
| 226 | $forum_tag = ($feed['type'] == 'posts') ? 'post' : 'topic'; |
---|
| 227 | |
---|
| 228 | foreach ($feed['items'] as $item) |
---|
| 229 | { |
---|
| 230 | echo "\t".'<'.$forum_tag.' id="'.$item['id'].'">'."\n"; |
---|
| 231 | |
---|
| 232 | echo "\t\t".'<title><![CDATA['.escape_cdata($item['title']).']]></title>'."\n"; |
---|
| 233 | echo "\t\t".'<link>'.pun_htmlspecialchars($item['link']).'</link>'."\n"; |
---|
| 234 | echo "\t\t".'<content><![CDATA['.escape_cdata($item['description']).']]></content>'."\n"; |
---|
| 235 | echo "\t\t".'<author>'."\n"; |
---|
| 236 | echo "\t\t\t".'<name><![CDATA['.escape_cdata($item['author']['name']).']]></name>'."\n"; |
---|
| 237 | |
---|
| 238 | if (isset($item['author']['email'])) |
---|
| 239 | echo "\t\t\t".'<email><![CDATA['.escape_cdata($item['author']['email']).']]></email>'."\n"; |
---|
| 240 | |
---|
| 241 | if (isset($item['author']['uri'])) |
---|
| 242 | echo "\t\t\t".'<uri>'.pun_htmlspecialchars($item['author']['uri']).'</uri>'."\n"; |
---|
| 243 | |
---|
| 244 | echo "\t\t".'</author>'."\n"; |
---|
| 245 | echo "\t\t".'<posted>'.gmdate('r', $item['pubdate']).'</posted>'."\n"; |
---|
| 246 | |
---|
| 247 | echo "\t".'</'.$forum_tag.'>'."\n"; |
---|
| 248 | } |
---|
| 249 | |
---|
| 250 | echo '</source>'."\n"; |
---|
| 251 | } |
---|
| 252 | |
---|
| 253 | |
---|
| 254 | // |
---|
| 255 | // Output $feed as HTML (using <li> tags) |
---|
| 256 | // |
---|
| 257 | function output_html($feed) |
---|
| 258 | { |
---|
| 259 | |
---|
| 260 | // Send the Content-type header in case the web server is setup to send something else |
---|
| 261 | header('Content-type: text/html; charset=utf-8'); |
---|
| 262 | header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); |
---|
| 263 | header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); |
---|
| 264 | header('Pragma: public'); |
---|
| 265 | |
---|
| 266 | foreach ($feed['items'] as $item) |
---|
| 267 | { |
---|
| 268 | if (utf8_strlen($item['title']) > FORUM_EXTERN_MAX_SUBJECT_LENGTH) |
---|
| 269 | $subject_truncated = pun_htmlspecialchars(pun_trim(utf8_substr($item['title'], 0, (FORUM_EXTERN_MAX_SUBJECT_LENGTH - 5)))).' âŠ'; |
---|
| 270 | else |
---|
| 271 | $subject_truncated = pun_htmlspecialchars($item['title']); |
---|
| 272 | |
---|
| 273 | echo '<li><a href="'.pun_htmlspecialchars($item['link']).'" title="'.pun_htmlspecialchars($item['title']).'">'.$subject_truncated.'</a></li>'."\n"; |
---|
| 274 | } |
---|
| 275 | } |
---|
| 276 | |
---|
| 277 | // Show recent discussions |
---|
| 278 | if ($action == 'feed') |
---|
| 279 | { |
---|
| 280 | require PUN_ROOT.'include/parser.php'; |
---|
| 281 | |
---|
| 282 | // Determine what type of feed to output |
---|
| 283 | $type = isset($_GET['type']) ? strtolower($_GET['type']) : 'html'; |
---|
| 284 | if (!in_array($type, array('html', 'rss', 'atom', 'xml'))) |
---|
| 285 | $type = 'html'; |
---|
| 286 | |
---|
| 287 | $show = isset($_GET['show']) ? intval($_GET['show']) : 15; |
---|
| 288 | if ($show < 1 || $show > 50) |
---|
| 289 | $show = 15; |
---|
| 290 | |
---|
| 291 | // Was a topic ID supplied? |
---|
| 292 | if (isset($_GET['tid'])) |
---|
| 293 | { |
---|
| 294 | $tid = intval($_GET['tid']); |
---|
| 295 | |
---|
| 296 | // Fetch topic subject |
---|
| 297 | $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()); |
---|
| 298 | if (!$db->num_rows($result)) |
---|
| 299 | { |
---|
| 300 | http_authenticate_user(); |
---|
| 301 | exit($lang_common['Bad request']); |
---|
| 302 | } |
---|
| 303 | |
---|
| 304 | $cur_topic = $db->fetch_assoc($result); |
---|
| 305 | |
---|
| 306 | if ($pun_config['o_censoring'] == '1') |
---|
| 307 | $cur_topic['subject'] = censor_words($cur_topic['subject']); |
---|
| 308 | |
---|
| 309 | // Setup the feed |
---|
| 310 | $feed = array( |
---|
| 311 | 'title' => $pun_config['o_board_title'].$lang_common['Title separator'].$cur_topic['subject'], |
---|
| 312 | 'link' => get_base_url(true).'/viewtopic.php?id='.$tid, |
---|
| 313 | 'description' => sprintf($lang_common['RSS description topic'], $cur_topic['subject']), |
---|
| 314 | 'items' => array(), |
---|
| 315 | 'type' => 'posts' |
---|
| 316 | ); |
---|
| 317 | |
---|
| 318 | // Fetch $show posts |
---|
| 319 | $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()); |
---|
| 320 | while ($cur_post = $db->fetch_assoc($result)) |
---|
| 321 | { |
---|
| 322 | $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']); |
---|
| 323 | |
---|
| 324 | $item = array( |
---|
| 325 | 'id' => $cur_post['id'], |
---|
| 326 | 'title' => $cur_topic['first_post_id'] == $cur_post['id'] ? $cur_topic['subject'] : $lang_common['RSS reply'].$cur_topic['subject'], |
---|
| 327 | 'link' => get_base_url(true).'/viewtopic.php?pid='.$cur_post['id'].'#p'.$cur_post['id'], |
---|
| 328 | 'description' => $cur_post['message'], |
---|
| 329 | 'author' => array( |
---|
| 330 | 'name' => $cur_post['poster'], |
---|
| 331 | ), |
---|
| 332 | 'pubdate' => $cur_post['posted'] |
---|
| 333 | ); |
---|
| 334 | |
---|
| 335 | if ($cur_post['poster_id'] > 1) |
---|
| 336 | { |
---|
| 337 | if ($cur_post['email_setting'] == '0' && !$pun_user['is_guest']) |
---|
| 338 | $item['author']['email'] = $cur_post['email']; |
---|
| 339 | |
---|
| 340 | $item['author']['uri'] = get_base_url(true).'/profile.php?id='.$cur_post['poster_id']; |
---|
| 341 | } |
---|
| 342 | else if ($cur_post['poster_email'] != '' && !$pun_user['is_guest']) |
---|
| 343 | $item['author']['email'] = $cur_post['poster_email']; |
---|
| 344 | |
---|
| 345 | $feed['items'][] = $item; |
---|
| 346 | } |
---|
| 347 | |
---|
| 348 | $output_func = 'output_'.$type; |
---|
| 349 | $output_func($feed); |
---|
| 350 | } |
---|
| 351 | else |
---|
| 352 | { |
---|
| 353 | $order_posted = isset($_GET['order']) && strtolower($_GET['order']) == 'posted'; |
---|
| 354 | $forum_name = ''; |
---|
| 355 | $forum_sql = ''; |
---|
| 356 | |
---|
| 357 | // Were any forum IDs supplied? |
---|
| 358 | if (isset($_GET['fid']) && is_scalar($_GET['fid']) && $_GET['fid'] != '') |
---|
| 359 | { |
---|
| 360 | $fids = explode(',', pun_trim($_GET['fid'])); |
---|
| 361 | $fids = array_map('intval', $fids); |
---|
| 362 | |
---|
| 363 | if (!empty($fids)) |
---|
| 364 | $forum_sql .= ' AND t.forum_id IN('.implode(',', $fids).')'; |
---|
| 365 | |
---|
| 366 | if (count($fids) == 1) |
---|
| 367 | { |
---|
| 368 | // Fetch forum name |
---|
| 369 | $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()); |
---|
| 370 | if ($db->num_rows($result)) |
---|
| 371 | $forum_name = $lang_common['Title separator'].$db->result($result); |
---|
| 372 | } |
---|
| 373 | } |
---|
| 374 | |
---|
| 375 | // Any forum IDs to exclude? |
---|
| 376 | if (isset($_GET['nfid']) && is_scalar($_GET['nfid']) && $_GET['nfid'] != '') |
---|
| 377 | { |
---|
| 378 | $nfids = explode(',', pun_trim($_GET['nfid'])); |
---|
| 379 | $nfids = array_map('intval', $nfids); |
---|
| 380 | |
---|
| 381 | if (!empty($nfids)) |
---|
| 382 | $forum_sql .= ' AND t.forum_id NOT IN('.implode(',', $nfids).')'; |
---|
| 383 | } |
---|
| 384 | |
---|
| 385 | // Only attempt to cache if caching is enabled and we have all or a single forum |
---|
| 386 | if ($pun_config['o_feed_ttl'] > 0 && ($forum_sql == '' || ($forum_name != '' && !isset($_GET['nfid'])))) |
---|
| 387 | $cache_id = 'feed'.sha1($pun_user['g_id'].'|'.$lang_common['lang_identifier'].'|'.($order_posted ? '1' : '0').($forum_name == '' ? '' : '|'.$fids[0])); |
---|
| 388 | |
---|
| 389 | // Load cached feed |
---|
| 390 | if (isset($cache_id) && file_exists(FORUM_CACHE_DIR.'cache_'.$cache_id.'.php')) |
---|
| 391 | include FORUM_CACHE_DIR.'cache_'.$cache_id.'.php'; |
---|
| 392 | |
---|
| 393 | $now = time(); |
---|
| 394 | if (!isset($feed) || $cache_expire < $now) |
---|
| 395 | { |
---|
| 396 | // Setup the feed |
---|
| 397 | $feed = array( |
---|
| 398 | 'title' => $pun_config['o_board_title'].$forum_name, |
---|
| 399 | 'link' => '/index.php', |
---|
| 400 | 'description' => sprintf($lang_common['RSS description'], $pun_config['o_board_title']), |
---|
| 401 | 'items' => array(), |
---|
| 402 | 'type' => 'topics' |
---|
| 403 | ); |
---|
| 404 | |
---|
| 405 | // Fetch $show topics |
---|
| 406 | $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 '.(isset($cache_id) ? 50 : $show)) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error()); |
---|
| 407 | while ($cur_topic = $db->fetch_assoc($result)) |
---|
| 408 | { |
---|
| 409 | if ($pun_config['o_censoring'] == '1') |
---|
| 410 | $cur_topic['subject'] = censor_words($cur_topic['subject']); |
---|
| 411 | |
---|
| 412 | $cur_topic['message'] = parse_message($cur_topic['message'], $cur_topic['hide_smilies']); |
---|
| 413 | |
---|
| 414 | $item = array( |
---|
| 415 | 'id' => $cur_topic['id'], |
---|
| 416 | 'title' => $cur_topic['subject'], |
---|
| 417 | 'link' => '/viewtopic.php?id='.$cur_topic['id'].($order_posted ? '' : '&action=new'), |
---|
| 418 | 'description' => $cur_topic['message'], |
---|
| 419 | 'author' => array( |
---|
| 420 | 'name' => $order_posted ? $cur_topic['poster'] : $cur_topic['last_poster'] |
---|
| 421 | ), |
---|
| 422 | 'pubdate' => $order_posted ? $cur_topic['posted'] : $cur_topic['last_post'] |
---|
| 423 | ); |
---|
| 424 | |
---|
| 425 | if ($cur_topic['poster_id'] > 1) |
---|
| 426 | { |
---|
| 427 | if ($cur_topic['email_setting'] == '0' && !$pun_user['is_guest']) |
---|
| 428 | $item['author']['email'] = $cur_topic['email']; |
---|
| 429 | |
---|
| 430 | $item['author']['uri'] = '/profile.php?id='.$cur_topic['poster_id']; |
---|
| 431 | } |
---|
| 432 | else if ($cur_topic['poster_email'] != '' && !$pun_user['is_guest']) |
---|
| 433 | $item['author']['email'] = $cur_topic['poster_email']; |
---|
| 434 | |
---|
| 435 | $feed['items'][] = $item; |
---|
| 436 | } |
---|
| 437 | |
---|
| 438 | // Output feed as PHP code |
---|
| 439 | if (isset($cache_id)) |
---|
| 440 | { |
---|
| 441 | $fh = @fopen(FORUM_CACHE_DIR.'cache_'.$cache_id.'.php', 'wb'); |
---|
| 442 | if (!$fh) |
---|
| 443 | error('Unable to write feed cache file to cache directory. Please make sure PHP has write access to the directory \''.pun_htmlspecialchars(FORUM_CACHE_DIR).'\'', __FILE__, __LINE__); |
---|
| 444 | |
---|
| 445 | fwrite($fh, '<?php'."\n\n".'$feed = '.var_export($feed, true).';'."\n\n".'$cache_expire = '.($now + ($pun_config['o_feed_ttl'] * 60)).';'."\n\n".'?>'); |
---|
| 446 | |
---|
| 447 | fclose($fh); |
---|
| 448 | |
---|
| 449 | if (function_exists('apc_delete_file')) |
---|
| 450 | @apc_delete_file(FORUM_CACHE_DIR.'cache_'.$cache_id.'.php'); |
---|
| 451 | } |
---|
| 452 | } |
---|
| 453 | |
---|
| 454 | // If we only want to show a few items but due to caching we have too many |
---|
| 455 | if (count($feed['items']) > $show) |
---|
| 456 | $feed['items'] = array_slice($feed['items'], 0, $show); |
---|
| 457 | |
---|
| 458 | // Prepend the current base URL onto some links. Done after caching to handle http/https correctly |
---|
| 459 | $feed['link'] = get_base_url(true).$feed['link']; |
---|
| 460 | |
---|
| 461 | foreach ($feed['items'] as $key => $item) |
---|
| 462 | { |
---|
| 463 | $feed['items'][$key]['link'] = get_base_url(true).$item['link']; |
---|
| 464 | |
---|
| 465 | if (isset($item['author']['uri'])) |
---|
| 466 | $feed['items'][$key]['author']['uri'] = get_base_url(true).$item['author']['uri']; |
---|
| 467 | } |
---|
| 468 | |
---|
| 469 | $output_func = 'output_'.$type; |
---|
| 470 | $output_func($feed); |
---|
| 471 | } |
---|
| 472 | |
---|
| 473 | exit; |
---|
| 474 | } |
---|
| 475 | |
---|
| 476 | // Show users online |
---|
| 477 | else if ($action == 'online' || $action == 'online_full') |
---|
| 478 | { |
---|
| 479 | // Load the index.php language file |
---|
| 480 | require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; |
---|
| 481 | |
---|
| 482 | // Fetch users online info and generate strings for output |
---|
| 483 | $num_guests = $num_users = 0; |
---|
| 484 | $users = array(); |
---|
| 485 | |
---|
| 486 | $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()); |
---|
| 487 | |
---|
| 488 | while ($pun_user_online = $db->fetch_assoc($result)) |
---|
| 489 | { |
---|
| 490 | if ($pun_user_online['user_id'] > 1) |
---|
| 491 | { |
---|
| 492 | $users[] = ($pun_user['g_view_users'] == '1') ? '<a href="'.pun_htmlspecialchars(get_base_url(true)).'/profile.php?id='.$pun_user_online['user_id'].'">'.pun_htmlspecialchars($pun_user_online['ident']).'</a>' : pun_htmlspecialchars($pun_user_online['ident']); |
---|
| 493 | ++$num_users; |
---|
| 494 | } |
---|
| 495 | else |
---|
| 496 | ++$num_guests; |
---|
| 497 | } |
---|
| 498 | |
---|
| 499 | // Send the Content-type header in case the web server is setup to send something else |
---|
| 500 | header('Content-type: text/html; charset=utf-8'); |
---|
| 501 | header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); |
---|
| 502 | header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); |
---|
| 503 | header('Pragma: public'); |
---|
| 504 | |
---|
| 505 | echo sprintf($lang_index['Guests online'], forum_number_format($num_guests)).'<br />'."\n"; |
---|
| 506 | |
---|
| 507 | if ($action == 'online_full' && !empty($users)) |
---|
| 508 | echo sprintf($lang_index['Users online'], implode(', ', $users)).'<br />'."\n"; |
---|
| 509 | else |
---|
| 510 | echo sprintf($lang_index['Users online'], forum_number_format($num_users)).'<br />'."\n"; |
---|
| 511 | |
---|
| 512 | exit; |
---|
| 513 | } |
---|
| 514 | |
---|
| 515 | // Show board statistics |
---|
| 516 | else if ($action == 'stats') |
---|
| 517 | { |
---|
| 518 | // Load the index.php language file |
---|
| 519 | require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; |
---|
| 520 | |
---|
| 521 | // Collect some statistics from the database |
---|
| 522 | if (file_exists(FORUM_CACHE_DIR.'cache_users_info.php')) |
---|
| 523 | include FORUM_CACHE_DIR.'cache_users_info.php'; |
---|
| 524 | |
---|
| 525 | if (!defined('PUN_USERS_INFO_LOADED')) |
---|
| 526 | { |
---|
| 527 | if (!defined('FORUM_CACHE_FUNCTIONS_LOADED')) |
---|
| 528 | require PUN_ROOT.'include/cache.php'; |
---|
| 529 | |
---|
| 530 | generate_users_info_cache(); |
---|
| 531 | require FORUM_CACHE_DIR.'cache_users_info.php'; |
---|
| 532 | } |
---|
| 533 | |
---|
| 534 | $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()); |
---|
| 535 | list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result); |
---|
| 536 | |
---|
| 537 | // Send the Content-type header in case the web server is setup to send something else |
---|
| 538 | header('Content-type: text/html; charset=utf-8'); |
---|
| 539 | header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); |
---|
| 540 | header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); |
---|
| 541 | header('Pragma: public'); |
---|
| 542 | |
---|
| 543 | echo sprintf($lang_index['No of users'], forum_number_format($stats['total_users'])).'<br />'."\n"; |
---|
| 544 | echo sprintf($lang_index['Newest user'], (($pun_user['g_view_users'] == '1') ? '<a href="'.pun_htmlspecialchars(get_base_url(true)).'/profile.php?id='.$stats['last_user']['id'].'">'.pun_htmlspecialchars($stats['last_user']['username']).'</a>' : pun_htmlspecialchars($stats['last_user']['username']))).'<br />'."\n"; |
---|
| 545 | echo sprintf($lang_index['No of topics'], forum_number_format($stats['total_topics'])).'<br />'."\n"; |
---|
| 546 | echo sprintf($lang_index['No of posts'], forum_number_format($stats['total_posts'])).'<br />'."\n"; |
---|
| 547 | |
---|
| 548 | exit; |
---|
| 549 | } |
---|
| 550 | |
---|
| 551 | // If we end up here, the script was called with some wacky parameters |
---|
| 552 | exit($lang_common['Bad request']); |
---|