diff -r 5e1f1e916419 -r 98bbc533541c punbb/extern.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/punbb/extern.php Sun Apr 06 00:28:50 2008 -0400 @@ -0,0 +1,519 @@ +'s) + + fid: One or more forum ID's (comma-separated). If ignored, + topics from all guest-readable forums will be pulled. + + nfid: One or more forum ID's (comma-separated) that are to be + excluded. E.g. the ID of a a test forum. + + tid: A topic ID from which to show posts. If a tid is supplied, + fid and nfid are ignored. + + show: Any integer value between 1 and 50. This variables is + ignored for RSS/Atom output. The default is 15. + + +/***********************************************************************/ + +// The length at which topic subjects will be truncated (for HTML output) +define('MAX_SUBJECT_LENGTH', 30); + + +// if (!defined('PUN_ROOT')) +// define('PUN_ROOT', './'); +// require PUN_ROOT.'include/common.php'; + +// import globals (I really hope this isn't dangerous) +foreach ( $GLOBALS as $key => $_ ) +{ + $$key =& $GLOBALS[$key]; +} + +($hook = get_hook('ex_start')) ? eval($hook) : null; + +if ($pun_user['g_read_board'] == '0') + exit($lang_common['No view']); + + +// +// Converts the CDATA end sequence ]]> into ]]> +// +function escape_cdata($str) +{ + return str_replace(']]>', ']]>', $str); +} + + +// +// Output $feed as RSS 2.0 +// +function output_rss($feed) +{ + global $lang_common, $pun_config; + + // Send XML/no cache headers + header('Content-Type: text/xml; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo ''."\r\n"; + echo ''."\r\n"; + echo "\t".''."\r\n"; + echo "\t\t".''.htmlspecialchars($feed['title']).''."\r\n"; + echo "\t\t".''.$feed['link'].''."\r\n"; + echo "\t\t".''.htmlspecialchars($feed['description']).''."\r\n"; + echo "\t\t".''.gmdate('r', count($feed['items']) ? $feed['items'][0]['pubdate'] : time()).''."\r\n"; + + if ($pun_config['o_show_version'] == '1') + echo "\t\t".'PunBB '.$pun_config['o_cur_version'].''."\r\n"; + else + echo "\t\t".'PunBB'."\r\n"; + + $num_items = count($feed['items']); + for ($i = 0; $i < $num_items; ++$i) + { + echo "\t\t".''."\r\n"; + echo "\t\t\t".''.htmlspecialchars($feed['items'][$i]['title']).''."\r\n"; + echo "\t\t\t".''.$feed['items'][$i]['link'].''."\r\n"; + echo "\t\t\t".''.htmlspecialchars($feed['items'][$i]['description']).''."\r\n"; + echo "\t\t\t".'dummy@email.com ('.htmlspecialchars($feed['items'][$i]['author']).')'."\r\n"; + echo "\t\t\t".''.gmdate('r', $feed['items'][$i]['pubdate']).''."\r\n"; + echo "\t\t\t".''.$feed['items'][$i]['link'].''."\r\n"; + echo "\t\t".''."\r\n"; + } + + echo "\t".''."\r\n"; + echo ''."\r\n"; +} + + +// +// Output $feed as Atom 1.0 +// +function output_atom($feed) +{ + global $lang_common, $pun_config; + + // Send XML/no cache headers + header('Content-Type: text/xml; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo ''."\r\n"; + echo ''."\r\n"; + + echo "\t".''.htmlspecialchars($feed['title']).''."\r\n"; + echo "\t".''."\r\n"; + echo "\t".''.gmdate('Y-m-d\TH:i:s\Z', $feed['items'][0]['pubdate']).''."\r\n"; + + if ($pun_config['o_show_version'] == '1') + echo "\t".'PunBB'."\r\n"; + else + echo "\t".'PunBB'."\r\n"; + + echo "\t".''.$feed['link'].''."\r\n"; + + $content_tag = ($feed['type'] == 'posts') ? 'content' : 'summary'; + + $num_items = count($feed['items']); + for ($i = 0; $i < $num_items; ++$i) + { + echo "\t\t".''."\r\n"; + echo "\t\t\t".''.htmlspecialchars($feed['items'][$i]['title']).''."\r\n"; + echo "\t\t\t".''."\r\n"; + echo "\t\t\t".'<'.$content_tag.' type="html">'.htmlspecialchars($feed['items'][$i]['description']).''."\r\n"; + echo "\t\t\t".''."\r\n"; + echo "\t\t\t\t".''.htmlspecialchars($feed['items'][$i]['author']).''."\r\n"; + echo "\t\t\t".''."\r\n"; + echo "\t\t\t".''.gmdate('Y-m-d\TH:i:s\Z', $feed['items'][$i]['pubdate']).''."\r\n"; + echo "\t\t\t".''.$feed['items'][$i]['link'].''."\r\n"; + echo "\t\t".''."\r\n"; + } + + echo ''."\r\n"; +} + + +// +// Output $feed as XML +// +function output_xml($feed) +{ + global $lang_common, $pun_config; + + // Send XML/no cache headers + header('Content-Type: text/xml; charset=utf-8'); + header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + + echo ''."\r\n"; + echo ''."\r\n"; + echo "\t".''.$feed['link'].''."\r\n"; + + $pun_tag = ($feed['type'] == 'posts') ? 'post' : 'topic'; + + $num_items = count($feed['items']); + for ($i = 0; $i < $num_items; ++$i) + { + echo "\t".'<'.$pun_tag.' id="'.$feed['items'][$i]['id'].'">'."\r\n"; + + echo "\t\t".''.htmlspecialchars($feed['items'][$i]['title']).''."\r\n"; + echo "\t\t".''.$feed['items'][$i]['link'].''."\r\n"; + echo "\t\t".''.htmlspecialchars($feed['items'][$i]['description']).''."\r\n"; + echo "\t\t".''.htmlspecialchars($feed['items'][$i]['author']).''."\r\n"; + echo "\t\t".''.gmdate('r', $feed['items'][$i]['pubdate']).''."\r\n"; + + echo "\t".''."\r\n"; + } + + echo ''."\r\n"; +} + + +// +// Output $feed as HTML (using
  • tags) +// +function output_html($feed) +{ + global $pun_config; + + $num_items = count($feed['items']); + for ($i = 0; $i < $num_items; ++$i) + { + if ($pun_config['o_censoring'] == '1') + $feed['items'][$i]['title'] = censor_words($feed['items'][$i]['title']); + + if (pun_strlen($feed['items'][$i]['title']) > MAX_SUBJECT_LENGTH) + $subject_truncated = htmlspecialchars(trim(substr($feed['items'][$i]['title'], 0, (MAX_SUBJECT_LENGTH-5)))).' …'; + else + $subject_truncated = htmlspecialchars($feed['items'][$i]['title']); + + echo '
  • '.$subject_truncated.'
  • '."\n"; + } +} + + +// +// Show recent discussions +// +if ($_GET['action'] == 'feed') +{ + // Determine what type of feed to output + $type = 'html'; + if (isset($_GET['type']) && is_scalar($_GET['type'])) + { + if (strtolower($_GET['type']) == 'rss') + $type = 'rss'; + else if (strtolower($_GET['type']) == 'atom') + $type = 'atom'; + else if (strtolower($_GET['type']) == 'xml') + $type = 'xml'; + } + + $forum_sql = ''; + + // Was a topic ID supplied? + if (isset($_GET['tid'])) + { + $tid = intval($_GET['tid']); + + // Fetch topic subject + $query = array( + 'SELECT' => 't.subject, t.num_replies', + 'FROM' => 'topics AS t', + 'JOINS' => array( + array( + 'LEFT JOIN' => 'forum_perms AS fp', + 'ON' => '(fp.forum_id=t.forum_id AND fp.group_id=2)' + ) + ), + 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL and t.id='.$tid + ); + + ($hook = get_hook('ex_qr_get_topic_data')) ? eval($hook) : null; + $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); + if (!$pun_db->num_rows($result)) + exit('Bad request. The link you followed is incorrect or outdated.'); + + $cur_topic = $pun_db->fetch_assoc($result); + + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + // Setup the feed + $feed = array( + 'title' => $pun_config['o_board_title'].' - '.$cur_topic['subject'], + 'link' => pun_link($pun_url['topic'], $tid), + 'description' => sprintf($lang_common['RSS description topic'], $cur_topic['subject']), + 'items' => array(), + 'type' => 'posts' + ); + + // Fetch 15 posts + $query = array( + 'SELECT' => 'p.id, p.poster, p.message, p.posted', + 'FROM' => 'posts AS p', + 'WHERE' => 'p.topic_id='.$tid, + 'ORDER BY' => 'p.posted DESC', + 'LIMIT' => '15' + ); + + ($hook = get_hook('ex_qr_get_posts')) ? eval($hook) : null; + $result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__); + while ($cur_post = $pun_db->fetch_assoc($result)) + { + $feed['items'][] = array( + 'id' => $cur_post['id'], + 'title' => $lang_common['RSS reply'].$cur_topic['subject'], + 'link' => pun_link($pun_url['post'], $cur_post['id']), + 'description' => $cur_post['message'], + 'author' => $cur_post['poster'], + 'pubdate' => $cur_post['posted'] + ); + } + + if (intval($cur_topic['num_replies']) <= 14) + $feed['items'][count($feed['items'])-1]['title'] = $cur_topic['subject']; + + ($hook = get_hook('ex_pre_topic_output')) ? eval($hook) : null; + + $output_func = 'output_'.$type; + $output_func($feed); + } + else + { + // Was any specific forum ID's supplied? + if (isset($_GET['fid']) && is_scalar($_GET['fid']) && $_GET['fid'] != '') + { + $fids = explode(',', trim($_GET['fid'])); + $fids = array_map('intval', $fids); + + if (!empty($fids)) + $forum_sql = ' AND f.id IN('.implode(',', $fids).')'; + } + + // Any forum ID's to exclude? + if (isset($_GET['nfid']) && is_scalar($_GET['nfid']) && $_GET['nfid'] != '') + { + $nfids = explode(',', trim($_GET['nfid'])); + $nfids = array_map('intval', $nfids); + + if (!empty($nfids)) + $forum_sql = ' AND f.id NOT IN('.implode(',', $nfids).')'; + } + + // Setup the feed + $feed = array( + 'title' => $pun_config['o_board_title'], + 'link' => pun_link($pun_url['index']), + 'description' => sprintf($lang_common['RSS description'], $pun_config['o_board_title']), + 'items' => array(), + 'type' => 'topics' + ); + + + if (isset($_GET['type']) && is_scalar($_GET['type']) && strtoupper($_GET['type']) == 'RSS') + $show = 15; + else + { + $show = isset($_GET['show']) ? intval($_GET['show']) : 15; + if ($show < 1 || $show > 50) + $show = 15; + } + + // Fetch $show topics + $query = array( + 'SELECT' => 't.id, t.poster, t.subject, t.last_post, t.last_poster, f.id AS fid, f.forum_name', + 'FROM' => 'topics AS t', + 'JOINS' => array( + array( + 'INNER JOIN' => 'forums AS f', + 'ON' => 'f.id=t.forum_id' + ), + array( + 'LEFT JOIN' => 'forum_perms AS fp', + 'ON' => '(fp.forum_id=f.id AND fp.group_id=2)' + ) + ), + 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL', + 'ORDER BY' => 't.last_post DESC', + 'LIMIT' => $show + ); + + if (isset($forum_sql)) + $query['WHERE'] .= $forum_sql; + + ($hook = get_hook('ex_qr_get_topics')) ? eval($hook) : null; + $result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__); + while ($cur_topic = $pun_db->fetch_assoc($result)) + { + if ($pun_config['o_censoring'] == '1') + $cur_topic['subject'] = censor_words($cur_topic['subject']); + + $feed['items'][] = array( + 'id' => $cur_topic['id'], + 'title' => $cur_topic['subject'], + 'link' => pun_link($pun_url['topic_new_posts'], $cur_topic['id']), + 'description' => $lang_common['Forum'].': '.$cur_topic['forum_name'].'', + 'author' => $cur_topic['last_poster'], + 'pubdate' => $cur_topic['last_post'] + ); + } + + ($hook = get_hook('ex_pre_forum_output')) ? eval($hook) : null; + + $output_func = 'output_'.$type; + $output_func($feed); + } + + return; +} + + +// +// Show users online +// +else if ($_GET['action'] == 'online' || $_GET['action'] == 'online_full') +{ + // Load the index.php language file + require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; + + // Fetch users online info and generate strings for output + $num_guests = $num_users = 0; + $users = array(); + + $query = array( + 'SELECT' => 'o.user_id, o.ident', + 'FROM' => 'online AS o', + 'WHERE' => 'o.idle=0', + 'ORDER BY' => 'o.ident' + ); + + ($hook = get_hook('ex_qr_get_users_online')) ? eval($hook) : null; + $result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__); + while ($pun_user_online = $pun_db->fetch_assoc($result)) + { + if ($pun_user_online['user_id'] > 1) + { + $users[] = ''.htmlspecialchars($pun_user_online['ident']).''; + ++$num_users; + } + else + ++$num_guests; + } + + echo $lang_index['Guests online'].': '.$num_guests.'
    '; + + if ($_GET['action'] == 'online_full') + echo $lang_index['Users online'].': '.implode(', ', $users).'
    '; + else + echo $lang_index['Users online'].': '.$num_users.'
    '; + + return; +} + + +// +// Show board statistics +// +else if ($_GET['action'] == 'stats') +{ + // Load the index.php language file + require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php'; + + // Collect some statistics from the database + $query = array( + 'SELECT' => 'COUNT(u.id)-1', + 'FROM' => 'users AS u' + ); + + ($hook = get_hook('ex_qr_get_user_count')) ? eval($hook) : null; + $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); + $stats['total_users'] = $pun_db->result($result); + + $query = array( + 'SELECT' => 'u.id, u.username', + 'FROM' => 'users AS u', + 'ORDER BY' => 'u.registered DESC', + 'LIMIT' => '1' + ); + + ($hook = get_hook('ex_qr_get_newest_user')) ? eval($hook) : null; + $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); + $stats['last_user'] = $pun_db->fetch_assoc($result); + + $query = array( + 'SELECT' => 'SUM(f.num_topics), SUM(f.num_posts)', + 'FROM' => 'forums AS f' + ); + + ($hook = get_hook('ex_qr_get_post_stats')) ? eval($hook) : null; + $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); + list($stats['total_topics'], $stats['total_posts']) = $pun_db->fetch_row($result); + + echo $lang_index['No of users'].': '.$stats['total_users'].'
    '; + echo $lang_index['Newest user'].': '.htmlspecialchars($stats['last_user']['username']).'
    '; + echo $lang_index['No of topics'].': '.intval($stats['total_topics']).'
    '; + echo $lang_index['No of posts'].': '.intval($stats['total_posts']); + + return; +} + + +($hook = get_hook('ex_new_action')) ? eval($hook) : null; + +// If we end up here, the script was called with some wacky parameters +exit($lang_common['Bad request']);