Вход Регистрация
Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/admin/sources/classes/backup.php
Строк: 357
<?php
/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.4.6
 * Back Up Model
 * Last Updated: $Date: 2012-05-10 21:10:13 +0100 (Thu, 10 May 2012) $
 * </pre>
 *
 * @author         Matt Mecham
 * @copyright    (c) 2001 - 2009 Invision Power Services, Inc.
 * @license        http://www.invisionpower.com/company/standards.php#license
 * @package        IP.Board
 * @link        http://www.invisionpower.com
 * @since        Tue. 15th June 2012
 * @version        $Rev: 10721 $
 *
 */

/**
 * Back up model
 * @author matt
 *
 */
class ipsBackup
{
    
/**
     * Holds the back-up variables
     * @var array
     */
    
private $Vars       = array();
    
    
/**
     * DB tables and primary keys
     * @var array
     */
    
private $Keys        = array();
    
/**
     * Contains list of tables NOT to gather.
     * @var array
     */
    
private $BlackList = array();
    
    
/**
     * Contains list of tables ONLY to gather.
     * @var array
     */
    
private $WhiteList = array();
    
    
/**
     * Contains all the schematic info. Use wisely, it can be 'uuuge (700k+)
     */
    
private $SchematicData = array();
    
    
/**
     * Limits for the batches
     * @var array
     */
    
private $Limits        = array( 'rows' => 0'bytes' => );
    
    
/**
     * Construct
     */
    
public function __construct()
    {
        
/* Make objects */
        
$this->registry ipsRegistry::instance();
        
$this->DB       $this->registry->DB();
        
        
/* Fetch *lists */
        
$this->BlackList $this->_getBlackList();
        
$this->Whitelist $this->_getWhiteList();
        
        
/* Fetch data variables */
        
$this->Vars         $this->_getVars();
        
        
/* Fetch db table pkeys */
        
$this->Keys      $this->_getKeys();
        
        
/* Set default limits for the batch pulling */
        
$this->setLimits'rows'10000 );
        
$this->setLimits'bytes'20 1024 1024 );
    }
    
    
/**
     * Add an insert/delete/update/replace query to our log
     * @param string $query
     * @param string $table
     */
    
public function addRawQueryToLog$query$table )
    {
        
/* This would be LOLs */
        
if ( $this->backUpRunning() && ! stristr'insert into ' $this->registry->dbFunctions()->getPrefix() . 'backup_queue'$query ) )
        {
            
$this->DB->insert'backup_queue', array( 'queue_entry_date'  => IPS_UNIX_TIME_NOW,
                                                      
'queue_entry_type'  => 5,
                                                      
'queue_entry_table' => $this->_stripPrefix$table ),
                                                      
'queue_entry_sql'   => $query ) );
        }
    }
    
    
/**
     * Is the back up system ready to process queries?
     *
     */
    
public function backUpRunning()
    {
        return ( 
$this->Vars['populate_all_done'] > ) ? true false;
    }

    
    
/**
     * Does it need to reset?
     *
     */
    
public function checkForRestart()
    {
        
/* Eventually we'll expand the system so it can be pinged to see if a restart is needed but for now... */
        
return ( ! $this->Vars['populate_all_done'] ) ? true false;
    }
    
    
/**
     * Send batch to the backup server
     */
    
public function sendBatch()
    {
        
/* Fetch kernel class */
        
require_once( IPS_KERNEL_PATH 'classFileManagement.php' );
        
$cfm = new classFileManagement();
        
        
/* Fetch DB data */
        
$tables        $this->_getDatabaseSchematics();
        
$sqlRows       = array();
        
$touchedTables = array();
        
$bytesUsed     '';
        
$topId           0;
        
$delIds           = array();
        
        
/* Do we need to restart? */
        
if ( $this->checkForRestart() )
        {
            
$this->populateLogWithAllTables();
            
            return 
true;
        }
        
        
/* Little short cut */
        
$p $this->registry->dbFunctions()->getPrefix();
        
        
/* Start looping on the table */
        
$this->DB->build( array( 'select' => '*',
                                 
'from'   => 'backup_queue',
                                 
'order'  => 'queue_id',
                                 
'limit'  => array( 0$this->Limits['rows'] ) ) );
        
        
$o $this->DB->execute();
        
        while( 
$row $this->DB->fetch$o ) )
        {
            
$tbl    $this->_stripPrefix$row['queue_entry_table'] );
            
