Вход Регистрация
Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/admin/sources/classes/archive/writer.php
Строк: 401
<?php
/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.4.6
 * Archive: Writer
 * By Matt Mecham
 * </pre>
 *
 * @author         $Author: ips_terabyte $
 * @copyright    (c) 2010 Invision Power Services, Inc.
 * @license        http://www.invisionpower.com/company/standards.php#license
 * @package        IP.Board
 * @link        http://www.invisionpower.com
 * @since        17th February 2010
 * @version        $Revision: 8644 $
 */

class classes_archive_writer
{
    
/**#@+
     * Registry objects
     *
     * @access    protected
     * @var        object
     */
    
protected $registry;
    protected 
$DB;
    protected 
$settings;
    protected 
$request;
    protected 
$lang;
    protected 
$member;
    protected 
$memberData;
    protected 
$cache;
    protected 
$caches;
    
/**#@-*/
    
    /**
     * Set current app
     */
    
private $_app '';
    
    
/**
     * Archive 'do' allowed fields
     */
    
private $_archiveOnFields = array( 'state'        => 'state',
                                       
'pinned'        => 'pinned',
                                       
'approved'    => 'approved',
                                       
'poll'        => 'poll_state',
                                       
'post'        => 'posts',
                                       
'view'        => 'views',
                                       
'rating'        => 'topic_rating_total',
                                       
'forum'        => 'forum_id',
                                       
'member'        => 'starter_id',
                                       
'lastpost'     => 'last_post' );
    
    
/**
     * Archive 'skip' allowed fields
     */
    
private $_archiveSkipFields = array( 'post'        => 'posts',
                                         
'view'        => 'views',
                                         
'rating'    => 'topic_rating_total',
                                         
'forum'    => 'forum_id',
                                         
'member'    => 'starter_id',
                                         
'lastpost' => 'last_post');
    
    
/**
     * Constructor
     *
     */
    
public function __construct()
    {
        
/* Make registry objects */
        
$this->registry        =  ipsRegistry::instance();
        
$this->DB            =  $this->registry->DB();
        
$this->settings        =& $this->registry->fetchSettings();
        
$this->request        =& $this->registry->fetchRequest();
        
$this->lang            =  $this->registry->getClass('class_localization');
        
$this->member        =  $this->registry->member();
        
$this->memberData    =& $this->registry->member()->fetchMemberData();
        
$this->cache        =  $this->registry->cache();
        
$this->caches        =& $this->registry->cache()->fetchCaches();
        
        
/* Check for class_forums */
        
if ( ipsRegistry::isClassLoaded('class_forums') !== TRUE )
        {
            
$classToLoad IPSLib::loadLibraryIPSLib::getAppDir'forums' ) . "/sources/classes/forums/class_forums.php"'class_forums''forums' );
            
$this->registry->setClass'class_forums', new $classToLoad$this->registry ) );
            
$this->registry->class_forums->forumsInit();
        }
        
        
/* Language class */
        
$this->registry->getClass('class_localization')->loadLanguageFile( array( 'public_global' ), 'core' );
        
        
/* Fetch engine class */
        
$this->settings['archive_engine'] = ( $this->settings['archive_engine'] ) ? $this->settings['archive_engine'] : 'sql';
        
        
/* Load up archive class */
        
$classToLoad IPSLib::loadLibraryIPS_ROOT_PATH 'sources/classes/archive/writer/' $this->settings['archive_engine'] . '.php''classes_archive_writer_' $this->settings['archive_engine'] );
        
$this->engine = new $classToLoad();
        
        if ( 
$this->engine->test() !== true )
        {
            
$this->error$this->lang->words['archive_fail_engine'].'-'.$testresult );
        }
    }

    
/**
     * It's magic!
     * @param string $method
     * @param array $arguments
     */
    
public function __call$method$arguments )
    {
        switch ( 
$method )
        {
            case 
'testConnection':
                return 
$this->engine->test();
            break;
            case 
'createTable':
                return 
$this->engine->createTable();
            break;
            case 
'flush':
                return 
$this->engine->flush();
            break;
        }
    }
    
    
/**
     * Updates posts
     *
     * @param    $what        Array of fields with vals to update
     * @param    $where        String of what to update
     */
    
public function update( array $what$where )
    {
        return 
$this->engine->update$what$where );
    }
    
    
/**
     * Set the current application
     * @param string $app
     */
    
public function setApp$app )
    {
        
$this->_app $app;
    }
    
    
/**
     * Get the application
     * @return string
     */
    
public function getApp()
    {
        return 
$this->_app;
    }
    
    
