SSI script | > Script written by Matt Mecham | > Date started: 29th April 2002 | > UPDATED for 2.0: 1st July 2004 | > UPDATED for 2.1: 13th Sept 2005 | +-------------------------------------------------------------------------- +-------------------------------------------------------------------------- | USAGE: +-------------------------------------------------------------------------- Simply call this script via PHP includes, or SSI .shtml tags to generate content on the fly, streamed into your own webpage. +-------------------------------------------------------------------------- | To show the last 10 topics and posts in the news forums... +-------------------------------------------------------------------------- include("http://domain.com/forums/ssi.php?a=news&show=10"); You can adjust the "show" attribute to display a different amount of topics. +-------------------------------------------------------------------------- | To show the board statistics +-------------------------------------------------------------------------- include("http://domain.com/forums/ssi.php?a=stats"); +-------------------------------------------------------------------------- | To show the active users stats (x Members, X Guests, etc) +-------------------------------------------------------------------------- include("http://domain.com/forums/ssi.php?a=active"); +-------------------------------------------------------------------------- | RSS / XML Syndication.. +-------------------------------------------------------------------------- RSS: http://domain.com/forums/ssi.php?a=out&f=1,2,3,4,5&show=10&type=rss XML: http://domain.com/forums/ssi.php?a=out&f=1,2,3,4,5&show=10&type=xml Will show last 10 topics in reverse chronological last post date order from all the forums in the comma separated list */ /** * Main executable wrapper. * * Set-up and load module to run * * @package InvisionPowerBoard * @author Matt Mecham * @version 2.1 */ /** * Script type * */ define( 'IPB_THIS_SCRIPT', 'public' ); define( 'IPB_LOAD_SQL' , 'queries' ); require_once( './init.php' ); //-------------------------------- // Other set up //-------------------------------- /** * Path to SSI templates directory * */ define( 'SSI_TEMPLATES_DIR', ROOT_PATH."ssi_templates" ); /** * Maximum number of topics to show * */ define( 'SSI_MAX_SHOW' , 100 ); /** * Allow SSI export. Enter "0" to turn off. * */ define( 'SSI_ALLOW_SYND' , 1 ); //=========================================================================== // MAIN PROGRAM //=========================================================================== $INFO = array(); //-------------------------------- // Load our classes //-------------------------------- require_once ROOT_PATH . "sources/ipsclass.php"; require_once ROOT_PATH . "sources/classes/class_forums.php"; require_once ROOT_PATH . "sources/classes/class_session.php"; require_once KERNEL_PATH . "class_converge.php"; require_once ROOT_PATH . "conf_global.php"; # Initiate super-class $ipsclass = new ipsclass(); $ipsclass->vars = $INFO; //-------------------------------- // The clocks a' tickin' //-------------------------------- $Debug = new Debug; $Debug->startTimer(); //-------------------------------- // Load the DB driver and such //-------------------------------- $ipsclass->init_db_connection(); //-------------------------------- // INIT other classes //-------------------------------- $ipsclass->sess = new session(); $ipsclass->sess->ipsclass =& $ipsclass; $ipsclass->forums = new forum_functions(); $ipsclass->forums->ipsclass =& $ipsclass; //-------------------------------- // Set up our vars //-------------------------------- $ipsclass->parse_incoming(); //-------------------------------- // Set converge //-------------------------------- $ipsclass->converge = new class_converge( $ipsclass->DB ); //-------------------------------- // Start off the cache array //-------------------------------- $ipsclass->cache_array = array_merge( array('attachtypes','bbcode', 'multimod','ranks','profilefields'), array('rss_calendar', 'rss_export','components','banfilters', 'settings', 'group_cache', 'systemvars', 'skin_id_cache', 'forum_cache', 'moderators', 'stats', 'languages') ); //=========================================================================== // Get cache... //=========================================================================== $ipsclass->init_cache_setup(); $ipsclass->init_load_cache( $ipsclass->cache_array ); //-------------------------------- // Set debug mode //-------------------------------- $ipsclass->DB->set_debug_mode( $ipsclass->vars['sql_debug'] == 1 ? intval($_GET['debug']) : 0 ); //-------------------------------- // Initialize the FUNC //-------------------------------- $ipsclass->initiate_ipsclass(); //-------------------------------- // Initialize the member info //-------------------------------- $ipsclass->member = $ipsclass->sess->authorise(); //----------------------------------------- // Cache md5 check //----------------------------------------- $ipsclass->md5_check = $ipsclass->return_md5_check(); //-------------------------------- // Initialize the forums //-------------------------------- $ipsclass->forums->strip_invisible = 1; $ipsclass->forums->forums_init(); //-------------------------------- // Load the skin //-------------------------------- $ipsclass->load_skin(); //-------------------------------- // Set the base URL //-------------------------------- $ipsclass->base_url = $ipsclass->vars['board_url'].'/index.'.$ipsclass->vars['php_ext']; //-------------------------------- // INIT class and pass... //-------------------------------- $runme = new ssi_autorun(); $runme->ipsclass =& $ipsclass; $runme->auto_run(); /** * Auto run class */ class ssi_autorun { /** * Auto run function */ function auto_run() { //-------------------------------- // What to do? //-------------------------------- switch ($this->ipsclass->input['a']) { case 'news': $this->do_news(); break; case 'active': $this->do_active(); break; case 'stats': $this->do_stats(); break; case 'out': if ( SSI_ALLOW_SYND == 1 ) { $this->do_syndication(); } else { exit(); } break; default: echo("An error occured whilst processing this directive"); exit(); break; } } /** * Do Syndication * * Export topics / titles from selected forums */ function do_syndication() { //---------------------------------------- // Sort out the forum ids //---------------------------------------- $tmp_forums = array(); $forums = array(); if ( $this->ipsclass->input['f'] ) { $tmp_forums = explode( ",", $this->ipsclass->input['f'] ); } else { fatal_error("Fatal error: no forum id specified"); } //---------------------------------------- // Intval the IDs //---------------------------------------- foreach ($tmp_forums as $f ) { $f = intval($f); if ( $f ) { $forums[] = $f; } } //---------------------------------------- // Check... //---------------------------------------- if ( count($forums) < 1 ) { fatal_error("Fatal error: no forum id specified"); } $sql_fields = implode( ",", $forums ); //---------------------------------------- // Number of topics to return? //---------------------------------------- $perpage = intval($this->ipsclass->input['show']) ? intval($this->ipsclass->input['show']) : 10; $perpage = ( $perpage > SSI_MAX_SHOW ) ? SSI_MAX_SHOW : $perpage; //---------------------------------------- // Load the template... //---------------------------------------- if ( $this->ipsclass->input['type'] == 'xml' ) { $template = $this->load_template("syndicate_xml.html"); } else { $template = $this->load_template("syndicate_rss.html"); } //---------------------------------------- // parse.. //---------------------------------------- $to_echo = ""; $top = ""; $row = ""; $bottom = ""; preg_match( "#\[TOP\](.+?)\[/TOP\]#is", $template, $match ); $top = trim($match[1]); preg_match( "#\[ROW\](.+?)\[/ROW\]#is", $template, $match ); $row = trim($match[1]); preg_match( "#\[BOTTOM\](.+?)\[/BOTTOM\]#is", $template, $match ); $bottom = trim($match[1]); //---------------------------------------- // Header parse... //---------------------------------------- @header("Content-Type: text/xml;charset={$this->ipsclass->vars['gb_char_set']}"); @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'); $to_echo .= $this->parse_template( $top, array ( 'board_url' => $this->ipsclass->base_url , 'board_name' => $this->ipsclass->vars['board_name'], ) ); //---------------------------------------- // Fix up //---------------------------------------- $group = $this->ipsclass->cache['group_cache'][ $this->ipsclass->vars['guest_group'] ]; $this->ipsclass->perm_id_array = explode( ",", $group['g_perm_id'] ); //---------------------------------------- // Get the topics, member info and other stuff //---------------------------------------- $this->ipsclass->DB->simple_construct( array( 'select' => '*', 'from' => 'topics', 'where' => "forum_id IN ($sql_fields) AND approved=1", 'order' => 'last_post DESC', 'limit' => array( 0, $perpage ) ) ); $this->ipsclass->DB->simple_exec(); if ( ! $this->ipsclass->DB->get_num_rows() ) { fatal_error("Could not get the information from the database"); } while ( $i = $this->ipsclass->DB->fetch_row() ) { $forum = $this->ipsclass->forums->forum_by_id[ $i['forum_id'] ]; if ( $this->ipsclass->check_perms( $forum['read_perms'] ) != TRUE ) { continue; } if ($forum['password'] != "" ) { continue; } $to_echo .= $this->parse_template( $row, array ( 'topic_title' => str_replace( '&#', '&#', $i['title'] ), 'topic_id' => $i['tid'], 'topic_link' => $this->ipsclass->base_url."?showtopic=".$i['tid'], 'forum_title' => htmlspecialchars($forum['name']), 'forum_id' => $i['forum_id'], 'last_poster_id' => $i['last_poster_id'], 'last_post_name' => $i['last_poster_name'], 'last_post_time' => $this->ipsclass->get_date( $i['last_post'] , 'LONG', 1 ), 'timestamp' => $i['last_post'], 'starter_id' => $i['starter_id'], 'starter_name' => $i['starter_name'], 'board_url' => $this->ipsclass->base_url , 'board_name' => $this->ipsclass->vars['board_name'], 'rfc_date' => date( 'r', $i['last_post'] ), ) ) . "\r\n"; } //---------------------------------------- // Print bottom... //---------------------------------------- echo $to_echo."\r\n".$bottom; exit(); } /** * Do Stats * * Show totals */ function do_stats() { //---------------------------------------- // Load the template... //---------------------------------------- $template = $this->load_template("stats.html"); //---------------------------------------- // INIT //---------------------------------------- $to_echo = ""; $time = time() - 900; //---------------------------------------- // Make sure we've got something //---------------------------------------- if ( ! is_array( $this->ipsclass->cache['stats'] ) ) { $this->ipsclass->cache['stats'] = array(); $this->ipsclass->update_cache( array( 'name' => 'stats', 'array' => 1, 'deletefirst' => 1 ) ); } $stats = $this->ipsclass->cache['stats']; $total_posts = $stats['total_replies']+$stats['total_topics']; $to_echo = $this->parse_template( $template, array ( 'total_posts' => $total_posts, 'topics' => $stats['total_topics'], 'replies' => $stats['total_replies'], 'members' => $stats['mem_count'] ) ); echo $to_echo; exit(); } /** * Do News * * Show news text */ function do_news() { //---------------------------------------- // Check //---------------------------------------- if ( (! $this->ipsclass->vars['news_forum_id']) or ($this->ipsclass->vars['news_forum_id'] == "" ) ) { fatal_error("No news forum assigned"); } //---------------------------------------- // INIT //---------------------------------------- $perpage = intval($this->ipsclass->input['show']) > 0 ? intval($this->ipsclass->input['show']) : 10; $perpage = ( $perpage > SSI_MAX_SHOW ) ? SSI_MAX_SHOW : $perpage; $to_echo = ""; //----------------------------------------- // Load the template... //----------------------------------------- $template = $this->load_template("news.html"); //----------------------------------------- // Get the topics, member info and other stuff //----------------------------------------- $this->ipsclass->DB->build_query( array( 'select' => 't.*', 'from' => array( 'topics' => 't' ), 'where' => "t.forum_id={$this->ipsclass->vars['news_forum_id']} AND t.approved=1", 'order' => 't.tid DESC', 'limit' => array( 0, $perpage ), 'add_join' => array( 0 => array( 'select' => 'm.members_display_name as member_name, m.mgroup, m.id as member_id,m.title as member_title', 'from' => array( 'members' => 'm' ), 'where' => "m.id=t.starter_id", 'type' => 'left' ), 1 => array( 'select' => 'p.*', 'from' => array( 'posts' => 'p' ), 'where' => "t.topic_firstpost=p.pid", 'type' => 'left' ) ) ) ); $this->ipsclass->DB->exec_query(); while ( $row = $this->ipsclass->DB->fetch_row() ) { $row['member_name'] = $row['member_name'] ? $row['member_name'] : $row['author_name']; $to_echo .= $this->parse_template( $template, array ( 'profile_link' => $this->ipsclass->base_url."?showuser=".intval($row['member_id']), 'member_name' => $row['member_name'], 'post_date' => $this->ipsclass->get_date( $row['post_date'], 'LONG', 1 ), 'topic_title' => $row['title'], 'post' => $row['post'], 'comments' => $row['posts'], 'view_all_link' => $this->ipsclass->base_url."?showtopic={$row['tid']}" ) ); } //----------------------------------------- // Get the macros and replace them //----------------------------------------- if ( is_array( $this->ipsclass->skin['_macros'] ) ) { foreach( $this->ipsclass->skin['_macros'] as $row ) { if ( $row['macro_value'] != "" ) { $to_echo = str_replace( "<{".$row['macro_value']."}>", $row['macro_replace'], $to_echo ); } } } $to_echo = preg_replace( "#([^/])style_images/(<\#IMG_DIR\#>|".preg_quote($this->ipsclass->skin['_imagedir'], '/').")#is", "\\1".$this->ipsclass->vars['board_url']."/style_images/\\2", $to_echo ); $to_echo = preg_replace( "#([^/])style_emoticons#is", "\\1".$this->ipsclass->vars['board_url']."/style_emoticons", $to_echo ); $to_echo = preg_replace( "#([^/])style_avatars#is" , "\\1".$this->ipsclass->vars['board_url']."/style_avatars", $to_echo ); $to_echo = preg_replace( "#([^/])jscripts#is" , "\\1".$this->ipsclass->vars['board_url']."/jscripts", $to_echo ); $to_echo = str_replace( "<#IMG_DIR#>", $this->ipsclass->skin['_imagedir'], $to_echo ); $to_echo = str_replace( "<#EMO_DIR#>", $this->ipsclass->skin['_emodir'] , $to_echo ); echo $to_echo; exit(); } /** * Do Active * * Show active users */ function do_active() { //-------------------------------- // Load the template... //-------------------------------- $template = $this->load_template("active.html"); //-------------------------------- // INIT //-------------------------------- $to_echo = ""; //-------------------------------- // Make sure we have a cut off... //-------------------------------- if ($this->ipsclass->vars['au_cutoff'] == "") { $this->ipsclass->vars['au_cutoff'] = 15; } //----------------------------------------- // Get the users from the DB //----------------------------------------- $cut_off = $this->ipsclass->vars['au_cutoff'] * 60; $time = time() - $cut_off; $rows = array(); $ar_time = time(); if ( $this->ipsclass->member['id'] ) { $rows = array( $ar_time => array( 'login_type' => substr($this->ipsclass->member['login_anonymous'],0, 1), 'running_time' => $ar_time, 'member_id' => $this->ipsclass->member['id'], 'member_name' => $this->ipsclass->member['members_display_name'], 'member_group' => $this->ipsclass->member['mgroup'] ) ); } $this->ipsclass->DB->simple_construct( array( 'select' => 'id, member_id, member_name, login_type, running_time, member_group', 'from' => 'sessions', 'where' => "running_time > $time", //'order' => "running_time DESC" // Sort in PHP to avoid filesort in SQL ) ); $this->ipsclass->DB->simple_exec(); //----------------------------------------- // FETCH... //----------------------------------------- while ( $r = $this->ipsclass->DB->fetch_row() ) { $rows[ $r['running_time'].'.'.$r['id'] ] = $r; } krsort( $rows ); //-------------------------------- // cache all printed members so we // don't double print them //-------------------------------- $cached = array(); $active = array(); foreach( $rows as $result ) { $last_date = $this->ipsclass->get_time( $result['running_time'] ); //----------------------------------------- // Bot? //----------------------------------------- if ( strstr( $result['id'], '_session' ) ) { //----------------------------------------- // Seen bot of this type yet? //----------------------------------------- $botname = preg_replace( '/^(.+?)=/', "\\1", $result['id'] ); if ( ! $cached[ $result['member_name'] ] ) { $cached[ $result['member_name'] ] = 1; } else { //----------------------------------------- // Yup, count others as guest //----------------------------------------- $active['GUESTS']++; } } //----------------------------------------- // Guest? //----------------------------------------- else if ( ! $result['member_id'] ) { $active['GUESTS']++; } //----------------------------------------- // Member? //----------------------------------------- else { if ( empty( $cached[ $result['member_id'] ] ) ) { $cached[ $result['member_id'] ] = 1; if ($result['login_type']) { $active['ANON']++; } else { $active['MEMBERS']++; } } } } $active['TOTAL'] = $active['MEMBERS'] + $active['GUESTS'] + $active['ANON']; $to_echo = $this->parse_template( $template, array ( 'total' => $active['TOTAL'] ? $active['TOTAL'] : 0 , 'members' => $active['MEMBERS'] ? $active['MEMBERS'] : 0, 'guests' => $active['GUESTS'] ? $active['GUESTS'] : 0, 'anon' => $active['ANON'] ? $active['ANON'] : 0, ) ); echo $to_echo; exit(); } /** * Parse template * * Parses the template. Duh. */ function parse_template( $template, $assigned=array() ) { foreach( $assigned as $word => $replace) { $template = preg_replace( "/\{$word\}/i", "$replace", $template ); } return $template; } /** * Load template * * Loads the template */ function load_template($template="") { $filename = SSI_TEMPLATES_DIR."/".$template; if ( file_exists($filename) ) { if ( $FH = fopen($filename, 'r') ) { $template = fread( $FH, filesize($filename) ); fclose($FH); } else { fatal_error("Couldn't open the template file"); } } else { fatal_error("Template file does not exist"); } return $template; } } ?>