$sql    '';
            
$fields = array();
            
            
$touchedTables$tbl ] = $tbl;
            
            if ( 
$row['queue_entry_sql'] )
            {
                
$sql $row['queue_entry_sql'];
            }
            else
            {
                
/* Get fields */
                
foreach( $tables$row['queue_entry_table'] ]['cols'] as $col )
                {
                    
$fields[] = $col['Field'];
                }
                
                if ( ! 
count$fields ) )
                {
                    
/* Empty - so remove this queue row or we'll never progress */
                    
$delIds[] = $row['queue_id'];
                    
                    continue;
                }
                
                
/* INSERT */
                
if ( $row['queue_entry_type'] == )
                {
                    
/* Get data */
                    
$pKey    $row['queue_entry_key'];
                    
$pKeyVal = ( $this->_isConcat$pKey ) ) ? addslashes$row['queue_entry_value'] ) : $row['queue_entry_value'];
                    
$data    = array();
                    
$vals    = array();
                    
                    
$data    $this->DB->buildAndFetch( array( 'select' => '`' implode"`, `"$fields ) . '`',
                                                                
'from'   => $tbl,
                                                                
'where'  => $pKey "='" $pKeyVal "'" ) );
                    
                    if ( ! 
is_array$data ) OR ! count$data ) )
                    {
                        
/* Empty - so remove this queue row or we'll never progress */
                        
$delIds[] = $row['queue_id'];
                        
                        continue;
                    }
                    
                    foreach( 
$data as $k => $v )
                    {
                        
$vals[] = $this->_makeValueSafeForQuery$v );
                    }
                    
                    
$sql  "INSERT INTO " $p $tbl "(`" implode"`, `"$fields ). "`) " .
                            
"VALUES( '" implode"', '"$vals ) . "');";
                }
            }
            
            
/* Got anything? */
            
if ( ! $sql )
            {
                
/* Empty - so remove this queue row or we'll never progress */
                
$delIds[] = $row['queue_id'];
                    
                continue;
            }
            
            
/* check size */
            
$bytesUsed += IPSLib::strlenToBytesstrlen$sql ) );
            
            
/* Truth time! */
            
if ( $bytesUsed >= $this->Limits['bytes'] )
            {
                break;
            }
            else
            {
                
$sqlRows[] = $sql;
                
                
/* top id to remove */
                
$topId $row['queue_id'];
            }
        }
        
        
/* Anything to delete? */
        
if ( count$delIds ) )
        {
            
$this->DB->delete'backup_queue''queue_id IN (' implode','array_values$delIds ) ) . ')' );
        }
        
        
/* What do we have? */
        
if ( $topId && count$sqlRows ) )
        {
            
$dataToSend $this->_createTextToSend$sqlRowsarray_keys$touchedTables ) );
                                    
            
$returnedData $cfm->postFileContents$this->_getBackupServerUrl(), array( 'backup_data' => @gzcompress$dataToSend ), 'lkey' => ipsRegistry::$settings['ipb_reg_number'] ) );
                
            
$test json_decodetrim$returnedData ), true );
            
            if ( 
is_array$test ) && $test['status'] == 'ok' )
            {
                
$this->DB->delete'backup_queue''queue_id <= ' intval$topId ) );
                
$this->_addLogintval$test['rows'] ), $test['status'] );
                
                
$this->Vars['rows_sent']  = intval$this->Vars['rows_sent'] ) + count$sqlRows );
                
$this->Vars['rows_total'] = $this->_getStoredRowCount();
                
$this->_setVars();
            }
            else
            {
                
# Fail lol
                
$this->_addLog0$test['status'] );
            }
        }
    }
    
    
/**
     * Do the first run
     * This will reset the system and re-populate the entire log table - USE WITH CAUTION!
     */
    