/**
     * Return archive on fields
     * @return array
     */
    
public function getArchiveOnFields()
    {
        return 
array_keys$this->_archiveOnFields );
    }
    
    
/**
     * Return archive skip fields
     * @return array
     */
    
public function getArchiveSkipFields()
    {
        return 
array_keys$this->_archiveSkipFields );
    }
    
    
/**
     * Write topics to the archive
     * @param    array    INTS
     */
    
public function write$pids=array() )
    {
        if ( ! 
count$pids ) )
        {
            return 
null;
        }
        
        
$topics          = array();
        
$forumIds        = array();
        
$completedTopics = array();
        
$workingTopics   = array();
        
$maxes             = array();
        
        
/* Load the attachments stuff */
        
$classToLoad  IPSLib::loadLibraryIPSLib::getAppDir'core' ) . '/sources/classes/attach/class_attach.php''class_attach' );
        
$class_attach = new $classToLoad$this->registry );
        
$class_attach->type 'post';
        
$class_attach->init();
        
        
/* Fetch data based on PIDs */
        
$this->DB->build( array( 'select' => 'p.*',
                                 
'from'   => array( 'posts' => 'p' ),
                                 
'where'  => 'p.pid IN (' implode','$pids ) . ')',
                                 
'order'  => 'p.topic_id ASC, p.pid ASC',
                                 
'add_join' => array( array( 'select' => 't.*',
                                                             
'from'   => array( 'topics' => 't' ),
                                                             
'where'  => 'p.topic_id=t.tid' ) ) ) );
        
        
$o $this->DB->execute();
        
        while( 
$post $this->DB->fetch$o ) )
        {
            
/* Write it */
            
$this->engine->set$post );
            
            
/* Collect some data */
            
if ( ! in_array$post['tid'], $topics ) )
            {
                
$post['_pids']          = 1;
                
$post['_lowPid']        = $post['pid'];
                
$post['_maxPid']        = $post['pid'];
                
$post['_topicCount']    = ( intval$post['posts'] ) + intval$post['topic_deleted_posts'] ) + intval$post['topic_queuedposts'] ) + );
                
$topics$post['tid'] ] = $post;
            }
            else
            {
                
$topics$post['tid'] ]['_maxPid'] = $post['pid'];
                
$topics$post['tid'] ]['_pids']++;
            }
                
            
/* Collect fids */
            
$forums$post['forum_id'] ] = $post['forum_id'];
        }
        
        
/* Got any topics? */
        
if ( ! count$topics ) )
        {
            return;
        }
        
        
/* Get the maxes */
        
$this->DB->build( array( 'select' => 'topic_id, MAX(pid) as i',
                                 
'from'   => 'posts',
                                 
'where'  => 'topic_id IN (' implode','array_keys$topics ) ) . ')',
                                 
'group'  => 'topic_id' ) );
        
        
$o $this->DB->execute();
        
        while( 
$t $this->DB->fetch$o ) )
        {
            
$maxes$t['topic_id'] ] = intval$t['i'] );
        }
        
        
/* Figure out how many topics have been completed */
        
foreach( $topics as $tid => $data )
        {
            
/* First pid matches topic first pid, so we have the first post in the topic
             * but have we got all the posts in this topic?
             */
            
if ( $maxes$tid ] == $data['_maxPid'] )
            {
                
$completedTopics[] = $data['tid'];
            }
            else
            {
                
$workingTopics[] = $data['tid'];
            }
        }
        
        
/* Update working */
        
if ( count$workingTopics ) )
        {
            
$this->DB->update'topics', array( 'topic_archive_status' => $this->registry->class_forums->fetchTopicArchiveFlag'working' ) ),'tid IN(' implode','$workingTopics ) . ')' );
        }
        
        
/* Update completed */
        
if ( count$completedTopics ) )
        {
            
$this->DB->update'topics', array( 'topic_archive_status' => $this->registry->class_forums->fetchTopicArchiveFlag'archived' ) ), 'tid IN(' implode','$completedTopics ) . ')' );
            
            
/* Archive attachments */
            
$class_attach->bulkArchive$completedTopics'attach_parent_id' );
            
            
/* Remove posts */
            
$this->DB->delete'posts''topic_id IN(' implode','$completedTopics ) . ')' );        
        }
        
        
/* Do forums */
        
foreach( $forums as $id )
        {
            
$this->registry->class_forums->forumRebuild$id );
        }
        
        
/* Log it */
        
$this->log$pids );
    }
    
    
/**
     * Process a batch. Genius.
     * $options is an array of keys and values:
     * process - INT - number of items to process in this batch
     * @return int count of topics archived
     */
    
