From cd6501c0171950f90d5d9867e13ae138b6067f79 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 12 Jun 2024 09:32:53 +0800 Subject: [PATCH] MDL-82158 core_cache: Moved disabled cache infrastructure --- cache/admin.php | 1 - cache/classes/allow_temporary_caches.php | 3 - cache/classes/disabled_cache.php | 215 +++++++ cache/classes/disabled_config.php | 208 ++++++ cache/classes/disabled_factory.php | 199 ++++++ .../{dummystore.php => dummy_cachestore.php} | 17 +- cache/classes/factory.php | 9 +- cache/disabledlib.php | 608 ------------------ cache/stores/apcu/addinstanceform.php | 12 +- cache/stores/file/addinstanceform.php | 16 +- cache/stores/redis/addinstanceform.php | 12 - lib/db/legacyclasses.php | 10 + 12 files changed, 648 insertions(+), 662 deletions(-) create mode 100644 cache/classes/disabled_cache.php create mode 100644 cache/classes/disabled_config.php create mode 100644 cache/classes/disabled_factory.php rename cache/classes/{dummystore.php => dummy_cachestore.php} (93%) delete mode 100644 cache/disabledlib.php diff --git a/cache/admin.php b/cache/admin.php index 6da94ffc69e..26633133300 100644 --- a/cache/admin.php +++ b/cache/admin.php @@ -28,7 +28,6 @@ require_once('../config.php'); require_once($CFG->dirroot.'/lib/adminlib.php'); require_once($CFG->dirroot.'/cache/locallib.php'); -require_once($CFG->dirroot.'/cache/forms.php'); // The first time the user visits this page we are going to reparse the definitions. // Just ensures that everything is up to date. diff --git a/cache/classes/allow_temporary_caches.php b/cache/classes/allow_temporary_caches.php index 83379c19df8..45fffe54a7f 100644 --- a/cache/classes/allow_temporary_caches.php +++ b/cache/classes/allow_temporary_caches.php @@ -60,9 +60,6 @@ class allow_temporary_caches { * If there are no other instances of this object, then all temporary caches will be discarded. */ public function __destruct() { - global $CFG; - require_once($CFG->dirroot . '/cache/disabledlib.php'); - self::$references--; if (self::$references === 0) { \cache_factory_disabled::clear_temporary_caches(); diff --git a/cache/classes/disabled_cache.php b/cache/classes/disabled_cache.php new file mode 100644 index 00000000000..7c94190bdab --- /dev/null +++ b/cache/classes/disabled_cache.php @@ -0,0 +1,215 @@ +. + +/** + * The cache loader class used when the Cache has been disabled. + * + * @package core_cache + * @copyright 2012 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class cache_disabled extends cache implements cache_loader_with_locking { + + /** + * Constructs the cache. + * + * @param cache_definition $definition + * @param cache_store $store + * @param null $loader Unused. + */ + public function __construct(cache_definition $definition, cache_store $store, $loader = null) { + if ($loader instanceof cache_data_source) { + // Set the data source to allow data sources to work when caching is entirely disabled. + $this->set_data_source($loader); + } + + // No other features are handled. + } + + /** + * Gets a key from the cache. + * + * @param int|string $key + * @param int $requiredversion Minimum required version of the data or cache::VERSION_NONE + * @param int $strictness Unused. + * @param mixed &$actualversion If specified, will be set to the actual version number retrieved + * @return bool + */ + protected function get_implementation($key, int $requiredversion, int $strictness, &$actualversion = null) { + $datasource = $this->get_datasource(); + if ($datasource !== false) { + if ($requiredversion === cache::VERSION_NONE) { + return $datasource->load_for_cache($key); + } else { + if (!$datasource instanceof cache_data_source_versionable) { + throw new \coding_exception('Data source is not versionable'); + } + $result = $datasource->load_for_cache_versioned($key, $requiredversion, $actualversion); + if ($result && $actualversion < $requiredversion) { + throw new \coding_exception('Data source returned outdated version'); + } + return $result; + } + } + return false; + } + + /** + * Gets many keys at once from the cache. + * + * @param array $keys + * @param int $strictness Unused. + * @return array + */ + public function get_many(array $keys, $strictness = IGNORE_MISSING) { + if ($this->get_datasource() !== false) { + return $this->get_datasource()->load_many_for_cache($keys); + } + + return array_combine($keys, array_fill(0, count($keys), false)); + } + + /** + * Sets a key value pair in the cache. + * + * @param int|string $key Unused. + * @param int $version Unused. + * @param mixed $data Unused. + * @param bool $setparents Unused. + * @return bool + */ + protected function set_implementation($key, int $version, $data, bool $setparents = true): bool { + return false; + } + + /** + * Sets many key value pairs in the cache at once. + * + * @param array $keyvaluearray Unused. + * @return int + */ + public function set_many(array $keyvaluearray) { + return 0; + } + + /** + * Deletes an item from the cache. + * + * @param int|string $key Unused. + * @param bool $recurse Unused. + * @return bool + */ + public function delete($key, $recurse = true) { + return false; + } + + /** + * Deletes many items at once from the cache. + * + * @param array $keys Unused. + * @param bool $recurse Unused. + * @return int + */ + public function delete_many(array $keys, $recurse = true) { + return 0; + } + + /** + * Checks if the cache has the requested key. + * + * @param int|string $key Unused. + * @param bool $tryloadifpossible Unused. + * @return bool + */ + public function has($key, $tryloadifpossible = false) { + $result = $this->get($key); + + return $result !== false; + } + + /** + * Checks if the cache has all of the requested keys. + * @param array $keys Unused. + * @return bool + */ + public function has_all(array $keys) { + if (!$this->get_datasource()) { + return false; + } + + foreach ($keys as $key) { + if (!$this->has($key)) { + return false; + } + } + return true; + } + + /** + * Checks if the cache has any of the requested keys. + * + * @param array $keys Unused. + * @return bool + */ + public function has_any(array $keys) { + foreach ($keys as $key) { + if ($this->has($key)) { + return true; + } + } + + return false; + } + + /** + * Purges all items from the cache. + * + * @return bool + */ + public function purge() { + return true; + } + + /** + * Pretend that we got a lock to avoid errors. + * + * @param int|string $key + * @return bool + */ + public function acquire_lock($key): bool { + return true; + } + + /** + * Pretend that we released a lock to avoid errors. + * + * @param int|string $key + * @return bool + */ + public function release_lock($key): bool { + return true; + } + + /** + * Pretend that we have a lock to avoid errors. + * + * @param int|string $key + * @return bool + */ + public function check_lock_state($key): bool { + return true; + } +} diff --git a/cache/classes/disabled_config.php b/cache/classes/disabled_config.php new file mode 100644 index 00000000000..f4995e6e323 --- /dev/null +++ b/cache/classes/disabled_config.php @@ -0,0 +1,208 @@ +. + +/** + * The cache config class used when the Cache has been disabled. + * + * @package core_cache + * @copyright 2012 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class cache_config_disabled extends config_writer { + + /** + * Returns an instance of the configuration writer. + * + * @return cache_config_disabled + */ + public static function instance() { + $factory = cache_factory::instance(); + return $factory->create_config_instance(true); + } + + /** + * Saves the current configuration. + */ + protected function config_save() { + // Nothing to do here. + } + + /** + * Generates a configuration array suitable to be written to the config file. + * + * @return array + */ + protected function generate_configuration_array() { + $configuration = array(); + $configuration['stores'] = $this->configstores; + $configuration['modemappings'] = $this->configmodemappings; + $configuration['definitions'] = $this->configdefinitions; + $configuration['definitionmappings'] = $this->configdefinitionmappings; + $configuration['locks'] = $this->configlocks; + return $configuration; + } + + /** + * Adds a plugin instance. + * + * @param string $name Unused. + * @param string $plugin Unused. + * @param array $configuration Unused. + * @return bool + * @throws cache_exception + */ + public function add_store_instance($name, $plugin, array $configuration = array()) { + return false; + } + + /** + * Sets the mode mappings. + * + * @param array $modemappings Unused. + * @return bool + * @throws cache_exception + */ + public function set_mode_mappings(array $modemappings) { + return false; + } + + /** + * Edits a give plugin instance. + * + * @param string $name Unused. + * @param string $plugin Unused. + * @param array $configuration Unused. + * @return bool + * @throws cache_exception + */ + public function edit_store_instance($name, $plugin, $configuration) { + return false; + } + + /** + * Deletes a store instance. + * + * @param string $name Unused. + * @return bool + * @throws cache_exception + */ + public function delete_store_instance($name) { + return false; + } + + /** + * Creates the default configuration and saves it. + * + * @param bool $forcesave Ignored because we are disabled! + * @return array + */ + public static function create_default_configuration($forcesave = false) { + global $CFG; + + // HACK ALERT. + // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the + // default store plugins are protected from deletion. + require_once($CFG->dirroot.'/cache/stores/file/lib.php'); + require_once($CFG->dirroot.'/cache/stores/session/lib.php'); + require_once($CFG->dirroot.'/cache/stores/static/lib.php'); + + $writer = new self; + $writer->configstores = array( + 'default_application' => array( + 'name' => 'default_application', + 'plugin' => 'file', + 'configuration' => array(), + 'features' => cachestore_file::get_supported_features(), + 'modes' => cache_store::MODE_APPLICATION, + 'default' => true, + ), + 'default_session' => array( + 'name' => 'default_session', + 'plugin' => 'session', + 'configuration' => array(), + 'features' => cachestore_session::get_supported_features(), + 'modes' => cache_store::MODE_SESSION, + 'default' => true, + ), + 'default_request' => array( + 'name' => 'default_request', + 'plugin' => 'static', + 'configuration' => array(), + 'features' => cachestore_static::get_supported_features(), + 'modes' => cache_store::MODE_REQUEST, + 'default' => true, + ) + ); + $writer->configdefinitions = array(); + $writer->configmodemappings = array( + array( + 'mode' => cache_store::MODE_APPLICATION, + 'store' => 'default_application', + 'sort' => -1 + ), + array( + 'mode' => cache_store::MODE_SESSION, + 'store' => 'default_session', + 'sort' => -1 + ), + array( + 'mode' => cache_store::MODE_REQUEST, + 'store' => 'default_request', + 'sort' => -1 + ) + ); + $writer->configlocks = array( + 'default_file_lock' => array( + 'name' => 'cachelock_file_default', + 'type' => 'cachelock_file', + 'dir' => 'filelocks', + 'default' => true + ) + ); + + return $writer->generate_configuration_array(); + } + + /** + * Updates the definition in the configuration from those found in the cache files. + * + * @param bool $coreonly Unused. + */ + public static function update_definitions($coreonly = false) { + // Nothing to do here. + } + + /** + * Locates all of the definition files. + * + * @param bool $coreonly Unused. + * @return array + */ + protected static function locate_definitions($coreonly = false) { + return array(); + } + + /** + * Sets the mappings for a given definition. + * + * @param string $definition Unused. + * @param array $mappings Unused. + * @throws coding_exception + */ + public function set_definition_mappings($definition, $mappings) { + // Nothing to do here. + } +} diff --git a/cache/classes/disabled_factory.php b/cache/classes/disabled_factory.php new file mode 100644 index 00000000000..8f3a14c88d0 --- /dev/null +++ b/cache/classes/disabled_factory.php @@ -0,0 +1,199 @@ +. + +/** + * The cache factory class used when the Cache has been disabled. + * + * @package core_cache + * @copyright 2012 Sam Hemelryk + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class cache_factory_disabled extends cache_factory { + /** @var array Array of temporary caches in use. */ + protected static $tempcaches = []; + + /** + * Returns an instance of the cache_factor method. + * + * @param bool $forcereload Unused. + * @return cache_factory + * @throws coding_exception + */ + public static function instance($forcereload = false) { + throw new coding_exception('You must not call to this cache factory within your code.'); + } + + /** + * Creates a definition instance or returns the existing one if it has already been created. + * + * @param string $component + * @param string $area + * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. + * @return cache_definition + */ + public function create_definition($component, $area, $unused = null) { + $definition = parent::create_definition($component, $area); + if ($definition->has_data_source()) { + return $definition; + } + + return cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area); + } + + /** + * Common public method to create a cache instance given a definition. + * + * @param cache_definition $definition + * @return cache_application|cache_session|cache_store + * @throws coding_exception + */ + public function create_cache(cache_definition $definition) { + $loader = null; + if ($definition->has_data_source()) { + $loader = $definition->get_data_source(); + } + return new cache_disabled($definition, $this->create_dummy_store($definition), $loader); + } + + /** + * Creates a cache object given the parameters for a definition. + * + * @param string $component + * @param string $area + * @param array $identifiers + * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. + * @return cache_application|cache_session|request_cache + */ + public function create_cache_from_definition($component, $area, array $identifiers = array(), $unused = null) { + // Temporary in-memory caches are sometimes allowed when caching is disabled. + if (\core_cache\allow_temporary_caches::is_allowed() && !$identifiers) { + $key = $component . '/' . $area; + if (array_key_exists($key, self::$tempcaches)) { + $cache = self::$tempcaches[$key]; + } else { + $definition = $this->create_definition($component, $area); + // The cachestore_static class returns true to all three 'SUPPORTS_' checks so it + // can be used with all definitions. + $store = new cachestore_static('TEMP:' . $component . '/' . $area); + $store->initialise($definition); + // We need to use a cache loader wrapper rather than directly returning the store, + // or it wouldn't have support for versioning. The cache_application class is used + // (rather than cache_request which might make more sense logically) because it + // includes support for locking, which might be necessary for some caches. + $cache = new cache_application($definition, $store); + self::$tempcaches[$key] = $cache; + } + return $cache; + } + + // Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php + // definitions as they use load_adhoc(). They are built as a new object on each call. + // We do not need to clone the definition because we know it's new. + $definition = $this->create_definition($component, $area); + $definition->set_identifiers($identifiers); + $cache = $this->create_cache($definition); + return $cache; + } + + /** + * Removes all temporary caches. + * + * Don't call this directly - used by {@see \core_cache\allow_temporary_caches}. + */ + public static function clear_temporary_caches(): void { + self::$tempcaches = []; + } + + /** + * Creates an ad-hoc cache from the given param. + * + * @param int $mode + * @param string $component + * @param string $area + * @param array $identifiers + * @param array $options An array of options, available options are: + * - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_ + * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars + * - staticacceleration : If set to true the cache will hold onto all data passing through it. + * - staticaccelerationsize : Sets the max size of the static acceleration array. + * @return cache_application|cache_session|request_cache + */ + public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) { + // Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php + // definitions as they use load_adhoc(). They are built as a new object on each call. + // We do not need to clone the definition because we know it's new. + $definition = cache_definition::load_adhoc($mode, $component, $area, $options); + $definition->set_identifiers($identifiers); + $cache = $this->create_cache($definition); + return $cache; + } + + /** + * Creates a store instance given its name and configuration. + * + * @param string $name Unused. + * @param array $details Unused. + * @param cache_definition $definition + * @return boolean|cache_store + */ + public function create_store_from_config($name, array $details, cache_definition $definition) { + return $this->create_dummy_store($definition); + } + + /** + * Creates a cache config instance with the ability to write if required. + * + * @param bool $writer Unused. + * @return cache_config_disabled|config_writer + */ + public function create_config_instance($writer = false) { + // We are always going to use the cache_config_disabled class for all regular request. + // However if the code has requested the writer then likely something is changing and + // we're going to need to interact with the config.php file. + // In this case we will still use the cache_config_writer. + $class = 'cache_config_disabled'; + if ($writer) { + // If the writer was requested then something is changing. + $class = 'cache_config_writer'; + } + if (!array_key_exists($class, $this->configs)) { + self::set_state(self::STATE_INITIALISING); + if ($class === 'cache_config_disabled') { + $configuration = $class::create_default_configuration(); + $this->configs[$class] = new $class; + } else { + $configuration = false; + // If we need a writer, we should get the classname from the generic factory. + // This is so alternative classes can be used if a different writer is required. + $this->configs[$class] = parent::get_disabled_writer(); + } + $this->configs[$class]->load($configuration); + } + self::set_state(self::STATE_READY); + + // Return the instance. + return $this->configs[$class]; + } + + /** + * Returns true if the cache API has been disabled. + * + * @return bool + */ + public function is_disabled() { + return true; + } +} diff --git a/cache/classes/dummystore.php b/cache/classes/dummy_cachestore.php similarity index 93% rename from cache/classes/dummystore.php rename to cache/classes/dummy_cachestore.php index f268cef50c9..12e6e429c80 100644 --- a/cache/classes/dummystore.php +++ b/cache/classes/dummy_cachestore.php @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . +namespace core_cache; + /** * Cache dummy store. * @@ -61,7 +63,7 @@ class cachestore_dummy extends cache_store { /** * Cache definition - * @var cache_definition + * @var definition */ protected $definition; @@ -110,9 +112,9 @@ class cachestore_dummy extends cache_store { /** * Initialises the store instance for a definition. - * @param cache_definition $definition + * @param definition $definition */ - public function initialise(cache_definition $definition) { + public function initialise(definition $definition) { // If the definition isn't using static acceleration then we need to be store data here. // The reasoning behind this is that: // - If the definition is using static acceleration then the cache loader is going to @@ -261,10 +263,10 @@ class cachestore_dummy extends cache_store { /** * Generates an instance of the cache store that can be used for testing. * - * @param cache_definition $definition + * @param definition $definition * @return false */ - public static function initialise_test_instance(cache_definition $definition) { + public static function initialise_test_instance(definition $definition) { $cache = new cachestore_dummy('Dummy store test'); if ($cache->is_ready()) { $cache->initialise($definition); @@ -289,3 +291,8 @@ class cachestore_dummy extends cache_store { return $this->name; } } + +// Alias this class to the old name. +// This file will be autoloaded by the legacyclasses autoload system. +// In future all uses of this class will be corrected and the legacy references will be removed. +class_alias(dummy_cachestore::class, \cachestore_dummy::class); diff --git a/cache/classes/factory.php b/cache/classes/factory.php index d2991a5d7f7..95a3e0a6a50 100644 --- a/cache/classes/factory.php +++ b/cache/classes/factory.php @@ -116,7 +116,6 @@ class cache_factory { if (defined('CACHE_DISABLE_ALL') && CACHE_DISABLE_ALL !== false) { // The cache has been disabled. Load disabledlib and start using the factory designed to handle this // situation. It will use disabled alternatives where available. - require_once($CFG->dirroot.'/cache/disabledlib.php'); self::$instance = new cache_factory_disabled(); } else if ((defined('PHPUNIT_TEST') && PHPUNIT_TEST) || defined('BEHAT_SITE_RUNNING')) { // We're using the test factory. @@ -464,12 +463,10 @@ class cache_factory { /** * Creates a dummy store object for use when a loader has no potential stores to use. * - * @param cache_definition $definition - * @return cachestore_dummy + * @param definition $definition + * @return dummy_cachestore */ protected function create_dummy_store(cache_definition $definition) { - global $CFG; - require_once($CFG->dirroot.'/cache/classes/dummystore.php'); $store = new cachestore_dummy(); $store->initialise($definition); return $store; @@ -597,8 +594,6 @@ class cache_factory { * MUC it was decided that this was just to risky and abusable. */ protected static function disable() { - global $CFG; - require_once($CFG->dirroot.'/cache/disabledlib.php'); self::$instance = new cache_factory_disabled(); } diff --git a/cache/disabledlib.php b/cache/disabledlib.php deleted file mode 100644 index 3538d1ed648..00000000000 --- a/cache/disabledlib.php +++ /dev/null @@ -1,608 +0,0 @@ -. - -/** - * This file contains classes that are used by the Cache API only when it is disabled. - * - * These classes are derivatives of other significant classes used by the Cache API customised specifically - * to only do what is absolutely necessary when initialising and using the Cache API when its been disabled. - * - * @package core - * @category cache - * @copyright 2012 Sam Hemelryk - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -/** - * Required as it is needed for cache_config_disabled which extends cache_config_writer. - */ -require_once($CFG->dirroot.'/cache/locallib.php'); - -/** - * The cache loader class used when the Cache has been disabled. - * - * @copyright 2012 Sam Hemelryk - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class cache_disabled extends cache implements cache_loader_with_locking { - - /** - * Constructs the cache. - * - * @param cache_definition $definition - * @param cache_store $store - * @param null $loader Unused. - */ - public function __construct(cache_definition $definition, cache_store $store, $loader = null) { - if ($loader instanceof cache_data_source) { - // Set the data source to allow data sources to work when caching is entirely disabled. - $this->set_data_source($loader); - } - - // No other features are handled. - } - - /** - * Gets a key from the cache. - * - * @param int|string $key - * @param int $requiredversion Minimum required version of the data or cache::VERSION_NONE - * @param int $strictness Unused. - * @param mixed &$actualversion If specified, will be set to the actual version number retrieved - * @return bool - */ - protected function get_implementation($key, int $requiredversion, int $strictness, &$actualversion = null) { - $datasource = $this->get_datasource(); - if ($datasource !== false) { - if ($requiredversion === cache::VERSION_NONE) { - return $datasource->load_for_cache($key); - } else { - if (!$datasource instanceof cache_data_source_versionable) { - throw new \coding_exception('Data source is not versionable'); - } - $result = $datasource->load_for_cache_versioned($key, $requiredversion, $actualversion); - if ($result && $actualversion < $requiredversion) { - throw new \coding_exception('Data source returned outdated version'); - } - return $result; - } - } - return false; - } - - /** - * Gets many keys at once from the cache. - * - * @param array $keys - * @param int $strictness Unused. - * @return array - */ - public function get_many(array $keys, $strictness = IGNORE_MISSING) { - if ($this->get_datasource() !== false) { - return $this->get_datasource()->load_many_for_cache($keys); - } - - return array_combine($keys, array_fill(0, count($keys), false)); - } - - /** - * Sets a key value pair in the cache. - * - * @param int|string $key Unused. - * @param int $version Unused. - * @param mixed $data Unused. - * @param bool $setparents Unused. - * @return bool - */ - protected function set_implementation($key, int $version, $data, bool $setparents = true): bool { - return false; - } - - /** - * Sets many key value pairs in the cache at once. - * - * @param array $keyvaluearray Unused. - * @return int - */ - public function set_many(array $keyvaluearray) { - return 0; - } - - /** - * Deletes an item from the cache. - * - * @param int|string $key Unused. - * @param bool $recurse Unused. - * @return bool - */ - public function delete($key, $recurse = true) { - return false; - } - - /** - * Deletes many items at once from the cache. - * - * @param array $keys Unused. - * @param bool $recurse Unused. - * @return int - */ - public function delete_many(array $keys, $recurse = true) { - return 0; - } - - /** - * Checks if the cache has the requested key. - * - * @param int|string $key Unused. - * @param bool $tryloadifpossible Unused. - * @return bool - */ - public function has($key, $tryloadifpossible = false) { - $result = $this->get($key); - - return $result !== false; - } - - /** - * Checks if the cache has all of the requested keys. - * @param array $keys Unused. - * @return bool - */ - public function has_all(array $keys) { - if (!$this->get_datasource()) { - return false; - } - - foreach ($keys as $key) { - if (!$this->has($key)) { - return false; - } - } - return true; - } - - /** - * Checks if the cache has any of the requested keys. - * - * @param array $keys Unused. - * @return bool - */ - public function has_any(array $keys) { - foreach ($keys as $key) { - if ($this->has($key)) { - return true; - } - } - - return false; - } - - /** - * Purges all items from the cache. - * - * @return bool - */ - public function purge() { - return true; - } - - /** - * Pretend that we got a lock to avoid errors. - * - * @param int|string $key - * @return bool - */ - public function acquire_lock($key): bool { - return true; - } - - /** - * Pretend that we released a lock to avoid errors. - * - * @param int|string $key - * @return bool - */ - public function release_lock($key): bool { - return true; - } - - /** - * Pretend that we have a lock to avoid errors. - * - * @param int|string $key - * @return bool - */ - public function check_lock_state($key): bool { - return true; - } -} - -/** - * The cache factory class used when the Cache has been disabled. - * - * @copyright 2012 Sam Hemelryk - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class cache_factory_disabled extends cache_factory { - /** @var array Array of temporary caches in use. */ - protected static $tempcaches = []; - - /** - * Returns an instance of the cache_factor method. - * - * @param bool $forcereload Unused. - * @return cache_factory - * @throws coding_exception - */ - public static function instance($forcereload = false) { - throw new coding_exception('You must not call to this cache factory within your code.'); - } - - /** - * Creates a definition instance or returns the existing one if it has already been created. - * - * @param string $component - * @param string $area - * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. - * @return cache_definition - */ - public function create_definition($component, $area, $unused = null) { - $definition = parent::create_definition($component, $area); - if ($definition->has_data_source()) { - return $definition; - } - - return cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area); - } - - /** - * Common public method to create a cache instance given a definition. - * - * @param cache_definition $definition - * @return cache_application|cache_session|cache_store - * @throws coding_exception - */ - public function create_cache(cache_definition $definition) { - $loader = null; - if ($definition->has_data_source()) { - $loader = $definition->get_data_source(); - } - return new cache_disabled($definition, $this->create_dummy_store($definition), $loader); - } - - /** - * Creates a cache object given the parameters for a definition. - * - * @param string $component - * @param string $area - * @param array $identifiers - * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. - * @return cache_application|cache_session|cache_request - */ - public function create_cache_from_definition($component, $area, array $identifiers = array(), $unused = null) { - // Temporary in-memory caches are sometimes allowed when caching is disabled. - if (\core_cache\allow_temporary_caches::is_allowed() && !$identifiers) { - $key = $component . '/' . $area; - if (array_key_exists($key, self::$tempcaches)) { - $cache = self::$tempcaches[$key]; - } else { - $definition = $this->create_definition($component, $area); - // The cachestore_static class returns true to all three 'SUPPORTS_' checks so it - // can be used with all definitions. - $store = new cachestore_static('TEMP:' . $component . '/' . $area); - $store->initialise($definition); - // We need to use a cache loader wrapper rather than directly returning the store, - // or it wouldn't have support for versioning. The cache_application class is used - // (rather than cache_request which might make more sense logically) because it - // includes support for locking, which might be necessary for some caches. - $cache = new cache_application($definition, $store); - self::$tempcaches[$key] = $cache; - } - return $cache; - } - - // Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php - // definitions as they use load_adhoc(). They are built as a new object on each call. - // We do not need to clone the definition because we know it's new. - $definition = $this->create_definition($component, $area); - $definition->set_identifiers($identifiers); - $cache = $this->create_cache($definition); - return $cache; - } - - /** - * Removes all temporary caches. - * - * Don't call this directly - used by {@see \core_cache\allow_temporary_caches}. - */ - public static function clear_temporary_caches(): void { - self::$tempcaches = []; - } - - /** - * Creates an ad-hoc cache from the given param. - * - * @param int $mode - * @param string $component - * @param string $area - * @param array $identifiers - * @param array $options An array of options, available options are: - * - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_ - * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars - * - staticacceleration : If set to true the cache will hold onto all data passing through it. - * - staticaccelerationsize : Sets the max size of the static acceleration array. - * @return cache_application|cache_session|cache_request - */ - public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) { - // Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php - // definitions as they use load_adhoc(). They are built as a new object on each call. - // We do not need to clone the definition because we know it's new. - $definition = cache_definition::load_adhoc($mode, $component, $area, $options); - $definition->set_identifiers($identifiers); - $cache = $this->create_cache($definition); - return $cache; - } - - /** - * Creates a store instance given its name and configuration. - * - * @param string $name Unused. - * @param array $details Unused. - * @param cache_definition $definition - * @return boolean|cache_store - */ - public function create_store_from_config($name, array $details, cache_definition $definition) { - return $this->create_dummy_store($definition); - } - - /** - * Creates a cache config instance with the ability to write if required. - * - * @param bool $writer Unused. - * @return cache_config_disabled|cache_config_writer - */ - public function create_config_instance($writer = false) { - // We are always going to use the cache_config_disabled class for all regular request. - // However if the code has requested the writer then likely something is changing and - // we're going to need to interact with the config.php file. - // In this case we will still use the cache_config_writer. - $class = 'cache_config_disabled'; - if ($writer) { - // If the writer was requested then something is changing. - $class = 'cache_config_writer'; - } - if (!array_key_exists($class, $this->configs)) { - self::set_state(self::STATE_INITIALISING); - if ($class === 'cache_config_disabled') { - $configuration = $class::create_default_configuration(); - $this->configs[$class] = new $class; - } else { - $configuration = false; - // If we need a writer, we should get the classname from the generic factory. - // This is so alternative classes can be used if a different writer is required. - $this->configs[$class] = parent::get_disabled_writer(); - } - $this->configs[$class]->load($configuration); - } - self::set_state(self::STATE_READY); - - // Return the instance. - return $this->configs[$class]; - } - - /** - * Returns true if the cache API has been disabled. - * - * @return bool - */ - public function is_disabled() { - return true; - } -} - -/** - * The cache config class used when the Cache has been disabled. - * - * @copyright 2012 Sam Hemelryk - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class cache_config_disabled extends cache_config_writer { - - /** - * Returns an instance of the configuration writer. - * - * @return cache_config_disabled - */ - public static function instance() { - $factory = cache_factory::instance(); - return $factory->create_config_instance(true); - } - - /** - * Saves the current configuration. - */ - protected function config_save() { - // Nothing to do here. - } - - /** - * Generates a configuration array suitable to be written to the config file. - * - * @return array - */ - protected function generate_configuration_array() { - $configuration = array(); - $configuration['stores'] = $this->configstores; - $configuration['modemappings'] = $this->configmodemappings; - $configuration['definitions'] = $this->configdefinitions; - $configuration['definitionmappings'] = $this->configdefinitionmappings; - $configuration['locks'] = $this->configlocks; - return $configuration; - } - - /** - * Adds a plugin instance. - * - * @param string $name Unused. - * @param string $plugin Unused. - * @param array $configuration Unused. - * @return bool - * @throws cache_exception - */ - public function add_store_instance($name, $plugin, array $configuration = array()) { - return false; - } - - /** - * Sets the mode mappings. - * - * @param array $modemappings Unused. - * @return bool - * @throws cache_exception - */ - public function set_mode_mappings(array $modemappings) { - return false; - } - - /** - * Edits a give plugin instance. - * - * @param string $name Unused. - * @param string $plugin Unused. - * @param array $configuration Unused. - * @return bool - * @throws cache_exception - */ - public function edit_store_instance($name, $plugin, $configuration) { - return false; - } - - /** - * Deletes a store instance. - * - * @param string $name Unused. - * @return bool - * @throws cache_exception - */ - public function delete_store_instance($name) { - return false; - } - - /** - * Creates the default configuration and saves it. - * - * @param bool $forcesave Ignored because we are disabled! - * @return array - */ - public static function create_default_configuration($forcesave = false) { - global $CFG; - - // HACK ALERT. - // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the - // default store plugins are protected from deletion. - require_once($CFG->dirroot.'/cache/stores/file/lib.php'); - require_once($CFG->dirroot.'/cache/stores/session/lib.php'); - require_once($CFG->dirroot.'/cache/stores/static/lib.php'); - - $writer = new self; - $writer->configstores = array( - 'default_application' => array( - 'name' => 'default_application', - 'plugin' => 'file', - 'configuration' => array(), - 'features' => cachestore_file::get_supported_features(), - 'modes' => cache_store::MODE_APPLICATION, - 'default' => true, - ), - 'default_session' => array( - 'name' => 'default_session', - 'plugin' => 'session', - 'configuration' => array(), - 'features' => cachestore_session::get_supported_features(), - 'modes' => cache_store::MODE_SESSION, - 'default' => true, - ), - 'default_request' => array( - 'name' => 'default_request', - 'plugin' => 'static', - 'configuration' => array(), - 'features' => cachestore_static::get_supported_features(), - 'modes' => cache_store::MODE_REQUEST, - 'default' => true, - ) - ); - $writer->configdefinitions = array(); - $writer->configmodemappings = array( - array( - 'mode' => cache_store::MODE_APPLICATION, - 'store' => 'default_application', - 'sort' => -1 - ), - array( - 'mode' => cache_store::MODE_SESSION, - 'store' => 'default_session', - 'sort' => -1 - ), - array( - 'mode' => cache_store::MODE_REQUEST, - 'store' => 'default_request', - 'sort' => -1 - ) - ); - $writer->configlocks = array( - 'default_file_lock' => array( - 'name' => 'cachelock_file_default', - 'type' => 'cachelock_file', - 'dir' => 'filelocks', - 'default' => true - ) - ); - - return $writer->generate_configuration_array(); - } - - /** - * Updates the definition in the configuration from those found in the cache files. - * - * @param bool $coreonly Unused. - */ - public static function update_definitions($coreonly = false) { - // Nothing to do here. - } - - /** - * Locates all of the definition files. - * - * @param bool $coreonly Unused. - * @return array - */ - protected static function locate_definitions($coreonly = false) { - return array(); - } - - /** - * Sets the mappings for a given definition. - * - * @param string $definition Unused. - * @param array $mappings Unused. - * @throws coding_exception - */ - public function set_definition_mappings($definition, $mappings) { - // Nothing to do here. - } -} diff --git a/cache/stores/apcu/addinstanceform.php b/cache/stores/apcu/addinstanceform.php index f9fc73e7e66..aa8081b8ccc 100644 --- a/cache/stores/apcu/addinstanceform.php +++ b/cache/stores/apcu/addinstanceform.php @@ -13,17 +13,7 @@ // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * The library file for the apcu cache store. - * - * This file is part of the apcu cache store, it contains the API for interacting with an instance of the store. - * - * @package cachestore_apcu - * @copyright 2014 Sam Hemelryk - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -defined('MOODLE_INTERNAL') || die(); -require_once($CFG->dirroot.'/cache/forms.php'); + /** * Form for adding a apcu instance. * diff --git a/cache/stores/file/addinstanceform.php b/cache/stores/file/addinstanceform.php index 4240d7f5952..5a2ac837f77 100644 --- a/cache/stores/file/addinstanceform.php +++ b/cache/stores/file/addinstanceform.php @@ -14,20 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * The library file for the file cache store. - * - * This file is part of the file cache store, it contains the API for interacting with an instance of the store. - * This is used as a default cache store within the Cache API. It should never be deleted. - * - * @package cachestore_file - * @category cache - * @copyright 2012 Sam Hemelryk - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require_once($CFG->dirroot.'/cache/forms.php'); - /** * Form for adding a file instance. * @@ -68,4 +54,4 @@ class cachestore_file_addinstance_form extends cachestore_addinstance_form { $form->setType('lockwait', PARAM_INT); $form->addHelpButton('lockwait', 'lockwait', 'cachestore_file'); } -} \ No newline at end of file +} diff --git a/cache/stores/redis/addinstanceform.php b/cache/stores/redis/addinstanceform.php index 770100c3765..6fa64c68a5f 100644 --- a/cache/stores/redis/addinstanceform.php +++ b/cache/stores/redis/addinstanceform.php @@ -14,18 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/** - * Redis Cache Store - Add instance form - * - * @package cachestore_redis - * @copyright 2013 Adam Durana - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->dirroot . '/cache/forms.php'); - /** * Form for adding instance of Redis Cache Store. * diff --git a/lib/db/legacyclasses.php b/lib/db/legacyclasses.php index 0cedfa86083..fa08e62d885 100644 --- a/lib/db/legacyclasses.php +++ b/lib/db/legacyclasses.php @@ -58,10 +58,15 @@ $legacyclasses = [ \cache_session::class => 'session_cache.php', \cache_cached_object::class => 'cached_object.php', \cache_config::class => 'config.php', + \cache_config_writer::class => 'config_writer.php', + \cache_config_disabled::class => 'disabled_config.php', + \cache_disabled::class => 'disabled_cache.php', + \config_writer::class => 'config_writer.php', \cache_data_source::class => 'data_source_interface.php', \cache_data_source_versionable::class => 'versionable_data_source_interface.php', \cache_exception::class => 'exception/cache_exception.php', \cache_factory::class => 'factory.php', + \cache_factory_disabled::class => 'disabled_factory.php', \cache_helper::class => 'helper.php', \cache_is_key_aware::class => 'key_aware_cache_interface.php', \cache_is_lockable::class => 'lockable_cache_interface.php', @@ -75,6 +80,11 @@ $legacyclasses = [ \cache_ttl_wrapper::class => 'ttl_wrapper.php', \cacheable_object::class => 'cacheable_object_interface.php', \cacheable_object_array::class => 'cacheable_object_array.php', + \cache_definition_mappings_form::class => 'form/cache_definition_mappings_form.php', + \cache_definition_sharing_form::class => 'form/cache_definition_sharing_form.php', + \cache_lock_form::class => 'form/cache_lock_form.php', + \cache_mode_mappings_form::class => 'form/cache_mode_mappings_form.php', + // Output API. \theme_config::class => 'output/theme_config.php',