* Invision Power Services * IP.Board v3.4.5 * Registry class for setup * Last Updated: $Date: 2013-05-02 23:43:16 -0400 (Thu, 02 May 2013) $ * * * @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: 12217 $ * */ /** * 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_once( 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(); /* Make sure it's a string */ if ( is_array( self::$request['section'] ) ) { self::$request['section'] = ''; } /* 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() { /* Can be called before 'applications' cache has been rebuilt, i.e. db checker when coming from 2.3.6 -> current */ if( !count(self::$applications) ) { ipsRegistry::DB()->build( array( 'select' => '*', 'from' => 'core_applications' ) ); ipsRegistry::DB()->execute(); while( $r = ipsRegistry::DB()->fetch() ) { self::$applications[ $r['app_directory'] ] = $r; } } 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;', '&', IPSText::parseCleanValue( urldecode( my_getenv('QUERY_STRING') ) ) ); ipsRegistry::$settings['query_string_real'] = str_replace( '&' , '&' , 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'] = 0;//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 ) { /* This is here for veeeeeery old 1.0.1 upgrades */ if( !ipsRegistry::DB()->checkForTable('cache_store') ) { ipsRegistry::DB()->query( "create table ".ipsRegistry::dbFunctions()->getPrefix()."cache_store ( cs_key varchar(255) NOT NULL default '', cs_value text NULL, cs_extra varchar(255) NOT NULL default '', PRIMARY KEY(cs_key) );" ); } 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(); } } } /** * Delete a cache from DB and alt cache store * * @param mixed Cache key, or array of cache keys * @return @e boolean */ static public function deleteCache( $keys ) { if ( is_string( $keys ) ) { ipsRegistry::DB()->delete( 'cache_store', "cs_key='{$keys}'" ); if ( is_object( self::$cacheLib ) ) { self::$cacheLib->removeFromCache( $keys ); } } elseif ( is_array( $keys ) && count( $keys ) ) { ipsRegistry::DB()->delete( 'cache_store', "cs_key IN('" . implode( "','", $keys ) . "')" ); if ( is_object( self::$cacheLib ) ) { foreach( $keys as $key ) { self::$cacheLib->removeFromCache( $keys ); } } } return TRUE; } } /** * 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 = 'unknown'; /** * 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 ); } }