Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+4 -4
View File
@@ -11,7 +11,7 @@
namespace IPS\Data;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -59,7 +59,7 @@ abstract class _AbstractData
$value = $this->decode( $this->get( $key ) );
if ( \IPS\CACHING_LOG )
{
$this->log[ sprintf( '%.4f', microtime(true) ) ] = array( 'get', $key, version_compare( PHP_VERSION, '5.4.0' ) >= 0 ? json_encode( $value, JSON_PRETTY_PRINT ) : json_encode( $value ), var_export( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ) );
$this->log[ sprintf( '%.4f', microtime(true) ) ] = array( 'get', $key, json_encode( $value, JSON_PRETTY_PRINT ), var_export( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ) );
}
$this->_data[ $key ] = $value;
}
@@ -83,7 +83,7 @@ abstract class _AbstractData
{
if ( \IPS\CACHING_LOG )
{
$this->log[ sprintf( '%.4f', microtime(true) ) ] = array( 'set', $key, version_compare( PHP_VERSION, '5.4.0' ) >= 0 ? json_encode( $value, JSON_PRETTY_PRINT ) : json_encode( $value ), var_export( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ) );
$this->log[ sprintf( '%.4f', microtime(true) ) ] = array( 'set', $key, json_encode( $value, JSON_PRETTY_PRINT ), var_export( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ) );
}
if ( $this->set( $key, $this->encode( $value ) ) )
@@ -95,7 +95,7 @@ abstract class _AbstractData
{
/* We can only really log if datastore fails, because if cache fails we create a catch-22 where settings can't/hasn't loaded but
we rely on that data for logging, so don't log if this is for cache */
$classname = explode( '\\', get_class( $this ) );
$classname = explode( '\\', \get_class( $this ) );
if( $classname[2] == 'Cache' )
{
+7 -20
View File
@@ -11,7 +11,7 @@
namespace IPS\Data;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -93,7 +93,7 @@ abstract class _Cache extends AbstractData
if ( \IPS\CACHING_LOG )
{
$this->log[ microtime(true) ] = array( 'set', $key, version_compare( PHP_VERSION, '5.4.0' ) >= 0 ? json_encode( $value, JSON_PRETTY_PRINT ) : json_encode( $value ), var_export( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ) );
$this->log[ microtime(true) ] = array( 'set', $key, json_encode( $value, JSON_PRETTY_PRINT ), var_export( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ) );
}
if ( $this->set( $key, $this->encode( $value ), $expire ) )
@@ -123,7 +123,7 @@ abstract class _Cache extends AbstractData
}
$data = $this->$key;
if( count( $data ) and isset( $data['value'] ) and isset( $data['expires'] ) )
if( \count( $data ) and isset( $data['value'] ) and isset( $data['expires'] ) )
{
/* Is it expired? */
if( $data['expires'] AND time() < $data['expires'] )
@@ -165,7 +165,7 @@ abstract class _Cache extends AbstractData
protected function _encryptionKey()
{
$password = \IPS\Settings::i()->sql_pass;
if ( function_exists( 'openssl_digest' ) and in_array( 'sha256', openssl_get_md_methods() ) )
if ( \function_exists( 'openssl_digest' ) and \in_array( 'sha256', openssl_get_md_methods() ) )
{
$password = openssl_digest( $password, 'sha256', TRUE );
}
@@ -180,15 +180,7 @@ abstract class _Cache extends AbstractData
*/
protected function encode( $value )
{
$value = json_encode( $value );
if ( function_exists( 'openssl_encrypt' ) and in_array( 'aes-256-ctr', openssl_get_cipher_methods() ) )
{
$iv = \IPS\Login::generateRandomString( 16 );
$value = $iv . openssl_encrypt( $value, 'aes-256-ctr', $this->_encryptionKey(), OPENSSL_RAW_DATA, $iv );
}
return $value;
return \IPS\Text\Encrypt::fromPlaintext( json_encode( $value ) )->tag();
}
/**
@@ -199,12 +191,7 @@ abstract class _Cache extends AbstractData
*/
protected function decode( $value )
{
if ( function_exists( 'openssl_encrypt' ) and in_array( 'aes-256-ctr', openssl_get_cipher_methods() ) )
{
$value = @openssl_decrypt( \substr( $value, 16 ), 'aes-256-ctr', $this->_encryptionKey(), OPENSSL_RAW_DATA, \substr( $value, 0, 16 ) );
}
return json_decode( $value, TRUE );
return json_decode( \IPS\Text\Encrypt::fromTag( $value )->decrypt(), TRUE );
}
/**
@@ -217,7 +204,7 @@ abstract class _Cache extends AbstractData
{
if ( parent::__isset( $key ) )
{
return ( is_array( $this->$key ) or $this->$key === 0 ) ? true : (bool) $this->$key;
return ( \is_array( $this->$key ) or $this->$key === 0 ) ? true : (bool) $this->$key;
}
return FALSE;
}
+3 -3
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -29,7 +29,7 @@ class _Apc extends \IPS\Data\Cache
*/
public static function supported()
{
return function_exists('apcu_fetch');
return \function_exists('apcu_fetch');
}
/**
@@ -57,7 +57,7 @@ class _Apc extends \IPS\Data\Cache
*
* @param string $key Key
* @param string $value Value
* @para, \IPS\DateTime $expire Expreation time, or NULL for no expiration
* @param \IPS\DateTime|NULL $expire Expreation time, or NULL for no expiration
* @return bool
*/
protected function set( $key, $value, \IPS\DateTime $expire = NULL )
+1 -1
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
+5 -5
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -100,7 +100,7 @@ class _Memcache extends \IPS\Data\Cache
/* Connect and add the servers that are defined to the pool */
$this->link = $this->_getLink();
$configuration['servers'] = ( !is_array( $configuration['servers'] ) ) ? array( $configuration['servers'] ) : $configuration['servers'];
$configuration['servers'] = ( !\is_array( $configuration['servers'] ) ) ? array( $configuration['servers'] ) : $configuration['servers'];
foreach( $configuration['servers'] as $server )
{
@@ -143,12 +143,12 @@ class _Memcache extends \IPS\Data\Cache
*
* @param string $key Key
* @param string $value Value
* @para, \IPS\DateTime $expire Expreation time, or NULL for no expiration
* @param \IPS\DateTime|NULL $expire Expreation time, or NULL for no expiration
* @return bool
*/
protected function set( $key, $value, \IPS\DateTime $expire = NULL )
{
if ( in_array( $key, $this->doesNotExist ) )
if ( \in_array( $key, $this->doesNotExist ) )
{
unset( $this->doesNotExist[ array_search( $key, $this->doesNotExist ) ] );
}
@@ -180,7 +180,7 @@ class _Memcache extends \IPS\Data\Cache
*/
protected function exists( $key )
{
if ( in_array( $key, $this->doesNotExist ) )
if ( \in_array( $key, $this->doesNotExist ) )
{
return FALSE;
}
+1 -1
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
+8 -18
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -25,7 +25,8 @@ class _Redis extends \IPS\Data\Cache
/**
* Constructor
*
* @return void
* @param array $configuration Configuration to use
* @return void
*/
public function __construct( $configuration )
{
@@ -79,15 +80,15 @@ class _Redis extends \IPS\Data\Cache
{
throw new \DomainException( 'datastore_redis_servers_err' );
}
} ),
}, NULL, NULL, 'redis_host' ),
'port' => new \IPS\Helpers\Form\Number( 'server_port', isset( $configuration['port'] ) ? $configuration['port'] : NULL, FALSE, array( 'placeholder' => '6379' ), function( $val )
{
if ( \IPS\Request::i()->cache_method === 'Redis' AND $val AND ( $val < 0 OR $val > 65535 ) )
{
throw new \DomainException( 'datastore_redis_servers_err' );
}
} ),
'password' => new \IPS\Helpers\Form\Password( 'server_password', isset( $configuration['password'] ) ? $configuration['password'] : '', FALSE ),
}, NULL, NULL, 'redis_port' ),
'password' => new \IPS\Helpers\Form\Password( 'server_password', isset( $configuration['password'] ) ? $configuration['password'] : '', FALSE, array(), NULL, NULL, NULL, 'redis_password' ),
);
}
@@ -99,7 +100,6 @@ class _Redis extends \IPS\Data\Cache
/**
* Get random string used in the keys to identify this site compared to other sites
*
* @param string $key
* @return string|FALSE Value from the _datastore; FALSE if key doesn't exist
*/
protected function _getRedisKey()
@@ -148,7 +148,7 @@ class _Redis extends \IPS\Data\Cache
*
* @param string $key Key
* @param string $value Value
* @param \IPS\DateTime $expire Expreation time, or NULL for no expiration
* @param \IPS\DateTime|NULL $expire Expreation time, or NULL for no expiration
* @return bool
*/
protected function set( $key, $value, \IPS\DateTime $expire = NULL )
@@ -200,7 +200,7 @@ class _Redis extends \IPS\Data\Cache
{
try
{
return (bool) \IPS\Redis::i()->delete( $this->_getRedisKey() . '_' . $key );
return (bool) \IPS\Redis::i()->del( $this->_getRedisKey() . '_' . $key );
}
catch( \RedisException $e )
{
@@ -222,14 +222,4 @@ class _Redis extends \IPS\Data\Cache
\IPS\Redis::i()->setex( 'redisKey', 604800, $this->_redisKey );
}
/**
* Log a page hit
*
* @param \IPS\Http\Url|NULL $url URL to log (or null)
* @return void
*/
public function logPageHit( $url=NULL )
{
return \IPS\Redis::i()->logPageHit( $url );
}
}
+2 -2
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -75,7 +75,7 @@ class _Test extends \IPS\Data\Cache
*
* @param string $key Key
* @param string $value Value
* @para, \IPS\DateTime $expire Expreation time, or NULL for no expiration
* @param \IPS\DateTime|NULL $expire Expreation time, or NULL for no expiration
* @return bool
*/
protected function set( $key, $value, \IPS\DateTime $expire = NULL )
+3 -3
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -29,7 +29,7 @@ class _Wincache extends \IPS\Data\Cache
*/
public static function supported()
{
return function_exists('wincache_ucache_get');
return \function_exists('wincache_ucache_get');
}
/**
@@ -57,7 +57,7 @@ class _Wincache extends \IPS\Data\Cache
*
* @param string $key Key
* @param string $value Value
* @para, \IPS\DateTime $expire Expreation time, or NULL for no expiration
* @param \IPS\DateTime|NULL $expire Expreation time, or NULL for no expiration
* @return bool
*/
protected function set( $key, $value, \IPS\DateTime $expire = NULL )
+3 -3
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Cache;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -29,7 +29,7 @@ class _Xcache extends \IPS\Data\Cache
*/
public static function supported()
{
return function_exists('xcache_get');
return \function_exists('xcache_get');
}
/**
@@ -57,7 +57,7 @@ class _Xcache extends \IPS\Data\Cache
*
* @param string $key Key
* @param string $value Value
* @para, \IPS\DateTime $expire Expreation time, or NULL for no expiration
* @param \IPS\DateTime|NULL $expire Expreation time, or NULL for no expiration
* @return bool
*/
protected function set( $key, $value, \IPS\DateTime $expire = NULL )
+46 -9
View File
@@ -11,7 +11,7 @@
namespace IPS\Data;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -36,8 +36,25 @@ abstract class _Store extends AbstractData
{
if( static::$instance === NULL )
{
$classname = 'IPS\Data\Store\\' . \IPS\STORE_METHOD;
static::$instance = new $classname( json_decode( \IPS\STORE_CONFIG, TRUE ) );
try
{
$classname = 'IPS\Data\Store\\' . \IPS\STORE_METHOD;
static::$instance = new $classname( json_decode( \IPS\STORE_CONFIG, TRUE ) );
}
catch( \IPS\Data\Store\Exception $e )
{
/* Fall back to MySQL (if not using it currently, and then FileSystem if we are) */
if ( \IPS\STORE_METHOD !== 'Database' )
{
$classname = 'IPS\Data\Store\Database';
}
else
{
$classname = 'IPS\Data\Store\FileSystem';
}
static::$instance = new $classname( json_decode( \IPS\STORE_CONFIG, TRUE ) );
}
}
return static::$instance;
@@ -58,6 +75,26 @@ abstract class _Store extends AbstractData
*/
public $log = array();
/**
* Test to see if this store works
*
* @return boolean
*/
public static function testStore()
{
try
{
$classname = 'IPS\Data\Store\\' . \IPS\STORE_METHOD;
$store = new $classname( json_decode( \IPS\STORE_CONFIG, TRUE ) );
return $store->test();
}
catch( \Exception $e )
{
return FALSE;
}
}
/**
* Load mutiple
* Used so if it is known that several are going to be needed, they can all be loaded into memory at the same time
@@ -125,7 +162,7 @@ abstract class _Store extends AbstractData
else
{
/* It exists in the caching engine, and we know the hash of the correct value... */
$cacheKeys = ( isset( $this->cacheKeys ) and is_array( $this->cacheKeys ) ) ? $this->cacheKeys : array();
$cacheKeys = ( isset( $this->cacheKeys ) and \is_array( $this->cacheKeys ) ) ? $this->cacheKeys : array();
if ( array_key_exists( $key, $cacheKeys ) and isset( \IPS\Data\Cache::i()->$key ) )
{
/* Get it... */
@@ -159,7 +196,7 @@ abstract class _Store extends AbstractData
if ( \IPS\Data\Cache::i()->checkKeys() === true )
{
/* And set the hash in the cacheKeys hash map */
$cacheKeys = ( isset( $this->cacheKeys ) and is_array( $this->cacheKeys ) ) ? $this->cacheKeys : array();
$cacheKeys = ( isset( $this->cacheKeys ) and \is_array( $this->cacheKeys ) ) ? $this->cacheKeys : array();
$cacheKeys[ $key ] = md5( json_encode( $value ) );
$this->cacheKeys = $cacheKeys;
}
@@ -190,9 +227,9 @@ abstract class _Store extends AbstractData
/* And set the hash in the cacheKeys hash map */
if ( \IPS\Data\Cache::i()->checkKeys() === true )
{
if ( ( isset( $this->cacheKeys ) and is_array( $this->cacheKeys ) ) )
if ( ( isset( $this->cacheKeys ) and \is_array( $this->cacheKeys ) ) )
{
$cacheKeys = is_array( $this->cacheKeys ) ? $this->cacheKeys : array();
$cacheKeys = \is_array( $this->cacheKeys ) ? $this->cacheKeys : array();
$cacheKeys[ $key ] = md5( json_encode( $value ) );
$this->cacheKeys = $cacheKeys;
}
@@ -228,7 +265,7 @@ abstract class _Store extends AbstractData
}
/* Only use it if the hash matches */
$cacheKeys = ( isset( $this->cacheKeys ) and is_array( $this->cacheKeys ) ) ? $this->cacheKeys : array();
$cacheKeys = ( isset( $this->cacheKeys ) and \is_array( $this->cacheKeys ) ) ? $this->cacheKeys : array();
if ( isset( $cacheKeys[ $key ] ) and $cacheKeys[ $key ] == md5( json_encode( $value ) ) )
{
return TRUE;
@@ -262,7 +299,7 @@ abstract class _Store extends AbstractData
/* And from the special map of hashes */
try
{
$cacheKeys = is_array( $this->cacheKeys ) ? $this->cacheKeys : array();
$cacheKeys = \is_array( $this->cacheKeys ) ? $this->cacheKeys : array();
}
/* If the cache doesn't exist we shouldn't error out with an uncaught OutOfRangeException */
catch( \OutOfRangeException $e )
+12 -7
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -63,15 +63,19 @@ class _Database extends \IPS\Data\Store
/* Otherwise, we also need a few more things depending on whether the user is logged in or not */
else
{
$this->initLoad[] = 'announcements';
$this->initLoad[] = 'loginMethods'; # Previously, this was only loaded for Guests, however both Guests and Logged In members interface with login handlers (ex. profile syncing).
$this->initLoad[] = 'widgets';
$this->initLoad[] = 'defaultStreamData';
$this->initLoad[] = 'acpNotifications';
$this->initLoad[] = 'emoticons';
if ( \IPS\Session\Front::loggedIn() )
{
$this->initLoad[] = 'administrators';
$this->initLoad[] = 'moderators';
$this->initLoad[] = 'emoticons';
}
else
{
$this->initLoad[] = 'loginHandlers';
$this->initLoad[] = 'group_promotions';
$this->initLoad[] = 'promoters';
}
}
}
@@ -99,7 +103,7 @@ class _Database extends \IPS\Data\Store
*/
public function get( $key )
{
if ( !$this->doneInitLoad and in_array( $key, $this->initLoad ) )
if ( !$this->doneInitLoad and \in_array( $key, $this->initLoad ) )
{
$this->loadIntoMemory( $this->initLoad );
$this->doneInitLoad = TRUE;
@@ -185,6 +189,7 @@ class _Database extends \IPS\Data\Store
/**
* Abstract Method: Clear All Caches
*
* @param NULL|string $exclude Key to exclude (keep)
* @return void
*/
public function clearAll( $exclude=NULL )
+26
View File
@@ -0,0 +1,26 @@
<?php
/**
* @brief Abstract Storage Class
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 07 May 2013
*/
namespace IPS\Data\Store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Cache Exception Class
*/
class _Exception extends \RuntimeException
{
}
+5 -4
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -151,7 +151,7 @@ CONTENTS;
static::$cache[ $key ] = $value;
/* Clear zend opcache if enabled */
if ( function_exists( 'opcache_invalidate' ) )
if ( \function_exists( 'opcache_invalidate' ) )
{
@opcache_invalidate( $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php' );
}
@@ -205,7 +205,7 @@ CONTENTS;
}
/* Clear zend opcache if enabled */
if ( function_exists( 'opcache_invalidate' ) )
if ( \function_exists( 'opcache_invalidate' ) )
{
@opcache_invalidate( $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php' );
}
@@ -216,6 +216,7 @@ CONTENTS;
/**
* Abstract Method: Clear All Caches
*
* @param NULL|string $exclude Key to exclude (keep)
* @return void
*/
public function clearAll( $exclude=NULL )
@@ -239,7 +240,7 @@ CONTENTS;
/* Clear zend opcache if enabled - we call reset here since we're wiping multiple files
and since this gets called as part of a general 'rebuild everything', a reset is
probably a good idea anyway */
if ( function_exists( 'opcache_reset' ) )
if ( \function_exists( 'opcache_reset' ) )
{
@opcache_reset();
}
+56 -8
View File
@@ -11,7 +11,7 @@
namespace IPS\Data\Store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -36,24 +36,48 @@ class _Redis extends \IPS\Data\Store
* Redis key
*/
protected $_redisKey;
/**
* Constructor
*
* @param array $configuration Configuration to use
* @return void
*/
public function __construct( $configuration )
{
try
{
$connection = \IPS\Redis::i()->connection('write');
if( !$connection )
{
throw new \RedisException;
}
}
catch( \RedisException $e )
{
throw new \IPS\Data\Store\Exception;
}
}
/**
* Get random string used in the keys to identify this site compared to other sites
*
* @param string $key
* @return string|FALSE Value from the _datastore; FALSE if key doesn't exist
*/
protected function _getRedisKey()
{
if ( !$this->_redisKey )
{
if ( !( $this->_redisKey = \IPS\Redis::i()->get( 'redisKey_store' ) ) )
/* Last access ensures that the data is not stale if we fail back to MySQL and then go back to Redis later */
if ( !( $this->_redisKey = \IPS\Redis::i()->get( 'redisKey_store' ) ) OR ! \IPS\Redis::i()->get( 'redisStore_lastAccess' ) )
{
$this->_redisKey = md5( mt_rand() );
\IPS\Redis::i()->setex( 'redisKey_store', 604800, $this->_redisKey );
\IPS\Redis::i()->setex( 'redisStore_lastAccess', ( 3 * 3600 ), time() );
}
}
return $this->_redisKey . '_str_';
}
@@ -62,10 +86,15 @@ class _Redis extends \IPS\Data\Store
*/
protected static $cache = array();
/**
* @brief Already updated lastAccess?
*/
protected static $updatedLastAccess = FALSE;
/**
* Abstract Method: Get
*
* @param string $key
* @param string $key Key
* @return string|FALSE Value from the _datastore; FALSE if key doesn't exist
*/
public function get( $key )
@@ -77,11 +106,18 @@ class _Redis extends \IPS\Data\Store
try
{
/* Set the last access time */
if ( static::$updatedLastAccess === FALSE )
{
\IPS\Redis::i()->setex( 'redisStore_lastAccess', ( 3 * 3600 ), time() );
static::$updatedLastAccess = TRUE;
}
$return = \IPS\Redis::i()->get( $this->_getRedisKey() . '_' . $key );
if ( $return !== FALSE )
if ( $return !== FALSE AND $decoded = \IPS\Redis::i()->decode( $return ) )
{
static::$cache[ $key ] = \IPS\Redis::i()->decode( $return );
static::$cache[ $key ] = $decoded;
return static::$cache[ $key ];
}
else
@@ -152,7 +188,8 @@ class _Redis extends \IPS\Data\Store
{
try
{
return (bool) \IPS\Redis::i()->delete( $this->_getRedisKey() . '_' . $key );
unset( static::$cache[ $key ] );
return (bool) \IPS\Redis::i()->del( $this->_getRedisKey() . '_' . $key );
}
catch( \RedisException $e )
{
@@ -179,4 +216,15 @@ class _Redis extends \IPS\Data\Store
return FALSE;
}
}
/**
* Test the datastore engine to make sure it's working
* Overloaded here to ensure that if we're using a cluster, there isn't a false error because of the delay with RW
*
* @return bool
*/
public function test()
{
return \IPS\Redis::i()->test();
}
}