public function populateLogWithAllTables$tablesToIndex=300 )
    {
        
$lastTable $this->Vars['populate_all_last_table'];
        
$lastProc  '';
        
        
/* Reset the system if not middle of processing */
        
if ( ! $lastTable )
        {
            
$this->_resetSystem();
        }
            
        
/* Little short cut */
        
$p $this->registry->dbFunctions()->getPrefix();
        
        
/* Lets go */
        
foreach( $this->Keys as $table => $pKey )
        {
            
/* Seek to the first unindexed table */
            
if ( ! $lastProc )
            {
                if ( 
$lastTable and $table != $lastTable )
                {
                    continue;
                }
                
                if ( ( 
$lastTable == $table ) || ! $lastTable )
                {
                    
$lastProc $table;
                }
            }
            
            
$this->DB->allow_sub_select 1;
            
            
$pKeyText = ( $this->_isConcat$pKey ) ) ? addslashes$pKey ) : $pKey;
            
            
/* Fetch, then */
            
$this->DB->query'INSERT INTO ' $p 'backup_queue (queue_entry_date, queue_entry_type, queue_entry_table, queue_entry_key, queue_entry_value, queue_entry_sql)' .
                              
"( SELECT UNIX_TIMESTAMP(), 1, '" $table "', '" $pKeyText "', " $pKey ", '' FROM " $table " )" );
            
            
$this->Vars['populate_all_last_table'] = $table;
            
$this->_setVars();
        }
        
        
/* We are all done */
        
if ( ( $lastTable && $lastProc == $this->Vars['populate_all_last_table'] ) OR ! $lastProc OR ( $tablesToIndex >= count$this->Keys ) ) )
        {
            
$this->Vars['rows_sent']               = 0;
            
$this->Vars['rows_total']               = $this->_getStoredRowCount();
            
$this->Vars['populate_all_done']       = IPS_UNIX_TIME_NOW;
            
$this->Vars['populate_all_last_table'] = '';
            
$this->_setVars();
        }
    }
    
    
/**
     * Ok to fetch the table data?
     * @param string $table
     */
    
public function isOkToGetThisTableData$table )
    {
        
$table $this->_stripPrefix$table );
        
        if ( 
count$this->Whitelist ) )
        {
            if ( 
in_array$table$this->Whitelist ) )
            {
                return 
true;
            }
        }
        
        return ( 
$this->_isBlackListTable$table ) ) ? false true;
    }
    
    
/**
     * Rebuilds the cache file so we can find out a little about the database structure
     */
    
public function rebuildPrimaryKeyCacheFile()
    {
        
$cache     = array();
        
$schematic $this->_getDatabaseSchematics();
        
        foreach( 
$schematic as $table => $data )
        {
            
$hasKey false;
            
            if ( 
count$data['idx'] ) )
            {
                foreach( 
$data['idx'] as $idx )
                {
                    if ( 
$idx['Key_name'] == 'PRIMARY' )
                    {
                        
$cache$table ] = $idx['Column_name'];
                        
$hasKey true;
                        break;
                    }
                }
            }
            
            if ( ! 
$hasKey )
            {
                
/* Lets make a key */
                
$c      0;
                
$concat = array();
                
                foreach( 
$data['cols'] as $col )
                {
                    if ( 
strtolower$col['Type'] ) != 'mediumtext' )
                    {
                        if ( 
stristrstrtolower$col['Type'] ), 'int(' ) )
                        {
                            
$concat[] = $col['Field'];
                        }
                        else
                        {
                            
$concat[] = 'SUBSTR(' $col['Field'] . ', 1, 32)';
                        }
                        
                        
$c++;
                    }
                    
                    if ( 
$c )
                    {
                        break;
                    }
                }
                
                
$cache$table ] = 'CONCAT_WS( ',', ' implode','$concat ) . ' )';
            }
        }
        
        
$contents '<' "?phpn" '$keyCache = ' var_export$cachetrue ) . ';' "n?" '>';
        
        if ( ! 
file_put_contents$this->_getBackUpKeyCacheFilename(), $contents ) )
        {
            
trigger_error'Не удалось записать файл кэша системы резервного копирования' );
        }
        
        
/* Reset table pkeys */
        
$this->Keys $this->_getKeys();
    }
    
    
/**
     * Set a per batch limit
     * @param string $key
     * @param string $value
     */
    
