2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
18 * Cache definition class
20 * This file is part of Moodle's cache API, affectionately called MUC.
21 * It contains the components that are requried in order to use caching.
25 * @copyright 2012 Sam Hemelryk
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 defined('MOODLE_INTERNAL') ||
die();
32 * The cache definition class.
34 * Cache definitions need to be defined in db/caches.php files.
35 * They can be constructed with the following options.
39 * [int] Sets the mode for the definition. Must be one of cache_store::MODE_*
43 * [bool] Set to true if your cache will only use simple keys for its items.
44 * Simple keys consist of digits, underscores and the 26 chars of the english language. a-zA-Z0-9_
45 * If true the keys won't be hashed before being passed to the cache store for gets/sets/deletes. It will be
46 * better for performance and possible only becase we know the keys are safe.
48 * [bool] If set to true we know that the data is scalar or array of scalar.
49 * + requireidentifiers
50 * [array] An array of identifiers that must be provided to the cache when it is created.
51 * + requiredataguarantee
52 * [bool] If set to true then only stores that can guarantee data will remain available once set will be used.
53 * + requiremultipleidentifiers
54 * [bool] If set to true then only stores that support multiple identifiers will be used.
55 * + requirelockingbeforewrite
56 * [bool] If set to true then the system will throw an exception if you try to write to
57 * the cache without having a lock on the relevant keys.
59 * [int] If set this will be used as the maximum number of entries within the cache store for this definition.
60 * Its important to note that cache stores don't actually have to acknowledge this setting or maintain it as a hard limit.
62 * [string] A class to use as the loader for this cache. This is an advanced setting and will allow the developer of the
63 * definition to take 100% control of the caching solution.
64 * Any class used here must inherit the cache_loader interface and must extend default cache loader for the mode they are
67 * [string] Suplements the above setting indicated the file containing the class to be used. This file is included when
70 * [string] A class to use as the data loader for this definition.
71 * Any class used here must inherit the cache_data_loader interface.
73 * [string] Supplements the above setting indicating the file containing the class to be used. This file is included when
75 * + staticacceleration
76 * The cache loader will keep an array of the items set and retrieved to the cache during the request.
77 * Consider using this setting when you know that there are going to be many calls to the cache for the same information.
78 * Requests for data in this array will be ultra fast, but it will cost memory.
79 * + staticaccelerationsize
80 * [int] This supplements the above setting by limiting the number of items in the static acceleration array.
81 * Tweaking this setting lower will allow you to minimise the memory implications above while hopefully still managing to
82 * offset calls to the cache store.
84 * [int] A time to live for the data (in seconds). It is strongly recommended that you don't make use of this and
85 * instead try to create an event driven invalidation system.
86 * Not all cache stores will support this natively and there are undesired performance impacts if the cache store does not.
88 * [bool] If set to true only the mapped cache store(s) will be used and the default mode store will not. This is a super
89 * advanced setting and should not be used unless absolutely required. It allows you to avoid the default stores for one
91 * + invalidationevents
92 * [array] An array of events that should cause this cache to invalidate some or all of the items within it.
94 * [int] The sharing options that are appropriate for this definition. Should be the sum of the possible options.
96 * [int] The default sharing option to use. It's highly recommended that you don't set this unless there is a very
97 * specific reason not to use the system default.
99 * [bool] The cache is able to safely run with multiple copies on different webservers without any need for administrator
100 * intervention to ensure that data stays in sync across nodes. This is usually managed by a revision
101 * system as seen in modinfo cache or language cache. Requiring purge on upgrade is not sufficient as
102 * it requires administrator intervention on each node to make it work.
104 * For examples take a look at lib/db/caches.php
108 * @copyright 2012 Sam Hemelryk
109 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
111 class cache_definition
{
113 /** The cache can be shared with everyone */
114 const SHARING_ALL
= 1;
115 /** The cache can be shared with other sites using the same siteid. */
116 const SHARING_SITEID
= 2;
117 /** The cache can be shared with other sites of the same version. */
118 const SHARING_VERSION
= 4;
119 /** The cache can be shared with other sites using the same key */
120 const SHARING_INPUT
= 8;
123 * The default sharing options available.
124 * All + SiteID + Version + Input.
126 const SHARING_DEFAULTOPTIONS
= 15;
128 * The default sharing option that gets used if none have been selected.
129 * SiteID. It is the most restrictive.
131 const SHARING_DEFAULT
= 2;
134 * The identifier for the definition
140 * The mode for the defintion. One of cache_store::MODE_*
146 * The component this definition is associated with.
149 protected $component;
152 * The area this definition is associated with.
158 * If set to true we know the keys are simple. a-zA-Z0-9_
161 protected $simplekeys = false;
164 * Set to true if we know the data is scalar or array of scalar.
167 protected $simpledata = false;
170 * An array of identifiers that must be provided when the definition is used to create a cache.
173 protected $requireidentifiers = array();
176 * If set to true then only stores that guarantee data may be used with this definition.
179 protected $requiredataguarantee = false;
182 * If set to true then only stores that support multple identifiers may be used with this definition.
185 protected $requiremultipleidentifiers = false;
188 * If set to true then we know that this definition requires the locking functionality.
189 * This gets set during construction based upon the setting requirelockingbeforewrite.
192 protected $requirelocking = false;
195 * Gets set to true if this definition requires a lock to be acquired before a write is attempted.
198 protected $requirelockingbeforewrite = false;
201 * Gets set to true if this definition requires searchable stores.
202 * @since Moodle 2.4.4
205 protected $requiresearchable = false;
208 * Sets the maximum number of items that can exist in the cache.
209 * Please note this isn't a hard limit, and doesn't need to be enforced by the caches. They can choose to do so optionally.
212 protected $maxsize = null;
215 * The class to use as the cache loader for this definition.
218 protected $overrideclass = null;
221 * The file in which the override class exists. This will be included if required.
222 * @var string Absolute path
224 protected $overrideclassfile = null;
227 * The data source class to use with this definition.
230 protected $datasource = null;
233 * The file in which the data source class exists. This will be included if required.
236 protected $datasourcefile = null;
239 * Set to true if the cache should hold onto items passing through it to speed up subsequent requests.
242 protected $staticacceleration = false;
245 * The maximum number of items that static acceleration cache should hold onto.
248 protected $staticaccelerationsize = false;
251 * The TTL for data in this cache. Please don't use this, instead use event driven invalidation.
257 * Set to true if this cache should only use mapped cache stores and not the default mode cache store.
260 protected $mappingsonly = false;
263 * An array of events that should cause this cache to invalidate.
266 protected $invalidationevents = array();
269 * An array of identifiers provided to this cache when it was initialised.
272 protected $identifiers = null;
275 * Key prefix for use with single key cache stores
278 protected $keyprefixsingle = null;
281 * Key prefix to use with cache stores that support multi keys.
284 protected $keyprefixmulti = null;
287 * A hash identifier of this definition.
290 protected $definitionhash = null;
293 * The selected sharing mode for this definition.
296 protected $sharingoptions;
299 * Whether this cache supports local storages.
302 protected $canuselocalstore = false;
305 * The selected sharing option.
306 * @var int One of self::SHARING_*
308 protected $selectedsharingoption = self
::SHARING_DEFAULT
;
311 * The user input key to use if the SHARING_INPUT option has been selected.
312 * @var string Must be ALPHANUMEXT
314 protected $userinputsharingkey = '';
317 * Creates a cache definition given a definition from the cache configuration or from a caches.php file.
320 * @param array $definition
321 * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
322 * @return cache_definition
323 * @throws coding_exception
325 public static function load($id, array $definition, $unused = null) {
328 if (!array_key_exists('mode', $definition)) {
329 throw new coding_exception('You must provide a mode when creating a cache definition');
331 if (!array_key_exists('component', $definition)) {
332 throw new coding_exception('You must provide a component when creating a cache definition');
334 if (!array_key_exists('area', $definition)) {
335 throw new coding_exception('You must provide an area when creating a cache definition');
337 $mode = (int)$definition['mode'];
338 $component = (string)$definition['component'];
339 $area = (string)$definition['area'];
344 $requireidentifiers = array();
345 $requiredataguarantee = false;
346 $requiremultipleidentifiers = false;
347 $requirelockingbeforewrite = false;
348 $requiresearchable = ($mode === cache_store
::MODE_SESSION
) ?
true : false;
350 $overrideclass = null;
351 $overrideclassfile = null;
353 $datasourcefile = null;
354 $staticacceleration = false;
355 $staticaccelerationsize = false;
357 $mappingsonly = false;
358 $invalidationevents = array();
359 $sharingoptions = self
::SHARING_DEFAULT
;
360 $selectedsharingoption = self
::SHARING_DEFAULT
;
361 $userinputsharingkey = '';
362 $canuselocalstore = false;
364 if (array_key_exists('simplekeys', $definition)) {
365 $simplekeys = (bool)$definition['simplekeys'];
367 if (array_key_exists('simpledata', $definition)) {
368 $simpledata = (bool)$definition['simpledata'];
370 if (array_key_exists('requireidentifiers', $definition)) {
371 $requireidentifiers = (array)$definition['requireidentifiers'];
373 if (array_key_exists('requiredataguarantee', $definition)) {
374 $requiredataguarantee = (bool)$definition['requiredataguarantee'];
376 if (array_key_exists('requiremultipleidentifiers', $definition)) {
377 $requiremultipleidentifiers = (bool)$definition['requiremultipleidentifiers'];
380 if (array_key_exists('requirelockingread', $definition)) {
381 debugging('The cache option requirelockingread is deprecated and now has no effect.',
384 if (array_key_exists('requirelockingwrite', $definition)) {
385 debugging('The cache option requirelockingwrite is deprecated and now has no effect. ' .
386 "Consider removing the option, or using requirelockingbeforewrite for the $component:$area definition",
389 if (array_key_exists('requirelockingbeforewrite', $definition)) {
390 $requirelockingbeforewrite = (bool)$definition['requirelockingbeforewrite'];
392 // This generic $requirelocking variable is kept in code in case we ever add
393 // another locking option, most obviously requirelockingbeforeread.
394 $requirelocking = $requirelockingbeforewrite;
396 if (array_key_exists('requiresearchable', $definition)) {
397 $requiresearchable = (bool)$definition['requiresearchable'];
400 if (array_key_exists('maxsize', $definition)) {
401 $maxsize = (int)$definition['maxsize'];
404 if (array_key_exists('overrideclass', $definition)) {
405 $overrideclass = $definition['overrideclass'];
407 if (array_key_exists('overrideclassfile', $definition)) {
408 $overrideclassfile = $definition['overrideclassfile'];
411 if (array_key_exists('datasource', $definition)) {
412 $datasource = $definition['datasource'];
414 if (array_key_exists('datasourcefile', $definition)) {
415 $datasourcefile = $definition['datasourcefile'];
418 if (array_key_exists('persistent', $definition)) {
419 // Ahhh this is the legacy persistent option.
420 $staticacceleration = (bool)$definition['persistent'];
422 if (array_key_exists('staticacceleration', $definition)) {
423 $staticacceleration = (bool)$definition['staticacceleration'];
425 if (array_key_exists('persistentmaxsize', $definition)) {
426 // Ahhh this is the legacy persistentmaxsize option.
427 $staticaccelerationsize = (int)$definition['persistentmaxsize'];
429 if (array_key_exists('staticaccelerationsize', $definition)) {
430 $staticaccelerationsize = (int)$definition['staticaccelerationsize'];
432 if (array_key_exists('ttl', $definition)) {
433 $ttl = (int)$definition['ttl'];
435 if (array_key_exists('mappingsonly', $definition)) {
436 $mappingsonly = (bool)$definition['mappingsonly'];
438 if (array_key_exists('invalidationevents', $definition)) {
439 $invalidationevents = (array)$definition['invalidationevents'];
441 if (array_key_exists('sharingoptions', $definition)) {
442 $sharingoptions = (int)$definition['sharingoptions'];
444 if (array_key_exists('selectedsharingoption', $definition)) {
445 $selectedsharingoption = (int)$definition['selectedsharingoption'];
446 } else if (array_key_exists('defaultsharing', $definition)) {
447 $selectedsharingoption = (int)$definition['defaultsharing'];
448 } else if ($sharingoptions ^
$selectedsharingoption) {
449 if ($sharingoptions & self
::SHARING_SITEID
) {
450 $selectedsharingoption = self
::SHARING_SITEID
;
451 } else if ($sharingoptions & self
::SHARING_VERSION
) {
452 $selectedsharingoption = self
::SHARING_VERSION
;
454 $selectedsharingoption = self
::SHARING_ALL
;
457 if (array_key_exists('canuselocalstore', $definition)) {
458 $canuselocalstore = (bool)$definition['canuselocalstore'];
461 if (array_key_exists('userinputsharingkey', $definition) && !empty($definition['userinputsharingkey'])) {
462 $userinputsharingkey = (string)$definition['userinputsharingkey'];
465 if (!is_null($overrideclass)) {
466 if (!is_null($overrideclassfile)) {
467 if (strpos($overrideclassfile, $CFG->dirroot
) !== 0) {
468 $overrideclassfile = $CFG->dirroot
.'/'.$overrideclassfile;
470 if (strpos($overrideclassfile, '../') !== false) {
471 throw new coding_exception('No path craziness allowed within override class file path.');
473 if (!file_exists($overrideclassfile)) {
474 throw new coding_exception('The override class file does not exist.');
476 require_once($overrideclassfile);
478 if (!class_exists($overrideclass)) {
479 throw new coding_exception('The override class does not exist.');
482 // Make sure that the provided class extends the default class for the mode.
483 if (get_parent_class($overrideclass) !== cache_helper
::get_class_for_mode($mode)) {
484 throw new coding_exception('The override class does not immediately extend the relevant cache class.');
488 if (!is_null($datasource)) {
489 if (!is_null($datasourcefile)) {
490 if (strpos($datasourcefile, $CFG->dirroot
) !== 0) {
491 $datasourcefile = $CFG->dirroot
.'/'.$datasourcefile;
493 if (strpos($datasourcefile, '../') !== false) {
494 throw new coding_exception('No path craziness allowed within data source file path.');
496 if (!file_exists($datasourcefile)) {
497 throw new coding_exception('The data source class file does not exist.');
499 require_once($datasourcefile);
501 if (!class_exists($datasource)) {
502 throw new coding_exception('The data source class does not exist.');
504 if (!array_key_exists('cache_data_source', class_implements($datasource))) {
505 throw new coding_exception('Cache data source classes must implement the cache_data_source interface');
509 $cachedefinition = new cache_definition();
510 $cachedefinition->id
= $id;
511 $cachedefinition->mode
= $mode;
512 $cachedefinition->component
= $component;
513 $cachedefinition->area
= $area;
514 $cachedefinition->simplekeys
= $simplekeys;
515 $cachedefinition->simpledata
= $simpledata;
516 $cachedefinition->requireidentifiers
= $requireidentifiers;
517 $cachedefinition->requiredataguarantee
= $requiredataguarantee;
518 $cachedefinition->requiremultipleidentifiers
= $requiremultipleidentifiers;
519 $cachedefinition->requirelocking
= $requirelocking;
520 $cachedefinition->requirelockingbeforewrite
= $requirelockingbeforewrite;
521 $cachedefinition->requiresearchable
= $requiresearchable;
522 $cachedefinition->maxsize
= $maxsize;
523 $cachedefinition->overrideclass
= $overrideclass;
524 $cachedefinition->overrideclassfile
= $overrideclassfile;
525 $cachedefinition->datasource
= $datasource;
526 $cachedefinition->datasourcefile
= $datasourcefile;
527 $cachedefinition->staticacceleration
= $staticacceleration;
528 $cachedefinition->staticaccelerationsize
= $staticaccelerationsize;
529 $cachedefinition->ttl
= $ttl;
530 $cachedefinition->mappingsonly
= $mappingsonly;
531 $cachedefinition->invalidationevents
= $invalidationevents;
532 $cachedefinition->sharingoptions
= $sharingoptions;
533 $cachedefinition->selectedsharingoption
= $selectedsharingoption;
534 $cachedefinition->userinputsharingkey
= $userinputsharingkey;
535 $cachedefinition->canuselocalstore
= $canuselocalstore;
537 return $cachedefinition;
541 * Creates an ah-hoc cache definition given the required params.
543 * Please note that when using an adhoc definition you cannot set any of the optional params.
544 * This is because we cannot guarantee consistent access and we don't want to mislead people into thinking that.
546 * @param int $mode One of cache_store::MODE_*
547 * @param string $component The component this definition relates to.
548 * @param string $area The area this definition relates to.
549 * @param array $options An array of options, available options are:
550 * - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
551 * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
552 * - overrideclass : The class to use as the loader.
553 * - staticacceleration : If set to true the cache will hold onto data passing through it.
554 * - staticaccelerationsize : Set it to an int to limit the size of the staticacceleration cache.
555 * @return cache_application|cache_session|cache_request
557 public static function load_adhoc($mode, $component, $area, array $options = array()) {
558 $id = 'adhoc/'.$component.'_'.$area;
561 'component' => $component,
564 if (!empty($options['simplekeys'])) {
565 $definition['simplekeys'] = $options['simplekeys'];
567 if (!empty($options['simpledata'])) {
568 $definition['simpledata'] = $options['simpledata'];
570 if (!empty($options['persistent'])) {
571 // Ahhh this is the legacy persistent option.
572 $definition['staticacceleration'] = (bool)$options['persistent'];
574 if (!empty($options['staticacceleration'])) {
575 $definition['staticacceleration'] = (bool)$options['staticacceleration'];
577 if (!empty($options['staticaccelerationsize'])) {
578 $definition['staticaccelerationsize'] = (int)$options['staticaccelerationsize'];
580 if (!empty($options['overrideclass'])) {
581 $definition['overrideclass'] = $options['overrideclass'];
583 if (!empty($options['sharingoptions'])) {
584 $definition['sharingoptions'] = $options['sharingoptions'];
586 return self
::load($id, $definition, null);
590 * Returns the cache loader class that should be used for this definition.
593 public function get_cache_class() {
594 if (!is_null($this->overrideclass
)) {
595 return $this->overrideclass
;
597 return cache_helper
::get_class_for_mode($this->mode
);
601 * Returns the id of this definition.
604 public function get_id() {
609 * Returns the name for this definition
612 public function get_name() {
613 $identifier = 'cachedef_'.clean_param($this->area
, PARAM_STRINGID
);
614 $component = $this->component
;
615 if ($component === 'core') {
616 $component = 'cache';
618 return new lang_string($identifier, $component);
622 * Returns the mode of this definition
623 * @return int One more cache_store::MODE_
625 public function get_mode() {
630 * Returns the area this definition is associated with.
633 public function get_area() {
638 * Returns the component this definition is associated with.
641 public function get_component() {
642 return $this->component
;
646 * Returns true if this definition is using simple keys.
648 * Simple keys contain only a-zA-Z0-9_
652 public function uses_simple_keys() {
653 return $this->simplekeys
;
657 * Returns the identifiers that are being used for this definition.
660 public function get_identifiers() {
661 if (!isset($this->identifiers
)) {
664 return $this->identifiers
;
668 * Returns the ttl in seconds for this definition if there is one, or null if not.
671 public function get_ttl() {
676 * Returns the maximum number of items allowed in this cache.
679 public function get_maxsize() {
680 return $this->maxsize
;
684 * Returns true if this definition should only be used with mappings.
687 public function is_for_mappings_only() {
688 return $this->mappingsonly
;
692 * Returns true if the data is known to be scalar or array of scalar.
695 public function uses_simple_data() {
696 return $this->simpledata
;
700 * Returns true if this definition requires a data guarantee from the cache stores being used.
703 public function require_data_guarantee() {
704 return $this->requiredataguarantee
;
708 * Returns true if this definition requires that the cache stores support multiple identifiers
711 public function require_multiple_identifiers() {
712 return $this->requiremultipleidentifiers
;
716 * Returns true if this definition requires locking functionality. Either read or write locking.
719 public function require_locking() {
720 return $this->requirelocking
;
724 * Returns true if this definition requires a lock to be aquired before a write is attempted.
727 public function require_locking_before_write() {
728 return $this->requirelockingbeforewrite
;
732 * Returns true if this definition allows local storage to be used for caching.
733 * @since Moodle 3.1.0
736 public function can_use_localstore() {
737 return $this->canuselocalstore
;
741 * Returns true if this definition requires a searchable cache.
742 * @since Moodle 2.4.4
745 public function require_searchable() {
746 return $this->requiresearchable
;
750 * Returns true if this definition has an associated data source.
753 public function has_data_source() {
754 return !is_null($this->datasource
);
758 * Returns an instance of the data source class used for this definition.
760 * @return cache_data_source
761 * @throws coding_exception
763 public function get_data_source() {
764 if (!$this->has_data_source()) {
765 throw new coding_exception('This cache does not use a data source.');
767 return forward_static_call(array($this->datasource
, 'get_instance_for_cache'), $this);
771 * Sets the identifiers for this definition, or updates them if they have already been set.
773 * @param array $identifiers
774 * @return bool false if no identifiers where changed, true otherwise.
775 * @throws coding_exception
777 public function set_identifiers(array $identifiers = array()) {
778 if ($this->identifiers
!== null) {
779 throw new coding_exception("You can only set identifiers on initial definition creation." .
780 " Define a new cache to set different identifiers.");
782 if (!empty($identifiers) && !empty($this->invalidationevents
)) {
783 throw new coding_exception("You cannot use event invalidation and identifiers at the same time.");
786 foreach ($this->requireidentifiers
as $identifier) {
787 if (!isset($identifiers[$identifier])) {
788 throw new coding_exception('Identifier required for cache has not been provided: '.$identifier);
792 $this->identifiers
= array();
794 foreach ($identifiers as $name => $value) {
795 $this->identifiers
[$name] = (string)$value;
797 // Reset the key prefix's they need updating now.
798 $this->keyprefixsingle
= null;
799 $this->keyprefixmulti
= null;
805 * Returns the requirements of this definition as a binary flag.
808 public function get_requirements_bin() {
810 if ($this->require_data_guarantee()) {
811 $requires +
= cache_store
::SUPPORTS_DATA_GUARANTEE
;
813 if ($this->require_multiple_identifiers()) {
814 $requires +
= cache_store
::SUPPORTS_MULTIPLE_IDENTIFIERS
;
816 if ($this->require_searchable()) {
817 $requires +
= cache_store
::IS_SEARCHABLE
;
823 * Please call {@link cache_definition::use_static_acceleration()} instead.
825 * @see cache_definition::use_static_acceleration()
826 * @deprecated since 2.6
828 public function should_be_persistent() {
829 throw new coding_exception('cache_definition::should_be_persistent() can not be used anymore.' .
830 ' Please use cache_definition::use_static_acceleration() instead.');
834 * Returns true if we should hold onto the data flowing through the cache.
836 * If set to true data flowing through the cache will be stored in a static variable
837 * to make subsequent requests for the data much faster.
841 public function use_static_acceleration() {
842 if ($this->mode
=== cache_store
::MODE_REQUEST
) {
843 // Request caches should never use static acceleration - it just doesn't make sense.
846 return $this->staticacceleration
;
850 * Please call {@link cache_definition::get_static_acceleration_size()} instead.
852 * @see cache_definition::get_static_acceleration_size()
853 * @deprecated since 2.6
855 public function get_persistent_max_size() {
856 throw new coding_exception('cache_definition::get_persistent_max_size() can not be used anymore.' .
857 ' Please use cache_definition::get_static_acceleration_size() instead.');
861 * Returns the max size for the static acceleration array.
864 public function get_static_acceleration_size() {
865 return $this->staticaccelerationsize
;
869 * Generates a hash of this definition and returns it.
872 public function generate_definition_hash() {
873 if ($this->definitionhash
=== null) {
874 $this->definitionhash
= md5("{$this->mode} {$this->component} {$this->area}");
876 return $this->definitionhash
;
880 * Generates a single key prefix for this definition
884 public function generate_single_key_prefix() {
885 if ($this->keyprefixsingle
=== null) {
886 $this->keyprefixsingle
= $this->mode
.'/'.$this->component
.'/'.$this->area
;
887 $this->keyprefixsingle
.= '/'.$this->get_cache_identifier();
888 $identifiers = $this->get_identifiers();
890 foreach ($identifiers as $key => $value) {
891 $this->keyprefixsingle
.= '/'.$key.'='.$value;
894 $this->keyprefixsingle
= md5($this->keyprefixsingle
);
896 return $this->keyprefixsingle
;
900 * Generates a multi key prefix for this definition
904 public function generate_multi_key_parts() {
905 if ($this->keyprefixmulti
=== null) {
906 $this->keyprefixmulti
= array(
907 'mode' => $this->mode
,
908 'component' => $this->component
,
909 'area' => $this->area
,
910 'siteidentifier' => $this->get_cache_identifier()
912 if (isset($this->identifiers
) && !empty($this->identifiers
)) {
913 $identifiers = array();
914 foreach ($this->identifiers
as $key => $value) {
915 $identifiers[] = htmlentities($key, ENT_QUOTES
, 'UTF-8').'='.htmlentities($value, ENT_QUOTES
, 'UTF-8');
917 $this->keyprefixmulti
['identifiers'] = join('&', $identifiers);
920 return $this->keyprefixmulti
;
924 * Check if this definition should invalidate on the given event.
926 * @param string $event
927 * @return bool True if the definition should invalidate on the event. False otherwise.
929 public function invalidates_on_event($event) {
930 return (in_array($event, $this->invalidationevents
));
934 * Check if the definition has any invalidation events.
936 * @return bool True if it does, false otherwise
938 public function has_invalidation_events() {
939 return !empty($this->invalidationevents
);
943 * Returns all of the invalidation events for this definition.
947 public function get_invalidation_events() {
948 return $this->invalidationevents
;
952 * Returns a cache identification string.
954 * @return string A string to be used as part of keys.
956 protected function get_cache_identifier() {
957 $identifiers = array();
958 if ($this->selectedsharingoption
& self
::SHARING_ALL
) {
959 // Nothing to do here.
961 if ($this->selectedsharingoption
& self
::SHARING_SITEID
) {
962 $identifiers[] = cache_helper
::get_site_identifier();
964 if ($this->selectedsharingoption
& self
::SHARING_VERSION
) {
965 $identifiers[] = cache_helper
::get_site_version();
967 if ($this->selectedsharingoption
& self
::SHARING_INPUT
&& !empty($this->userinputsharingkey
)) {
968 $identifiers[] = $this->userinputsharingkey
;
971 return join('/', $identifiers);
975 * Returns true if this definition requires identifiers.
979 public function has_required_identifiers() {
980 return (count($this->requireidentifiers
) > 0);
984 * Returns the possible sharing options that can be used with this defintion.
988 public function get_sharing_options() {
989 return $this->sharingoptions
;
993 * Returns the user entered sharing key for this definition.
997 public function get_user_input_sharing_key() {
998 return $this->userinputsharingkey
;
1002 * Returns the user selected sharing option for this definition.
1006 public function get_selected_sharing_option() {
1007 return $this->selectedsharingoption
;