MDL-40903 cache: coding style tidyup pre-integration
[moodle.git] / cache / classes / definition.php
CommitLineData
8139ad13
SH
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 * Cache definition class
19 *
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.
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
29defined('MOODLE_INTERNAL') || die();
30
31/**
32 * The cache definition class.
33 *
34 * Cache definitions need to be defined in db/caches.php files.
35 * They can be constructed with the following options.
36 *
37 * Required settings:
38 * + mode
39 * [int] Sets the mode for the definition. Must be one of cache_store::MODE_*
40 *
41 * Optional settings:
47834bcd
SH
42 * + simplekeys
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.
2e1e266c
SH
47 * + simpledata
48 * [bool] If set to true we know that the data is scalar or array of scalar.
8139ad13
SH
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 * + requirelockingread
56 * [bool] If set to true then a lock will be gained before reading from the cache store. It is recommended not to use
57 * this setting unless 100% absolutely positively required. Remember 99.9% of caches will NOT need this setting.
58 * This setting will only be used for application caches presently.
59 * + requirelockingwrite
60 * [bool] If set to true then a lock will be gained before writing to the cache store. As above this is not recommended
61 * unless truly needed. Please think about the order of your code and deal with race conditions there first.
62 * This setting will only be used for application caches presently.
63 * + maxsize
64 * [int] If set this will be used as the maximum number of entries within the cache store for this definition.
65 * Its important to note that cache stores don't actually have to acknowledge this setting or maintain it as a hard limit.
66 * + overrideclass
67 * [string] A class to use as the loader for this cache. This is an advanced setting and will allow the developer of the
68 * definition to take 100% control of the caching solution.
69 * Any class used here must inherit the cache_loader interface and must extend default cache loader for the mode they are
70 * using.
71 * + overrideclassfile
72 * [string] Suplements the above setting indicated the file containing the class to be used. This file is included when
73 * required.
74 * + datasource
75 * [string] A class to use as the data loader for this definition.
76 * Any class used here must inherit the cache_data_loader interface.
77 * + datasourcefile
78 * [string] Suplements the above setting indicated the file containing the class to be used. This file is included when
79 * required.
083fa877
SH
80 * + persistentdata
81 * The cache loader will keep an array of the items set and retrieved to the cache during the request.
82 * Consider using this setting when you know that there are going to be many calls to the cache for the same information.
83 * Requests for data in this array will be ultra fast, but it will cost memory.
8139ad13
SH
84 * + persistentmaxsize
85 * [int] This supplements the above setting by limiting the number of items in the caches persistent array of items.
86 * Tweaking this setting lower will allow you to minimise the memory implications above while hopefully still managing to
87 * offset calls to the cache store.
88 * + ttl
89 * [int] A time to live for the data (in seconds). It is strongly recommended that you don't make use of this and
90 * instead try to create an event driven invalidation system.
91 * Not all cache stores will support this natively and there are undesired performance impacts if the cache store does not.
92 * + mappingsonly
93 * [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
94 * advanced setting and should not be used unless absolutely required. It allows you to avoid the default stores for one
95 * reason or another.
96 * + invalidationevents
97 * [array] An array of events that should cause this cache to invalidate some or all of the items within it.
46e17f04
SH
98 * + sharingoptions
99 * [int] The sharing options that are appropriate for this definition. Should be the sum of the possible options.
5f5776c1
SH
100 * + defaultsharing
101 * [int] The default sharing option to use. It's highly recommended that you don't set this unless there is a very
102 * specific reason not to use the system default.
8139ad13
SH
103 *
104 * For examples take a look at lib/db/caches.php
105 *
106 * @package core
107 * @category cache
108 * @copyright 2012 Sam Hemelryk
109 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
110 */
111class cache_definition {
112
46e17f04
SH
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;
121
122 /**
123 * The default sharing options available.
124 * All + SiteID + Version + Input.
125 */
126 const SHARING_DEFAULTOPTIONS = 15;
127 /**
128 * The default sharing option that gets used if none have been selected.
129 * SiteID. It is the most restrictive.
130 */
131 const SHARING_DEFAULT = 2;
132
8139ad13
SH
133 /**
134 * The identifier for the definition
135 * @var string
136 */
137 protected $id;
138
139 /**
140 * The mode for the defintion. One of cache_store::MODE_*
141 * @var int
142 */
143 protected $mode;
144
145 /**
146 * The component this definition is associated with.
147 * @var string
148 */
149 protected $component;
150
151 /**
152 * The area this definition is associated with.
153 * @var string
154 */
155 protected $area;
156
47834bcd
SH
157 /**
158 * If set to true we know the keys are simple. a-zA-Z0-9_
159 * @var bool
160 */
161 protected $simplekeys = false;
162
2e1e266c
SH
163 /**
164 * Set to true if we know the data is scalar or array of scalar.
165 * @var bool
166 */
167 protected $simpledata = false;
168
8139ad13
SH
169 /**
170 * An array of identifiers that must be provided when the definition is used to create a cache.
171 * @var array
172 */
173 protected $requireidentifiers = array();
174
175 /**
176 * If set to true then only stores that guarantee data may be used with this definition.
177 * @var bool
178 */
179 protected $requiredataguarantee = false;
180
181 /**
182 * If set to true then only stores that support multple identifiers may be used with this definition.
183 * @var bool
184 */
185 protected $requiremultipleidentifiers = false;
186
187 /**
188 * If set to true then we know that this definition requires the locking functionality.
189 * This gets set during construction based upon the settings requirelockingread and requirelockingwrite.
190 * @var bool
191 */
192 protected $requirelocking = false;
193
194 /**
195 * Set to true if this definition requires read locking.
196 * @var bool
197 */
198 protected $requirelockingread = false;
199
200 /**
201 * Gets set to true if this definition requires write locking.
202 * @var bool
203 */
204 protected $requirelockingwrite = false;
205
dbd2ea4e
SH
206 /**
207 * Gets set to true if this definition requires searchable stores.
208 * @since 2.4.4
209 * @var bool
210 */
211 protected $requiresearchable = false;
212
8139ad13
SH
213 /**
214 * Sets the maximum number of items that can exist in the cache.
215 * 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.
216 * @var int
217 */
218 protected $maxsize = null;
219
220 /**
221 * The class to use as the cache loader for this definition.
222 * @var string
223 */
224 protected $overrideclass = null;
225
226 /**
227 * The file in which the override class exists. This will be included if required.
228 * @var string Absolute path
229 */
230 protected $overrideclassfile = null;
231
232 /**
233 * The data source class to use with this definition.
234 * @var string
235 */
236 protected $datasource = null;
237
238 /**
239 * The file in which the data source class exists. This will be included if required.
240 * @var string
241 */
242 protected $datasourcefile = null;
243
244 /**
245 * The data source class aggregate to use. This is a super advanced setting.
246 * @var string
247 */
248 protected $datasourceaggregate = null;
249
250 /**
083fa877 251 * Set to true if the cache should hold onto items passing through it to speed up subsequent requests.
8139ad13
SH
252 * @var bool
253 */
083fa877 254 protected $persistentdata = false;
8139ad13
SH
255
256 /**
257 * The persistent item array max size.
258 * @var int
259 */
260 protected $persistentmaxsize = false;
261
262 /**
263 * The TTL for data in this cache. Please don't use this, instead use event driven invalidation.
264 * @var int
265 */
266 protected $ttl = 0;
267
268 /**
269 * Set to true if this cache should only use mapped cache stores and not the default mode cache store.
270 * @var bool
271 */
272 protected $mappingsonly = false;
273
274 /**
275 * An array of events that should cause this cache to invalidate.
276 * @var array
277 */
278 protected $invalidationevents = array();
279
280 /**
281 * An array of identifiers provided to this cache when it was initialised.
282 * @var array
283 */
284 protected $identifiers = array();
285
286 /**
287 * Key prefix for use with single key cache stores
288 * @var string
289 */
290 protected $keyprefixsingle = null;
291
292 /**
293 * Key prefix to use with cache stores that support multi keys.
294 * @var array
295 */
296 protected $keyprefixmulti = null;
297
298 /**
299 * A hash identifier of this definition.
300 * @var string
301 */
302 protected $definitionhash = null;
303
46e17f04
SH
304 /**
305 * The selected sharing mode for this definition.
306 * @var int
307 */
308 protected $sharingoptions;
309
310 /**
311 * The selected sharing option.
312 * @var int One of self::SHARING_*
313 */
314 protected $selectedsharingoption = self::SHARING_DEFAULT;
315
316 /**
317 * The user input key to use if the SHARING_INPUT option has been selected.
318 * @var string Must be ALPHANUMEXT
319 */
320 protected $userinputsharingkey = '';
321
8139ad13
SH
322 /**
323 * Creates a cache definition given a definition from the cache configuration or from a caches.php file.
324 *
325 * @param string $id
326 * @param array $definition
327 * @param string $datasourceaggregate
328 * @return cache_definition
329 * @throws coding_exception
330 */
331 public static function load($id, array $definition, $datasourceaggregate = null) {
e0a568e2
SH
332 global $CFG;
333
8139ad13
SH
334 if (!array_key_exists('mode', $definition)) {
335 throw new coding_exception('You must provide a mode when creating a cache definition');
336 }
337 if (!array_key_exists('component', $definition)) {
758dbdf8 338 throw new coding_exception('You must provide a component when creating a cache definition');
8139ad13
SH
339 }
340 if (!array_key_exists('area', $definition)) {
758dbdf8 341 throw new coding_exception('You must provide an area when creating a cache definition');
8139ad13
SH
342 }
343 $mode = (int)$definition['mode'];
344 $component = (string)$definition['component'];
345 $area = (string)$definition['area'];
346
170f821b 347 // Set the defaults.
47834bcd 348 $simplekeys = false;
2e1e266c 349 $simpledata = false;
8139ad13
SH
350 $requireidentifiers = array();
351 $requiredataguarantee = false;
352 $requiremultipleidentifiers = false;
353 $requirelockingread = false;
354 $requirelockingwrite = false;
5cba0c4b 355 $requiresearchable = ($mode === cache_store::MODE_SESSION) ? true : false;
8139ad13
SH
356 $maxsize = null;
357 $overrideclass = null;
358 $overrideclassfile = null;
359 $datasource = null;
360 $datasourcefile = null;
083fa877 361 $persistentdata = false;
8139ad13
SH
362 $persistentmaxsize = false;
363 $ttl = 0;
364 $mappingsonly = false;
365 $invalidationevents = array();
46e17f04
SH
366 $sharingoptions = self::SHARING_DEFAULT;
367 $selectedsharingoption = self::SHARING_DEFAULT;
368 $userinputsharingkey = '';
8139ad13 369
47834bcd
SH
370 if (array_key_exists('simplekeys', $definition)) {
371 $simplekeys = (bool)$definition['simplekeys'];
372 }
2e1e266c
SH
373 if (array_key_exists('simpledata', $definition)) {
374 $simpledata = (bool)$definition['simpledata'];
375 }
8139ad13
SH
376 if (array_key_exists('requireidentifiers', $definition)) {
377 $requireidentifiers = (array)$definition['requireidentifiers'];
378 }
379 if (array_key_exists('requiredataguarantee', $definition)) {
380 $requiredataguarantee = (bool)$definition['requiredataguarantee'];
381 }
382 if (array_key_exists('requiremultipleidentifiers', $definition)) {
383 $requiremultipleidentifiers = (bool)$definition['requiremultipleidentifiers'];
384 }
385
386 if (array_key_exists('requirelockingread', $definition)) {
387 $requirelockingread = (bool)$definition['requirelockingread'];
388 }
389 if (array_key_exists('requirelockingwrite', $definition)) {
390 $requirelockingwrite = (bool)$definition['requirelockingwrite'];
391 }
392 $requirelocking = $requirelockingwrite || $requirelockingread;
393
dbd2ea4e
SH
394 if (array_key_exists('requiresearchable', $definition)) {
395 $requiresearchable = (bool)$definition['requiresearchable'];
396 }
397
8139ad13
SH
398 if (array_key_exists('maxsize', $definition)) {
399 $maxsize = (int)$definition['maxsize'];
400 }
401
402 if (array_key_exists('overrideclass', $definition)) {
403 $overrideclass = $definition['overrideclass'];
404 }
405 if (array_key_exists('overrideclassfile', $definition)) {
406 $overrideclassfile = $definition['overrideclassfile'];
407 }
408
409 if (array_key_exists('datasource', $definition)) {
410 $datasource = $definition['datasource'];
411 }
412 if (array_key_exists('datasourcefile', $definition)) {
413 $datasourcefile = $definition['datasourcefile'];
414 }
415
416 if (array_key_exists('persistent', $definition)) {
083fa877
SH
417 // Ahhh this is the legacy persistent option.
418 $persistentdata = (bool)$definition['persistent'];
419 }
420 if (array_key_exists('persistentdata', $definition)) {
421 $persistentdata = (bool)$definition['persistentdata'];
8139ad13
SH
422 }
423 if (array_key_exists('persistentmaxsize', $definition)) {
424 $persistentmaxsize = (int)$definition['persistentmaxsize'];
425 }
426 if (array_key_exists('ttl', $definition)) {
427 $ttl = (int)$definition['ttl'];
428 }
429 if (array_key_exists('mappingsonly', $definition)) {
430 $mappingsonly = (bool)$definition['mappingsonly'];
431 }
432 if (array_key_exists('invalidationevents', $definition)) {
433 $invalidationevents = (array)$definition['invalidationevents'];
434 }
46e17f04
SH
435 if (array_key_exists('sharingoptions', $definition)) {
436 $sharingoptions = (int)$definition['sharingoptions'];
437 }
438 if (array_key_exists('selectedsharingoption', $definition)) {
439 $selectedsharingoption = (int)$definition['selectedsharingoption'];
440 } else if (array_key_exists('defaultsharing', $definition)) {
441 $selectedsharingoption = (int)$definition['defaultsharing'];
442 } else if ($sharingoptions ^ $selectedsharingoption) {
443 if ($sharingoptions & self::SHARING_SITEID) {
444 $selectedsharingoption = self::SHARING_SITEID;
445 } else if ($sharingoptions & self::SHARING_VERSION) {
446 $selectedsharingoption = self::SHARING_VERSION;
447 } else {
448 $selectedsharingoption = self::SHARING_ALL;
449 }
450 }
451
452 if (array_key_exists('userinputsharingkey', $definition) && !empty($definition['userinputsharingkey'])) {
453 $userinputsharingkey = (string)$definition['userinputsharingkey'];
454 }
8139ad13
SH
455
456 if (!is_null($overrideclass)) {
457 if (!is_null($overrideclassfile)) {
e0a568e2
SH
458 if (strpos($overrideclassfile, $CFG->dirroot) !== 0) {
459 $overrideclassfile = $CFG->dirroot.'/'.$overrideclassfile;
460 }
461 if (strpos($overrideclassfile, '../') !== false) {
462 throw new coding_exception('No path craziness allowed within override class file path.');
463 }
8139ad13
SH
464 if (!file_exists($overrideclassfile)) {
465 throw new coding_exception('The override class file does not exist.');
466 }
467 require_once($overrideclassfile);
468 }
469 if (!class_exists($overrideclass)) {
470 throw new coding_exception('The override class does not exist.');
471 }
472
473 // Make sure that the provided class extends the default class for the mode.
474 if (get_parent_class($overrideclass) !== cache_helper::get_class_for_mode($mode)) {
475 throw new coding_exception('The override class does not immediately extend the relevant cache class.');
476 }
477 }
478
479 if (!is_null($datasource)) {
480 if (!is_null($datasourcefile)) {
e0a568e2
SH
481 if (strpos($datasourcefile, $CFG->dirroot) !== 0) {
482 $datasourcefile = $CFG->dirroot.'/'.$datasourcefile;
483 }
484 if (strpos($datasourcefile, '../') !== false) {
485 throw new coding_exception('No path craziness allowed within data source file path.');
486 }
8139ad13 487 if (!file_exists($datasourcefile)) {
e0a568e2 488 throw new coding_exception('The data source class file does not exist.');
8139ad13
SH
489 }
490 require_once($datasourcefile);
491 }
492 if (!class_exists($datasource)) {
e0a568e2 493 throw new coding_exception('The data source class does not exist.');
8139ad13
SH
494 }
495 if (!array_key_exists('cache_data_source', class_implements($datasource))) {
496 throw new coding_exception('Cache data source classes must implement the cache_data_source interface');
497 }
498 }
499
500 $cachedefinition = new cache_definition();
501 $cachedefinition->id = $id;
502 $cachedefinition->mode = $mode;
503 $cachedefinition->component = $component;
504 $cachedefinition->area = $area;
47834bcd 505 $cachedefinition->simplekeys = $simplekeys;
2e1e266c 506 $cachedefinition->simpledata = $simpledata;
8139ad13
SH
507 $cachedefinition->requireidentifiers = $requireidentifiers;
508 $cachedefinition->requiredataguarantee = $requiredataguarantee;
509 $cachedefinition->requiremultipleidentifiers = $requiremultipleidentifiers;
510 $cachedefinition->requirelocking = $requirelocking;
511 $cachedefinition->requirelockingread = $requirelockingread;
512 $cachedefinition->requirelockingwrite = $requirelockingwrite;
dbd2ea4e 513 $cachedefinition->requiresearchable = $requiresearchable;
8139ad13
SH
514 $cachedefinition->maxsize = $maxsize;
515 $cachedefinition->overrideclass = $overrideclass;
516 $cachedefinition->overrideclassfile = $overrideclassfile;
517 $cachedefinition->datasource = $datasource;
518 $cachedefinition->datasourcefile = $datasourcefile;
519 $cachedefinition->datasourceaggregate = $datasourceaggregate;
083fa877 520 $cachedefinition->persistentdata = $persistentdata;
8139ad13
SH
521 $cachedefinition->persistentmaxsize = $persistentmaxsize;
522 $cachedefinition->ttl = $ttl;
523 $cachedefinition->mappingsonly = $mappingsonly;
524 $cachedefinition->invalidationevents = $invalidationevents;
46e17f04
SH
525 $cachedefinition->sharingoptions = $sharingoptions;
526 $cachedefinition->selectedsharingoption = $selectedsharingoption;
527 $cachedefinition->userinputsharingkey = $userinputsharingkey;
8139ad13
SH
528
529 return $cachedefinition;
530 }
531
532 /**
533 * Creates an ah-hoc cache definition given the required params.
534 *
535 * Please note that when using an adhoc definition you cannot set any of the optional params.
536 * This is because we cannot guarantee consistent access and we don't want to mislead people into thinking that.
537 *
538 * @param int $mode One of cache_store::MODE_*
539 * @param string $component The component this definition relates to.
540 * @param string $area The area this definition relates to.
2566210c
SH
541 * @param array $options An array of options, available options are:
542 * - simplekeys : Set to true if the keys you will use are a-zA-Z0-9_
543 * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
544 * - overrideclass : The class to use as the loader.
083fa877
SH
545 * - persistentdata : If set to true the cache will hold onto data passing through it.
546 * - persistentmaxsize : Set it to an int to limit the size of the persistentdata cache.
8139ad13
SH
547 * @return cache_application|cache_session|cache_request
548 */
2566210c 549 public static function load_adhoc($mode, $component, $area, array $options = array()) {
8139ad13
SH
550 $id = 'adhoc/'.$component.'_'.$area;
551 $definition = array(
552 'mode' => $mode,
553 'component' => $component,
554 'area' => $area,
8139ad13 555 );
2566210c
SH
556 if (!empty($options['simplekeys'])) {
557 $definition['simplekeys'] = $options['simplekeys'];
558 }
559 if (!empty($options['simpledata'])) {
560 $definition['simpledata'] = $options['simpledata'];
561 }
562 if (!empty($options['persistent'])) {
083fa877
SH
563 // Ahhh this is the legacy persistent option.
564 $definition['persistentdata'] = (bool)$options['persistent'];
565 }
566 if (!empty($options['persistentdata'])) {
567 $definition['persistentdata'] = (bool)$options['persistentdata'];
568 }
569 if (!empty($options['persistentmaxsize'])) {
570 $definition['persistentmaxsize'] = (int)$options['persistentmaxsize'];
2566210c
SH
571 }
572 if (!empty($options['overrideclass'])) {
573 $definition['overrideclass'] = $options['overrideclass'];
8139ad13 574 }
46e17f04
SH
575 if (!empty($options['sharingoptions'])) {
576 $definition['sharingoptions'] = $options['sharingoptions'];
577 }
8139ad13
SH
578 return self::load($id, $definition, null);
579 }
580
581 /**
582 * Returns the cache loader class that should be used for this definition.
583 * @return string
584 */
585 public function get_cache_class() {
586 if (!is_null($this->overrideclass)) {
587 return $this->overrideclass;
588 }
589 return cache_helper::get_class_for_mode($this->mode);
590 }
591
592 /**
593 * Returns the id of this definition.
594 * @return string
595 */
596 public function get_id() {
597 return $this->id;
598 }
599
600 /**
601 * Returns the name for this definition
602 * @return string
603 */
604 public function get_name() {
605 $identifier = 'cachedef_'.clean_param($this->area, PARAM_STRINGID);
606 $component = $this->component;
607 if ($component === 'core') {
608 $component = 'cache';
609 }
610 return new lang_string($identifier, $component);
611 }
612
613 /**
614 * Returns the mode of this definition
615 * @return int One more cache_store::MODE_
616 */
617 public function get_mode() {
618 return $this->mode;
619 }
620
621 /**
622 * Returns the area this definition is associated with.
623 * @return string
624 */
625 public function get_area() {
626 return $this->area;
627 }
628
629 /**
630 * Returns the component this definition is associated with.
631 * @return string
632 */
633 public function get_component() {
634 return $this->component;
635 }
636
47834bcd 637 /**
702651c7
SH
638 * Returns true if this definition is using simple keys.
639 *
640 * Simple keys contain only a-zA-Z0-9_
641 *
47834bcd
SH
642 * @return bool
643 */
644 public function uses_simple_keys() {
645 return $this->simplekeys;
646 }
647
8139ad13
SH
648 /**
649 * Returns the identifiers that are being used for this definition.
650 * @return array
651 */
652 public function get_identifiers() {
653 return $this->identifiers;
654 }
655
656 /**
657 * Returns the ttl in seconds for this definition if there is one, or null if not.
658 * @return int|null
659 */
660 public function get_ttl() {
661 return $this->ttl;
662 }
663
664 /**
665 * Returns the maximum number of items allowed in this cache.
666 * @return int
667 */
668 public function get_maxsize() {
669 return $this->maxsize;
670 }
671
672 /**
673 * Returns true if this definition should only be used with mappings.
674 * @return bool
675 */
676 public function is_for_mappings_only() {
677 return $this->mappingsonly;
678 }
679
2e1e266c
SH
680 /**
681 * Returns true if the data is known to be scalar or array of scalar.
682 * @return bool
683 */
684 public function uses_simple_data() {
685 return $this->simpledata;
686 }
687
8139ad13
SH
688 /**
689 * Returns true if this definition requires a data guarantee from the cache stores being used.
690 * @return bool
691 */
692 public function require_data_guarantee() {
693 return $this->requiredataguarantee;
694 }
695
696 /**
697 * Returns true if this definition requires that the cache stores support multiple identifiers
698 * @return bool
699 */
700 public function require_multiple_identifiers() {
701 return $this->requiremultipleidentifiers;
702 }
703
704 /**
705 * Returns true if this definition requires locking functionality. Either read or write locking.
706 * @return bool
707 */
708 public function require_locking() {
709 return $this->requirelocking;
710 }
711
712 /**
713 * Returns true if this definition requires read locking.
714 * @return bool
715 */
716 public function require_locking_read() {
717 return $this->requirelockingread;
718 }
719
720 /**
721 * Returns true if this definition requires write locking.
722 * @return bool
723 */
724 public function require_locking_write() {
725 return $this->requirelockingwrite;
726 }
727
dbd2ea4e
SH
728 /**
729 * Returns true if this definition requires a searchable cache.
730 * @since 2.4.4
731 * @return bool
732 */
733 public function require_searchable() {
734 return $this->requiresearchable;
735 }
736
8139ad13
SH
737 /**
738 * Returns true if this definition has an associated data source.
739 * @return bool
740 */
741 public function has_data_source() {
742 return !is_null($this->datasource);
743 }
744
745 /**
746 * Returns an instance of the data source class used for this definition.
747 *
748 * @return cache_data_source
749 * @throws coding_exception
750 */
751 public function get_data_source() {
752 if (!$this->has_data_source()) {
758dbdf8 753 throw new coding_exception('This cache does not use a data source.');
8139ad13
SH
754 }
755 return forward_static_call(array($this->datasource, 'get_instance_for_cache'), $this);
756 }
757
758 /**
759 * Sets the identifiers for this definition, or updates them if they have already been set.
760 *
761 * @param array $identifiers
762 * @throws coding_exception
763 */
764 public function set_identifiers(array $identifiers = array()) {
765 foreach ($this->requireidentifiers as $identifier) {
f5c26383 766 if (!isset($identifiers[$identifier])) {
8139ad13
SH
767 throw new coding_exception('Identifier required for cache has not been provided: '.$identifier);
768 }
769 }
770 foreach ($identifiers as $name => $value) {
771 $this->identifiers[$name] = (string)$value;
772 }
773 // Reset the key prefix's they need updating now.
774 $this->keyprefixsingle = null;
775 $this->keyprefixmulti = null;
776 }
777
778 /**
779 * Returns the requirements of this definition as a binary flag.
780 * @return int
781 */
782 public function get_requirements_bin() {
783 $requires = 0;
784 if ($this->require_data_guarantee()) {
785 $requires += cache_store::SUPPORTS_DATA_GUARANTEE;
786 }
787 if ($this->require_multiple_identifiers()) {
788 $requires += cache_store::SUPPORTS_MULTIPLE_IDENTIFIERS;
789 }
dbd2ea4e
SH
790 if ($this->require_searchable()) {
791 $requires += cache_store::IS_SEARCHABLE;
792 }
8139ad13
SH
793 return $requires;
794 }
795
796 /**
797 * Returns true if this definitions cache should be made persistent.
083fa877
SH
798 *
799 * Please call data_should_be_persistent instead.
800 *
801 * @deprecated since 2.6
8139ad13
SH
802 * @return bool
803 */
804 public function should_be_persistent() {
8bc1d659 805 debugging('should_be_persistent has been deprecated please call data_should_be_persistent instead', DEBUG_DEVELOPER);
083fa877
SH
806 return $this->data_should_be_persistent();
807 }
808
809 /**
8bc1d659
SH
810 * Returns true if we should hold onto the data flowing through the cache.
811 *
812 * If set to true data flowing through the cache will be stored in a static variable
813 * to make subsequent requests for the data much faster.
814 *
083fa877
SH
815 * @return bool
816 */
817 public function data_should_be_persistent() {
818 if ($this->mode === cache_store::MODE_REQUEST) {
819 // Request caches should never use persistent data - it just doesn't make sense.
820 return false;
821 }
822 return $this->persistentdata || $this->mode === cache_store::MODE_SESSION;
8139ad13
SH
823 }
824
825 /**
826 * Returns the max size for the persistent item array in the cache.
827 * @return int
828 */
829 public function get_persistent_max_size() {
830 return $this->persistentmaxsize;
831 }
832
833 /**
834 * Generates a hash of this definition and returns it.
835 * @return string
836 */
837 public function generate_definition_hash() {
838 if ($this->definitionhash === null) {
839 $this->definitionhash = md5("{$this->mode} {$this->component} {$this->area}");
840 }
841 return $this->definitionhash;
842 }
843
844 /**
845 * Generates a single key prefix for this definition
846 *
847 * @return string
848 */
849 public function generate_single_key_prefix() {
850 if ($this->keyprefixsingle === null) {
e0d9b7c0 851 $this->keyprefixsingle = $this->mode.'/'.$this->component.'/'.$this->area;
7634410b 852 $this->keyprefixsingle .= '/'.$this->get_cache_identifier();
8139ad13
SH
853 $identifiers = $this->get_identifiers();
854 if ($identifiers) {
855 foreach ($identifiers as $key => $value) {
856 $this->keyprefixsingle .= '/'.$key.'='.$value;
857 }
858 }
859 $this->keyprefixsingle = md5($this->keyprefixsingle);
860 }
861 return $this->keyprefixsingle;
862 }
863
864 /**
865 * Generates a multi key prefix for this definition
866 *
867 * @return array
868 */
869 public function generate_multi_key_parts() {
870 if ($this->keyprefixmulti === null) {
871 $this->keyprefixmulti = array(
872 'mode' => $this->mode,
873 'component' => $this->component,
874 'area' => $this->area,
7634410b 875 'siteidentifier' => $this->get_cache_identifier()
8139ad13
SH
876 );
877 if (!empty($this->identifiers)) {
878 $identifiers = array();
879 foreach ($this->identifiers as $key => $value) {
1a4596e4 880 $identifiers[] = htmlentities($key, ENT_QUOTES, 'UTF-8').'='.htmlentities($value, ENT_QUOTES, 'UTF-8');
8139ad13
SH
881 }
882 $this->keyprefixmulti['identifiers'] = join('&', $identifiers);
883 }
884 }
885 return $this->keyprefixmulti;
886 }
887
888 /**
889 * Check if this definition should invalidate on the given event.
890 *
891 * @param string $event
892 * @return bool True if the definition should invalidate on the event. False otherwise.
893 */
894 public function invalidates_on_event($event) {
895 return (in_array($event, $this->invalidationevents));
896 }
897
898 /**
899 * Check if the definition has any invalidation events.
900 *
901 * @return bool True if it does, false otherwise
902 */
903 public function has_invalidation_events() {
904 return !empty($this->invalidationevents);
905 }
906
907 /**
908 * Returns all of the invalidation events for this definition.
909 *
910 * @return array
911 */
912 public function get_invalidation_events() {
913 return $this->invalidationevents;
914 }
7634410b
SH
915
916 /**
917 * Returns a cache identification string.
918 *
919 * @return string A string to be used as part of keys.
920 */
921 protected function get_cache_identifier() {
46e17f04
SH
922 $identifiers = array();
923 if ($this->selectedsharingoption & self::SHARING_ALL) {
924 // Nothing to do here.
925 } else {
926 if ($this->selectedsharingoption & self::SHARING_SITEID) {
927 $identifiers[] = cache_helper::get_site_identifier();
928 }
929 if ($this->selectedsharingoption & self::SHARING_VERSION) {
930 $identifiers[] = cache_helper::get_site_version();
931 }
932 if ($this->selectedsharingoption & self::SHARING_INPUT && !empty($this->userinputsharingkey)) {
933 $identifiers[] = $this->userinputsharingkey;
934 }
935 }
936 return join('/', $identifiers);
7634410b 937 }
045fe95c
SH
938
939 /**
940 * Returns true if this definition requires identifiers.
941 *
942 * @param bool
943 */
944 public function has_required_identifiers() {
945 return (count($this->requireidentifiers) > 0);
946 }
8bc1d659 947}