Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
/cache/ -> lib.php (source)
   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   * The core cache API.
  19   *
  20   * Pretty much just includes the mandatory classes and contains the misc classes that arn't worth separating into individual files.
  21   *
  22   * This file is part of Moodle's cache API, affectionately called MUC.
  23   * It contains the components that are requried in order to use caching.
  24   *
  25   * @package    core
  26   * @category   cache
  27   * @copyright  2012 Sam Hemelryk
  28   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  29   */
  30  
  31  defined('MOODLE_INTERNAL') || die();
  32  
  33  // Include the required classes.
  34  require_once($CFG->dirroot.'/cache/classes/interfaces.php');
  35  require_once($CFG->dirroot.'/cache/classes/config.php');
  36  require_once($CFG->dirroot.'/cache/classes/helper.php');
  37  require_once($CFG->dirroot.'/cache/classes/factory.php');
  38  require_once($CFG->dirroot.'/cache/classes/loaders.php');
  39  require_once($CFG->dirroot.'/cache/classes/store.php');
  40  require_once($CFG->dirroot.'/cache/classes/definition.php');
  41  
  42  /**
  43   * A cached object wrapper.
  44   *
  45   * This class gets used when the data is an object that has implemented the cacheable_object interface.
  46   *
  47   * @package    core
  48   * @category   cache
  49   * @copyright  2012 Sam Hemelryk
  50   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  51   */
  52  class cache_cached_object {
  53  
  54      /**
  55       * The class of the cacheable object
  56       * @var string
  57       */
  58      protected $class;
  59  
  60      /**
  61       * The data returned by the cacheable_object prepare_to_cache method.
  62       * @var mixed
  63       */
  64      protected $data;
  65  
  66      /**
  67       * Constructs a cached object wrapper.
  68       * @param cacheable_object $obj
  69       */
  70      public function __construct(cacheable_object $obj) {
  71          $this->class = get_class($obj);
  72          $this->data = $obj->prepare_to_cache();
  73      }
  74  
  75      /**
  76       * Restores the data as an instance of the cacheable_object class.
  77       * @return object
  78       */
  79      public function restore_object() {
  80          $class = $this->class;
  81          return $class::wake_from_cache($this->data);
  82      }
  83  }
  84  
  85  /**
  86   * A wrapper class used to handle ttl when the cache store doesn't natively support it.
  87   *
  88   * This class is exactly why you should use event driving invalidation of cache data rather than relying on ttl.
  89   *
  90   * @package    core
  91   * @category   cache
  92   * @copyright  2012 Sam Hemelryk
  93   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  94   */
  95  class cache_ttl_wrapper {
  96  
  97      /**
  98       * The data being stored.
  99       * @var mixed
 100       */
 101      public $data;
 102  
 103      /**
 104       * When the cache data expires as a timestamp.
 105       * @var int
 106       */
 107      public $expires;
 108  
 109      /**
 110       * Constructs a ttl cache wrapper.
 111       *
 112       * @param mixed $data
 113       * @param int $ttl The time to live in seconds.
 114       */
 115      public function __construct($data, $ttl) {
 116          $this->data = $data;
 117          $this->expires = cache::now() + (int)$ttl;
 118      }
 119  
 120      /**
 121       * Returns true if the data has expired.
 122       * @return int
 123       */
 124      public function has_expired() {
 125          return ($this->expires < cache::now());
 126      }
 127  }
 128  
 129  /**
 130   * A cache exception class. Just allows people to catch cache exceptions.
 131   *
 132   * @package    core
 133   * @category   cache
 134   * @copyright  2012 Sam Hemelryk
 135   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 136   */
 137  class cache_exception extends moodle_exception {
 138      /**
 139       * Constructs a new exception
 140       *
 141       * @param string $errorcode
 142       * @param string $module
 143       * @param string $link
 144       * @param mixed $a
 145       * @param mixed $debuginfo
 146       */
 147      public function __construct($errorcode, $module = 'cache', $link = '', $a = null, $debuginfo = null) {
 148          // This may appear like a useless override but you will notice that we have set a MUCH more useful default for $module.
 149          parent::__construct($errorcode, $module, $link, $a, $debuginfo);
 150      }
 151  }
 152  
 153  /**
 154   * An array of cacheable objects.
 155   *
 156   * This class allows a developer to create an array of cacheable objects and store that.
 157   * The cache API doesn't check items within an array to see whether they are cacheable. Such a check would be very costly to both
 158   * arrays using cacheable object and those that don't.
 159   * Instead the developer must explicitly use a cacheable_object_array instance.
 160   *
 161   * The following is one example of how this class can be used.
 162   * <code>
 163   * $data = array();
 164   * $data[] = new cacheable_object('one');
 165   * $data[] = new cacheable_object('two');
 166   * $data[] = new cacheable_object('three');
 167   * $cache->set(new cacheable_object_array($data));
 168   * </code>
 169   * Another example would be
 170   * <code>
 171   * $data = new cacheable_object_array();
 172   * $data[] = new cacheable_object('one');
 173   * $data[] = new cacheable_object('two');
 174   * $data[] = new cacheable_object('three');
 175   * $cache->set($data);
 176   * </code>
 177   *
 178   * @copyright  2012 Sam Hemelryk
 179   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 180   */
 181  class cacheable_object_array extends ArrayObject implements cacheable_object {
 182  
 183      /**
 184       * Constructs a new array object instance.
 185       * @param array $items
 186       */
 187      final public function __construct(array $items = array()) {
 188          parent::__construct($items, ArrayObject::STD_PROP_LIST);
 189      }
 190  
 191      /**
 192       * Returns the data to cache for this object.
 193       *
 194       * @return array An array of cache_cached_object instances.
 195       * @throws coding_exception
 196       */
 197      final public function prepare_to_cache() {
 198          $result = array();
 199          foreach ($this as $key => $value) {
 200              if ($value instanceof cacheable_object) {
 201                  $value = new cache_cached_object($value);
 202              } else {
 203                  throw new coding_exception('Only cacheable_object instances can be added to a cacheable_array');
 204              }
 205              $result[$key] = $value;
 206          }
 207          return $result;
 208      }
 209  
 210      /**
 211       * Returns the cacheable_object_array that was originally sent to the cache.
 212       *
 213       * @param array $data
 214       * @return cacheable_object_array
 215       * @throws coding_exception
 216       */
 217      final static public function wake_from_cache($data) {
 218          if (!is_array($data)) {
 219              throw new coding_exception('Invalid data type when reviving cacheable_array data');
 220          }
 221          $result = array();
 222          foreach ($data as $key => $value) {
 223              $result[$key] = $value->restore_object();
 224          }
 225          $class = __CLASS__;
 226          return new $class($result);
 227      }
 228  }