public function processBatch$options=array() )
    {
        
/* Archiver running? */
        
if ( ! $this->settings['archive_on'] )
        {
            return 
false;
        }
        
        
/* Init vars */
        
$query           $this->getArchiveWhereQuery();
        
$topics          = array();
        
$forums          = array();
        
$pids            = array();
        
        
/* Fix up options */
        
$options['process'] = ( is_numeric$options['process'] ) && $options['process'] > ) ? $options['process'] : 250;
        
        if ( 
$query === null )
        {
            return 
null;
        }
        
        
/* First see if we have a topic in progress */
        
$working $this->DB->buildAndFetch( array( 'select' => '*',
                                                    
'from'   => 'topics',
                                                    
'where'  => 'topic_archive_status=' $this->registry->class_forums->fetchTopicArchiveFlag'working' ),
                                                    
'order'  => 'tid ASC',
                                                    
'limit'  => array( 0) ) );
        
        
/* Got one? */
        
if ( $working['tid'] )
        {
            
$doneSoFar $this->engine->getDoneSoFarByTid$working['tid'] );
            
            
$postTable $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as count, MAX(pid) as max',
                                                          
'from'   => 'posts',
                                                          
'where'  => 'pid > ' intval$doneSoFar['max'] ) . ' AND topic_id=' $working['tid'] ) );
            
            
/* Mark topic complete if there's no posts left - This should not strictly be necessary but an old bug can leave topics in limbo */
            
if ( !$postTable['count'] )
            {
                
$this->DB->update'topics', array( 'topic_archive_status' => $this->registry->class_forums->fetchTopicArchiveFlag'archived' ) ), 'tid=' $working['tid'] );
            
                
/* Archive any attachments */
                
$classToLoad  IPSLib::loadLibraryIPSLib::getAppDir'core' ) . '/sources/classes/attach/class_attach.php''class_attach' );
                
$class_attach = new $classToLoad$this->registry );
                
$class_attach->type 'post';
                
$class_attach->init();
            
                
$class_attach->bulkArchive( array( $working['tid'] ), 'attach_parent_id' );
            
                
/* Remove posts */
                
$this->DB->delete'posts''topic_id =' $working['tid'] );
            }            
            
            
/* Select remaining Pids */
            
$this->DB->build( array( 'select' => 'pid',
                                     
'from'   => 'posts',
                                     
'where'  => 'pid > ' intval$doneSoFar['max'] ) . ' AND topic_id=' $working['tid'],
                                     
'order'  => 'pid ASC',
                                     
'limit'  => array( 0$options['process'] ) ) );
            
            
$o $this->DB->execute();
            
            while( 
$post $this->DB->fetch$o ) )
            {
                
$pids$post['pid'] ] = $post['pid'];
            }
            
            
/* Update process for below */
            
$options['process'] -= count$pids );
        }
        
        
/* Carry on? */
        
if ( $options['process'] > )
        {
            
/* Collect topic IDs first */
            
$this->DB->build( array( 'select' => '*',
                                     
'from'   => 'topics',
                                     
'where'  => $query ' AND (posts + topic_deleted_posts + topic_queuedposts ) >= 0',
                                     
/**
                                      * We can't check for posts > 0 because if the topic has only the first post it will skip them
                                      * 
                                      * @link    http://community.invisionpower.com/tracker/issue-37131-archive-posts-missing-old-topics-with-post-count-0/
                                      */
                                     //'where'  => $query . ' AND (posts + topic_deleted_posts + topic_queuedposts ) > 0',
                                     
'order'  => 'tid ASC',
                                     
'limit'  => array( 0$options['process'] ) ) );
            
            
$o $this->DB->execute();
            
            
$counter 0;
            
            while( 
$topic $this->DB->fetch$o ) )
            {
                
$topics[] = $topic['tid'];
                
                
$counter += ( $topic['posts'] + $topic['topic_deleted_posts'] + $topic['topic_queuedposts'] ) + 1;
                
                if ( 
$counter >= $options['process'] )
                {
                    break;
                }
            }
            
            
/* Got anything? */
            
if ( count$topics ) )
            {    
                
/* Now fetch the PIDS */
                
$this->DB->build( array( 'select' => 'pid',
                                         
'from'   => 'posts',
                                         
'where'  => 'topic_id IN (' implode','$topics ) . ')',
                                         
'order'  => 'topic_id ASC, pid ASC',
                                         
'limit'  => array( 0$options['process'] ) ) );
                
                
$o $this->DB->execute();
                
                while( 
$post $this->DB->fetch$o ) )
                {
                    
$pids$post['pid'] ] = $post['pid'];
                }
            }
        }
        
        