public function setLimits$key$value )
    {
        switch( 
$key )
        {
            case 
'row':
            case 
'pergo':
            case 
'rows':
                
$this->Limits['rows'] = $value;
            break;
            case 
'bytes':
            case 
'b':
                
$this->Limits['bytes'] = $value;
            break;
            case 
'kb':
                
$this->Limits['bytes'] = $value 1024;
            break;
            case 
'mb':
                
$this->Limits['bytes'] = $value 1024 1024;
            break;
        }
    }
    
    
/**
     * Get the number of rows in the queue table
     * @return int, yo
     */
    
private function _getStoredRowCount()
    {
        
$count $this->DB->buildAndFetch( array( 'select' => 'count(*) as tnuoc''from' => 'backup_queue' ) );
        
        return 
$count['tnuoc'];
    }
    
    
/**
     * Resets the system and preps for re-logging all
     */
    
private function _resetSystem()
    {
        
/* Reset */
        
$this->Vars['populate_all_start']      = IPS_UNIX_TIME_NOW;
        
$this->Vars['populate_all_done']       = 0;
        
$this->Vars['populate_all_last_table'] = '';
    
        
$this->_setVars();
        
        
/* Delete current logs */
        
$this->DB->delete('backup_queue');
        
$this->DB->delete('backup_log');
        
        
/* Rebuild cache file */
        
$this->rebuildPrimaryKeyCacheFile();
    }
    
    
/**
     * Gets the database keys
     * @return array
     */
    
private function _getKeys()
    {
        
$keyCache = array();
    
        if ( ! 
is_file$this->_getBackUpKeyCacheFilename() ) )
        {
            
$this->rebuildPrimaryKeyCacheFile();
        }
    
        include( 
$this->_getBackUpKeyCacheFilename() );
        
        return 
$keyCache;
    }
    
    
/**
     * Gets the vars from the deebee
     * @return array:
     */
    
private function _getVars()
    {
        
$vars = array();
        
        
$db $this->DB->buildAndFetchAll( array( 'select' => '*',
                                                  
'from'   => 'backup_vars' ) );
        
        if ( 
is_array$db ) )
        {
            foreach( 
$db as $var )
            {
                
$vars$var['backup_var_key'] ] = $var['backup_var_value'];
            }
        }

        if( !isset(
$vars['populate_all_done']) )
        {
            
$vars['populate_all_done']    = 0;
        }

        return 
$vars;
    }
    
    
/**
     * Update the variables 
     */
    
private function _setVars()
    {
        foreach( 
$this->Vars as $k => $v )
        {
            
$this->DB->replace'backup_vars',array( 'backup_var_key' => $k'backup_var_value' => $v ), array( 'backup_var_key' ) );
        }
    }
    
    
/**
     * Removes table prefix if one exists
     * @param string $table
     * @return string
     */
    
private function _stripPrefix$table )
    {
        if ( 
$this->registry->dbFunctions()->getPrefix() && preg_match"/^" $this->registry->dbFunctions()->getPrefix() ."/i"$table ) )
        {
            
$table preg_replace"/^" $this->registry->dbFunctions()->getPrefix() ."(.*)$/i"'1'$table );
        }
        
        return 
$table;
    }
    
    
/**
     * Returns ignored tables
     */
    
private function _getWhiteList()
    {
        return array();
    }
    
    
/**
     * Returns ignored tables
     */
    
private function _getBlackList()
    {
        
/* @todo abstract this puppy */
        
return array( 'admin_login_logs',
                      
'admin_logs',
                      
'api_log',
                      
'backup_log',
                      
'backup_queue',
                      
'backup_vars',
                      
'blog_askimet_logs',
                      
'blog_trackback_spamlogs',
                      
'blog_views',
                      
'chat_log_archive',
                      
'content_cache_posts',
                      
'content_cache_sigs',
                      
'core_editor_autosave',
                      
'core_item_markers',
                      
'core_like_cache',
                      
'core_share_links_caches',
                      
'core_share_links_log',
                      
'core_tags_cache',
                      
'error_logs',
                      
'gallery_image_views',
                      
'mail_error_logs',
                      
'moderator_logs',
                      
'profile_friends_flood',
                      
'profile_portal_views',
                      
'reputation_cache',
                      
'search_sessions',
                      
'sessions',
                      
'skin_cache',
                      
'skin_templates_cache',
                      
'spam_service_log',
                      
'spider_logs',
                      
'task_logs',
                      
'topic_views' );
    }
    
