Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
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 29 defined('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: 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. 47 * + simpledata 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. 58 * + maxsize 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. 61 * + overrideclass 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 65 * using. 66 * + overrideclassfile 67 * [string] Suplements the above setting indicated the file containing the class to be used. This file is included when 68 * required. 69 * + datasource 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. 72 * + datasourcefile 73 * [string] Supplements the above setting indicating the file containing the class to be used. This file is included when 74 * required. 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. 83 * + ttl 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. 87 * + mappingsonly 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 90 * reason or another. 91 * + invalidationevents 92 * [array] An array of events that should cause this cache to invalidate some or all of the items within it. 93 * + sharingoptions 94 * [int] The sharing options that are appropriate for this definition. Should be the sum of the possible options. 95 * + defaultsharing 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. 98 * + canuselocalstore 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. 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 */ 111 class cache_definition { 112 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 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 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 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 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 setting requirelockingbeforewrite. 190 * @var bool 191 */ 192 protected $requirelocking = false; 193 194 /** 195 * Gets set to true if this definition requires a lock to be acquired before a write is attempted. 196 * @var bool 197 */ 198 protected $requirelockingbeforewrite = false; 199 200 /** 201 * Gets set to true if this definition requires searchable stores. 202 * @since Moodle 2.4.4 203 * @var bool 204 */ 205 protected $requiresearchable = false; 206 207 /** 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. 210 * @var int 211 */ 212 protected $maxsize = null; 213 214 /** 215 * The class to use as the cache loader for this definition. 216 * @var string 217 */ 218 protected $overrideclass = null; 219 220 /** 221 * The file in which the override class exists. This will be included if required. 222 * @var string Absolute path 223 */ 224 protected $overrideclassfile = null; 225 226 /** 227 * The data source class to use with this definition. 228 * @var string 229 */ 230 protected $datasource = null; 231 232 /** 233 * The file in which the data source class exists. This will be included if required. 234 * @var string 235 */ 236 protected $datasourcefile = null; 237 238 /** 239 * Set to true if the cache should hold onto items passing through it to speed up subsequent requests. 240 * @var bool 241 */ 242 protected $staticacceleration = false; 243 244 /** 245 * The maximum number of items that static acceleration cache should hold onto. 246 * @var int 247 */ 248 protected $staticaccelerationsize = false; 249 250 /** 251 * The TTL for data in this cache. Please don't use this, instead use event driven invalidation. 252 * @var int 253 */ 254 protected $ttl = 0; 255 256 /** 257 * Set to true if this cache should only use mapped cache stores and not the default mode cache store. 258 * @var bool 259 */ 260 protected $mappingsonly = false; 261 262 /** 263 * An array of events that should cause this cache to invalidate. 264 * @var array 265 */ 266 protected $invalidationevents = array(); 267 268 /** 269 * An array of identifiers provided to this cache when it was initialised. 270 * @var array 271 */ 272 protected $identifiers = null; 273 274 /** 275 * Key prefix for use with single key cache stores 276 * @var string 277 */ 278 protected $keyprefixsingle = null; 279 280 /** 281 * Key prefix to use with cache stores that support multi keys. 282 * @var array 283 */ 284 protected $keyprefixmulti = null; 285 286 /** 287 * A hash identifier of this definition. 288 * @var string 289 */ 290 protected $definitionhash = null; 291 292 /** 293 * The selected sharing mode for this definition. 294 * @var int 295 */ 296 protected $sharingoptions; 297 298 /** 299 * Whether this cache supports local storages. 300 * @var bool 301 */ 302 protected $canuselocalstore = false; 303 304 /** 305 * The selected sharing option. 306 * @var int One of self::SHARING_* 307 */ 308 protected $selectedsharingoption = self::SHARING_DEFAULT; 309 310 /** 311 * The user input key to use if the SHARING_INPUT option has been selected. 312 * @var string Must be ALPHANUMEXT 313 */ 314 protected $userinputsharingkey = ''; 315 316 /** 317 * Creates a cache definition given a definition from the cache configuration or from a caches.php file. 318 * 319 * @param string $id 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 324 */ 325 public static function load($id, array $definition, $unused = null) { 326 global $CFG; 327 328 if (!array_key_exists('mode', $definition)) { 329 throw new coding_exception('You must provide a mode when creating a cache definition'); 330 } 331 if (!array_key_exists('component', $definition)) { 332 throw new coding_exception('You must provide a component when creating a cache definition'); 333 } 334 if (!array_key_exists('area', $definition)) { 335 throw new coding_exception('You must provide an area when creating a cache definition'); 336 } 337 $mode = (int)$definition['mode']; 338 $component = (string)$definition['component']; 339 $area = (string)$definition['area']; 340 341 // Set the defaults. 342 $simplekeys = false; 343 $simpledata = false; 344 $requireidentifiers = array(); 345 $requiredataguarantee = false; 346 $requiremultipleidentifiers = false; 347 $requirelockingbeforewrite = false; 348 $requiresearchable = ($mode === cache_store::MODE_SESSION) ? true : false; 349 $maxsize = null; 350 $overrideclass = null; 351 $overrideclassfile = null; 352 $datasource = null; 353 $datasourcefile = null; 354 $staticacceleration = false; 355 $staticaccelerationsize = false; 356 $ttl = 0; 357 $mappingsonly = false; 358 $invalidationevents = array(); 359 $sharingoptions = self::SHARING_DEFAULT; 360 $selectedsharingoption = self::SHARING_DEFAULT; 361 $userinputsharingkey = ''; 362 $canuselocalstore = false; 363 364 if (array_key_exists('simplekeys', $definition)) { 365 $simplekeys = (bool)$definition['simplekeys']; 366 } 367 if (array_key_exists('simpledata', $definition)) { 368 $simpledata = (bool)$definition['simpledata']; 369 } 370 if (array_key_exists('requireidentifiers', $definition)) { 371 $requireidentifiers = (array)$definition['requireidentifiers']; 372 } 373 if (array_key_exists('requiredataguarantee', $definition)) { 374 $requiredataguarantee = (bool)$definition['requiredataguarantee']; 375 } 376 if (array_key_exists('requiremultipleidentifiers', $definition)) { 377 $requiremultipleidentifiers = (bool)$definition['requiremultipleidentifiers']; 378 } 379 380 if (array_key_exists('requirelockingread', $definition)) { 381 debugging('The cache option requirelockingread is deprecated and now has no effect.', 382 DEBUG_DEVELOPER); 383 } 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", 387 DEBUG_DEVELOPER); 388 } 389 if (array_key_exists('requirelockingbeforewrite', $definition)) { 390 $requirelockingbeforewrite = (bool)$definition['requirelockingbeforewrite']; 391 } 392 // This generic $requirelocking variable is kept in code in case we ever add 393 // another locking option, most obviously requirelockingbeforeread. 394 $requirelocking = $requirelockingbeforewrite; 395 396 if (array_key_exists('requiresearchable', $definition)) { 397 $requiresearchable = (bool)$definition['requiresearchable']; 398 } 399 400 if (array_key_exists('maxsize', $definition)) { 401 $maxsize = (int)$definition['maxsize']; 402 } 403 404 if (array_key_exists('overrideclass', $definition)) { 405 $overrideclass = $definition['overrideclass']; 406 } 407 if (array_key_exists('overrideclassfile', $definition)) { 408 $overrideclassfile = $definition['overrideclassfile']; 409 } 410 411 if (array_key_exists('datasource', $definition)) { 412 $datasource = $definition['datasource']; 413 } 414 if (array_key_exists('datasourcefile', $definition)) { 415 $datasourcefile = $definition['datasourcefile']; 416 } 417 418 if (array_key_exists('persistent', $definition)) { 419 // Ahhh this is the legacy persistent option. 420 $staticacceleration = (bool)$definition['persistent']; 421 } 422 if (array_key_exists('staticacceleration', $definition)) { 423 $staticacceleration = (bool)$definition['staticacceleration']; 424 } 425 if (array_key_exists('persistentmaxsize', $definition)) { 426 // Ahhh this is the legacy persistentmaxsize option. 427 $staticaccelerationsize = (int)$definition['persistentmaxsize']; 428 } 429 if (array_key_exists('staticaccelerationsize', $definition)) { 430 $staticaccelerationsize = (int)$definition['staticaccelerationsize']; 431 } 432 if (array_key_exists('ttl', $definition)) { 433 $ttl = (int)$definition['ttl']; 434 } 435 if (array_key_exists('mappingsonly', $definition)) { 436 $mappingsonly = (bool)$definition['mappingsonly']; 437 } 438 if (array_key_exists('invalidationevents', $definition)) { 439 $invalidationevents = (array)$definition['invalidationevents']; 440 } 441 if (array_key_exists('sharingoptions', $definition)) { 442 $sharingoptions = (int)$definition['sharingoptions']; 443 } 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; 453 } else { 454 $selectedsharingoption = self::SHARING_ALL; 455 } 456 } 457 if (array_key_exists('canuselocalstore', $definition)) { 458 $canuselocalstore = (bool)$definition['canuselocalstore']; 459 } 460 461 if (array_key_exists('userinputsharingkey', $definition) && !empty($definition['userinputsharingkey'])) { 462 $userinputsharingkey = (string)$definition['userinputsharingkey']; 463 } 464 465 if (!is_null($overrideclass)) { 466 if (!is_null($overrideclassfile)) { 467 if (strpos($overrideclassfile, $CFG->dirroot) !== 0) { 468 $overrideclassfile = $CFG->dirroot.'/'.$overrideclassfile; 469 } 470 if (strpos($overrideclassfile, '../') !== false) { 471 throw new coding_exception('No path craziness allowed within override class file path.'); 472 } 473 if (!file_exists($overrideclassfile)) { 474 throw new coding_exception('The override class file does not exist.'); 475 } 476 require_once($overrideclassfile); 477 } 478 if (!class_exists($overrideclass)) { 479 throw new coding_exception('The override class does not exist.'); 480 } 481 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.'); 485 } 486 } 487 488 if (!is_null($datasource)) { 489 if (!is_null($datasourcefile)) { 490 if (strpos($datasourcefile, $CFG->dirroot) !== 0) { 491 $datasourcefile = $CFG->dirroot.'/'.$datasourcefile; 492 } 493 if (strpos($datasourcefile, '../') !== false) { 494 throw new coding_exception('No path craziness allowed within data source file path.'); 495 } 496 if (!file_exists($datasourcefile)) { 497 throw new coding_exception('The data source class file does not exist.'); 498 } 499 require_once($datasourcefile); 500 } 501 if (!class_exists($datasource)) { 502 throw new coding_exception('The data source class does not exist.'); 503 } 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'); 506 } 507 } 508 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; 536 537 return $cachedefinition; 538 } 539 540 /** 541 * Creates an ah-hoc cache definition given the required params. 542 * 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. 545 * 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 556 */ 557 public static function load_adhoc($mode, $component, $area, array $options = array()) { 558 $id = 'adhoc/'.$component.'_'.$area; 559 $definition = array( 560 'mode' => $mode, 561 'component' => $component, 562 'area' => $area, 563 ); 564 if (!empty($options['simplekeys'])) { 565 $definition['simplekeys'] = $options['simplekeys']; 566 } 567 if (!empty($options['simpledata'])) { 568 $definition['simpledata'] = $options['simpledata']; 569 } 570 if (!empty($options['persistent'])) { 571 // Ahhh this is the legacy persistent option. 572 $definition['staticacceleration'] = (bool)$options['persistent']; 573 } 574 if (!empty($options['staticacceleration'])) { 575 $definition['staticacceleration'] = (bool)$options['staticacceleration']; 576 } 577 if (!empty($options['staticaccelerationsize'])) { 578 $definition['staticaccelerationsize'] = (int)$options['staticaccelerationsize']; 579 } 580 if (!empty($options['overrideclass'])) { 581 $definition['overrideclass'] = $options['overrideclass']; 582 } 583 if (!empty($options['sharingoptions'])) { 584 $definition['sharingoptions'] = $options['sharingoptions']; 585 } 586 return self::load($id, $definition, null); 587 } 588 589 /** 590 * Returns the cache loader class that should be used for this definition. 591 * @return string 592 */ 593 public function get_cache_class() { 594 if (!is_null($this->overrideclass)) { 595 return $this->overrideclass; 596 } 597 return cache_helper::get_class_for_mode($this->mode); 598 } 599 600 /** 601 * Returns the id of this definition. 602 * @return string 603 */ 604 public function get_id() { 605 return $this->id; 606 } 607 608 /** 609 * Returns the name for this definition 610 * @return string 611 */ 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'; 617 } 618 return new lang_string($identifier, $component); 619 } 620 621 /** 622 * Returns the mode of this definition 623 * @return int One more cache_store::MODE_ 624 */ 625 public function get_mode() { 626 return $this->mode; 627 } 628 629 /** 630 * Returns the area this definition is associated with. 631 * @return string 632 */ 633 public function get_area() { 634 return $this->area; 635 } 636 637 /** 638 * Returns the component this definition is associated with. 639 * @return string 640 */ 641 public function get_component() { 642 return $this->component; 643 } 644 645 /** 646 * Returns true if this definition is using simple keys. 647 * 648 * Simple keys contain only a-zA-Z0-9_ 649 * 650 * @return bool 651 */ 652 public function uses_simple_keys() { 653 return $this->simplekeys; 654 } 655 656 /** 657 * Returns the identifiers that are being used for this definition. 658 * @return array 659 */ 660 public function get_identifiers() { 661 if (!isset($this->identifiers)) { 662 return array(); 663 } 664 return $this->identifiers; 665 } 666 667 /** 668 * Returns the ttl in seconds for this definition if there is one, or null if not. 669 * @return int|null 670 */ 671 public function get_ttl() { 672 return $this->ttl; 673 } 674 675 /** 676 * Returns the maximum number of items allowed in this cache. 677 * @return int 678 */ 679 public function get_maxsize() { 680 return $this->maxsize; 681 } 682 683 /** 684 * Returns true if this definition should only be used with mappings. 685 * @return bool 686 */ 687 public function is_for_mappings_only() { 688 return $this->mappingsonly; 689 } 690 691 /** 692 * Returns true if the data is known to be scalar or array of scalar. 693 * @return bool 694 */ 695 public function uses_simple_data() { 696 return $this->simpledata; 697 } 698 699 /** 700 * Returns true if this definition requires a data guarantee from the cache stores being used. 701 * @return bool 702 */ 703 public function require_data_guarantee() { 704 return $this->requiredataguarantee; 705 } 706 707 /** 708 * Returns true if this definition requires that the cache stores support multiple identifiers 709 * @return bool 710 */ 711 public function require_multiple_identifiers() { 712 return $this->requiremultipleidentifiers; 713 } 714 715 /** 716 * Returns true if this definition requires locking functionality. Either read or write locking. 717 * @return bool 718 */ 719 public function require_locking() { 720 return $this->requirelocking; 721 } 722 723 /** 724 * Returns true if this definition requires a lock to be aquired before a write is attempted. 725 * @return bool 726 */ 727 public function require_locking_before_write() { 728 return $this->requirelockingbeforewrite; 729 } 730 731 /** 732 * Returns true if this definition allows local storage to be used for caching. 733 * @since Moodle 3.1.0 734 * @return bool 735 */ 736 public function can_use_localstore() { 737 return $this->canuselocalstore; 738 } 739 740 /** 741 * Returns true if this definition requires a searchable cache. 742 * @since Moodle 2.4.4 743 * @return bool 744 */ 745 public function require_searchable() { 746 return $this->requiresearchable; 747 } 748 749 /** 750 * Returns true if this definition has an associated data source. 751 * @return bool 752 */ 753 public function has_data_source() { 754 return !is_null($this->datasource); 755 } 756 757 /** 758 * Returns an instance of the data source class used for this definition. 759 * 760 * @return cache_data_source 761 * @throws coding_exception 762 */ 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.'); 766 } 767 return forward_static_call(array($this->datasource, 'get_instance_for_cache'), $this); 768 } 769 770 /** 771 * Sets the identifiers for this definition, or updates them if they have already been set. 772 * 773 * @param array $identifiers 774 * @return bool false if no identifiers where changed, true otherwise. 775 * @throws coding_exception 776 */ 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."); 781 } 782 if (!empty($identifiers) && !empty($this->invalidationevents)) { 783 throw new coding_exception("You cannot use event invalidation and identifiers at the same time."); 784 } 785 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); 789 } 790 } 791 792 $this->identifiers = array(); 793 794 foreach ($identifiers as $name => $value) { 795 $this->identifiers[$name] = (string)$value; 796 } 797 // Reset the key prefix's they need updating now. 798 $this->keyprefixsingle = null; 799 $this->keyprefixmulti = null; 800 801 return true; 802 } 803 804 /** 805 * Returns the requirements of this definition as a binary flag. 806 * @return int 807 */ 808 public function get_requirements_bin() { 809 $requires = 0; 810 if ($this->require_data_guarantee()) { 811 $requires += cache_store::SUPPORTS_DATA_GUARANTEE; 812 } 813 if ($this->require_multiple_identifiers()) { 814 $requires += cache_store::SUPPORTS_MULTIPLE_IDENTIFIERS; 815 } 816 if ($this->require_searchable()) { 817 $requires += cache_store::IS_SEARCHABLE; 818 } 819 return $requires; 820 } 821 822 /** 823 * Please call {@link cache_definition::use_static_acceleration()} instead. 824 * 825 * @see cache_definition::use_static_acceleration() 826 * @deprecated since 2.6 827 */ 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.'); 831 } 832 833 /** 834 * Returns true if we should hold onto the data flowing through the cache. 835 * 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. 838 * 839 * @return bool 840 */ 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. 844 return false; 845 } 846 return $this->staticacceleration; 847 } 848 849 /** 850 * Please call {@link cache_definition::get_static_acceleration_size()} instead. 851 * 852 * @see cache_definition::get_static_acceleration_size() 853 * @deprecated since 2.6 854 */ 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.'); 858 } 859 860 /** 861 * Returns the max size for the static acceleration array. 862 * @return int 863 */ 864 public function get_static_acceleration_size() { 865 return $this->staticaccelerationsize; 866 } 867 868 /** 869 * Generates a hash of this definition and returns it. 870 * @return string 871 */ 872 public function generate_definition_hash() { 873 if ($this->definitionhash === null) { 874 $this->definitionhash = md5("{$this->mode} {$this->component} {$this->area}"); 875 } 876 return $this->definitionhash; 877 } 878 879 /** 880 * Generates a single key prefix for this definition 881 * 882 * @return string 883 */ 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(); 889 if ($identifiers) { 890 foreach ($identifiers as $key => $value) { 891 $this->keyprefixsingle .= '/'.$key.'='.$value; 892 } 893 } 894 $this->keyprefixsingle = md5($this->keyprefixsingle); 895 } 896 return $this->keyprefixsingle; 897 } 898 899 /** 900 * Generates a multi key prefix for this definition 901 * 902 * @return array 903 */ 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() 911 ); 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'); 916 } 917 $this->keyprefixmulti['identifiers'] = join('&', $identifiers); 918 } 919 } 920 return $this->keyprefixmulti; 921 } 922 923 /** 924 * Check if this definition should invalidate on the given event. 925 * 926 * @param string $event 927 * @return bool True if the definition should invalidate on the event. False otherwise. 928 */ 929 public function invalidates_on_event($event) { 930 return (in_array($event, $this->invalidationevents)); 931 } 932 933 /** 934 * Check if the definition has any invalidation events. 935 * 936 * @return bool True if it does, false otherwise 937 */ 938 public function has_invalidation_events() { 939 return !empty($this->invalidationevents); 940 } 941 942 /** 943 * Returns all of the invalidation events for this definition. 944 * 945 * @return array 946 */ 947 public function get_invalidation_events() { 948 return $this->invalidationevents; 949 } 950 951 /** 952 * Returns a cache identification string. 953 * 954 * @return string A string to be used as part of keys. 955 */ 956 protected function get_cache_identifier() { 957 $identifiers = array(); 958 if ($this->selectedsharingoption & self::SHARING_ALL) { 959 // Nothing to do here. 960 } else { 961 if ($this->selectedsharingoption & self::SHARING_SITEID) { 962 $identifiers[] = cache_helper::get_site_identifier(); 963 } 964 if ($this->selectedsharingoption & self::SHARING_VERSION) { 965 $identifiers[] = cache_helper::get_site_version(); 966 } 967 if ($this->selectedsharingoption & self::SHARING_INPUT && !empty($this->userinputsharingkey)) { 968 $identifiers[] = $this->userinputsharingkey; 969 } 970 } 971 return join('/', $identifiers); 972 } 973 974 /** 975 * Returns true if this definition requires identifiers. 976 * 977 * @param bool 978 */ 979 public function has_required_identifiers() { 980 return (count($this->requireidentifiers) > 0); 981 } 982 983 /** 984 * Returns the possible sharing options that can be used with this defintion. 985 * 986 * @return int 987 */ 988 public function get_sharing_options() { 989 return $this->sharingoptions; 990 } 991 992 /** 993 * Returns the user entered sharing key for this definition. 994 * 995 * @return string 996 */ 997 public function get_user_input_sharing_key() { 998 return $this->userinputsharingkey; 999 } 1000 1001 /** 1002 * Returns the user selected sharing option for this definition. 1003 * 1004 * @return int 1005 */ 1006 public function get_selected_sharing_option() { 1007 return $this->selectedsharingoption; 1008 } 1009 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body