Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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.
  13  //
  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/>.
  16  
  17  /**
  18   * This file contains classes that are used by the Cache API only when it is disabled.
  19   *
  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.
  22   *
  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
  27   */
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  /**
  32   * Required as it is needed for cache_config_disabled which extends cache_config_writer.
  33   */
  34  require_once($CFG->dirroot.'/cache/locallib.php');
  35  
  36  /**
  37   * The cache loader class used when the Cache has been disabled.
  38   *
  39   * @copyright  2012 Sam Hemelryk
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class cache_disabled extends cache {
  43  
  44      /**
  45       * Constructs the cache.
  46       *
  47       * @param cache_definition $definition
  48       * @param cache_store $store
  49       * @param null $loader Unused.
  50       */
  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);
  55          }
  56  
  57          // No other features are handled.
  58      }
  59  
  60      /**
  61       * Gets a key from the cache.
  62       *
  63       * @param int|string $key
  64       * @param int $strictness Unused.
  65       * @return bool
  66       */
  67      public function get($key, $strictness = IGNORE_MISSING) {
  68          if ($this->get_datasource() !== false) {
  69              return $this->get_datasource()->load_for_cache($key);
  70          }
  71  
  72          return false;
  73      }
  74  
  75      /**
  76       * Gets many keys at once from the cache.
  77       *
  78       * @param array $keys
  79       * @param int $strictness Unused.
  80       * @return array
  81       */
  82      public function get_many(array $keys, $strictness = IGNORE_MISSING) {
  83          if ($this->get_datasource() !== false) {
  84              return $this->get_datasource()->load_many_for_cache($keys);
  85          }
  86  
  87          return array_combine($keys, array_fill(0, count($keys), false));
  88      }
  89  
  90      /**
  91       * Sets a key value pair in the cache.
  92       *
  93       * @param int|string $key Unused.
  94       * @param mixed $data Unused.
  95       * @return bool
  96       */
  97      public function set($key, $data) {
  98          return false;
  99      }
 100  
 101      /**
 102       * Sets many key value pairs in the cache at once.
 103       *
 104       * @param array $keyvaluearray Unused.
 105       * @return int
 106       */
 107      public function set_many(array $keyvaluearray) {
 108          return 0;
 109      }
 110  
 111      /**
 112       * Deletes an item from the cache.
 113       *
 114       * @param int|string $key Unused.
 115       * @param bool $recurse Unused.
 116       * @return bool
 117       */
 118      public function delete($key, $recurse = true) {
 119          return false;
 120      }
 121  
 122      /**
 123       * Deletes many items at once from the cache.
 124       *
 125       * @param array $keys Unused.
 126       * @param bool $recurse Unused.
 127       * @return int
 128       */
 129      public function delete_many(array $keys, $recurse = true) {
 130          return 0;
 131      }
 132  
 133      /**
 134       * Checks if the cache has the requested key.
 135       *
 136       * @param int|string $key Unused.
 137       * @param bool $tryloadifpossible Unused.
 138       * @return bool
 139       */
 140      public function has($key, $tryloadifpossible = false) {
 141          $result = $this->get($key);
 142  
 143          return $result !== false;
 144      }
 145  
 146      /**
 147       * Checks if the cache has all of the requested keys.
 148       * @param array $keys Unused.
 149       * @return bool
 150       */
 151      public function has_all(array $keys) {
 152          if (!$this->get_datasource()) {
 153              return false;
 154          }
 155  
 156          foreach ($keys as $key) {
 157              if (!$this->has($key)) {
 158                  return false;
 159              }
 160          }
 161          return true;
 162      }
 163  
 164      /**
 165       * Checks if the cache has any of the requested keys.
 166       *
 167       * @param array $keys Unused.
 168       * @return bool
 169       */
 170      public function has_any(array $keys) {
 171          foreach ($keys as $key) {
 172              if ($this->has($key)) {
 173                  return true;
 174              }
 175          }
 176  
 177          return false;
 178      }
 179  
 180      /**
 181       * Purges all items from the cache.
 182       *
 183       * @return bool
 184       */
 185      public function purge() {
 186          return true;
 187      }
 188  }
 189  
 190  /**
 191   * The cache factory class used when the Cache has been disabled.
 192   *
 193   * @copyright  2012 Sam Hemelryk
 194   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 195   */
 196  class cache_factory_disabled extends cache_factory {
 197  
 198      /**
 199       * Returns an instance of the cache_factor method.
 200       *
 201       * @param bool $forcereload Unused.
 202       * @return cache_factory
 203       * @throws coding_exception
 204       */
 205      public static function instance($forcereload = false) {
 206          throw new coding_exception('You must not call to this cache factory within your code.');
 207      }
 208  
 209      /**
 210       * Creates a definition instance or returns the existing one if it has already been created.
 211       *
 212       * @param string $component
 213       * @param string $area
 214       * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
 215       * @return cache_definition
 216       */
 217      public function create_definition($component, $area, $unused = null) {
 218          $definition = parent::create_definition($component, $area);
 219          if ($definition->has_data_source()) {
 220              return $definition;
 221          }
 222  
 223          return cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area);
 224      }
 225  
 226      /**
 227       * Common public method to create a cache instance given a definition.
 228       *
 229       * @param cache_definition $definition
 230       * @return cache_application|cache_session|cache_store
 231       * @throws coding_exception
 232       */
 233      public function create_cache(cache_definition $definition) {
 234          $loader = null;
 235          if ($definition->has_data_source()) {
 236              $loader = $definition->get_data_source();
 237          }
 238          return new cache_disabled($definition, $this->create_dummy_store($definition), $loader);
 239      }
 240  
 241      /**
 242       * Creates a cache object given the parameters for a definition.
 243       *
 244       * @param string $component
 245       * @param string $area
 246       * @param array $identifiers
 247       * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
 248       * @return cache_application|cache_session|cache_request
 249       */
 250      public function create_cache_from_definition($component, $area, array $identifiers = array(), $unused = null) {
 251          // Regular cache definitions are cached inside create_definition().  This is not the case for disabledlib.php
 252          // definitions as they use load_adhoc().  They are built as a new object on each call.
 253          // We do not need to clone the definition because we know it's new.
 254          $definition = $this->create_definition($component, $area);
 255          $definition->set_identifiers($identifiers);
 256          $cache = $this->create_cache($definition);
 257          return $cache;
 258      }
 259  
 260      /**
 261       * Creates an ad-hoc cache from the given param.
 262       *
 263       * @param int $mode
 264       * @param string $component
 265       * @param string $area
 266       * @param array $identifiers
 267       * @param array $options An array of options, available options are:
 268       *   - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
 269       *   - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
 270       *   - staticacceleration : If set to true the cache will hold onto all data passing through it.
 271       *   - staticaccelerationsize : Sets the max size of the static acceleration array.
 272       * @return cache_application|cache_session|cache_request
 273       */
 274      public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) {
 275          // Regular cache definitions are cached inside create_definition().  This is not the case for disabledlib.php
 276          // definitions as they use load_adhoc().  They are built as a new object on each call.
 277          // We do not need to clone the definition because we know it's new.
 278          $definition = cache_definition::load_adhoc($mode, $component, $area, $options);
 279          $definition->set_identifiers($identifiers);
 280          $cache = $this->create_cache($definition);
 281          return $cache;
 282      }
 283  
 284      /**
 285       * Creates a store instance given its name and configuration.
 286       *
 287       * @param string $name Unused.
 288       * @param array $details Unused.
 289       * @param cache_definition $definition
 290       * @return boolean|cache_store
 291       */
 292      public function create_store_from_config($name, array $details, cache_definition $definition) {
 293          return $this->create_dummy_store($definition);
 294      }
 295  
 296      /**
 297       * Creates a cache config instance with the ability to write if required.
 298       *
 299       * @param bool $writer Unused.
 300       * @return cache_config_disabled|cache_config_writer
 301       */
 302      public function create_config_instance($writer = false) {
 303          // We are always going to use the cache_config_disabled class for all regular request.
 304          // However if the code has requested the writer then likely something is changing and
 305          // we're going to need to interact with the config.php file.
 306          // In this case we will still use the cache_config_writer.
 307          $class = 'cache_config_disabled';
 308          if ($writer) {
 309              // If the writer was requested then something is changing.
 310              $class = 'cache_config_writer';
 311          }
 312          if (!array_key_exists($class, $this->configs)) {
 313              self::set_state(self::STATE_INITIALISING);
 314              if ($class === 'cache_config_disabled') {
 315                  $configuration = $class::create_default_configuration();
 316                  $this->configs[$class] = new $class;
 317              } else {
 318                  $configuration = false;
 319                  // If we need a writer, we should get the classname from the generic factory.
 320                  // This is so alternative classes can be used if a different writer is required.
 321                  $this->configs[$class] = parent::get_disabled_writer();
 322              }
 323              $this->configs[$class]->load($configuration);
 324          }
 325          self::set_state(self::STATE_READY);
 326  
 327          // Return the instance.
 328          return $this->configs[$class];
 329      }
 330  
 331      /**
 332       * Returns true if the cache API has been disabled.
 333       *
 334       * @return bool
 335       */
 336      public function is_disabled() {
 337          return true;
 338      }
 339  }
 340  
 341  /**
 342   * The cache config class used when the Cache has been disabled.
 343   *
 344   * @copyright  2012 Sam Hemelryk
 345   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 346   */
 347  class cache_config_disabled extends cache_config_writer {
 348  
 349      /**
 350       * Returns an instance of the configuration writer.
 351       *
 352       * @return cache_config_disabled
 353       */
 354      public static function instance() {
 355          $factory = cache_factory::instance();
 356          return $factory->create_config_instance(true);
 357      }
 358  
 359      /**
 360       * Saves the current configuration.
 361       */
 362      protected function config_save() {
 363          // Nothing to do here.
 364      }
 365  
 366      /**
 367       * Generates a configuration array suitable to be written to the config file.
 368       *
 369       * @return array
 370       */
 371      protected function generate_configuration_array() {
 372          $configuration = array();
 373          $configuration['stores'] = $this->configstores;
 374          $configuration['modemappings'] = $this->configmodemappings;
 375          $configuration['definitions'] = $this->configdefinitions;
 376          $configuration['definitionmappings'] = $this->configdefinitionmappings;
 377          $configuration['locks'] = $this->configlocks;
 378          return $configuration;
 379      }
 380  
 381      /**
 382       * Adds a plugin instance.
 383       *
 384       * @param string $name Unused.
 385       * @param string $plugin Unused.
 386       * @param array $configuration Unused.
 387       * @return bool
 388       * @throws cache_exception
 389       */
 390      public function add_store_instance($name, $plugin, array $configuration = array()) {
 391          return false;
 392      }
 393  
 394      /**
 395       * Sets the mode mappings.
 396       *
 397       * @param array $modemappings Unused.
 398       * @return bool
 399       * @throws cache_exception
 400       */
 401      public function set_mode_mappings(array $modemappings) {
 402          return false;
 403      }
 404  
 405      /**
 406       * Edits a give plugin instance.
 407       *
 408       * @param string $name Unused.
 409       * @param string $plugin Unused.
 410       * @param array $configuration Unused.
 411       * @return bool
 412       * @throws cache_exception
 413       */
 414      public function edit_store_instance($name, $plugin, $configuration) {
 415          return false;
 416      }
 417  
 418      /**
 419       * Deletes a store instance.
 420       *
 421       * @param string $name Unused.
 422       * @return bool
 423       * @throws cache_exception
 424       */
 425      public function delete_store_instance($name) {
 426          return false;
 427      }
 428  
 429      /**
 430       * Creates the default configuration and saves it.
 431       *
 432       * @param bool $forcesave Ignored because we are disabled!
 433       * @return array
 434       */
 435      public static function create_default_configuration($forcesave = false) {
 436          global $CFG;
 437  
 438          // HACK ALERT.
 439          // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the
 440          // default store plugins are protected from deletion.
 441          require_once($CFG->dirroot.'/cache/stores/file/lib.php');
 442          require_once($CFG->dirroot.'/cache/stores/session/lib.php');
 443          require_once($CFG->dirroot.'/cache/stores/static/lib.php');
 444  
 445          $writer = new self;
 446          $writer->configstores = array(
 447              'default_application' => array(
 448                  'name' => 'default_application',
 449                  'plugin' => 'file',
 450                  'configuration' => array(),
 451                  'features' => cachestore_file::get_supported_features(),
 452                  'modes' => cache_store::MODE_APPLICATION,
 453                  'default' => true,
 454              ),
 455              'default_session' => array(
 456                  'name' => 'default_session',
 457                  'plugin' => 'session',
 458                  'configuration' => array(),
 459                  'features' => cachestore_session::get_supported_features(),
 460                  'modes' => cache_store::MODE_SESSION,
 461                  'default' => true,
 462              ),
 463              'default_request' => array(
 464                  'name' => 'default_request',
 465                  'plugin' => 'static',
 466                  'configuration' => array(),
 467                  'features' => cachestore_static::get_supported_features(),
 468                  'modes' => cache_store::MODE_REQUEST,
 469                  'default' => true,
 470              )
 471          );
 472          $writer->configdefinitions = array();
 473          $writer->configmodemappings = array(
 474              array(
 475                  'mode' => cache_store::MODE_APPLICATION,
 476                  'store' => 'default_application',
 477                  'sort' => -1
 478              ),
 479              array(
 480                  'mode' => cache_store::MODE_SESSION,
 481                  'store' => 'default_session',
 482                  'sort' => -1
 483              ),
 484              array(
 485                  'mode' => cache_store::MODE_REQUEST,
 486                  'store' => 'default_request',
 487                  'sort' => -1
 488              )
 489          );
 490          $writer->configlocks = array(
 491              'default_file_lock' => array(
 492                  'name' => 'cachelock_file_default',
 493                  'type' => 'cachelock_file',
 494                  'dir' => 'filelocks',
 495                  'default' => true
 496              )
 497          );
 498  
 499          return $writer->generate_configuration_array();
 500      }
 501  
 502      /**
 503       * Updates the definition in the configuration from those found in the cache files.
 504       *
 505       * @param bool $coreonly Unused.
 506       */
 507      public static function update_definitions($coreonly = false) {
 508          // Nothing to do here.
 509      }
 510  
 511      /**
 512       * Locates all of the definition files.
 513       *
 514       * @param bool $coreonly Unused.
 515       * @return array
 516       */
 517      protected static function locate_definitions($coreonly = false) {
 518          return array();
 519      }
 520  
 521      /**
 522       * Sets the mappings for a given definition.
 523       *
 524       * @param string $definition Unused.
 525       * @param array $mappings Unused.
 526       * @throws coding_exception
 527       */
 528      public function set_definition_mappings($definition, $mappings) {
 529          // Nothing to do here.
 530      }
 531  }