/**
     * Return database schematic information
     */
    
private function _getDatabaseSchematics()
    {
        if ( 
count$this->SchematicData ) )
        {
            return 
$this->SchematicData;
        }
        
        
$this->DB->query"SHOW TABLE STATUS FROM `" $this->registry->dbFunctions()->getDatabaseName() . "`" );
        
        
/* Loop through the results */
        
$this->SchematicData = array();
        
        while( 
$row $this->DB->fetch() )
        {
            
/* Check to ensure it's a table for this install... */
            
if ( $this->registry->dbFunctions()->getPrefix() && ! preg_match"/^" $this->registry->dbFunctions()->getPrefix() ."/i"$row['Name'] ) )
            {
                continue;
            }
            
            if ( ! 
$this->isOkToGetThisTableData$row['Name'] ) )
            {
                continue;
            }        
            
            
/* Add to output array */
            
$this->SchematicData$row['Name'] ] = array( 'cols' => array(), 'idx' => array(), 'data' => $row );
        }
        
        
/* Now fetch table information */
        
foreach( $this->SchematicData as $name => $data )
        {
            
/* Fetch data */
            
$this->DB->query"DESCRIBE " $name );
            
            while( 
$row $this->DB->fetch() )
            {
                
$this->SchematicData$name ]['cols'][] = $row;
            }
            
            
/* Fetch index data */
            
$this->DB->query"SHOW INDEX FROM `" $this->registry->dbFunctions()->getDatabaseName() . "`.`" $name "`" );
            
            while( 
$row $this->DB->fetch() )
            {
                
$this->SchematicData$name ]['idx'][] = $row;
            }
        }
        
        return 
$this->SchematicData;
    }
    
    
/**
     * Check to see if this is an ignored table
     * @param string $table
     */
    
private function _isBlackListTable$table )
    {
        return ( 
in_array$table$this->BlackList ) ) ? true false;
    }
    
    
/**
     * Add slashes to single quotes to stop sql breaks
     *
     * @param    string    $value    String to add slashes too
     * @return    string
     */
    
private function _makeValueSafeForQuery$value )
    {
        return 
$this->DB->addSlashes$value );
    }
    
    
/**
     * @param string $str
     * @return boolean
     */
    
private function _isConcat$str )
    {
        return ( 
substr$str010 ) == 'CONCAT_WS(' ) ? true false;
    }
    
    
/**
     * Creates the post text
     * @param string $sqlData
     */
    
private function _createTextToSend$sqlData$touchedTables=null )
    {
        
$tables       $this->_getDatabaseSchematics();
        
$tblsToSend   = array();
        
$tblsToCreate = array();
        
$schematic    '';
        
        
/* Little short cut */
        
$p $this->registry->dbFunctions()->getPrefix();
        
        if ( 
is_array$touchedTables ) )
        {
            foreach( 
$touchedTables as $tbl )
            {
                
/* $touchedTables has no prefix */
                
$tblsToSend$p $tbl ] = $tables$p $tbl ];
                
                
$this->DB->query"SHOW CREATE TABLE " $p $tbl );
                
$_f $this->DB->fetch();
                
                
$tblsToCreate[] = str_replace( array( "n""r" ), "n"$_f['Create Table'] );
            }
        }
        
        
$document serialize( array( 'tableData' => $tblsToSend'createTables' => $tblsToCreate'sql' => $sqlData'vars' => $this->Vars ) );
        
        return 
$document;
    }
    
    
/**
     * Should be face-smashingly obvious.
     * @return string
     */
    
private function _getBackUpKeyCacheFilename()
    {
        return 
IPS_CACHE_PATH 'cache/backUpKeyCache.php';
    }
    
    
/**
     * Gets the backup server URL (clearly)
     * @return string
     */
    
private function _getBackupServerUrl()
    {
        return 
'http://gateway.backuptest.lw.ipslink.com/index.php';
    }
    
    
/**
     * Adds a log to the back up system
     * @param int $rows
     * @param string $status
     */
    
private function _addLog$rows$status )
    {
        
$this->DB->insert'backup_log', array( 'log_row_count' => $rows'log_result' => $status ) );
    }
}
Онлайн: 2
Реклама