/* Process */
        
$this->write$pids );
        
        return 
count$pids );
    }
    
    
/**
     * Give me a key and I'll give you a DB field you lucky beasts
     * @param string $key
     */
    
public function getDbFieldFromKey$key )
    {
        return ( isset( 
$this->_archiveOnFields$key ] ) ) ? $this->_archiveOnFields$key ] : null;
    }
    
    
/**
     * Get a count of how many topics the current settings would archive off
     * if performed in one go
     * @param array $rules [Optional]
     * @return array    array( count, total, percentage )
     */
    
public function getArchivePossibleCount$rules=array() )
    {
        
$query  $this->getArchiveWhereQuery$rulesfalsetrue );    

        
$return = array( 'count' => null'percentage' => 0'total' => );
         
        if ( 
$query !== null )
        {
            
$total $this->DB->buildAndFetch( array( 'select' => 'count(*) as count',
                                                      
'from'   => 'topics',
                                                       
'where'  => $query  ' AND state != 'link'' ) );
            
            
$all   $this->DB->buildAndFetch( array( 'select' => 'count(*) as count',
                                                       
'from'   => 'topics' ) );
            
            
$return['count'] = intval$total['count'] );
            
$return['total'] = intval$all['count'] );
            
            if ( 
$return['count'] && $return['total'] )
            {
                
$return['percentage'] = round( ( $return['count'] / $return['total'] ) * 100);
            }
        }
        
        return 
$return;
    }
    
    
/**
     * Returns the WHERE portion of a query string required to fetch topics to archive
     * @param array $rules [Optional]
     */
    
public function getArchiveWhereQuery$rules=array(), $onlyGetUnarchived=true$excludeExcluded=false )
    {
        
$where    = ( $onlyGetUnarchived ) ? array( 'topic_archive_status=' $this->registry->class_forums->fetchTopicArchiveFlag'not' ) ) : array();
        
$whereNot = ( $excludeExcluded ) ? array( 'topic_archive_status=' $this->registry->class_forums->fetchTopicArchiveFlag'exclude' ) ) : array();
        
        
/* If no input, fetch from deebee */
        
if ( ! count$rules ) )
        {
            
$rules $this->getRulesFromDb();
        }
        
        
/* Hello mum! */
        
if ( is_array$rules ) && count$rules ) )
        {
            if ( 
is_array$rules['archive'] ) )
            {
                foreach( 
$rules['archive'] as $key => $data )
                {
                    
$result $this->_buildQueryBit$key$datatrue );
                    
                    if ( 
$result !== null )
                    {
                        
$where[] = $result;
                    }
                }
            }
            
            if ( 
is_array$rules['skip'] ) )
            {
                foreach( 
$rules['skip'] as $key => $data )
                {
                    
$result $this->_buildQueryBit$key$datafalse );
                    
                    if ( 
$result !== null )
                    {
                        
$where[] = $result;
                    }
                }
            }
        }
        
        foreach ( 
$whereNot as $w )
        {
            
$where[] = "!({$w})";
        }
        
        if ( 
count$where ) )
        {
            
/* Only fetch non-deleted topics */
            
$where[] = $this->registry->class_forums->fetchTopicHiddenQuery( array( 'hidden''visible' ) );
            
            return 
implode' AND '$where );
        }
        else
        {
            return 
null;
        }
    }
    
    
/**
     * Fetch the rules form the database
     */
    
public function getRulesFromDb()
    {
        
$rules = array();
        
        
$this->DB->build( array( 'select' => '*',
                                 
'from'   => 'core_archive_rules',
                                 
'where'  => 'archive_app='' . $this->DB->addSlashes( $this->getApp() ) . ''' ) );
        
        
$this->DB->execute();
        
        while( 
$row $this->DB->fetch() )
        {
            
$whut = ( $row['archive_skip'] ) ? 'skip' 'archive';
            
            
$rules$whut ][ $row['archive_field'] ] = array( 'value' => $row['archive_value'],
                                                              
'text'  => $row['archive_text'],
                                                              
'unit'  => $row['archive_unit'] );
        }
        
        return 
$rules;
    }
    
    
/**
     * Take a post and returned archive friendly array
     * @param array $post
     * @return array
     */
    
public function nativeToArchiveFields$post )
    {
        
$archive = array( 'archive_id'                => intval$post['pid'] ),
                          
'archive_author_id'         => intval$post['author_id'] ),
                          
'archive_author_name'       => $post['author_name'],
                          
'archive_ip_address'        => $post['ip_address'],
                          
