Version 4.1.2

This commit is contained in:
Neo committed 2025-12-19 05:32:19 -08:00
1 parent 3ba79295ee
commit 28bd025b35
1131 files changed
+63658 -20579

No files matched your search

+14
View File
@@ -147,4 +147,18 @@ abstract class _Cache extends AbstractData
}
}
/**
* Clear All Caches
*
* @return void
*/
public function clearAll()
{
/* cacheKeys stored md5 hashes of the correct value, and the cache
is only used if the value it returns matches the hash, so clearing
this out invalidates all caches, even if the caching engine
does not allow us to actually clear them */
\IPS\Data\Store::i()->cacheKeys = array();
}
}
+1 -1
View File
@@ -113,7 +113,7 @@ class _Apc extends \IPS\Data\Cache
*/
public function clearAll()
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Flush all caches from APC", 'cache' );
parent::clearAll();
apc_clear_cache();
}
}
-127
View File
@@ -1,127 +0,0 @@
<?php
/**
* @brief eAccelerator Cache Class
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 17 Sept 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\Data\Cache;
/* 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;
}
/**
* eAccelerator Storage Class
*/
class _Eaccelerator extends \IPS\Data\Cache
{
/**
* Server supports this method?
*
* @return bool
*/
public static function supported()
{
return function_exists('eaccelerator_get');
}
/**
* Abstract Method: Get
*
* @param string $key Key
* @return string Value from the _datastore
*/
protected function get( $key )
{
if( isset( $this->cache[ $key ] ) )
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Get {$key} from eAccelerator (already loaded)", 'cache' );
return $this->cache[ $key ];
}
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Get {$key} from eAccelerator", 'cache' );
$this->cache[ $key ] = eaccelerator_get( \IPS\SUITE_UNIQUE_KEY . '_' . $key );
return $this->cache[ $key ];
}
/**
* Abstract Method: Set
*
* @param string $key Key
* @param string $value Value
* @return bool
*/
protected function set( $key, $value )
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Set {$key} in eAccelerator", 'cache' );
eaccelerator_lock( \IPS\SUITE_UNIQUE_KEY . '_' . $key );
$result = (bool) eaccelerator_put( \IPS\SUITE_UNIQUE_KEY . '_' . $key, $value );
eaccelerator_unlock( \IPS\SUITE_UNIQUE_KEY . '_' . $key );
return $result;
}
/**
* Abstract Method: Exists?
*
* @param string $key Key
* @return bool
*/
protected function exists( $key )
{
if( isset( $this->cache[ $key ] ) )
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Check exists {$key} from eAccelerator (already loaded)", 'cache' );
return TRUE;
}
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Check exists {$key} from eAccelerator", 'cache' );
return (bool) $this->get( $key );
}
/**
* Abstract Method: Delete
*
* @param string $key Key
* @return bool
*/
protected function delete( $key )
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Delete {$key} from eAccelerator", 'cache' );
return (bool) eaccelerator_rm( \IPS\SUITE_UNIQUE_KEY . '_' . $key );
}
/**
* Destructor
*
* @return void
*/
public function __destruct()
{
if( function_exists( 'eaccelerator_gc' ) )
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "eAccelerator GC", 'cache' );
eaccelerator_gc();
}
}
/**
* Abstract Method: Clear All Caches
*
* @return void
*/
public function clearAll()
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Flush all caches from eAccelerator (not implemented)", 'cache' );
}
}
+3 -2
View File
@@ -171,10 +171,10 @@ class _Memcache extends \IPS\Data\Cache
else
{
$value = $this->link->get( \IPS\SUITE_UNIQUE_KEY . '_' . $key );
if( method_exists( $this->link, 'getResultCode' ) )
{
if ( $this->link->getResultCode() == \Memcached::RES_NOTFOUND )
if ( $this->link->getResultCode() == \Memcached::RES_NOTFOUND or $value === FALSE )
{
$this->doesNotExist[] = $key;
return FALSE;
@@ -232,6 +232,7 @@ class _Memcache extends \IPS\Data\Cache
*/
public function clearAll()
{
parent::clearAll();
$this->link->flush();
}
}
+1
View File
@@ -144,6 +144,7 @@ class _None extends \IPS\Data\Cache
*/
public function clearAll()
{
parent::clearAll();
try
{
\IPS\Db::i()->delete( 'core_cache' );
+2 -11
View File
@@ -155,7 +155,8 @@ class _Redis extends \IPS\Data\Cache
}
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Check exists {$key} from Redis", 'cache' );
return $this->link->exists( $key );
/* We do a get instead of an exists() check because it will cause the cache value to be fetched and cached inline, saving another call to the server */
return ( $this->get( $key ) === FALSE ) ? FALSE : TRUE;
}
/**
@@ -184,14 +185,4 @@ class _Redis extends \IPS\Data\Cache
$this->link->close();
}
}
/**
* Abstract Method: Clear All Caches
*
* @return void
*/
public function clearAll()
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Flush all caches from Redis (not implemented)", 'cache' );
}
}
+1
View File
@@ -114,6 +114,7 @@ class _Test extends \IPS\Data\Cache
*/
public function clearAll()
{
parent::clearAll();
foreach ( new \DirectoryIterator( $this->_path ) as $file )
{
if ( !$file->isDot() and $file != 'index.html' )
+1 -1
View File
@@ -104,7 +104,7 @@ class _Wincache extends \IPS\Data\Cache
*/
public function clearAll()
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Flush all caches from Wincache", 'cache' );
parent::clearAll();
wincache_ucache_clear();
}
}
-10
View File
@@ -95,14 +95,4 @@ class _Xcache extends \IPS\Data\Cache
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Delete {$key} from Xcache", 'cache' );
return (bool) xcache_unset( \IPS\SUITE_UNIQUE_KEY . '_' . $key );
}
/**
* Abstract Method: Clear All Caches
*
* @return void
*/
public function clearAll()
{
\IPS\Log::i( LOG_DEBUG )->setIpAddress( $_SERVER['REMOTE_ADDR'] )->write( "Flush all caches from Xcache (not implemented)", 'cache' );
}
}
+57 -48
View File
@@ -79,43 +79,45 @@ abstract class _Store extends AbstractData
*/
public function __get( $key )
{
if( \IPS\CACHE_METHOD !== 'None' )
{
if( isset( $this->cacheKeys ) )
{
$cacheKeys = $this->cacheKeys;
if( !is_array( $cacheKeys ) )
{
$cacheKeys = array();
}
}
else
{
$cacheKeys = array();
}
}
/* Try to get it from the cache store... */
try
{
if ( \IPS\CACHE_METHOD !== 'None' and $key !== 'cacheKeys' and isset( $cacheKeys[ $key ] ) and isset( \IPS\Data\Cache::i()->$key ) )
{
$value = \IPS\Data\Cache::i()->$key;
if ( $cacheKeys[ $key ] === md5( json_encode( $value ) ) )
{
return $value;
}
}
throw new \OutOfRangeException;
}
catch ( \OutOfRangeException $e )
{
$value = parent::__get( $key );
/* If caching is enabled, and this isn't the special map of hashes... */
if ( \IPS\CACHE_METHOD !== 'None' and $key !== 'cacheKeys' )
{
/* And 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();
if ( isset( $cacheKeys[ $key ] ) and isset( \IPS\Data\Cache::i()->$key ) )
{
/* Get it... */
$value = \IPS\Data\Cache::i()->$key;
/* But only use it if the hash matches */
if ( $cacheKeys[ $key ] === md5( json_encode( $value ) ) )
{
return $value;
}
}
}
/* Still here? throw an exception so we get it from the data storage engine */
throw new \OutOfRangeException;
}
/* If we couldn't get it from the cache engine, get it from the data storage engine */
catch ( \OutOfRangeException $e )
{
/* Actually get it... */
$value = parent::__get( $key );
/* If caching is enabled, and this isn't the special map of hashes... */
if ( \IPS\CACHE_METHOD !== 'None' and $key !== 'cacheKeys' )
{
/* Set it in the caching engine... */
\IPS\Data\Cache::i()->$key = $value;
/* And set the hash in the cacheKeys hash map */
$cacheKeys = ( isset( $this->cacheKeys ) and is_array( $this->cacheKeys ) ) ? $this->cacheKeys : array();
$cacheKeys[ $key ] = md5( json_encode( $value ) );
$this->cacheKeys = $cacheKeys;
}
@@ -133,13 +135,17 @@ abstract class _Store extends AbstractData
*/
public function __set( $key, $value )
{
/* Actually set it in the data storage engine */
parent::__set( $key, $value );
/* If caching is enabled, and this isn't the special map of hashes... */
if ( \IPS\CACHE_METHOD !== 'None' and $key !== 'cacheKeys' )
{
/* Then also set it in the cache... */
\IPS\Data\Cache::i()->$key = $value;
if ( isset( $this->cacheKeys ) )
/* And set the hash in the cacheKeys hash map */
if ( ( isset( $this->cacheKeys ) and is_array( $this->cacheKeys ) ) )
{
$cacheKeys = is_array( $this->cacheKeys ) ? $this->cacheKeys : array();
$cacheKeys[ $key ] = md5( json_encode( $value ) );
@@ -160,19 +166,25 @@ abstract class _Store extends AbstractData
*/
public function __isset( $key )
{
if ( \IPS\CACHE_METHOD !== 'None' and $key !== 'cacheKeys' and isset( $this->cacheKeys ) and isset( $this->cacheKeys[ $key ] ) and isset( \IPS\Data\Cache::i()->$key ) )
/* If caching is enabled, and this isn't the special map of hashes, try to get it from the cache store... */
if ( \IPS\CACHE_METHOD !== 'None' and $key !== 'cacheKeys' )
{
try
/* Does it exist in the caching engine? */
if ( isset( \IPS\Data\Cache::i()->$key ) )
{
/* Get it... */
$value = \IPS\Data\Cache::i()->$key;
if ( $this->cacheKeys[ $key ] === md5( json_encode( $value ) ) )
/* But only use it if the hash matches */
$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;
}
}
catch ( \OutOfRangeException $e ) { }
}
}
}
/* If we're still here, check the data storage engine... */
return parent::__isset( $key );
}
@@ -184,22 +196,19 @@ abstract class _Store extends AbstractData
*/
public function __unset( $key )
{
/* Unset it in the data storage engine */
parent::__unset( $key );
/* If caching is enabled, and this isn't the special map of hashes, remove it from the cache store... */
if ( \IPS\CACHE_METHOD !== 'None' and $key !== 'cacheKeys' )
{
/* Remove it from the cache store... */
unset( \IPS\Data\Cache::i()->$key );
if ( isset( $this->cacheKeys ) )
{
$cacheKeys = is_array( $this->cacheKeys ) ? $this->cacheKeys : array();
if( isset( $cacheKeys[ $key ] ) )
{
unset( $cacheKeys[ $key ] );
$this->cacheKeys = $cacheKeys;
}
}
/* And from the special map of hashes */
$cacheKeys = is_array( $this->cacheKeys ) ? $this->cacheKeys : array();
unset( $cacheKeys[ $key ] );
$this->cacheKeys = $cacheKeys;
}
}
}
+15 -6
View File
@@ -55,16 +55,25 @@ class _Database extends \IPS\Data\Store
* @return void
*/
public function __construct()
{
if ( \IPS\Session\Front::loggedIn() )
{
/* When caching is enabled, we only need cacheKeys, the rest will come from the cache */
if ( \IPS\CACHE_METHOD !== 'None' )
{
$this->initLoad[] = 'administrators';
$this->initLoad[] = 'moderators';
$this->initLoad[] = 'emoticons';
$this->initLoad = array( 'cacheKeys' );
}
/* Otherwise, we also need a few more things depending on whether the user is logged in or not */
else
{
$this->initLoad[] = 'loginHandlers';
if ( \IPS\Session\Front::loggedIn() )
{
$this->initLoad[] = 'administrators';
$this->initLoad[] = 'moderators';
$this->initLoad[] = 'emoticons';
}
else
{
$this->initLoad[] = 'loginHandlers';
}
}
}
+9 -1
View File
@@ -95,7 +95,7 @@ class _FileSystem extends \IPS\Data\Store
{
/* It is remotely possible that the file was removed in between an exists check and a get call on a busy site,
so we need to make sure the file still exists in order to prevent a php warning */
clearstatcache( FALSE, $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php' );
clearstatcache();
if ( file_exists( $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php' ) )
{
@@ -126,6 +126,14 @@ CONTENTS;
$result = (bool) @\file_put_contents( $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php', $contents, LOCK_EX );
/* Sometimes LOCK_EX is unavailable and throws file_put_contents(): Exclusive locks are not supported for this stream.
While we would prefer an exclusive lock, it would be better to write the file if possible. */
if( !$result )
{
@unlink( $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php' );
$result = (bool) @\file_put_contents( $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php', $contents );
}
@chmod( $this->_path . '/' . $key . '.' . \IPS\SUITE_UNIQUE_KEY . '.php', \IPS\IPS_FILE_PERMISSION );
static::$cache[ $key ] = $value;