Вход Регистрация
Файл: admin/setup/sources/base/ipsRegistry_setup.php
Строк: 1439
<?php

/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.3.3
 * Registry class for setup
 * Last Updated: $Date: 2012-05-11 11:17:52 -0400 (Fri, 11 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        1st December 2008
 * @version        $Revision: 10727 $
 *
 */

/**
 * ipsRegistry class for install/upgrade
 * @package    IP.Board
 * @ignore
 */
class ipsRegistry
{
    
/**
     * Stored values
     *
     * @access    private
     * @var        array
     */
    
private $values                = array();

    
/**
     * Registry instance
     *
     * @access    private
     * @var        object
     */
    
private static $instance;

    
/**
     * Are we initiated
     *
     * @access    private
     * @var        bool
     */
    
private static $initiated    = FALSE;

    
/**
     * Singleton handles
     *
     * @access    private
     * @var        array
     */
    
private static $handles        = array();

    
/**#@+
     * Holds core variable data
     *
     * @access    private
     * @var        array
     */
    
private static $_coreVariables            = array();
    private static 
$_masterCoreVariables    = array();
    
/**#@-*/

    /**
     * Stored object references
     *
     * @access    private
     * @var        array
     */
    
private static $classes    = array();

    
/**
     * Global config data
     *
     * @access    public
     * @var        array
     */
    
static public $_config    = array();

    
/**#@+
     * Stored URLs
     *
     * @access    public
     * @var        mixed    Array, string
     */
    
static public $urls                = array();
    static public 
$processed_url    = '';
    
/**#@-*/

    /**
     * Server load
     *
     * @access    public
     * @var        string
     */
    
static public $server_load;

    
/**#@+
     * Version numbers
     *
     * @access    public
     * @var        string
     */
    
static public $version            = IPB_VERSION;
    static public 
$acpversion        = IPB_LONG_VERSION;
    static public 
$vn_full            = '';
    static public 
$vn_build_date    = '';
    static public 
$vn_build_reason    = '';
    
/**#@-*/

    /**#@+
     * Applications and modules
     *
     * @access    public
     * @var        mixed        Array, string
     */
    
static public $applications            = array();
    static public 
$modules                = array();
    static public 
$modules_by_section    = array();
    static public 
$current_application    = '';
    static public 
$current_module        = '';
    static public 
$current_section        = '';
    
/**#@-*/

    /**
     * Application class vars
     *
     * @access    public
     * @var        array
     */
    
static public $app_class    = array();

    
/**
     * Settings
     *
     * @access    public
     * @var        array
     */
    
static public $settings        = array();

    
/**
     * Request params
     *
     * @access    public
     * @var        array
     */
    
static public $request        = array();

    
/**
     * Singleton init
     *
     * @access    public
     * @return    object        Reference to ourself
     */
    
static public function instance()
    {
        if ( ! 
self::$instance )
        {
            
self::$instance = new self();
        }
        return 
self::$instance;
    }

    
/**
     * Custom destructor
     *
     * @access    public
     * @return    @e void
     */
    
static public function __myDestruct()
    {
        foreach( 
self::$handles as $name => $obj )
        {
            if ( 
method_exists( $obj, '__myDestruct' ) )
            {
                
$obj->__myDestruct();
            }
        }
    }

    
/**
     * Initiate the registry
     *
     * @access    public
     * @return    @e void
     */
    
public static function init()
    {
        if ( 
self::$initiated === TRUE )
        {
            return 
FALSE;
        }

        
self::$initiated = TRUE;
        
        
/* Log current upgrade step */
        
self::logUpgradeStep();

        
/* Load static classes */
        
require( IPS_ROOT_PATH . "sources/base/core.php" );/*noLibHook*/
        
require( IPS_ROOT_PATH . "sources/base/ipsMember.php" );/*noLibHook*/
        
require( IPS_ROOT_PATH . "setup/sources/base/setup.php" );/*noLibHook*/

        /* Load conf global and set up DB */
        
if ( IPS_IS_UPGRADER )
        {
            if ( ! 
is_file( DOC_IPS_ROOT_PATH . "conf_global.php" ) )
            {
                print 
"Файл " . DOC_IPS_ROOT_PATH . "conf_global.php не найден!";
                exit();
            }

            
self::loadConfGlobal();

            
/* Got settings? */
            
if ( ! ipsRegistry::$settings['sql_driver'] )
            {
                print 
"Файл " . DOC_IPS_ROOT_PATH . "conf_global.php не содержит нужных настроек.";
                exit();
            }

            
self::setDBHandle();
        }
        else
        {
            
/* Ensure char set is defined */
            
if( ! defined( 'IPS_DOC_CHAR_SET' ) )
            {
                
define( 'IPS_DOC_CHAR_SET', strtoupper( IPSSetUp::charSet ) );
            }
            
            if ( ! 
defined('IPS_CACHE_PATH') )
            {
                
define( 'IPS_CACHE_PATH', DOC_IPS_ROOT_PATH );
            }

            require 
IPS_ROOT_PATH . "setup/sources/base/install.php";/*noLibHook*/
        
}

        
/* Input set up... */
        
if ( is_array( $_POST ) and count( $_POST ) )
        {
            foreach( 
$_POST as $key => $value )
            {
                
# Skip post arrays
                
if ( ! is_array( $value ) )
                {
                    
$_POST[ $key ] = IPSText::stripslashes( $value );
                }
            }
        }

        
//-----------------------------------------
        // Clean globals, first.
        //-----------------------------------------

        
IPSLib::cleanGlobals( $_GET );
        
IPSLib::cleanGlobals( $_POST );
        
IPSLib::cleanGlobals( $_COOKIE );
        
IPSLib::cleanGlobals( $_REQUEST );

        
# GET first
        
$input = IPSLib::parseIncomingRecursively( $_GET, array() );

        
# Then overwrite with POST
        
self::$request = IPSLib::parseIncomingRecursively( $_POST, $input );

        
# Assign request method
        
self::$request['request_method'] = strtolower( my_getenv('REQUEST_METHOD') );

        
self::_setUpAppData();

        
/* Get caches */
        
self::$handles['caches']   = ips_CacheRegistry::instance();

        if ( 
IPS_IS_UPGRADER )
        {
            
/* Make sure all is well before we proceed */
            
self::instance()->setUpSettings();

            
/* Build module and application caches */
            
self::instance()->checkCaches();

            
/* Load 'legacy' systems */
            
$file = '';

            if ( 
IPSSetUp::is300plus() === TRUE )
            {
                
$file = '3xx.php';
            }
            else if ( 
IPSSetUp::is200plus() === TRUE )
            {
                
$file = '2xx.php';
            }
            else
            {
                
$file = '1xx.php';
            }

            require_once( 
IPS_ROOT_PATH . 'setup/sources/legacy/' . $file );/*noLibHook*/
            
self::instance()->setClass( 'legacy', new upgradeLegacy( self::instance() ) );
        }

        
/* Set up member */
        
self::$handles['member']   = ips_MemberRegistry::instance();

        
# Thaw saved data
        
IPSSetUp::thawSavedData();

        
/* Gather other classes */
        
require_once( IPS_ROOT_PATH . 'setup/sources/classes/output/output.php' );/*noLibHook*/

        
self::instance()->setClass( 'output', new output( self::instance(), TRUE ) );

        
# Fetch global config
        
if ( self::readGlobalConfig() === FALSE )
        {
            
self::getClass('output')->addError( "Невозможно загрузить config.xml" );
        }

        if ( 
IPS_IS_UPGRADER )
        {
            
/* Check session status */
            
$validationStatus  = self::member()->sessionClass()->getStatus();
            
$validationMessage = self::member()->sessionClass()->getMessage();

            if ( ( 
self::$request['section'] AND self::$request['section'] != 'index' ) AND ( ! $validationStatus ) )
            {
                
/* Force log in */
                
self::getClass('output')->setTitle( "Обновление: Ошибка" );
                
self::getClass('output')->setNextAction( '' );
                
self::getClass('output')->addContent( self::getClass('output')->template()->page_error( $validationMessage ) );
                
self::getClass('output')->sendOutput();
                exit();
            }
        }
        else
        {
            
# Installer locked?
            
if ( is_file( DOC_IPS_ROOT_PATH . 'cache/installer_lock.php' ) )
            {
                
self::getClass('output')->setTitle( "Установка: Ошибка" );
                
self::getClass('output')->setNextAction( '' );
                
self::getClass('output')->addContent( self::getClass('output')->template()->page_locked() );
                
self::getClass('output')->sendOutput();
                exit();
            }
        }
    }
    
    
/**
     * Log the step we are in the upgrade routine
     */
     
static public function logUpgradeStep()
     {
         
$_log    = date('r') . "n";
         
$_log    .= $_SERVER['REQUEST_URI'] . "n";
         
         
$_filename    = "UPGRADE_LOG_" . date('d_m_Y') . '.cgi';
         
         
file_put_contents( DOC_IPS_ROOT_PATH . 'cache/' . $_filename, $_log, FILE_APPEND );
     }

    
/**
     * Load conf_global
     *
     * @access    public
     * @return    @e void
     */
    
static public function loadConfGlobal()
    {
        
/* Load config file */
        
if ( is_file( DOC_IPS_ROOT_PATH . 'conf_global.php' ) )
        {
            
$INFO = array();
            require( 
DOC_IPS_ROOT_PATH . 'conf_global.php' );/*noLibHook*/

            
if ( is_array( $INFO ) && count( $INFO ) )
            {
                foreach( 
$INFO as $key => $val )
                {
                    
ipsRegistry::$settings[ $key ]    = $val;
                }
            }
        }
    }

    
/**
     * Set database handle
     *
     * @access    public
     * @return    @e void
     */
    
static public function setDBHandle()
    {
        
self::$handles['db'] = ips_DBRegistry::instance();
        
self::$handles['db']->setDB( ipsRegistry::$settings['sql_driver'] );
    }

    
/**
     * Auto loads next action
     *
     * @access    public
     * @param    string        Section key
     * @return    @e void
     */
    
static public function autoLoadNextAction( $section )
    {
        
self::getClass('output')->currentPage = $section;
        
self::$request['do'] = '';

        
$_class = IPS_APP_COMPONENT . '_' . $section;

        require_once( 
IPS_ROOT_PATH . 'setup/applications/' . IPS_APP_COMPONENT . '/sections/' . $section . '.php' );/*noLibHook*/
        
$action = new $_class();
        
$action->makeRegistryShortcuts( self::instance() );
        
$action->doExecute( self::instance() );
        return;
    }

    
/**
     * Read conf_global
     *
     * @access    public
     * @return    bool
     */
    
static public function readGlobalConfig()
    {
        
/* Fetch core writeable files */
        
require_once( IPS_KERNEL_PATH . 'classXML.php' );/*noLibHook*/
        
$xml    = new classXML( IPSSetUp::charSet );

        try
        {
            
$xml->load( IPS_ROOT_PATH . 'setup/xml/config.xml' );

            foreach( 
$xml->fetchElements( 'package' ) as $xmlelement )
            {
                
$data = $xml->fetchElementsFromRecord( $xmlelement );

                
self::$_config = $data;
            }

            return 
TRUE;
        }
        catch( 
Exception $error )
        {
            return 
FALSE;
        }
    }

    
/**
     * Grabs apps bitwise array
     *
     * @access    public
     * @param    string    $appDir
     * @return    string    Core variables
     */
    
static public function fetchBitWiseOptions( $appDir )
    {
        if ( 
$appDir == 'global' )
        {
            return 
self::_fetchCoreVariables( 'bitwise' );
        }
        else
        {
            return 
self::_fetchAppCoreVariables( $appDir, 'bitwise' );
        }
    }
    
    
/**
     * Fetch global config data as array
     *
     * @access    public
     * @return    array
     */
    
static public function fetchGlobalConfigAsArray()
    {
        return 
is_array( self::$_config ) ? self::$_config : array();
    }

    
/**
     * Fetch global config value
     *
     * @access    public
     * @param    string        Key
     * @return    string
     */
    
static public function fetchGlobalConfigValue( $key )
    {
        return isset( 
self::$_config[ $key ] ) ? self::$_config[ $key ] : FALSE;
    }

    
/**
     * Grab the app class file
     *
     * @param    string        $app    Application to check for app class
     * @return    mixed        Null if invalid or no app passed, otherwise app class object
     */
    
public static function getAppClass( $app='' )
    {
        if( !
$app OR !is_string($app) )
        {
            return 
null;
        }

        
# Load app class
        
if ( ! isset( self::$app_class[ $app ] ) )
        {
            
self::$app_class[ $app ] = null;

            
$_file = IPSLib::getAppDir( $app ) . '/app_class_' . $app . '.php';
            
$_name = 'app_class_' . $app;

            if ( 
is_file( $_file ) )
            {
                
$classToLoad = IPSLib::loadLibrary( $_file, $_name, $app );
                
                
self::$app_class[ $app ] = new $classToLoad( self::instance() );
            }
        }
        
        return 
self::$app_class[ $app ];
    }

    
/**
     * Loads application's core variables (if required)
     *
     * @access    public
     * @param    string        App key (dir.. that's directory, not duuhr)
     * @return    @e void
     */
    
static public function _loadCoreVariables()
    {
        if ( ! 
is_object( self::$_masterCoreVariables['__CLASS__'] ) )
        {
            require_once( 
IPS_ROOT_PATH . 'extensions/coreVariables.php' );/*noLibHook*/

            /* Add handle */
            
self::$_masterCoreVariables['__CLASS__'] = new coreVariables();
        }
    }

    
/**
     * Fetches apps core variable data
     *
     * @access    public
     * @param    string        Type of variable to return
     * @return    string
     */
    
public static function _fetchCoreVariables( $type )
    {
        if ( ! 
is_array( self::$_masterCoreVariables[ $type ] ) )
        {
            
self::_loadCoreVariables();

            switch( 
$type )
            {
                case 
'cache':
                case 
'cacheload':
                    
$return = self::$_masterCoreVariables['__CLASS__']->fetchCaches();
                    
self::$_masterCoreVariables['cache']     = is_array( $return['caches'] )    ? $return['caches'] : array();
                    
self::$_masterCoreVariables['cacheload'] = is_array( $return['cacheload'] ) ? $return['cacheload'] : array();
                break;
                case 
'redirect':
                    
$return = self::$_masterCoreVariables['__CLASS__']->fetchRedirects();
                    
self::$_masterCoreVariables['redirect'] = is_array( $return ) ? $return : array();
                break;
                case 
'templates':
                    
$return = self::$_masterCoreVariables['__CLASS__']->fetchTemplates();
                    
self::$_masterCoreVariables['templates'] = is_array( $return ) ? $return : array();
                break;
                case 
'bitwise':
                    
$return = self::$_masterCoreVariables['__CLASS__']->fetchBitwise();
                    
self::$_masterCoreVariables['bitwise'] = is_array( $return ) ? $return : array();
                break;
            }
        }

        return 
self::$_masterCoreVariables[ $type ];
    }

    
/**
     * Loads application's core variables (if required)
     *
     * @access    private
     * @param    string        App key (dir.. that's directory, not duuhr)
     * @return    @e void
     */
    
static private function _loadAppCoreVariables( $appDir )
    {
        if ( ! isset( 
self::$_coreVariables[ $appDir ] ) )
        {
            if( 
is_file( IPSLib::getAppDir( $appDir ) . '/extensions/coreVariables.php' ) )
            {
                require( 
IPSLib::getAppDir( $appDir ) . '/extensions/coreVariables.php' );/*noLibHook*/

                /* Add caches */
                
self::$_coreVariables[ $appDir ]['cache']     = is_array( $CACHE ) ? $CACHE : array();
                
self::$_coreVariables[ $appDir ]['cacheload'] = is_array( $_LOAD ) ? $_LOAD : array();

                
/* Add redirect */
                
self::$_coreVariables[ $appDir ]['redirect'] = is_array( $_RESET ) ? $_RESET : array();

                
/* Add bitwise */
                
self::$_coreVariables[ $appDir ]['bitwise']  = is_array( $_BITWISE ) ? $_BITWISE : array();
            }
        }
    }

    
/**
     * Fetches apps core variable data
     *
     * @access    public
     * @param    string        App dir
     * @param    string        Type of variable to return
     * @return    string
     */
    
static public function _fetchAppCoreVariables( $appDir, $type )
    {
        if ( ! 
is_array( self::$_coreVariables[ $appDir ][ $type ] ) )
        {
            
self::_loadAppCoreVariables( $appDir );
        }

        return 
self::$_coreVariables[ $appDir ][ $type ];
    }

    
/**
     * Store object handles so we don't need to reinit them
     *
     * @access    public
     * @param    string        Key
     * @param    object        Value
     * @return    @e void
     */
    
static public function setClass( $key='', $value='' )
    {
        
self::instance()->checkForInit();

        if ( ! 
$key OR ! $value )
        {
            throw new 
Exception( "Не хватает ключа или значения" );
        }
        else if ( ! 
is_object( $value ) )
        {
            throw new 
Exception( "$value не является объектом" );
        }

        
self::$classes[ $key ] = $value;
    }

    
/**
     * Function for retrieving class handles
     * AUTOLOADED classes are as follows:
     * KERNEL -> class_captcha
     * KERNEL -> classTemplateEngine (templateEngine)
     * CORE   -> localization class
     *
     * @access    public
     * @param    string        Key
     * @return    object
     */
    
static public function getClass( $key )
    {
        
self::instance()->checkForInit();

        
/* Do some magic here to retreive common classes without
           having to initialize them first */
        
if ( ! isset( self::$classes[ $key ] ) || ! is_object( self::$classes[ $key ] ) )
        {
            switch( 
$key )
            {
                default:
                    throw new 
Exception( "$key не является объектом" );
                break;
                case 
'class_captcha':
                    require_once( 
IPS_KERNEL_PATH . 'classCaptcha.php' );/*noLibHook*/
                    
self::$classes['class_captcha'] = new classCaptcha( self::instance() );
                break;
                case 
'templateEngine':
                    require_once( 
IPS_KERNEL_PATH . 'classTemplateEngine.php' );/*noLibHook*/
                    
self::$classes['templateEngine'] = new classTemplate( IPS_ROOT_PATH . 'sources/template_plugins' );
                break;
                case 
'class_localization':
                    require_once( 
IPS_ROOT_PATH    . 'sources/classes/class_localization.php' );/*noLibHook*/
                    
self::$classes['class_localization'] = new class_localization( self::instance() );
                break;
                case 
'permissions':
                    require_once( 
IPS_ROOT_PATH    . 'sources/classes/class_public_permissions.php' );/*noLibHook*/
                    
self::$classes['permissions'] = new classPublicPermissions( self::instance() );
                break;
                
/* Yes I know this is forums app and not global, but it's still called so much this is a good idea */
                
case 'class_forums':
                    require_once( 
IPSLib::getAppDir( 'forums' ) . "/sources/classes/forums/class_forums.php" );/*noLibHook*/
                    
self::$classes['class_forums'] = new class_forums( self::instance() );
                    
self::$classes['class_forums']->strip_invisible    = true;
                    
self::$classes['class_forums']->forumsInit();
                break;
                case 
'classItemMarking':
                    
$classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/itemmarking/classItemMarking.php', 'classItemMarking' );
                    
self::$classes['classItemMarking'] = new $classToLoad( self::instance() );
                break;
                
            }

            return 
self::$classes[ $key ];
        }
        else
        {
            return 
self::$classes[ $key ];
        }
    }

    
/**
     * Return a list of classes
     * IN_DEV ONLY
     *
     * @access    public
     * @return    mixed         Array of items, or false
     */
    
public static function getLoadedClassesAsArray()
    {
        if ( ! 
IN_DEV )
        {
            return 
FALSE;
        }
        else
        {
            return 
array_keys( self::$classes );
        }
    }

    
/**
     * Shortcut for accessing registry objects
     *
     * @access    public
     * @param    string        Key
     * @return    object
     */
    
public function __get( $key )
    {
        
self::instance()->checkForInit();

        
$_class = self::getClass( $key );

        if ( 
is_object( $_class ) )
        {
            return 
$_class;
        }
    }

    
/**
     * Find out if a class is loaded
     *
     * @access    public
     * @param    string    Key
     * @return    bool
     */
    
static public function isClassLoaded( $key )
    {
        return ( isset( 
self::$classes[ $key ] ) && is_object( self::$classes[ $key ] ) ) ? TRUE : FALSE;
    }

    
/**
     * Get database object
     *
     * @access    public
     * @param    string    DB connection key
     * @return    object
     */
    
static public function DB( $key='' )
    {
        if ( 
self::$settings['sql_user'] )
        {
            
self::instance()->checkForInit();
            return 
self::$handles['db']->getDB( $key );
        }
    }

    
/**
     * Get database functions object
     *
     * @access    public
     * @param    string    DB connection key
     * @return    object
     */
    
static public function dbFunctions( $key='' )
    {
        
self::instance()->checkForInit();
        return 
self::$handles['db'];
    }

    
/**
     * Get cache object
     *
     * @access    public
     * @return    object
     */
    
static public function cache()
    {
        
self::instance()->checkForInit();
        return 
self::$handles['caches'];
    }

    
/**
     * Get cache object
     *
     * @access    public
     * @return    array
     * @see        fetchSettings()
     */
    
static public function settings()
    {
        
self::instance()->checkForInit();
        return 
ipsRegistry::$settings;
    }

    
/**
     * Fetch all the settings
     *
     * @access    public
     * @return    array
     */
    
static public function &fetchSettings()
    {
        return 
ipsRegistry::$settings;
    }

    
/**
     * Fetch request items
     *
     * @access    public
     * @return    array
     */
    
static public function &fetchRequest()
    {
        return 
ipsRegistry::$request;
    }

    
/**
     * Fetch request items
     *
     * @access    public
     * @return    array
     * @see        fetchRequest()
     */
    
static public function request()
    {
        
self::instance()->checkForInit();
        return 
ipsRegistry::$request;
    }

    
/**
     * Fetch member object
     *
     * @access    public
     * @return    object
     */
    
static public function member()
    {
        
self::instance()->checkForInit();

        if( isset( 
self::$handles['member'] ) )
        {
            return 
self::$handles['member'];
        }
    }

    
/**
     * Returns the current application
     *
     * @access    public
     * @return    string
     */
    
static public function getCurrentApplication()
    {
        return 
self::$current_application;
    }

    
/**
     * Returns an array of applications
     *
     * @access    public
     * @return    array
     */
    
public function getApplications()
    {
        return 
self::$applications;
    }

    
/**
     * Check to see if we are initialized
     *
     * @access    protected
     * @return    @e void
     */
    
protected function checkForInit()
    {
        if ( 
self::$initiated !== TRUE )
        {
            throw new 
Exception('ipsRegistry не был инициализирован. Инициализируйте его с помощью ipsRegistry::init()' );
        }
    }



    
/**
     * Set up request redirect stuff
     *
     * @return    @e void
     * @author    MattMecham
     * @access    protected
     */
    
protected static function _setUpAppData()
    {
        
$_default = ( IPS_IS_UPGRADER ) ? 'upgrade' : 'install';

        
# Finalize the app component constants
        
$_appcomponent = preg_replace( "/[^a-zA-Z0-9-_]/", "" , ( isset( $_REQUEST['app'] ) && trim( $_REQUEST['app'] ) ? $_REQUEST['app'] : $_default ) );
        
define( 'IPS_APP_COMPONENT', ( $_appcomponent ) ? $_appcomponent : $_default );

        
self::$current_section = IPSText::alphanumericalClean( $_REQUEST['section'] );
    }

    
/**
     * Set up settings
     *
     * @return    @e void
     * @author    MattMecham
     * @access    protected
     */
    
protected function setUpSettings()
    {
        
$settings_cache = self::$handles['caches']->getCache('settings');

        if ( ! 
is_array( $settings_cache ) OR ! count( $settings_cache ) )
        {
            
/* Ok, if we're an upgrader and we're 1.3... */
            
if ( IPS_IS_UPGRADER )
            {
                
$settings_cache = array();
            }
            else
            {
                throw new 
Exception( "Невозможно инициализировать реестр, кеш настроек пуст или не найден." );
            }
        }

        foreach( 
$settings_cache as $k => $v )
        {
            
ipsRegistry::$settings[$k] = $v;
        }
        
        if ( ! 
defined('IPS_CACHE_PATH') )
        {
            
define( 'IPS_CACHE_PATH', ( IPS_IS_UPGRADER ) ? ( ! empty( ipsRegistry::$settings['ipb_cache_path'] ) ? ipsRegistry::$settings['ipb_cache_path'] : DOC_IPS_ROOT_PATH ) :  DOC_IPS_ROOT_PATH );
        }

        
//-----------------------------------------
        // Back up base URL
        //-----------------------------------------

        
ipsRegistry::$settings['base_url']           = ( ipsRegistry::$settings['board_url'] ) ? ipsRegistry::$settings['board_url'] : ipsRegistry::$settings['base_url'];
        
ipsRegistry::$settings['_original_base_url'] = ipsRegistry::$settings['base_url'];

        
//-----------------------------------------
        // Make a safe query string
        //-----------------------------------------

        
ipsRegistry::$settings['query_string_safe'] = str_replace( '&amp;amp;', '&amp;', IPSText::parseCleanValue( urldecode( my_getenv('QUERY_STRING') ) ) );
        
ipsRegistry::$settings['query_string_real'] = str_replace( '&amp;'    , '&'    , ipsRegistry::$settings['query_string_safe'] );

        
//-----------------------------------------
        // Format it..
        //-----------------------------------------

        
ipsRegistry::$settings['query_string_formatted'] = str_replace( ipsRegistry::$settings['board_url'] . '/index.'.ipsRegistry::$settings['php_ext'].'?', '', ipsRegistry::$settings['query_string_safe'] );
        
ipsRegistry::$settings['query_string_formatted'] = preg_replace( "#s=([a-z0-9]){32}#", '', ipsRegistry::$settings['query_string_formatted'] );

        
//-----------------------------------------
        // Default settings
        //-----------------------------------------

        
ipsRegistry::$settings['_admin_link'] = ipsRegistry::$settings['base_url'] . '/' . CP_DIRECTORY . '/index.php';
        
ipsRegistry::$settings['max_user_name_length'] = ipsRegistry::$settings['max_user_name_length'] ? ipsRegistry::$settings['max_user_name_length'] : 26;

        
# Upload
        
ipsRegistry::$settings['upload_dir'] = ipsRegistry::$settings['upload_dir'] ? ipsRegistry::$settings['upload_dir'] : DOC_IPS_ROOT_PATH.'uploads';
        
ipsRegistry::$settings['upload_url'] = ipsRegistry::$settings['upload_url'] ? ipsRegistry::$settings['upload_url'] :ipsRegistry::$settings['base_url']  . '/uploads';

        
# Char set
        
ipsRegistry::$settings['gb_char_set'] = ipsRegistry::$settings['gb_char_set'] ? ipsRegistry::$settings['gb_char_set'] : 'UTF-8';

        if( !
defined( 'IPS_DOC_CHAR_SET' ) )
        {
            
define( 'IPS_DOC_CHAR_SET', ipsRegistry::$settings['gb_char_set'] );
        }

        
# If htaccess mod rewrite is on, enforce path_info usage
        
ipsRegistry::$settings['url_type'] = ( ipsRegistry::$settings['htaccess_mod_rewrite'] ) ? 'path_info' : ipsRegistry::$settings['url_type'];
    }

    
/**
     * Check caches
     *
     * @return    @e void
     * @author    MattMecham
     * @access    protected
     */
    
protected function checkCaches()
    {
        
//-----------------------------------------
        // Check app cache data
        //-----------------------------------------

        
$group_cache = self::$handles['caches']->getCache('group_cache');

        if ( ! 
is_array( $group_cache ) OR ! count( $group_cache ) )
        {
            
/* Another catch for IPB 1.3 */
            
if ( IPS_IS_UPGRADER )
            {
                if ( 
IPSSetUp::is200plus() !== TRUE )
                {
                    
/* Er.. don't actually think we need 'em to be honest */
                    
self::DB()->delete( 'cache_store', 'cs_key='group_cache'' );

                    
self::DB()->build( array( 'select' => '*',
                                              
'from'     => 'groups' ) );

                    
self::DB()->execute();

                    
$groups = array();

                    while( 
$row = self::DB()->fetch() )
                    {
                        
$groups[ $row['g_id'] ] = $row;
                    }

                    
self::DB()->insert( 'cache_store', array( 'cs_key'   => 'group_cache',
                                                              
'cs_value' => serialize( $groups ) ) );
                }
                else
                {
                    
//$this->cache()->rebuildCache( 'group_cache', 'global' );
                
}
            }
        }

        
$app_cache = self::$handles['caches']->getCache('app_cache');
        
        
//-----------------------------------------
        // Build app data and APP specific load requests
        //-----------------------------------------

        
if( is_array($app_cache) AND count($app_cache) )
        {
            foreach( 
$app_cache as $_app_dir => $_app_data )
            {
                if ( !
IPS_IS_TASK AND ( IPS_AREA == 'public' && ! $_app_data['app_public_title'] ) )
                {
                    continue;
                }
    
                
$_app_data['app_public_title'] = ( $_app_data['app_public_title'] ) ? $_app_data['app_public_title'] : $_app_data['app_title'];
                
self::$applications[ $_app_dir ] = $_app_data;
            }
        }
        
        
/* Sort by position */
        
uasort( self::$applications, 'ipsRegistry::_appPositionSort' );
    }

    
/**
     * Sort by position
     *
     * @return    integer
     */
    
protected static function _appPositionSort( $a, $b )
    {
        
$a['app_position'] = ( isset( $a['app_position'] ) ) ? $a['app_position'] : 0;
        
$b['app_position'] = ( isset( $b['app_position'] ) ) ? $b['app_position'] : 0;
        
        return ( 
$a['app_position'] > $b['app_position'] ) ? +1 : -1;
    }
}

/**
 * ips_base_Registry
 *
 */
abstract class ips_base_Registry
{
    
/**
     * Generic data storage for each class that extends ips_base_Registry
     *
     * @access    protected
     * @var        array
     */
    
protected $data_store = array();

    
/**
     * get()
     *
     * Returns the value for the specified key from the data_store, can be overriden by child classes
     *
     * @access    public
     * @param    mixed $key
     * @return    mixed
     */
    
protected function get( $key )
    {
        if( isset( 
$this->data_store[ $key ] ) )
        {
            return 
$this->data_store[ $key ];
        }
        else
        {
            return 
'';
        }
    }

    
/**
     * set()
     *
     * Sets a value in the data_store
     *
     * @access    public
     * @param    mixed $key
     * @param    mixed $val
     * @return    mixed
     */
    
protected function set( $key, $val )
    {
        
$this->data_store[ $key ] = $val;
    }
}

/**
 * Base Database class
 */
class ips_DBRegistry extends ips_base_Registry
{
    
/**
     * DB instance
     *
     * @access    private
     * @var        object
     */
    
private static $instance;

    
/**
     * Static array for variables
     *
     * @access    private
     * @var        array
     */
    
private static $vars        = array();

    
/**
     * Static DB prefixes
     *
     * @access    private
     * @var        array
     */
    
private static $dbPrefixes    = array( '__default__' => '' );

    
/**
     * Static DB driver
     *
     * @access    private
     * @var        array
     */
    
private static $dbDrivers    = array( '__default__' => '' );

    
/**
     * Static default DB object
     *
     * @access    private
     * @var        string
     */
    
private static $defaultKey    = '__default__';

    
/**
     * Cache files tried to load
     *
     * @access    private
     * @var        array
     */
    
private static $_queryFilesTriedToLoad = array();

    
/**
     * Cache file parsed names
     *
     * @access    private
     * @var        array
     */
    
private static $_queryFilesNames = array();

    
/**
     * Singleton init
     *
     * @access    public
     * @return    object
     */
    
static public function instance()
    {
        if ( ! 
self::$instance )
        {
            
self::$instance = new self();
        }

        return 
self::$instance;
    }

    
/**
     * Get DB instance
     *
     * @access    public
     * @param    string    Key
     * @return    object
     */
    
static public function getDB( $key='' )
    {
        
$key = ( $key ) ? $key : self::$defaultKey;

        return 
self::instance()->get( $key );
    }

    
/**
     * Return the prefix for this connection
     *
     * @access    public
     * @param    string    Key
     * @return    string
     */
    
static public function getPrefix( $key='' )
    {
        
$key = ( $key ) ? $key : self::$defaultKey;

        if ( isset(
self::$dbPrefixes[$key]) )
        {
            return 
self::$dbPrefixes[ $key ];
        }
        else
        {
            throw new 
Exception( "Ключ соединения с базой данных $key не найден" );
        }
    }

    
/**
     * Returns the driver type currently in use, ex: mysql
     *
     * @access    public
     * @param    string    $key    Key of the db connection to check
     * @return    object
     */
    
static public function getDriverType( $key= '' )
    {
        
/* Set Key */
        
$key = ( $key ) ? $key : self::$defaultKey;

        return 
self::$dbDrivers[ $key ];
    }

    
/**
     * Sets the DB instance
     *
     * @access    public
     * @param    object    $db_driver    DB instance
     * @param    string    $key        Key of the db connection to check
     * @return    @e void
     */

    
static function setDB( $db_driver, $key='' )
    {
        
/* INIT */
        
$db_driver        = strtolower( $db_driver );
        
$query_file_extra = ( IPS_AREA == 'admin' ) ? '_admin' : '';
        
$key              = ( $key ) ? $key : self::$defaultKey;

        
/* Fix up settings */
        
if ( ! class_exists( 'dbMain' ) )
        {
            require_once ( 
IPS_KERNEL_PATH . 'classDb' . ucwords($db_driver) . ".php" );/*noLibHook*/
        
}

        
$classname = "db_driver_" . $db_driver;

        
/* INIT Object */
        
self::instance()->dbObjects[ $key ] = new $classname;

        
self::instance()->dbObjects[ $key ]->obj['sql_database']         = ipsRegistry::$settings['sql_database'];
        
self::instance()->dbObjects[ $key ]->obj['sql_user']             = ipsRegistry::$settings['sql_user'];
        
self::instance()->dbObjects[ $key ]->obj['sql_port']             = ipsRegistry::$settings['sql_port'];
        
self::instance()->dbObjects[ $key ]->obj['sql_socket']             = isset(ipsRegistry::$settings['sql_socket']) ? ipsRegistry::$settings['sql_socket'] : null;
        
self::instance()->dbObjects[ $key ]->obj['sql_pass']             = str_replace( '\'', ''', ipsRegistry::$settings['sql_pass'] );
        self::instance()->dbObjects[ $key ]->obj['
sql_host']             = ipsRegistry::$settings['sql_host'];
        self::instance()->dbObjects[ $key ]->obj['
sql_charset']          = ipsRegistry::$settings['sql_charset'];
        self::instance()->dbObjects[ $key ]->obj['
sql_tbl_prefix']       = ipsRegistry::$settings['sql_tbl_prefix'] ? ipsRegistry::$settings['sql_tbl_prefix'] : '';
        self::instance()->dbObjects[ $key ]->obj['
force_new_connection'] = ( $key != self::$defaultKey ) ? 1 : 0;
        self::instance()->dbObjects[ $key ]->obj['
persistent']             = isset(ipsRegistry::$settings['persistent']) ? ipsRegistry::$settings['persistent'] : 0;
        self::instance()->dbObjects[ $key ]->obj['
use_shutdown']         = IPS_USE_SHUTDOWN;
        # Error log
        self::instance()->dbObjects[ $key ]->obj['
error_log']            = DOC_IPS_ROOT_PATH . 'cache/sql_error_log_'.date('m_d_y').'.cgi';
        self::instance()->dbObjects[ $key ]->obj['
use_error_log']        = IN_DEV ? 0 : 1;
        # Debug log - Don'
t use this on a production board!
        
self::instance()->dbObjects[ $key ]->obj['debug_log']            = DOC_IPS_ROOT_PATH . 'cache/sql_debug_log_'.date('m_d_y').'.cgi';
        
self::instance()->dbObjects[ $key ]->obj['use_debug_log']        = IN_DEV ? 0 : 0;

        
//---------------------------------------------
        // Required vars?
        //---------------------------------------------

        
if ( is_array( self::instance()->dbObjects[ $key ]->connect_vars ) and count( self::instance()->dbObjects[ $key ]->connect_vars ) )
        {
            foreach( 
self::instance()->dbObjects[ $key ]->connect_vars as $k => $v )
            {
                
self::instance()->dbObjects[ $key ]->connect_vars[ $k ] = ipsRegistry::$settings[ $k ];
            }
        }

        
//------------------------------------------
        // Backwards compat
        //------------------------------------------

        
if ( ! self::instance()->dbObjects[ $key ]->connect_vars['mysql_tbl_type'] )
        {
            
self::instance()->dbObjects[ $key ]->connect_vars['mysql_tbl_type'] = 'myisam';
        }

        
//------------------------------------------
        // Update settings
        //------------------------------------------

        
self::$dbPrefixes[ $key ] = self::instance()->dbObjects[ $key ]->obj['sql_tbl_prefix'];
        
self::$dbDrivers[ $key ]  = $db_driver;

        
//------------------------------------------
        // Get a DB connection
        //------------------------------------------

        
self::instance()->dbObjects[ $key ]->connect();

        
self::instance()->set( $key, self::instance()->dbObjects[ $key ] );
    }

    
/**
     * Fetch query file, if available
     *
     * @access    public
     * @param    string        'public' or 'admin'
     * @param    string        App dir
     * @param    string        Key
     * @return    boolean
     */
    
static public function loadQueryFile( $where, $app, $key='' )
    {
        
$key    = ( $key ) ? $key : self::$defaultKey;
        
$where  = ( $where == 'admin' ) ? 'admin' : 'public';
        
$driver = self::getDriverType( $key );

        
/* Already tried to load? */
        
if ( isset( self::$_queryFilesTriedToLoad[ $app . '-' . $driver ] ) )
        {
            return;
        }
        else
        {
            
self::$_queryFilesTriedToLoad[ $app . '-' . $driver ] = 1;
        }

        
$file   = self::fetchQueryFileName( $where, $app, $key );
        
$class  = self::fetchQueryFileClassName( $where, $app, $key );

        
IPSDebug::addMessage( "* Checking for query cache file: " . $file );

        if ( 
is_file( $file ) )
        {
            
self::getDB( $key )->loadCacheFile( $file, $class, TRUE );
            return 
TRUE;
        }
        else
        {
            return 
FALSE;
        }
    }

    
/**
     * Fetch query file, if available
     *
     * @access    public
     * @param    string        'public' or 'admin'
     * @param    string        App dir
     * @param    string        Key
     * @return    File name
     */
    
static public function fetchQueryFileClassName( $where, $app, $key='' )
    {
        
$key    = ( $key ) ? $key : self::$defaultKey;
        
$where  = ( $where == 'admin' ) ? 'admin' : 'public';

        return 
$where . '_' . $app . '_sql_queries';
    }

    
/**
     * Fetch query file, if available
     *
     * @access    public
     * @param    string        'public' or 'admin'
     * @param    string        App dir
     * @param    string        Key
     * @return    File name
     */
    
static public function fetchQueryFileName( $where, $app, $key='' )
    {
        
$key    = ( $key ) ? $key : self::$defaultKey;
        
$where  = ( $where == 'admin' ) ? 'admin' : 'public';
        
$driver = self::getDriverType( $key );

        
/* Already tried to load? */
        
if ( ! isset( self::$_queryFilesNames[ $app . '-' . $driver ] ) )
        {
            
self::$_queryFilesNames[ $app . '-' . $driver ] = IPSLib::getAppDir( $app ) . '/sql/' . $driver . '_' . $where . '.php';
        }

        return 
self::$_queryFilesNames[ $app . '-' . $driver ];
    }
}

/**
 * Stub class to prevent other classes from breaking
 */
class ips_CacheRegistry extends ips_base_Registry
{
    
/**
     * Instance
     *
     * @access    private
     * @var        object
     */
    
private static $instance;

    
/**
     * Save options
     *
     * @access    private
     * @var        array
     */
    
private $save_options        = array();

    
/**
     * Cache library
     *
     * @access    private
     * @var        object
     */
    
private static $cacheLib;

    
/**
     * Holds debug info
     *
     * @access    public
     * @var        array
     */
    
public $debugInfo            = array();

    
/**
     * Initialized flag
     *
     * @access    private
     * @var        bool
     */
    
private static $initiated    = FALSE;

    
/**
     * Singleton instance
     *
     * @access    public
     * @return    object
     */
    
static public function instance()
    {
        if ( ! 
self::$instance )
        {
            
self::$instance = new self();
            
self::$instance->init();
        }

        return 
self::$instance;
    }

    
/**
     * Initialize class
     *
     * @access    private
     * @return    @e void
     */
    
private function init()
    {
        if ( 
IPS_IS_UPGRADER )
        {
            if ( 
self::$initiated !== TRUE )
            {
                
//--------------------------------
                // Eaccelerator...
                //--------------------------------

                
if( function_exists('eaccelerator_get') AND ipsRegistry::$settings['use_eaccelerator'] == 1 )
                {
                    require 
IPS_KERNEL_PATH.'interfaces/interfaceCache.php';/*noLibHook*/
                    
require IPS_KERNEL_PATH.'classCacheEaccelerator.php';/*noLibHook*/
                    
self::$cacheLib = new classCacheEaccelerator( ipsRegistry::$settings['board_url'] );
                }

                
//--------------------------------
                // Memcache
                //--------------------------------

                
else if( function_exists('memcache_connect') AND ipsRegistry::$settings['use_memcache'] == 1 )
                {
                    require 
IPS_KERNEL_PATH.'interfaces/interfaceCache.php';/*noLibHook*/
                    
require IPS_KERNEL_PATH.'classCacheMemcache.php';/*noLibHook*/
                    
self::$cacheLib = new classCacheMemcache( ipsRegistry::$settings['board_url'], ipsRegistry::$settings );
                }

                
//--------------------------------
                // XCache...
                //--------------------------------

                
else if( function_exists('xcache_get') AND ipsRegistry::$settings['use_xcache'] == 1 )
                {
                    require 
IPS_KERNEL_PATH.'interfaces/interfaceCache.php';/*noLibHook*/
                    
require IPS_KERNEL_PATH.'classCacheXcache.php';/*noLibHook*/
                    
self::$cacheLib = new classCacheXcache( ipsRegistry::$settings['board_url'] );
                }

                
//--------------------------------
                // APC...
                //--------------------------------

                
else if( function_exists('apc_fetch') AND ipsRegistry::$settings['use_apc'] == 1 )
                {
                    require 
IPS_KERNEL_PATH.'interfaces/interfaceCache.php';/*noLibHook*/
                    
require IPS_KERNEL_PATH.'classCacheApc.php';/*noLibHook*/
                    
self::$cacheLib = new classCacheApc( ipsRegistry::$settings['board_url'] );
                }

                
//--------------------------------
                // Diskcache
                //--------------------------------

                
else if( ipsRegistry::$settings['use_diskcache'] == 1 )
                {
                    require 
IPS_KERNEL_PATH.'interfaces/interfaceCache.php';/*noLibHook*/
                    
require IPS_KERNEL_PATH.'classCacheDiskcache.php';/*noLibHook*/
                    
self::$cacheLib = new classCacheDiskcache( ipsRegistry::$settings['board_url'] );
                }

                if( 
is_object(self::$cacheLib) AND self::$cacheLib->crashed )
                {
                    
// There was a problem - not installed maybe?
                    
self::$cacheLib = NULL;
                }

                
$caches         = array();
                
$_caches        = array();
                
$_load            = array();
                
$_pre_load      = IPSDebug::getMemoryDebugFlag();

                
//-----------------------------------------
                // Get default cache list
                //-----------------------------------------

                
$CACHE = ipsRegistry::_fetchCoreVariables( 'cache' );
                
$_LOAD = ipsRegistry::_fetchCoreVariables( 'cacheload' );

                if ( 
is_array( $CACHE ) )
                {
                    foreach( 
$CACHE as $key => $data )
                    {
                        if ( isset(
$data['acp_only']) AND $data['acp_only'] AND IPS_AREA != 'admin' )
                        {
                            continue;
                        }

                        
$_caches[ $key ]    = $CACHE;

                        if ( 
$data['default_load'] )
                        {
                            
$caches[ $key ] = $key;
                        }
                    }

                    if( 
count($_LOAD) )
                    {
                        foreach( 
$_LOAD as $key => $one )
                        {
                            
$_load[ $key ] = $key;
                        }
                    }
                }

                
//-----------------------------------------
                // Get application cache list
                //-----------------------------------------

                
if ( IPS_APP_COMPONENT )
                {
                    
$CACHE = ipsRegistry::_fetchAppCoreVariables( IPS_APP_COMPONENT, 'cache' );
                    
$_LOAD = ipsRegistry::_fetchAppCoreVariables( IPS_APP_COMPONENT, 'cacheload' );

                    if ( 
is_array( $CACHE ) )
                    {
                        foreach( 
$CACHE as $key => $data )
                        {
                            if ( isset( 
$data['acp_only'] ) && $data['acp_only'] AND IPS_AREA != 'admin' )
                            {
                                continue;
                            }

                            
$_caches[ $key ]    = $CACHE;

                            if ( 
$data['default_load'] )
                            {
                                
$caches[ $key ] = $key;
                            }
                        }

                        if( 
count($_LOAD) )
                        {
                            foreach( 
$_LOAD as $key => $one )
                            {
                                
$_load[ $key ] = $key;
                            }
                        }
                    }
                }

                if( 
is_array($_load) AND count($_load) )
                {
                    foreach( 
$_load as $key )
                    {
                        
$caches[ $key ] = $key;
                    }
                }

                
//-----------------------------------------
                // Load 'em
                //-----------------------------------------

                
self::_loadCaches( $caches );

            }

            
self::$initiated = TRUE;
        }
        else
        {
            
self::$initiated = TRUE;
            
self::instance()->data_store = array();
        }
    }

    
/**
     * Load cache(s)
     *
     * @param    array     Array of caches to load: array( 'group_cache', 'forum_cache' )
     * @return    mixed    Loaded Cache
     * @access     private
     * @author    MattMecham
     */
    
private static function _loadCaches( $caches=array() )
    {
        if ( ! 
is_array( $caches ) OR ! count( $caches ) )
        {
            return 
NULL;
        }

        
//-----------------------------------------
        // Finalize
        //-----------------------------------------

        
$cachelist = "'".implode( "','", $caches )."'";

        
//--------------------------------
        // Eaccelerator...
        //--------------------------------

        
if ( is_object( self::$cacheLib ) )
        {
            
$temp_cache      = array();
            
$new_cache_array = array();

            foreach( 
$caches as $key )
            {
                
$temp_cache[$key] = self::$cacheLib->getFromCache( $key );

                if ( ! 
$temp_cache[$key] )
                {
                    
$new_cache_array[] = $key;
                }
                else
                {
                    if ( 
is_string($temp_cache[$key]) AND strstr( $temp_cache[$key], "a:" ) !== false )
                    {
                        
self::instance()->data_store[ $key ] = unserialize( $temp_cache[$key] );
                    }
                    else if( 
$temp_cache[$key] == "EMPTY" )
                    {
                        
self::instance()->data_store[ $key ] = NULL;
                    }
                    else
                    {
                        
self::instance()->data_store[ $key ] = $temp_cache[$key];
                    }
                }
            }

            
$cachearray = $new_cache_array;

            unset(
$new_cache_array, $temp_cache);
        }

        
//--------------------------------
        // Get from DB...
        //--------------------------------

        
if ( $cachelist )
        {
            
ipsRegistry::DB()->build( array( 'select' => '*', 'from' => 'cache_store', 'where' => "cs_key IN ( $cachelist )" ) );
            
ipsRegistry::DB()->execute();

            
$_seenKeys = array();

            while ( 
$r = ipsRegistry::DB()->fetch() )
            {
                
$_seenKeys[ $r['cs_key'] ] = $r['cs_key'];

                
self::instance()->debugInfo[ $r['cs_key'] ] = array( 'size' => IPSLib::strlenToBytes( strlen($r['cs_value']) ) );

                if ( 
$r['cs_array'] OR substr( $r['cs_value'], 0, 2 ) == "a:" )
                {
                    
self::instance()->data_store[ $r['cs_key'] ] = unserialize( $r['cs_value'] );

                    if ( ! 
is_array( self::instance()->data_store[ $r['cs_key'] ] ) )
                    {
                        
self::instance()->data_store[ $r['cs_key'] ] = array();
                    }
                }
                else
                {
                    
self::instance()->data_store[ $r['cs_key'] ] = ( $r['cs_value'] ) ? $r['cs_value'] : NULL;
                }

                if ( 
is_object( self::$cacheLib ) )
                {
                    if ( ! 
$r['cs_value'] )
                    {
                        
$r['cs_value'] = "EMPTY";
                    }

                    
self::$cacheLib->putInCache( $r['cs_key'], $r['cs_value'] );
                }
            }
        }

        
//-----------------------------------------
        // Make sure each key is in data_store otherwise
        // repeated calls will keep trying to load it
        //-----------------------------------------

        
foreach( $caches as $_cache )
        {
            if ( ! 
in_array( $_cache, $_seenKeys ) )
            {
                
self::instance()->data_store[ $_cache ] = NULL;
            }
        }
    }

    
/**
     * Set a cache
     *
     * @access    protected
     * @param    string    Cache Key
     * @param    mixed    Cache value (typically an array)
     * @return    @e void
     */
    
protected function cacheSet( $key, $val )
    {
        
/* Update in_memory cache */
        
$this->data_store[ $key ] = $val;

        
$this->save_options['donow'] = isset($this->save_options['donow']) ? $this->save_options['donow'] : 0;

        
//-----------------------------------------
        // Next...
        //-----------------------------------------

        
if ( $key )
        {
            if ( ! isset(
$val) OR ! $val )
            {
                if ( isset(
$this->save_options['array']) AND $this->save_options['array'] )
                {
                    
$value = serialize($this->data_store[ $key ]);
                }
                else
                {
                    
$value = $this->data_store[ $key ];
                }
            }
            else
            {
                if ( isset(
$this->save_options['array']) AND $this->save_options['array'] )
                {
                    
$value = serialize($val);
                }
                else
                {
                    
$value = $val;
                }
            }

            
ipsRegistry::DB()->preventAddSlashes( array( 'cs_key' => 1 ) );

            if ( 
$this->save_options['donow'] )
            {
                
ipsRegistry::DB()->replace( 'cache_store', array( 'cs_array' => intval($this->save_options['array']), 'cs_key' => $key, 'cs_value' => $value, 'cs_updated' => time() ), array( 'cs_key' ) );
            }
            else
            {
                
ipsRegistry::DB()->replace( 'cache_store', array( 'cs_array' => intval($this->save_options['array']), 'cs_key' => $key, 'cs_value' => $value, 'cs_updated' => time() ), array( 'cs_key' ), true );
            }
        }

        
/* Reest... */
        
$this->save_options = array();
    }

    
/**
     * Check to see if the cache exists or not
     *
     * @access    public
     * @param    string        Cache name
     * @return    boolean
     */
    
static public function exists( $key )
    {
        return 
FALSE;
    }

    
/**
     * Override the get() ArrayAccess method for the cache lib
     * The default method just pulls from data_store, but the cache library can dynamically load caches, so we need
     * to properly use getCache so the cache is loaded if it's not already
     *
     * @access    protected
     * @param    mixed    $key
     * @return    string
     */
    
protected function get( $key )
    {
        if ( ! 
in_array( $key, array_keys( self::instance()->data_store ) ) )
        {
            
$cache = self::instance()->getCache( $key );
        }
        else
        {
            
$cache = self::instance()->data_store[ $key ];
        }

        return 
$cache;
    }

    
/**
     * Get the cache
     * If the cache has not been loaded during init(), then it'll load the
     * cache.
     *
     * @access    public
     * @param    string    Cache key
     * @param    mixed    The loaded cache [typically an array]
     * @return    string
     */
    
static public function getCache( $key )
    {
        if ( ! 
in_array( $key, array_keys( self::instance()->data_store ) ) )
        {
            if ( 
IPS_IS_UPGRADER )
            {
                
self::_loadCaches( array( $key ) );
            }

            
$cache = self::instance()->data_store[ $key ];
        }
        else
        {
            
$cache = self::instance()->data_store[ $key ];
        }

        return 
$cache;
    }


    
/**
     * Fetch all the caches as a reference
     *
     * @access    public
     * @return    array
     */
    
static public function &fetchCaches()
    {
        return 
self::instance()->data_store;
    }

    
/**
     * Update a cache temporarily (do not save to db)
     *
     * @access    public
     * @param    string    Cache key
     * @param    mixed    Cache value
     * @return    @e void
     */
    
static public function updateCacheWithoutSaving( $key, $value )
    {
        
self::instance()->data_store[ $key ] = $value;
    }

    
/**
     * Update a cache permanantly (save to db)
     *
     * @access    public
     * @param    string    Cache key
     * @param    mixed    Cache value
     * @param    array     Options
     * @return    mixed
     */
    
static public function setCache( $key, $value, $options=array() )
    {
        if ( ! 
$key )
        {
            throw new 
Exception( "В setCache не хватает ключа" );
        }

        
self::instance()->save_options = $options;
        return 
self::instance()->cacheSet( $key, $value );
    }
    
    
/**
     * Store into cache library
     *
     * @access    public
     * @param    string    Key
     * @param    mixed    Item to cache
     * @param    int        Time to live
     * @return    mixed
     */
    
static public function putWithCacheLib( $key, $value, $ttl=0 )
    {
        return 
true;
    }
    
    
/**
     * Rebuild a cache
     *
     * @access    public
     * @param    string    Cache key
     * @param    string    Application
     * @return    @e void
     */
    
static public function rebuildCache( $key, $app='' )
    {
        
/* INIT */
        
$app        = IPSText::alphanumericalClean( $app );
        
$_caches    = array();
    
        if( 
$app )
        {
            if ( 
$app == 'global' )
            {
                
$_caches = ipsRegistry::_fetchCoreVariables( 'cache' );
            }
            else
            {
                
/* isset there is needed to prevent issues on applications installation */
                
if( isset( ipsRegistry::$applications[$app] ) && !IPSLib::appIsInstalled($app) )
                {
                    return;
                }

                
$_caches = ipsRegistry::_fetchAppCoreVariables( $app, 'cache' );
            }
        }
        else
        {
            
/* Get all caches from all apps */
            
$_caches = ipsRegistry::_fetchCoreVariables( 'cache' );
            
            foreach( 
ipsRegistry::$applications as $appDir => $appData )
            {
                
$CACHE = ipsRegistry::_fetchAppCoreVariables( $appDir, 'cache' );
                
                if ( 
is_array( $CACHE ) )
                {
                    
$_caches = array_merge( $_caches, $CACHE );
                }
            }
        }
        
        
/* Rebuild the cache, if found */
        
if( isset( $_caches[ $key ] ) )
        {
            
$file_to_check = $_caches[ $key ]['recache_file'];

            if ( 
$file_to_check AND is_file( $file_to_check ) )
            {
                
$_func  = $_caches[ $key ]['recache_function'];
                
                
/* Hackish way to check for action overloader */
                
if ( strpos( $file_to_check, '/modules_' ) !== FALSE )
                {
                    
$_class = IPSLib::loadActionOverloader( $file_to_check, $_caches[ $key ]['recache_class'] );
                }
                elseif ( 
$app )
                {
                    
$_class = IPSLib::loadLibrary( $file_to_check, $_caches[ $key ]['recache_class'], ($app == 'global') ? 'core' : $app );
                }
                                
                
/* Fallback */
                
if ( !$_class )
                {
                    
$_class = $_caches[ $key ]['recache_class'];
                }
                                
                
$recache = new $_class( ipsRegistry::instance() );

                if( 
method_exists( $recache, 'makeRegistryShortcuts' ) )
                {
                    
$recache->makeRegistryShortcuts( ipsRegistry::instance() );
                }

                
$recache->$_func();
            }
        }
    }
}

/**
 * Base application class
 */
class ips_MemberRegistry extends ips_base_Registry
{
    
/**
     * Object instance
     *
     * @access    private
     * @var        object
     */
    
private static $instance;

    
/**
     * Settings
     *
     * @access    private
     * @var        array
     */
    
private $settings            = array();

    
/**
     * Member data
     *
     * @access    protected
     * @var        array
     */
    
protected static $member    = array();

    
/**
     * Member id
     *
     * @access    public
     * @var        int
     */
    
public $member_id        = 0;

    
/**
     * Perm mask id
     *
     * @access    public
     * @var        int
     */
    
public $perm_id            = 0;

    
/**
     * Array of perm mask ids
     *
     * @access    public
     * @var        array
     */
    
public $perm_id_array    = array();

    
/**
     * Hash to use in forms
     *
     * @access    public
     * @var        string
     */
    
public $form_hash        = '';

    
/**
     * Language pack id
     *
     * @access    public
     * @var        int
     */
    
public $language_id        = '1';

    
/**
     * Skin id
     *
     * @access    public
     * @var        int
     */
    
public $skin_id            = 0;

    
/**
     * Member preferences
     *
     * @access    public
     * @var        array
     */
    
public $preferences        = array();

    
/**
     * Member session id
     *
     * @access    public
     * @var        string
     */
    
public $session_id        = 0;

    
/**
     * Session type
     *
     * @access    public
     * @var        string
     */
    
public $session_type    = '';

    
/**
     * Member IP Address
     *
     * @access    public
     * @var        string
     */
    
public $ip_address        = '';

    
/**
     * Member last click timestamp
     *
     * @access    public
     * @var        int
     */
    
public $last_click        = 0;

    
/**
     * Member location
     *
     * @access    public
     * @var        string
     */
    
public $location        = '';

    
/**
     * ACP tab data
     *
     * @access    public
     * @var        array
     */
    
public $acp_tab_data    = array();

    
/**
     * Member user agent
     *
     * @access    public
     * @var        string
     */
    
public $user_agent            = '';

    
/**
     * Member browser info
     *
     * @access    public
     * @var        array
     */
    
public $browser                = array();

    
/**
     * Member operating system
     *
     * @access    public
     * @var        string
     */
    
public $operating_system    = 'неизвестно';

    
/**
     * Is this a bot?
     *
     * @access    public
     * @var        bool
     */
    
public $is_not_human        = false;

    
/**
     * Users this member is ignoring
     *
     * @access    public
     * @var        array
     */
    
public $ignored_users        = array();

    
/**
     * Session class
     *
     * @access    private
     * @var        object
     */
    
private static $session_class;

    
/**
     * Initialized yet?
     *
     * @access    public
     * @var        bool
     */
    
private static $initiated    = FALSE;

    
/**
     * Initialize this object
     *
     * @access    public
     * @return    object
     */
    
static public function instance()
    {
        if ( ! 
self::$instance )
        {
            
self::$instance = new self();
            
self::init();
        }

        return 
self::$instance;
    }

    
/**
     * Destructor
     *
     * @access    public
     * @return    @e void
     */
    
public function __myDestruct()
    {
    }

    
/**
     * Our singleton INIT function
     *
     * @access    protected
     * @return    @e void
     */
    
protected static function init()
    {
        if ( 
self::$initiated !== TRUE )
        {
            
//-----------------------------------------
            // IP Address
            //-----------------------------------------

            
if ( ipsRegistry::$settings['xforward_matching'] )
            {
                foreach( 
array_reverse( explode( ',', my_getenv('HTTP_X_FORWARDED_FOR') ) ) as $x_f )
                {
                    
$addrs[] = trim($x_f);
                }

                
$addrs[] = my_getenv('HTTP_CLIENT_IP');
                
$addrs[] = my_getenv('HTTP_X_CLUSTER_CLIENT_IP');
                
$addrs[] = my_getenv('HTTP_PROXY_USER');
            }

            
$addrs[] = my_getenv('REMOTE_ADDR');

            
//-----------------------------------------
            // Do we have one yet?
            //-----------------------------------------

            
foreach ( $addrs as $ip )
            {
                
//-----------------------------------------
                // IP v4
                //-----------------------------------------
                
                
if ( IPSLib::validateIPv4( $ip ) )
                {
                    
self::instance()->ip_address    = $ip;
                    break;
                }
                
                
//-----------------------------------------
                // IP v6
                //-----------------------------------------
                
                
else if ( IPSLib::validateIPv6( $ip ) )
                {
                    
self::instance()->ip_address = $ip;
                    break;
                }
            }

            
//-----------------------------------------
            // Make sure we take a valid IP address
            //-----------------------------------------

            
if ( !self::instance()->ip_address AND ! isset( $_SERVER['SHELL'] ) AND $_SERVER['SESSIONNAME'] != 'Console' )
            {
                print 
"Невозможно определить ваш IPv4 адрес";
                exit();
            }

            if ( 
IPS_IS_UPGRADER )
            {
                require_once( 
IPS_ROOT_PATH . "setup/sources/classes/session/sessions.php" );/*noLibHook*/

                
self::$session_class = new sessions();
            }
            else
            {
                
self::setMember(0);
            }
        }
    }

    
/**
     * Interface to session class
     *
     * @access    public
     * @return    object
     */
    
public static function sessionClass()
    {
        return 
self::$session_class;
    }

    
/**
     * Get a member property
     *
     * @access    public
     * @param    string    Key
     * @return    mixed    Member property
     */
    
static public function getProperty( $key )
    {
        return 
self::instance()->get( $key );
    }

    
/**
     * Set a member property
     *
     * @access    public
     * @param    string    Key
     * @param    mixed    Value
     * @return    @e void
     */
    
static public function setProperty( $key, $value )
    {
        return 
self::instance()->set( $key, $value );
    }

    
/**
     * Fetch all the member data as a reference
     *
     * @access    public
     * @return    array
     */
    
static public function &fetchMemberData()
    {
        return 
self::instance()->data_store;
    }

    
/**
     * Set current member to the member ID specified
     *
     * @param    integer    Member ID
     * @return    @e void
     */
    
static public function setMember( $member_id )
    {
        
//-----------------------------------------
        // INIT
        //-----------------------------------------

        
$member_id = intval( $member_id );
        
$addrs     = array();

        
//-----------------------------------------
        // If we have a member ID, set up the member
        //-----------------------------------------

        
if ( $member_id )
        {
            
self::instance()->data_store = IPSMember::load( $member_id, 'extendedProfile,customFields,groups,itemMarkingStorage' );
        }

        
/* Got a member ID? */
        
if ( !empty($member_id) && self::instance()->data_store['member_id'] )
            {
                
self::setUpMember();

                
# Form hash
                
self::instance()->form_hash = md5( self::instance()->data_store['email'].'&'.self::instance()->data_store['member_login_key'].'&'.self::instance()->data_store['joined'] );
            }
            else
            {
                
self::instance()->data_store = IPSMember::setUpGuest();

            
self::instance()->perm_id       = !empty(self::instance()->data_store['org_perm_id']) ? self::instance()->data_store['org_perm_id'] : self::instance()->data_store['g_perm_id'];
            
self::instance()->perm_id_array = explode( ',', self::instance()->perm_id );

            
# Form hash
            
self::instance()->form_hash = md5("this is only here to prevent it breaking on guests");
        }

        
//-----------------------------------------
        // Set member data
        //-----------------------------------------

        
self::instance()->member_id = $member_id;
    }

    
/**
     * Set up a member's perms based on secondary groups
     *
     * @access    public
     * @param    array     Member data
     * @return    array     New member data
     */
    
static public function setUpSecondaryGroups( $data )
    {
        if ( isset(
$data['mgroup_others']) AND $data['mgroup_others'] )
        {
            
$cache            = ipsRegistry::cache()->getCache('group_cache');
            
$groups_id        = explode( ',', $data['mgroup_others'] );
            
$exclude        = array( 'g_title', 'g_icon', 'prefix', 'suffix', 'g_promotion', 'g_photo_max_vars' );
            
$less_is_more    = array( 'g_search_flood' );
            
$zero_is_best    = array( 'g_attach_max', 'g_attach_per_post', 'g_edit_cutoff', 'g_max_messages' );

            
# Blog
            
$zero_is_best = array_merge( $zero_is_best, array( 'g_blog_attach_max', 'g_blog_attach_per_entry', 'g_blog_preventpublish' ) );

            
# Gallery
            
$zero_is_best = array_merge( $zero_is_best, array( 'g_max_diskspace', 'g_max_upload', 'g_max_transfer', 'g_max_views', 'g_album_limit', 'g_img_album_limit', 'g_movie_size' ) );

            if ( 
count( $groups_id ) )
            {
                foreach( 
$groups_id as $pid )
                {
                    if ( ! isset(
$cache[ $pid ]['g_id']) OR ! $cache[ $pid ]['g_id'] )
                    {
                        continue;
                    }

                    
//-----------------------------------------
                    // Loop through and mix
                    //-----------------------------------------

                    
foreach( $cache[ $pid ] as $k => $v )
                    {
                        if ( ! 
in_array( $k, $exclude ) )
                        {
                            
//-----------------------------------------
                            // Add to perm id list
                            //-----------------------------------------

                            
if ( $k == 'g_perm_id' )
                            {
                                
$data['g_perm_id'] .= ','.$v;
                            }
                            else if ( 
in_array( $k, $zero_is_best ) )
                            {
                                if ( 
$data[ $k ] == 0 )
                                {
                                    continue;
                                }
                                else if( 
$v == 0 )
                                {
                                    
$data[ $k ] = 0;
                                }
                                else if ( 
$v > $data[ $k ] )
                                {
                                    
$data[ $k ] = $v;
                                }
                            }
                            else if ( 
in_array( $k, $less_is_more ) )
                            {
                                if ( 
$v < $data[ $k ] )
                                {
                                    
$data[ $k ] = $v;
                                }
                            }
                            else
                            {
                                if ( 
$v > $data[ $k ] )
                                {
                                    
$data[ $k ] = $v;
                                }
                            }
                        }
                    }
                }
            }

            
//-----------------------------------------
            // Tidy perms_id
            //-----------------------------------------

            
$rmp = array();
            
$tmp = explode( ',', IPSText::cleanPermString($data['g_perm_id']) );

            if ( 
count( $tmp ) )
            {
                foreach( 
$tmp as $t )
                {
                    
$rmp[ $t ] = $t;
                }
            }

            if ( 
count( $rmp ) )
            {
                
$data['g_perm_id'] = implode( ',', $rmp );
            }
        }

        return 
$data;
    }

    
/**
     * Set up a member
     *
     * @access    private
     * @return    @e void
     */
    
static public function setUpMember()
    {
        
//-----------------------------------------
        // INIT
        //-----------------------------------------

        
$cache = ipsRegistry::cache()->getCache('group_cache');

        
//-----------------------------------------
        // Set up main 'display' group
        //-----------------------------------------

        
self::instance()->data_store = is_array($cache[ self::instance()->data_store['member_group_id'] ]) ? array_merge( self::instance()->data_store, $cache[ self::instance()->data_store['member_group_id'] ] ) : self::instance()->data_store;

        
//-----------------------------------------
        // Work out permissions
        //-----------------------------------------

        
self::instance()->data_store = self::instance()->setUpSecondaryGroups( self::instance()->data_store );

        
self::instance()->perm_id       = ( isset(self::instance()->data_store['org_perm_id']) AND self::instance()->data_store['org_perm_id'] ) ? self::instance()->data_store['org_perm_id'] : self::instance()->data_store['g_perm_id'];
        
self::instance()->perm_id_array = explode( ",", self::instance()->perm_id );
    }
}
Онлайн: 2
Реклама