'archive_content_date'      => intval$post['post_date'] ),
                          
'archive_content'              => $post['post'],
                          
'archive_queued'              => $post['queued'],
                          
'archive_topic_id'          => intval$post['topic_id'] ),
                          
'archive_is_first'          => intval$post['new_topic'] ),
                          
'archive_bwoptions'         => $post['post_bwoptions'],
                          
'archive_added'              => IPS_UNIX_TIME_NOW,
                          
'archive_attach_key'        => $post['post_key'],
                          
'archive_html_mode'        => $post['post_htmlstate'],
                          
'archive_show_signature'   => $post['use_sig'],
                          
'archive_show_emoticons'   => $post['use_emo'],
                          
'archive_show_edited_by'   => $post['append_edit'],
                          
'archive_edit_time'        => intval$post['edit_time'] ),
                          
'archive_edit_name'        => $post['edit_name'],
                          
'archive_edit_reason'      => $post['post_edit_reason'],
                          
'archive_forum_id'         => intval$post['forum_id'] ) );
        
        return 
$archive;
                        
    }
    
    
/**
     * Logs archive action
     * @param array $ids
     */
    
public function log$ids )
    {
        
$this->DB->insert'core_archive_log', array( 'archlog_date'       => IPS_UNIX_TIME_NOW,
                                                      
'archlog_app'        => $this->getApp(),
                                                      
'archlog_ids'        => serialize$ids ),
                                                      
'archlog_is_restore' => 0,
                                                      
'archlog_count'      => count$ids ) ) );    
    }
    
    
/**
     * Logs archive action
     * @param array $ids
     * @param boolean $isRestore
     */
    
public function error$msg )
    {
        
$this->DB->insert'core_archive_log', array( 'archlog_date'       => IPS_UNIX_TIME_NOW,
                                                      
'archlog_app'        => $this->getApp(),
                                                      
'archlog_msg'        => $msg,
                                                      
'archlog_is_error'   => ) );    
    }
    
    
/**
     * Build a WHERE segment
     * @param string $key
     * @param data $data
     * @param boolean $archiveOn Archive = true, skip = false
     */
    
protected function _buildQueryBit$key$data$archiveOn )
    {
        
$strOp = ( $archiveOn ) ? '='  '!=';
        
$inOp  = ( $archiveOn ) ? 'IN' 'NOT IN';
        
        switch( 
$key )
        {
            case 
'state':
                if ( 
$data['value'] != '' && $data['value'] != '-' )
                {
                    return 
$this->getDbFieldFromKey$key ) . $strOp "'" $data['value'] . "'"
                }
             break;
            case 
'pinned':
            case 
'approved':
            case 
'poll':
                if ( 
$data['value'] != '' && $data['value'] != '-' )
                {
                    return 
$this->getDbFieldFromKey$key ) . $strOp intval$data['value'] ); 
                }
            break;
            case 
'post':
            case 
'view':
            case 
'rating':
                if ( 
is_numeric$data['text'] ) && $data['text'] > )
                {
                    return 
$this->getDbFieldFromKey$key ) . $data['value'] . intval$data['text'] ); 
                }
            break;
            case 
'lastpost':
                if ( 
is_numeric$data['text'] ) && $data['text'] > )
                {
                    switch( 
$data['unit'] )
                    {
                        case 
'd':
                            
$seconds 86400;
                        break;
                        case 
'm':
                            
$seconds 2592000;
                        break;
                        case 
'y':
                            
$seconds 31536000;
                        break;
                    }
                    
                    
$time IPS_UNIX_TIME_NOW - ( $seconds intval$data['text'] ) );
                    
                    
/* Switch around for skipping */
                    
$data['value'] = ( $archiveOn ) ? $data['value'] : ( $data['value'] == '>' '<' '>' );
                    
                    return 
$this->getDbFieldFromKey$key ) . ' ' $data['value'] . ' ' $time;
                }
            break;
            case 
'forum':
            case 
'member':
                if ( 
$data['text'] )
                {
                    if ( 
IPSLib::isSerialized$data['text'] ) )
                    {
                        
$ids unserialize$data['text'] );
                    }
                    else
                    {
                        
$ids = array();
                    }
                    
                    
$inOp = ( $data['value'] == '+' ) ? 'IN' 'NOT IN';
                    
                    if ( 
is_array$ids ) && count$ids ) )
                    {
                        return 
$this->getDbFieldFromKey$key ) . ' ' $inOp '(' implode(','$ids ) . ')';
                    }
                }
            break;
        }
        
        return 
null;
    }
}
Онлайн: 2
Реклама