Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/admin/sources/classes/archive/restore.php
Строк: 271
<?php
/**
* <pre>
* Invision Power Services
* IP.Board v3.4.6
* Archive: Reader
* 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 18th November 2011
* @version $Revision: 8644 $
*/
/**
* Restores topics that are either manually flagged or via settings
* from the Admin CP.
*
* Manually flagged topics are always restored first.
* @author matt
*
*/
class classes_archive_restore
{
/**#@+
* 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 = '';
/**
* 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::loadLibrary( IPSLib::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::loadLibrary( IPS_ROOT_PATH . 'sources/classes/archive/restore/' . $this->settings['archive_engine'] . '.php', 'classes_archive_restore_' . $this->settings['archive_engine'] );
$this->engine = new $classToLoad();
}
/**
* 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;
}
/**
* Restore posts to the topic
* @param array INTS
*/
public function restore( $pids=array() )
{
if ( ! count( $pids ) )
{
return null;
}
$topics = array();
$forumIds = array();
$completedTopics = array();
$workingTopics = array();
$maxes = array();
/* Load the attachments stuff */
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'core' ) . '/sources/classes/attach/class_attach.php', 'class_attach' );
$class_attach = new $classToLoad( $this->registry );
$class_attach->type = 'post';
$class_attach->init();
/* Load the attachments stuff */
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'forums' ) . '/sources/classes/topics.php', 'app_forums_classes_topics' );
$topicClass = new $classToLoad( $this->registry );
/* Fetch data based on PIDs */
$posts = $topicClass->getPosts( array( 'postId' => $pids,
'sortField' => 'pid',
'sortOrder' => 'asc',
'postType' => array('visible', 'sdelete', 'hidden', 'pdelete', 'oktoremove'),
'skipForumCheck' => true,
'isArchivedTopic' => true ) );
foreach( $posts as $pid => $post )
{
/* Write it */
$this->engine->set( $post );
/* Collect some data */
if ( ! in_array( $post['tid'], $topics ) )
{
$post['_pids'] = 1;
$post['_lowPid'] = $post['archive_id'];
$post['_maxPid'] = $post['archive_id'];
$post['_topicCount'] = ( intval( $post['posts'] ) + intval( $post['topic_deleted_posts'] ) + intval( $post['topic_queuedposts'] ) + 1 );
$topics[ $post['tid'] ] = $post;
}
else
{
$topics[ $post['tid'] ]['_maxPid'] = $post['archive_id'];
$topics[ $post['tid'] ]['_pids']++;
}
/* Collect fids */
$forums[ $post['forum_id'] ] = $post['forum_id'];
}
foreach( $topics AS $k => $v )
{
$topics[$k]['_realMaxPid'] = $this->engine->getMaxPidInTid( $k );
}
/* 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['_realMaxPid'] )
{
$completedTopics[] = $data['tid'];
}
else if ( $maxes[ $tid ] > $data['_realMaxPid'] )
{
/* If this is true, the local post table has a higher PID than the archive table
and this should never happen, so lets investigate */
$_topic = $this->DB->buildAndFetch( array( 'select' => 'posts', 'from' => 'topics', 'where' => 'tid=' . intval( $tid ) ) );
$_post = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as count', 'from' => 'posts', 'where' => 'topic_id=' . intval( $tid ) ) );
/* Local database has all the data.. so lets call it done */
if ( ( $_topic['posts'] + 1 ) == $_post['count'] )
{
$completedTopics[] = $data['tid'];
}
else
{
/* Be cautious */
$workingTopics[] = $data['tid'];
}
}
else
{
$workingTopics[] = $data['tid'];
}
}
/* Update completed */
if ( count( $completedTopics ) )
{
$this->DB->update( 'topics', array( 'topic_archive_status' => $this->registry->class_forums->fetchTopicArchiveFlag( 'exclude' ) ), 'tid IN(' . implode( ',', $completedTopics ) . ')' );
/* Archive attachments */
$class_attach->bulkUnarchive( $completedTopics, 'attach_parent_id' );
/* Remove posts */
$this->engine->removePostsByTids( $completedTopics );
}
/* Flag as archived */
$this->engine->setAsRestoredByPids( $pids );
/* Do forums */
foreach( $forums as $id )
{
$this->registry->class_forums->forumRebuild( $id );
}
/* Log it */
$this->log( $pids, true );
}
/**
* 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() )
{
$restoreData = $this->getRestoreData();
$topics = array();
$forums = array();
$pids = array();
/* Fix up options */
$options['process'] = ( is_numeric( $options['process'] ) && $options['process'] > 0 ) ? $options['process'] : 250;
if ( ! $restoreData['restore_min_tid'] && ! $restoreData['restore_max_tid'] && ! count( $restoreData['restore_manual_tids'] ) )
{
return false;
}
/* Any manually flagged? */
if ( count( $restoreData['restore_manual_tids'] ) )
{
/* Select remaining Pids */
$pids = $this->engine->getPidsInTids( IPSLib::cleanIntArray( array_keys( $restoreData['restore_manual_tids'] ) ), $options['process'] );
/* Did we complete topics? */
foreach( $restoreData['restore_manual_tids'] as $tid => $maxPid )
{
if ( in_array( $maxPid, array_keys( $pids ) ) )
{
$this->deleteManualId( $tid );
}
}
/* All done? */
if ( ! count( $pids ) )
{
$restoreData['restore_manual_tids'] = array();
$this->setRestoreData( $restoreData );
}
/* Update process for below */
$options['process'] -= count( $pids );
}
/* Now fetch the max/min if archiver is on */
if ( $this->settings['archive_on'] && $options['process'] > 0 && $restoreData['restore_min_tid'] && $restoreData['restore_max_tid'] )
{
$date = IPS_UNIX_TIME_NOW - ( 86400 * intval( $this->settings['archive_restore_days'] ) );
$pids = $this->engine->getPidsBetweenTidsAndDate( $restoreData['restore_min_tid'], $restoreData['restore_max_tid'], $date, $options['process'] );
/* All done? */
if ( ! count( $pids ) )
{
$restoreData['restore_min_tid'] = 0;
$restoreData['restore_max_tid'] = 0;
$this->setRestoreData( $restoreData );
}
}
/* Process */
$this->restore( $pids );
return count( $pids );
}
/**
* Flag an item for manual unarchive
* @param int $id
*/
public function setManualUnarchive( $id )
{
/* Init */
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'forums' ) . "/sources/classes/topics.php", 'app_forums_classes_topics', 'forums' );
$topicClass = new $classToLoad( $this->registry );
$topic = $topicClass->getTopicById( $id );
if ( $topic['tid'] && $this->registry->class_forums->fetchArchiveTopicType( $topic ) == 'archived' )
{
$topicClass->updateTopic( $topic['tid'], array( 'topic_archive_status' => $this->registry->class_forums->fetchTopicArchiveFlag('restore') ) );
$this->insertManualId( $id );
}
}
/**
* Add an ID to the manual restore filter
*/
public function insertManualId( $id )
{
$data = $this->getRestoreData();
$max = $this->engine->getMaxPidInTid( $id );
$data['restore_manual_tids'][ $id ] = $max;
$this->setRestoreData( $data );
}
/**
* Delete an ID from the manual restore filter
*/
public function deleteManualId( $id )
{
$data = $this->getRestoreData();
if ( in_array( $id, array_keys( $data['restore_manual_tids'] ) ) )
{
unset( $data['restore_manual_tids'][ $id ] );
$this->setRestoreData( $data );
}
}
/**
* Get restore data
*/
public function getRestoreData()
{
$data = $this->DB->buildAndFetch( array( 'select' => '*',
'from' => 'core_archive_restore' ) );
if ( IPSLib::isSerialized( $data['restore_manual_tids'] ) )
{
$data['restore_manual_tids'] = unserialize( $data['restore_manual_tids'] );
}
else
{
$data['restore_manual_tids'] = array();
}
return $data;
}
/**
* Set restore data
* @param array
*/
public function setRestoreData( $data )
{
if ( is_array( $data['restore_manual_tids'] ) )
{
$data['restore_manual_tids'] = serialize( $data['restore_manual_tids'] );
}
$data['restore_min_tid'] = intval( $data['restore_min_tid'] );
$data['restore_max_tid'] = intval( $data['restore_max_tid'] );
$this->DB->delete( 'core_archive_restore');
$this->DB->insert( 'core_archive_restore', $data );
}
/**
* Take an archive row and returned native friendly array
* @param array $post
* @return array
*/
public function archiveToNativeFields( $post )
{
$native = array( 'pid' => intval( $post['archive_id'] ),
'author_id' => intval( $post['archive_author_id'] ),
'author_name' => $post['archive_author_name'],
'ip_address' => $post['archive_ip_address'],
'post_date' => intval( $post['archive_content_date'] ),
'post' => $post['archive_content'],
'queued' => $post['archive_queued'],
'topic_id' => intval( $post['archive_topic_id'] ),
'new_topic' => intval( $post['archive_is_first'] ),
'post_bwoptions' => $post['archive_bwoptions'],
'post_key' => $post['archive_attach_key'],
'post_htmlstate' => $post['archive_html_mode'],
'use_sig' => $post['archive_show_signature'],
'use_emo' => $post['archive_show_emoticons'],
'append_edit' => $post['archive_show_edited_by'],
'edit_time' => $post['archive_edit_time'],
'edit_name' => $post['archive_edit_name'],
'post_edit_reason' => $post['archive_edit_reason'] );
return $native;
}
/**
* 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' => 1,
'archlog_count' => count( $ids ) ) );
}
}