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']); |
---|