Files
2025-12-19 00:26:08 -08:00

654 lines
20 KiB
PHP

#!/usr/local/bin/php
<?php
/*
+--------------------------------------------------------------------------
| Invision Power Board
| ========================================
| by Matthew Mecham
| (c) 2001 - 2005 Invision Power Services
| http://www.invisionpower.com
| ========================================
| Web: http://www.invisionboard.com
| Email: matt@invisionpower.com
+---------------------------------------------------------------------------
| INVISION POWER BOARD IS NOT FREE SOFTWARE!
| http://www.invisionboard.com/?license
+---------------------------------------------------------------------------
| > $Date: 2007-05-11 22:54:34 +0100 (Fri, 11 May 2007) $
| > $Revision: 994 $
| > $Author: bfarber $
+---------------------------------------------------------------------------
|
| > SHELL SCRIPT: Rebuild Posts
|
+--------------------------------------------------------------------------
*/
/**
* Script type
*
*/
define( 'IPB_THIS_SCRIPT', 'public' );
define( 'IPB_LOAD_SQL' , 'queries' );
if ( ! file_exists( './init.php' ) )
{
myprint( "ERROR: This script MUST be placed in your forum's root directory.\n" );
exit(0);
}
require_once( './init.php' );
//===========================================================================
// MAIN PROGRAM
//===========================================================================
$INFO = array();
//--------------------------------
// Load our classes
//--------------------------------
require_once ROOT_PATH . "sources/ipsclass.php";
require_once ROOT_PATH . "sources/classes/class_display.php";
require_once ROOT_PATH . "sources/classes/class_session.php";
require_once ROOT_PATH . "sources/classes/class_forums.php";
require_once KERNEL_PATH . "class_converge.php";
if ( file_exists( ROOT_PATH . "conf_global.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();
//--------------------------------
// Set debug mode
//--------------------------------
$ipsclass->DB->set_debug_mode( 0 );
$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('badwords','emoticons','attachtypes','bbcode', 'multimod','ranks','profilefields','skin_remap', '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 );
//--------------------------------
// Initialize the FUNC
//--------------------------------
$ipsclass->initiate_ipsclass();
//--------------------------------
// Initialize the forums
//--------------------------------
$ipsclass->forums->strip_invisible = 1;
$ipsclass->forums->forums_init();
//--------------------------------
// Load the skin
//--------------------------------
$ipsclass->load_skin();
$ppu = 0;
$tpu = 0;
if( isset($ipsclass->member['view_prefs']) )
{
list($ppu,$tpu) = explode( "&", $ipsclass->member['view_prefs'] );
}
$ipsclass->vars['display_max_topics'] = ($tpu > 0) ? $tpu : $ipsclass->vars['display_max_topics'];
$ipsclass->vars['display_max_posts'] = ($ppu > 0) ? $ppu : $ipsclass->vars['display_max_posts'];
//===========================================================================
// Set up the session ID stuff
//===========================================================================
if ( $ipsclass->session_type == 'cookie' )
{
$ipsclass->session_id = "";
$ipsclass->base_url = $ipsclass->vars['board_url'].'/index.'.$ipsclass->vars['php_ext'].'?';
}
else
{
$ipsclass->base_url = $ipsclass->vars['board_url'].'/index.'.$ipsclass->vars['php_ext'].'?s='.$ipsclass->session_id.'&amp;';
}
$ipsclass->js_base_url = $ipsclass->vars['board_url'].'/index.'.$ipsclass->vars['php_ext'].'?s='.$ipsclass->session_id.'&';
//--------------------------------
// Set up the forum_read cookie
//--------------------------------
$ipsclass->hdl_forum_read_cookie();
//===========================================================================
// Set up defaults
//===========================================================================
$ipsclass->skin_id = $ipsclass->skin['_setid'];
$ipsclass->vars['img_url'] = $ipsclass->vars['ipb_img_url'] ? $ipsclass->vars['ipb_img_url'] . 'style_images/' . $ipsclass->skin['_imagedir'] : 'style_images/' . $ipsclass->skin['_imagedir'];
$ipsclass->vars['AVATARS_URL'] = $ipsclass->vars['ipb_img_url'] ? $ipsclass->vars['ipb_img_url'] . 'style_avatars' : 'style_avatars';
$ipsclass->vars['EMOTICONS_URL'] = $ipsclass->vars['ipb_img_url'] ? $ipsclass->vars['ipb_img_url'] . 'style_emoticons/<#EMO_DIR#>' : 'style_emoticons/<#EMO_DIR#>';
$ipsclass->vars['mime_img'] = $ipsclass->vars['ipb_img_url'] ? $ipsclass->vars['ipb_img_url'] . 'style_images/<#IMG_DIR#>' : 'style_images/<#IMG_DIR#>';
//--------------------------------
// Set up our language choice
//--------------------------------
if ( !isset($ipsclass->vars['default_language']) OR $ipsclass->vars['default_language'] == "")
{
$ipsclass->vars['default_language'] = 'en';
}
//-----------------------------------------
// Load language
//-----------------------------------------
$ipsclass->load_language('lang_global');
//-----------------------------------------
// Continue
//-----------------------------------------
require_once( ROOT_PATH."sources/handlers/han_parse_bbcode.php" );
$parser = new parse_bbcode();
$parser->ipsclass =& $ipsclass;
$parser->allow_update_caches = 0;
//-----------------------------------------
// Get input stream
//-----------------------------------------
$stdin = fopen('php://stdin', 'r');
//-----------------------------------------
// Ask what we're doing...
//-----------------------------------------
myprint( "--------------------------------------------\nWelcome to the IP.Board Shell Post Rebuilder\n--------------------------------------------\nWhat do you wish to rebuild? [p=Posts, c=Calendar Events, m=Personal Messages, a=Announcements, s=Signatures]\nEnter: " );
$option = getoption();
//-----------------------------------------
// What did we choose?
//-----------------------------------------
if ( $option != 'p' AND $option != 'c' AND $option != 'm' AND $option != 'a' AND $option != 's' )
{
myprint( "Incorrect option chosen\n");
exit(0);
}
$type = '';
switch( $option )
{
case 'p':
$type = 'posts';
$human = 'Posts';
break;
case 'c':
$type = 'cal';
$human = 'Calendar Events';
break;
case 'm':
$type = 'pms';
$human = 'Personal Messages';
break;
case 's':
$type = 'sigs';
$human = 'Signatures';
break;
case 'a':
$type = 'announce';
$human = 'Announcements';
break;
}
//-----------------------------------------
// CHOICE: Days or ID
//-----------------------------------------
myprint( "You have selected to rebuild: " . $human . "\n--------------------------------------------\nDo you want to rebuild from the last X days items or start from a specific ID? [0=Rebuild from the beginning, d=Rebuild from last X days, n=Rebuild from an ID]\nEnter: " );
$option = getoption();
if ( $option == 'd' )
{
# DAYS
myprint( "Enter the number of days to rebuild from [Entering 30 will rebuild all items from the past 30 days]:\nEnter: " );
$option = intval( getoption() );
$date = 86400 * $option;
$time = time() - $date;
# Find starting ID
switch( $type )
{
case 'cal':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'event_id', 'from' => 'cal_events', 'where' => 'event_unixstamp >= ' . $time, 'limit' => array(1) ) );
$max = intval( $tmp['event_id'] );
break;
case 'announce':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'announce_id', 'from' => 'announcements', 'where' => 'announce_start >= ' . $time, 'limit' => array(1) ) );
$max = intval( $tmp['announce_id'] );
break;
case 'pms':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'msg_id', 'from' => 'message_text', 'where' => 'msg_date >= ' . $time, 'limit' => array(1) ) );
$max = intval( $tmp['msg_id'] );
break;
case 'sigs':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'id', 'from' => 'member_extra', 'where' => "signature != '' AND joined >= " . $time, 'limit' => array(1) ) );
$max = intval( $tmp['id'] );
break;
case 'posts':
default:
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'pid', 'from' => 'posts', 'where' => 'post_date >= ' . $time, 'limit' => array(1) ) );
$max = intval( $tmp['pid'] );
break;
}
$start = $max;
}
else if ( $option == 'n' )
{
# Number
myprint( "Enter the ID to start from:\nEnter: " );
$option = getoption();
$start = intval( $option );
}
else
{
# All
$start = 0;
}
myprint( "Rebuilding {$human}, starting at ID " . $start . "\nRebuild how many? [Enter how many you'd like to rebuild. Hit enter to rebuild all]:\nEnter: " );
$option = getoption();
$end = ( $end > 0 ) ? intval( $end ) : 0;
$done = 0;
$_BATCH = 500;
$_LAST_ID = intval( $start );
$time_start = time();
$COMPLETE = 0;
//-----------------------------------------
// Start the loop...
//-----------------------------------------
while( $COMPLETE == 0 )
{
//-----------------------------------------
// Got any more?
//-----------------------------------------
switch( $type )
{
case 'cal':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'MAX(event_id) as max', 'from' => 'cal_events', 'where' => 'event_id > ' . $_LAST_ID ) );
$max = intval( $tmp['max'] );
break;
case 'announce':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'MAX(announce_id) as max', 'from' => 'announcements', 'where' => 'announce_id > ' . $_LAST_ID ) );
$max = intval( $tmp['max'] );
break;
case 'pms':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'MAX(msg_id) as max', 'from' => 'message_text', 'where' => 'msg_id > ' . $_LAST_ID ) );
$max = intval( $tmp['max'] );
break;
case 'sigs':
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'MAX(id) as max', 'from' => 'member_extra', 'where' => "signature != '' AND id > " . $_LAST_ID ) );
$max = intval( $tmp['max'] );
break;
case 'posts':
default:
$tmp = $ipsclass->DB->simple_exec_query( array( 'select' => 'MAX(pid) as max', 'from' => 'posts', 'where' => 'pid > ' . $_LAST_ID ) );
$max = intval( $tmp['max'] );
break;
}
if ( ! $max OR $_LAST_ID > $max )
{
$COMPLETE = 1;
}
myprint( "\nStarting batch: Last ID=" . $_LAST_ID . " Max ID=" . $max );
//-----------------------------------------
// Avoid limit...
//-----------------------------------------
switch( $type )
{
case 'cal':
$ipsclass->DB->build_query( array( 'select' => 'e.*',
'from' => array( 'cal_events' => 'e' ),
'order' => 'e.event_id ASC',
'where' => 'e.event_id > ' . $_LAST_ID,
'limit' => array( $_BATCH ),
'add_join' => array( 1 => array( 'type' => 'left',
'select' => 'm.mgroup',
'from' => array( 'members' => 'm' ),
'where' => "m.id=e.event_member_id"
) )
) );
break;
case 'announce':
$ipsclass->DB->build_query( array( 'select' => 'a.*',
'from' => array( 'announcements' => 'a' ),
'order' => 'a.announce_id ASC',
'where' => 'a.announce_id > ' . $_LAST_ID,
'limit' => array( $_BATCH ),
'add_join' => array( 1 => array( 'type' => 'left',
'select' => 'm.mgroup',
'from' => array( 'members' => 'm' ),
'where' => "m.id=a.announce_member_id"
) )
) );
break;
case 'pms':
$ipsclass->DB->build_query( array( 'select' => 'p.*',
'from' => array( 'message_text' => 'p' ),
'order' => 'p.msg_id ASC',
'where' => 'p.msg_id > ' . $_LAST_ID,
'limit' => array( $_BATCH ),
'add_join' => array( 1 => array( 'type' => 'left',
'select' => 'm.mgroup',
'from' => array( 'members' => 'm' ),
'where' => "m.id=p.msg_author_id"
) )
) );
break;
case 'sigs':
$ipsclass->DB->build_query( array( 'select' => 'me.signature, me.id',
'from' => array( 'member_extra' => 'me' ),
'order' => 'me.id ASC',
'where' => "me.signature != '' AND me.id > " . $_LAST_ID,
'limit' => array( $_BATCH ),
'add_join' => array( 1 => array( 'type' => 'left',
'select' => 'm.mgroup',
'from' => array( 'members' => 'm' ),
'where' => "m.id=me.id"
) )
) );
break;
case 'posts':
default:
$ipsclass->DB->build_query( array( 'select' => 'p.*',
'from' => array( 'posts' => 'p' ),
'where' => 'p.pid > ' . $_LAST_ID,
'limit' => array( $_BATCH ),
'add_join' => array( 1 => array( 'type' => 'left',
'select' => 't.forum_id',
'from' => array( 'topics' => 't' ),
'where' => "t.tid=p.topic_id"
),
2 => array( 'type' => 'left',
'select' => 'm.mgroup',
'from' => array( 'members' => 'm' ),
'where' => "m.id=p.author_id"
) )
) );
break;
}
$outer = $ipsclass->DB->exec_query();
//-----------------------------------------
// Process...
//-----------------------------------------
while( $r = $ipsclass->DB->fetch_row( $outer ) )
{
//-----------------------------------------
// Reset time limit
//-----------------------------------------
@set_time_limit( 0 );
$parser->quote_open = 0;
$parser->quote_closed = 0;
$parser->quote_error = 0;
$parser->error = '';
$parser->image_count = 0;
$ipsclass->member['g_bypass_badwords'] = $ipsclass->cache['group_cache'][ $r['mgroup'] ]['g_bypass_badwords'];
switch( $type )
{
case 'cal':
$parser->parse_smilies = $r['event_smilies'];
$parser->parse_html = 0;
$parser->parse_bbcode = 1;
$rawpost = $parser->pre_edit_parse( $r['event_content'] );
break;
case 'announce':
$parser->parse_smilies = 1;
$parser->parse_html = $r['announce_html_enabled'];
$parser->parse_nl2br = 1;
$parser->parse_bbcode = 1;
$rawpost = $parser->pre_edit_parse( $r['announce_post'] );
break;
case 'pms':
$parser->parse_smilies = 1;
$parser->parse_nl2br = 1;
$parser->parse_html = $ipsclass->vars['msg_allow_html'];
$parser->parse_bbcode = $ipsclass->vars['msg_allow_code'];
$rawpost = $parser->pre_edit_parse( $r['msg_post'] );
break;
case 'sigs':
$parser->parse_smilies = 0;
$parser->parsing_signature = 1;
$parser->parse_html = $ipsclass->vars['sig_allow_html'];
$parser->parse_bbcode = $ipsclass->vars['sig_allow_ibc'];
$rawpost = $parser->pre_edit_parse( $r['signature'] );
break;
case 'posts':
default:
$parser->parse_smilies = $r['use_emo'];
$parser->parse_html = ( $ipsclass->cache['forum_cache'][ $r['forum_id'] ]['use_html'] AND
$ipsclass->cache['group_cache'][ $r['mgroup'] ]['g_dohtml'] ) ? 1 : 0;
$parser->parse_bbcode = $ipsclass->cache['forum_cache'][ $r['forum_id'] ]['use_ibc'];
$rawpost = $parser->pre_edit_parse( $r['post'] );
break;
}
$newpost = $parser->pre_db_parse( $rawpost );
//-----------------------------------------
// Remove old \' escaping
//-----------------------------------------
$newpost = str_replace( "\\'", "'", $newpost );
//-----------------------------------------
// Convert old dohtml?
//-----------------------------------------
$htmlstate = 0;
if ( strstr( strtolower($newpost), '[dohtml]' ) )
{
//-----------------------------------------
// Can we use HTML?
//-----------------------------------------
if ( $type == 'posts' AND $ipsclass->cache['forum_cache'][ $r['forum_id'] ]['use_html'] )
{
$htmlstate = 2;
}
$newpost = preg_replace( "#\[dohtml\]#i" , "", $newpost );
$newpost = preg_replace( "#\[/dohtml\]#i", "", $newpost );
}
else
{
$htmlstate = intval( $r['post_htmlstate'] );
}
//-----------------------------------------
// Convert old attachment tags
//-----------------------------------------
$newpost = preg_replace( "#\[attachmentid=(\d+?)\]#is", "[attachment=\\1:attachment]", $newpost );
$newpost = $parser->pre_display_parse( $newpost );
if ( $newpost OR $type == 'sigs' )
{
switch( $type )
{
case 'posts':
$ipsclass->DB->do_update( 'posts', array( 'post' => $newpost, 'post_htmlstate' => $htmlstate ), 'pid='.$r['pid'] );
$string = substr( $r['post'], 0, 30 ) . '...';
$last = $r['pid'];
break;
case 'pms':
$ipsclass->DB->do_update( 'message_text', array( 'msg_post' => $newpost ), 'msg_id='.$r['msg_id'] );
$string = substr( $r['msg_post'], 0, 30 ) . '...';
$last = $r['msg_id'];
break;
case 'sigs':
$ipsclass->DB->do_update( 'member_extra', array( 'signature' => $newpost ), 'id='.$r['id'] );
$string = $r['members_display_name'];
$last = $r['id'];
break;
case 'cal':
$ipsclass->DB->do_update( 'cal_events', array( 'event_content' => $newpost ), 'event_id='.$r['event_id'] );
$string = substr( $r['event_content'], 0, 30 ) . '...';
$last = $r['event_id'];
break;
case 'announce':
$ipsclass->DB->do_update( 'announcements', array( 'announce_post' => $newpost ), 'announce_id='.$r['announce_id'] );
$string = substr( $r['announce_post'], 0, 30 ) . '...';
$last = $r['announce_id'];
break;
}
}
//-----------------------------------------
// Clear out DB cached queries
//-----------------------------------------
$ipsclass->DB->obj['cached_queries'] = array();
$done++;
$_LAST_ID = $last;
myprint( "[ID:" . $last . '] ' . $string );
if ( $end > 0 AND $done > $end )
{
$COMPLETE = 1;
}
}
}
$time_end = time();
$time_taken = ( $time_end - $time_start) / 60;
myprint( "\nALL DONE! ($done rebuilt)" );
myprint( "Time Taken: $time_taken minutes" );
@fclose( $stdin );
exit(0);
//-----------------------------------------
// My get
//-----------------------------------------
function getoption()
{
global $stdin;
//$stdin = fopen('php://stdin', 'r');
$option = trim( fgets( $stdin ) );
//fclose( $stdin );
return $option;
}
//-----------------------------------------
// FUNC: Write out
//-----------------------------------------
function myprint( $message, $newline="\n" )
{
$stdout = fopen('php://stdout', 'w');
fwrite( $stdout, $message . $newline );
fclose( $stdout );
}
?>