MDL-77086 badges: Improve debugging
[moodle.git] / cache / disabledlib.php
blob380a474804397b22ee93a589cbc382ab749d436d
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * This file contains classes that are used by the Cache API only when it is disabled.
20 * These classes are derivatives of other significant classes used by the Cache API customised specifically
21 * to only do what is absolutely necessary when initialising and using the Cache API when its been disabled.
23 * @package core
24 * @category cache
25 * @copyright 2012 Sam Hemelryk
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 defined('MOODLE_INTERNAL') || die();
31 /**
32 * Required as it is needed for cache_config_disabled which extends cache_config_writer.
34 require_once($CFG->dirroot.'/cache/locallib.php');
36 /**
37 * The cache loader class used when the Cache has been disabled.
39 * @copyright 2012 Sam Hemelryk
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 class cache_disabled extends cache {
44 /**
45 * Constructs the cache.
47 * @param cache_definition $definition
48 * @param cache_store $store
49 * @param null $loader Unused.
51 public function __construct(cache_definition $definition, cache_store $store, $loader = null) {
52 if ($loader instanceof cache_data_source) {
53 // Set the data source to allow data sources to work when caching is entirely disabled.
54 $this->set_data_source($loader);
57 // No other features are handled.
60 /**
61 * Gets a key from the cache.
63 * @param int|string $key
64 * @param int $requiredversion Minimum required version of the data or cache::VERSION_NONE
65 * @param int $strictness Unused.
66 * @param mixed &$actualversion If specified, will be set to the actual version number retrieved
67 * @return bool
69 protected function get_implementation($key, int $requiredversion, int $strictness, &$actualversion = null) {
70 $datasource = $this->get_datasource();
71 if ($datasource !== false) {
72 if ($requiredversion === cache::VERSION_NONE) {
73 return $datasource->load_for_cache($key);
74 } else {
75 if (!$datasource instanceof cache_data_source_versionable) {
76 throw new \coding_exception('Data source is not versionable');
78 $result = $datasource->load_for_cache_versioned($key, $requiredversion, $actualversion);
79 if ($result && $actualversion < $requiredversion) {
80 throw new \coding_exception('Data source returned outdated version');
82 return $result;
85 return false;
88 /**
89 * Gets many keys at once from the cache.
91 * @param array $keys
92 * @param int $strictness Unused.
93 * @return array
95 public function get_many(array $keys, $strictness = IGNORE_MISSING) {
96 if ($this->get_datasource() !== false) {
97 return $this->get_datasource()->load_many_for_cache($keys);
100 return array_combine($keys, array_fill(0, count($keys), false));
104 * Sets a key value pair in the cache.
106 * @param int|string $key Unused.
107 * @param int $version Unused.
108 * @param mixed $data Unused.
109 * @param bool $setparents Unused.
110 * @return bool
112 protected function set_implementation($key, int $version, $data, bool $setparents = true): bool {
113 return false;
117 * Sets many key value pairs in the cache at once.
119 * @param array $keyvaluearray Unused.
120 * @return int
122 public function set_many(array $keyvaluearray) {
123 return 0;
127 * Deletes an item from the cache.
129 * @param int|string $key Unused.
130 * @param bool $recurse Unused.
131 * @return bool
133 public function delete($key, $recurse = true) {
134 return false;
138 * Deletes many items at once from the cache.
140 * @param array $keys Unused.
141 * @param bool $recurse Unused.
142 * @return int
144 public function delete_many(array $keys, $recurse = true) {
145 return 0;
149 * Checks if the cache has the requested key.
151 * @param int|string $key Unused.
152 * @param bool $tryloadifpossible Unused.
153 * @return bool
155 public function has($key, $tryloadifpossible = false) {
156 $result = $this->get($key);
158 return $result !== false;
162 * Checks if the cache has all of the requested keys.
163 * @param array $keys Unused.
164 * @return bool
166 public function has_all(array $keys) {
167 if (!$this->get_datasource()) {
168 return false;
171 foreach ($keys as $key) {
172 if (!$this->has($key)) {
173 return false;
176 return true;
180 * Checks if the cache has any of the requested keys.
182 * @param array $keys Unused.
183 * @return bool
185 public function has_any(array $keys) {
186 foreach ($keys as $key) {
187 if ($this->has($key)) {
188 return true;
192 return false;
196 * Purges all items from the cache.
198 * @return bool
200 public function purge() {
201 return true;
205 * Pretend that we got a lock to avoid errors.
207 * @param string $key
208 * @return bool
210 public function acquire_lock(string $key) : bool {
211 return true;
215 * Pretend that we released a lock to avoid errors.
217 * @param string $key
218 * @return void
220 public function release_lock(string $key) : bool {
221 return true;
226 * The cache factory class used when the Cache has been disabled.
228 * @copyright 2012 Sam Hemelryk
229 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
231 class cache_factory_disabled extends cache_factory {
232 /** @var array Array of temporary caches in use. */
233 protected static $tempcaches = [];
236 * Returns an instance of the cache_factor method.
238 * @param bool $forcereload Unused.
239 * @return cache_factory
240 * @throws coding_exception
242 public static function instance($forcereload = false) {
243 throw new coding_exception('You must not call to this cache factory within your code.');
247 * Creates a definition instance or returns the existing one if it has already been created.
249 * @param string $component
250 * @param string $area
251 * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
252 * @return cache_definition
254 public function create_definition($component, $area, $unused = null) {
255 $definition = parent::create_definition($component, $area);
256 if ($definition->has_data_source()) {
257 return $definition;
260 return cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area);
264 * Common public method to create a cache instance given a definition.
266 * @param cache_definition $definition
267 * @return cache_application|cache_session|cache_store
268 * @throws coding_exception
270 public function create_cache(cache_definition $definition) {
271 $loader = null;
272 if ($definition->has_data_source()) {
273 $loader = $definition->get_data_source();
275 return new cache_disabled($definition, $this->create_dummy_store($definition), $loader);
279 * Creates a cache object given the parameters for a definition.
281 * @param string $component
282 * @param string $area
283 * @param array $identifiers
284 * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
285 * @return cache_application|cache_session|cache_request
287 public function create_cache_from_definition($component, $area, array $identifiers = array(), $unused = null) {
288 // Temporary in-memory caches are sometimes allowed when caching is disabled.
289 if (\core_cache\allow_temporary_caches::is_allowed() && !$identifiers) {
290 $key = $component . '/' . $area;
291 if (array_key_exists($key, self::$tempcaches)) {
292 $cache = self::$tempcaches[$key];
293 } else {
294 $definition = $this->create_definition($component, $area);
295 // The cachestore_static class returns true to all three 'SUPPORTS_' checks so it
296 // can be used with all definitions.
297 $cache = new cachestore_static('TEMP:' . $component . '/' . $area);
298 $cache->initialise($definition);
299 self::$tempcaches[$key] = $cache;
301 return $cache;
304 // Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php
305 // definitions as they use load_adhoc(). They are built as a new object on each call.
306 // We do not need to clone the definition because we know it's new.
307 $definition = $this->create_definition($component, $area);
308 $definition->set_identifiers($identifiers);
309 $cache = $this->create_cache($definition);
310 return $cache;
314 * Removes all temporary caches.
316 * Don't call this directly - used by {@see \core_cache\allow_temporary_caches}.
318 public static function clear_temporary_caches(): void {
319 self::$tempcaches = [];
323 * Creates an ad-hoc cache from the given param.
325 * @param int $mode
326 * @param string $component
327 * @param string $area
328 * @param array $identifiers
329 * @param array $options An array of options, available options are:
330 * - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
331 * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
332 * - staticacceleration : If set to true the cache will hold onto all data passing through it.
333 * - staticaccelerationsize : Sets the max size of the static acceleration array.
334 * @return cache_application|cache_session|cache_request
336 public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) {
337 // Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php
338 // definitions as they use load_adhoc(). They are built as a new object on each call.
339 // We do not need to clone the definition because we know it's new.
340 $definition = cache_definition::load_adhoc($mode, $component, $area, $options);
341 $definition->set_identifiers($identifiers);
342 $cache = $this->create_cache($definition);
343 return $cache;
347 * Creates a store instance given its name and configuration.
349 * @param string $name Unused.
350 * @param array $details Unused.
351 * @param cache_definition $definition
352 * @return boolean|cache_store
354 public function create_store_from_config($name, array $details, cache_definition $definition) {
355 return $this->create_dummy_store($definition);
359 * Creates a cache config instance with the ability to write if required.
361 * @param bool $writer Unused.
362 * @return cache_config_disabled|cache_config_writer
364 public function create_config_instance($writer = false) {
365 // We are always going to use the cache_config_disabled class for all regular request.
366 // However if the code has requested the writer then likely something is changing and
367 // we're going to need to interact with the config.php file.
368 // In this case we will still use the cache_config_writer.
369 $class = 'cache_config_disabled';
370 if ($writer) {
371 // If the writer was requested then something is changing.
372 $class = 'cache_config_writer';
374 if (!array_key_exists($class, $this->configs)) {
375 self::set_state(self::STATE_INITIALISING);
376 if ($class === 'cache_config_disabled') {
377 $configuration = $class::create_default_configuration();
378 $this->configs[$class] = new $class;
379 } else {
380 $configuration = false;
381 // If we need a writer, we should get the classname from the generic factory.
382 // This is so alternative classes can be used if a different writer is required.
383 $this->configs[$class] = parent::get_disabled_writer();
385 $this->configs[$class]->load($configuration);
387 self::set_state(self::STATE_READY);
389 // Return the instance.
390 return $this->configs[$class];
394 * Returns true if the cache API has been disabled.
396 * @return bool
398 public function is_disabled() {
399 return true;
404 * The cache config class used when the Cache has been disabled.
406 * @copyright 2012 Sam Hemelryk
407 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
409 class cache_config_disabled extends cache_config_writer {
412 * Returns an instance of the configuration writer.
414 * @return cache_config_disabled
416 public static function instance() {
417 $factory = cache_factory::instance();
418 return $factory->create_config_instance(true);
422 * Saves the current configuration.
424 protected function config_save() {
425 // Nothing to do here.
429 * Generates a configuration array suitable to be written to the config file.
431 * @return array
433 protected function generate_configuration_array() {
434 $configuration = array();
435 $configuration['stores'] = $this->configstores;
436 $configuration['modemappings'] = $this->configmodemappings;
437 $configuration['definitions'] = $this->configdefinitions;
438 $configuration['definitionmappings'] = $this->configdefinitionmappings;
439 $configuration['locks'] = $this->configlocks;
440 return $configuration;
444 * Adds a plugin instance.
446 * @param string $name Unused.
447 * @param string $plugin Unused.
448 * @param array $configuration Unused.
449 * @return bool
450 * @throws cache_exception
452 public function add_store_instance($name, $plugin, array $configuration = array()) {
453 return false;
457 * Sets the mode mappings.
459 * @param array $modemappings Unused.
460 * @return bool
461 * @throws cache_exception
463 public function set_mode_mappings(array $modemappings) {
464 return false;
468 * Edits a give plugin instance.
470 * @param string $name Unused.
471 * @param string $plugin Unused.
472 * @param array $configuration Unused.
473 * @return bool
474 * @throws cache_exception
476 public function edit_store_instance($name, $plugin, $configuration) {
477 return false;
481 * Deletes a store instance.
483 * @param string $name Unused.
484 * @return bool
485 * @throws cache_exception
487 public function delete_store_instance($name) {
488 return false;
492 * Creates the default configuration and saves it.
494 * @param bool $forcesave Ignored because we are disabled!
495 * @return array
497 public static function create_default_configuration($forcesave = false) {
498 global $CFG;
500 // HACK ALERT.
501 // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the
502 // default store plugins are protected from deletion.
503 require_once($CFG->dirroot.'/cache/stores/file/lib.php');
504 require_once($CFG->dirroot.'/cache/stores/session/lib.php');
505 require_once($CFG->dirroot.'/cache/stores/static/lib.php');
507 $writer = new self;
508 $writer->configstores = array(
509 'default_application' => array(
510 'name' => 'default_application',
511 'plugin' => 'file',
512 'configuration' => array(),
513 'features' => cachestore_file::get_supported_features(),
514 'modes' => cache_store::MODE_APPLICATION,
515 'default' => true,
517 'default_session' => array(
518 'name' => 'default_session',
519 'plugin' => 'session',
520 'configuration' => array(),
521 'features' => cachestore_session::get_supported_features(),
522 'modes' => cache_store::MODE_SESSION,
523 'default' => true,
525 'default_request' => array(
526 'name' => 'default_request',
527 'plugin' => 'static',
528 'configuration' => array(),
529 'features' => cachestore_static::get_supported_features(),
530 'modes' => cache_store::MODE_REQUEST,
531 'default' => true,
534 $writer->configdefinitions = array();
535 $writer->configmodemappings = array(
536 array(
537 'mode' => cache_store::MODE_APPLICATION,
538 'store' => 'default_application',
539 'sort' => -1
541 array(
542 'mode' => cache_store::MODE_SESSION,
543 'store' => 'default_session',
544 'sort' => -1
546 array(
547 'mode' => cache_store::MODE_REQUEST,
548 'store' => 'default_request',
549 'sort' => -1
552 $writer->configlocks = array(
553 'default_file_lock' => array(
554 'name' => 'cachelock_file_default',
555 'type' => 'cachelock_file',
556 'dir' => 'filelocks',
557 'default' => true
561 return $writer->generate_configuration_array();
565 * Updates the definition in the configuration from those found in the cache files.
567 * @param bool $coreonly Unused.
569 public static function update_definitions($coreonly = false) {
570 // Nothing to do here.
574 * Locates all of the definition files.
576 * @param bool $coreonly Unused.
577 * @return array
579 protected static function locate_definitions($coreonly = false) {
580 return array();
584 * Sets the mappings for a given definition.
586 * @param string $definition Unused.
587 * @param array $mappings Unused.
588 * @throws coding_exception
590 public function set_definition_mappings($definition, $mappings) {
591 // Nothing to do here.