Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'wip-MDL-25290-m24-compact' of git://github.com/samhemel…

…ryk/moodle
  • Loading branch information...
commit 990853afbe5668b71e7c8b1f310a78920ea361e7 2 parents 2105f57 + 267ebe0
Eloy Lafuente (stronk7) stronk7 authored

Showing 59 changed files with 11,981 additions and 0 deletions. Show diff stats Hide diff stats

  1. +16 0 admin/settings/plugins.php
  2. +1 0  admin/settings/server.php
  3. +207 0 cache/README.md
  4. +201 0 cache/admin.php
  5. +472 0 cache/classes/config.php
  6. +715 0 cache/classes/definition.php
  7. +277 0 cache/classes/dummystore.php
  8. +340 0 cache/classes/factory.php
  9. +456 0 cache/classes/helper.php
  10. +692 0 cache/classes/interfaces.php
  11. +1,454 0 cache/classes/loaders.php
  12. +211 0 cache/forms.php
  13. +150 0 cache/lib.php
  14. +942 0 cache/locallib.php
  15. +26 0 cache/locks/file/lang/en/cachelock_file.php
  16. +237 0 cache/locks/file/lib.php
  17. +339 0 cache/renderer.php
  18. +59 0 cache/stores/file/addinstanceform.php
  19. +37 0 cache/stores/file/lang/en/cachestore_file.php
  20. +570 0 cache/stores/file/lib.php
  21. +32 0 cache/stores/file/version.php
  22. +50 0 cache/stores/memcache/addinstanceform.php
  23. +43 0 cache/stores/memcache/lang/en/cachestore_memcache.php
  24. +376 0 cache/stores/memcache/lib.php
  25. +33 0 cache/stores/memcache/settings.php
  26. +31 0 cache/stores/memcache/version.php
  27. +77 0 cache/stores/memcached/addinstanceform.php
  28. +67 0 cache/stores/memcached/lang/en/cachestore_memcached.php
  29. +460 0 cache/stores/memcached/lib.php
  30. +33 0 cache/stores/memcached/settings.php
  31. +31 0 cache/stores/memcached/version.php
  32. +97 0 cache/stores/mongodb/addinstanceform.php
  33. +43 0 cache/stores/mongodb/lang/en/cachestore_mongodb.php
  34. +484 0 cache/stores/mongodb/lib.php
  35. +33 0 cache/stores/mongodb/settings.php
  36. +29 0 cache/stores/mongodb/version.php
  37. +31 0 cache/stores/session/lang/en/cachestore_session.php
  38. +429 0 cache/stores/session/lib.php
  39. +32 0 cache/stores/session/version.php
  40. +31 0 cache/stores/static/lang/en/cachestore_static.php
  41. +425 0 cache/stores/static/lib.php
  42. +32 0 cache/stores/static/version.php
  43. +202 0 cache/testperformance.php
  44. +619 0 cache/tests/cache_test.php
  45. +148 0 cache/tests/fixtures/lib.php
  46. +425 0 cache/tests/locallib_test.php
  47. +11 0 config-dist.php
  48. +10 0 lang/en/admin.php
  49. +119 0 lang/en/cache.php
  50. +4 0 lang/en/plugin.php
  51. +58 0 lib/db/caches.php
  52. +40 0 lib/moodlelib.php
  53. +6 0 lib/phpunit/classes/util.php
  54. +8 0 lib/pluginlib.php
  55. +3 0  lib/sessionlib.php
  56. +9 0 lib/setup.php
  57. +3 0  phpunit.xml.dist
  58. +9 0 theme/base/style/admin.css
  59. +6 0 theme/base/style/core.css
16 admin/settings/plugins.php
@@ -492,6 +492,22 @@
492 492 }
493 493 }
494 494
  495 +// Now add the Cache plugins
  496 +if ($hassiteconfig) {
  497 + $ADMIN->add('modules', new admin_category('cache', new lang_string('caching', 'cache')));
  498 + $ADMIN->add('cache', new admin_externalpage('cacheconfig', new lang_string('cacheconfig', 'cache'), $CFG->wwwroot .'/cache/admin.php'));
  499 + $ADMIN->add('cache', new admin_externalpage('cachetestperformance', new lang_string('testperformance', 'cache'), $CFG->wwwroot . '/cache/testperformance.php'));
  500 + $ADMIN->add('cache', new admin_category('cachestores', new lang_string('cachestores', 'cache')));
  501 + foreach (get_plugin_list('cachestore') as $plugin => $path) {
  502 + $settingspath = $path.'/settings.php';
  503 + if (file_exists($settingspath)) {
  504 + $settings = new admin_settingpage('cachestore_'.$plugin.'_settings', new lang_string('pluginname', 'cachestore_'.$plugin), 'moodle/site:config');
  505 + include($settingspath);
  506 + $ADMIN->add('cachestores', $settings);
  507 + }
  508 + }
  509 +}
  510 +
495 511 /// Add all local plugins - must be always last!
496 512 if ($hassiteconfig) {
497 513 $ADMIN->add('modules', new admin_category('localplugins', new lang_string('localplugins')));
1  admin/settings/server.php
@@ -216,6 +216,7 @@
216 216 array( '0' => new lang_string('no'),
217 217 '1' => new lang_string('yes'))));
218 218 */
  219 +
219 220 $ADMIN->add('server', $temp);
220 221
221 222
207 cache/README.md
Source Rendered
... ... @@ -0,0 +1,207 @@
  1 +MUC development code
  2 +====================
  3 +
  4 +Congratulations you've found the MUC development code.
  5 +This code is still very much in development and as such is not (and is know to not) function correctly or completely at the moment.
  6 +Of course that will all be well and truly sorted out WELL before this gets integrated.
  7 +
  8 +Sample code snippets
  9 +--------------------
  10 +
  11 +A definition:
  12 +
  13 + $definitions = array(
  14 + 'core_string' => array( // Required, unique
  15 + 'mode' => cache_store::MODE_APPLICATION, // Required
  16 + 'component' => 'core', // Required
  17 + 'area' => 'string', // Required
  18 + 'requireidentifiers' => array( // Optional
  19 + 'lang',
  20 + 'component'
  21 + ),
  22 + 'requiredataguarantee' => false, // Optional
  23 + 'requiremultipleidentifiers' => false, // Optional
  24 + 'overrideclass' => null, // Optional
  25 + 'overrideclassfile' => null, // Optional
  26 + 'datasource' => null, // Optional
  27 + 'datasourcefile' => null, // Optional
  28 + 'persistent' => false, // Optional
  29 + 'ttl' => 0, // Optional
  30 + 'mappingsonly' => false // Optional
  31 + 'invalidationevents' => array( // Optional
  32 + 'contextmarkeddirty'
  33 + ),
  34 + )
  35 + );
  36 +
  37 +Getting a something from a cache using the definition:
  38 +
  39 + $cache = cache::make('core', 'string');
  40 + if (!$component = $cache->get('component')) {
  41 + // get returns false if its not there and can't be loaded.
  42 + $component = generate_data();
  43 + $cache->set($component);
  44 + }
  45 +
  46 +The same thing but from using params:
  47 +
  48 + $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'core', 'string');
  49 + if (!$component = $cache->get('component')) {
  50 + // get returns false if its not there and can't be loaded.
  51 + $component = generate_data();
  52 + $cache->set($component);
  53 + }
  54 +
  55 +If a data source had been specified in the definition the following would be all that was needed.
  56 +
  57 + $cache = cache::make('core', 'string');
  58 + $component = $cache->get('component');
  59 +
  60 +The bits that make up the cache API
  61 +-----------------------------------
  62 +
  63 +There are several parts that _**will**_ make up this solution:
  64 +
  65 +### Loader
  66 +The loader is central to the whole thing.
  67 +It is used by the end developer to get an object that handles caching.
  68 +90% of end developers will not need to know or use anything else about the cache API.
  69 +In order to get a loader you must use one of two static methods, make, or make_with_params.
  70 +To the end developer interacting with the loader is simple and is dictated by the cache_loader interface.
  71 +Internally there is lots of magic going on. The important parts to know about are:
  72 +* There are two ways to get with a loader, the first with a definition (discussed below) the second with params. When params are used they are turned into an adhoc definition with default params.
  73 +* A loader get passed three things when being constructed, a definition, a store, and another loader or datasource if there is either.
  74 +* If a loader is the third arg then requests will be chained to provide redundancy.
  75 +* If a data source is provided then requests for an item that is not cached will be passed to the data source and that will be expected to load the data. If it loads data that data is stored in each store on its way back to the user.
  76 +* There are three core loaders. One for each application, session, and request.
  77 +* A custom loader can be used. It will be provided by the definition (thus cannot be used with adhoc definitions) and must override the appropriate core loader
  78 +* The loader handles ttl for stores that don't natively support ttl.
  79 +* The application loader handles locking for stores that don't natively support locking.
  80 +
  81 +### Store
  82 +The store is the bridge between the cache API and a cache solution.
  83 +Cache store plugins exist within moodle/cache/store.
  84 +The administrator of a site can configure multiple instances of each plugin, the configuration gets initialised as a store for the loader when required in code (during construction of the loader).
  85 +The following points highlight things you should know about stores.
  86 +* A cache_store interface is used to define the requirements of a store plugin.
  87 +* The store plugin can inherit the cache_is_lockable interface to handle its own locking.
  88 +* The store plugin can inherit the cache_is_key_aware interface to handle is own has checks.
  89 +* Store plugins inform the cache API about the things they support. Features can be required by a definition.
  90 +** Data guarantee - Data is guaranteed to exist in the cache once it is set there. It is never cleaned up to free space or because it has not been recently used.
  91 +** Multiple identifiers - Rather than a single string key, the parts that make up the key are passed as an array.
  92 +** Native TTL support - When required the store supports native ttl and doesn't require the cache API to manage ttl of things given to the store.
  93 +
  94 +### Definition
  95 +_Definitions were not a part of the previous proposal._
  96 +Definitions are cache definitions. They will be located within a new file for each component/plugin at **db/caches.php**.
  97 +They can be used to set all of the requirements of a cache instance and are used to ensure that a cache can only be interacted with in the same way no matter where it is being used.
  98 +It also ensure that caches are easy to use, the config is stored in the definition and the developer using the cache does not need to know anything about it.
  99 +When getting a loader you can either provide a definition name, or a set or params.
  100 +* If you provide a definition name then the matching definition is found and used to construct a loader for you.
  101 +* If you provide params then an adhoc definition is created. It will have defaults and will not have any special requirements or options set.
  102 +
  103 +Definitions are designed to be used in situations where things are more than basic.
  104 +
  105 +The following settings are required for a definition:
  106 +* name - Identifies the definition and must be unique.
  107 +* mode - Application, session, request.
  108 +* component - The component associated the definition is associated with.
  109 +* area - Describes the stuff being cached.
  110 +
  111 +The following optional settings can also be defined:
  112 +* requireidentifiers - Any identifiers the definition requires. Must be provided when creating the loader.
  113 +* requiredataguarantee - If set to true then only stores that support data guarantee will be used.
  114 +* requiremultipleidentifiers - If set to true then only stores that support multiple identifiers will be used.
  115 +* overrideclass - If provided this class will be used for the loader. It must extend on of the core loader classes (based upon mode).
  116 +* overrideclassfile - Included if required when using the overrideclass param.
  117 +* datasource - If provided this class will be used as a data source for the definition. It must implement the cache_data_source interface.
  118 +* datasourcefile - Included if required when using the datasource param.
  119 +* persistent - If set to true the loader will be stored when first created and provided to subsequent requests. More on this later.
  120 +* ttl - Can be used to set a ttl value for data being set for this cache.
  121 +* mappingsonly - This definition can only be used if there is a store mapping for it. More on this later.
  122 +* invalidationevents - An array of events that should trigger this cache to invalidate.
  123 +
  124 +The persist option.
  125 +As noted the persist option causes the loader generated for this definition to be stored when first created. Subsequent requests for this definition will be given the original loader instance.
  126 +Data passed to or retrieved from the loader and its chained loaders gets cached by the instance.
  127 +This option should be used when you know you will require the loader several times and perhaps in different areas of code.
  128 +Because it caches key=>value data it avoids the need to re-fetch things from stores after the first request. Its good for performance, bad for memory.
  129 +It should be used sparingly.
  130 +
  131 +The mappingsonly option.
  132 +The administrator of a site can create mappings between stores and definitions. Allowing them to designate stores for specific definitions (caches).
  133 +Setting this option to true means that the definition can only be used if a mapping has been made for it.
  134 +Normally if no mappings exist then the default store for the definition mode is used.
  135 +
  136 +### Data source
  137 +Data sources allow cache _misses_ (requests for a key that doesn't exist) to be handled and loaded internally.
  138 +The loader gets used as the last resort if provided and means that code using the cache doesn't need to handle the situation that information isn't cached.
  139 +They can be specified in a cache definition and must implement the cache_data_source interface.
  140 +
  141 +### How it all chains together.
  142 +Consider the following if you can:
  143 +
  144 +Basic request for information (no frills):
  145 +
  146 + => Code calls get
  147 + => Loader handles get, passes the request to its store
  148 + <= Memcache doesn't have the data. sorry.
  149 + <= Loader returns the result.
  150 + |= Code couldn't get the data from the cache. It must generate it and then ask the loader to cache it.
  151 +
  152 +Advanced initial request for information not already cached (has chained stores and data source):
  153 +
  154 + => Code calls get
  155 + => Loader handles get, passes the request to its store
  156 + => Memcache handles request, doesn't have it passes it to the chained store
  157 + => File (default store) doesn't have it requests it from the loader
  158 + => Data source - makes required db calls, processes information
  159 + ...database calls...
  160 + ...processing and moulding...
  161 + <= Data source returns the information
  162 + <= File caches the information on its way back through
  163 + <= Memcache caches the information on its way back through
  164 + <= Loader returns the data to the user.
  165 + |= Code the code now has the data.
  166 +
  167 +Subsequent request for information:
  168 +
  169 + => Code calls get
  170 + => Loader handles get, passes the request to its store
  171 + <= Store returns the data
  172 + <= Loader returns the data
  173 + |= Code has the data
  174 +
  175 +Other internal magic you should be aware of
  176 +-------------------------------------------
  177 +The following should fill you in on a bit more of the behind the scenes stuff for the cache API.
  178 +
  179 +### Helper class
  180 +There is a helper class called cache_helper which is abstract with static methods.
  181 +This class handles much of the internal generation and initialisation requirements.
  182 +In normal use this class will not be needed outside of the API (mostly internal use only)
  183 +
  184 +### Configuration
  185 +There are two configuration classes cache_config and cache_config_writer.
  186 +The reader class is used for every request, the writer is only used when modifying the configuration.
  187 +Because the cache API is designed to cache database configuration and meta data it must be able to operate prior to database configuration being loaded.
  188 +To get around this we store the configuration information in a file in the dataroot.
  189 +The configuration file contains information on the configured store instances, definitions collected from definition files, and mappings.
  190 +That information is stored and loaded in the same way we work with the lang string files.
  191 +This means that we use the cache API as soon as it has been included.
  192 +
  193 +### Invalidation
  194 +Cache information can be invalidated in two ways.
  195 +1. pass a definition name and the keys to be invalidated (or none to invalidate the whole cache).
  196 +2. pass an event and the keys to be invalidated.
  197 +
  198 +The first method is designed to be used when you have a single known definition you want to invalidate entries from within.
  199 +The second method is a lot more intensive for the system. There are defined invalidation events that definitions can "subscribe" to (through the definitions invalidationevents option).
  200 +When you invalidate by event the cache API finds all of the definitions that subscribe to the event, it then loads the stores for each of those definitions and purges the keys from each store.
  201 +This is obviously a recursive and therefor intense process.
  202 +
  203 +TODO's and things still to think about
  204 +--------------------------------------
  205 +
  206 + 1. Definitions don't really need/use the component/area identifiers presently. They may be useful in the future... they may not be.
  207 + We should consider whether we leave them, or remove them.
201 cache/admin.php
... ... @@ -0,0 +1,201 @@
  1 +<?php
  2 +// This file is part of Moodle - http://moodle.org/
  3 +//
  4 +// Moodle is free software: you can redistribute it and/or modify
  5 +// it under the terms of the GNU General Public License as published by
  6 +// the Free Software Foundation, either version 3 of the License, or
  7 +// (at your option) any later version.
  8 +//
  9 +// Moodle is distributed in the hope that it will be useful,
  10 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 +// GNU General Public License for more details.
  13 +//
  14 +// You should have received a copy of the GNU General Public License
  15 +// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16 +
  17 +/**
  18 + * The administration and management interface for the cache setup and configuration.
  19 + *
  20 + * This file is part of Moodle's cache API, affectionately called MUC.
  21 + *
  22 + * @package core
  23 + * @category cache
  24 + * @copyright 2012 Sam Hemelryk
  25 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26 + */
  27 +
  28 +require_once('../config.php');
  29 +require_once($CFG->dirroot.'/lib/adminlib.php');
  30 +require_once($CFG->dirroot.'/cache/locallib.php');
  31 +require_once($CFG->dirroot.'/cache/forms.php');
  32 +
  33 +$action = optional_param('action', null, PARAM_ALPHA);
  34 +
  35 +admin_externalpage_setup('cacheconfig');
  36 +$context = context_system::instance();
  37 +
  38 +$stores = cache_administration_helper::get_store_instance_summaries();
  39 +$plugins = cache_administration_helper::get_store_plugin_summaries();
  40 +$definitions = cache_administration_helper::get_definition_summaries();
  41 +$defaultmodestores = cache_administration_helper::get_default_mode_stores();
  42 +$locks = cache_administration_helper::get_lock_summaries();
  43 +
  44 +$title = new lang_string('cacheadmin', 'cache');
  45 +$mform = null;
  46 +$notification = null;
  47 +$notifysuccess = true;
  48 +
  49 +if (!empty($action) && confirm_sesskey()) {
  50 + switch ($action) {
  51 + case 'rescandefinitions' : // Rescan definitions.
  52 + cache_config_writer::update_definitions();
  53 + redirect($PAGE->url);
  54 + break;
  55 + case 'addstore' : // Add the requested store.
  56 + $plugin = required_param('plugin', PARAM_PLUGIN);
  57 + $mform = cache_administration_helper::get_add_store_form($plugin);
  58 + $title = get_string('addstore', 'cache', $plugins[$plugin]['name']);
  59 + if ($mform->is_cancelled()) {
  60 + rediect($PAGE->url);
  61 + } else if ($data = $mform->get_data()) {
  62 + $config = cache_administration_helper::get_store_configuration_from_data($data);
  63 + $writer = cache_config_writer::instance();
  64 + unset($config['lock']);
  65 + foreach ($writer->get_locks() as $lock => $lockconfig) {
  66 + if ($lock == $data->lock) {
  67 + $config['lock'] = $data->lock;
  68 + }
  69 + }
  70 + $writer->add_store_instance($data->name, $data->plugin, $config);
  71 + redirect($PAGE->url, get_string('addstoresuccess', 'cache', $plugins[$plugin]['name']), 5);
  72 + }
  73 + break;
  74 + case 'editstore' : // Edit the requested store.
  75 + $plugin = required_param('plugin', PARAM_PLUGIN);
  76 + $store = required_param('store', PARAM_TEXT);
  77 + $mform = cache_administration_helper::get_edit_store_form($plugin, $store);
  78 + $title = get_string('addstore', 'cache', $plugins[$plugin]['name']);
  79 + if ($mform->is_cancelled()) {
  80 + rediect($PAGE->url);
  81 + } else if ($data = $mform->get_data()) {
  82 + $config = cache_administration_helper::get_store_configuration_from_data($data);
  83 + $writer = cache_config_writer::instance();
  84 + unset($config['lock']);
  85 + foreach ($writer->get_locks() as $lock => $lockconfig) {
  86 + if ($lock == $data->lock) {
  87 + $config['lock'] = $data->lock;
  88 + }
  89 + }
  90 + $writer->edit_store_instance($data->name, $data->plugin, $config);
  91 + redirect($PAGE->url, get_string('editstoresuccess', 'cache', $plugins[$plugin]['name']), 5);
  92 + }
  93 + break;
  94 + case 'deletestore' : // Delete a given store.
  95 + $store = required_param('store', PARAM_TEXT);
  96 + $confirm = optional_param('confirm', false, PARAM_BOOL);
  97 +
  98 + if (!array_key_exists($store, $stores)) {
  99 + $notifysuccess = false;
  100 + $notification = get_string('invalidstore');
  101 + } else if ($stores[$store]['mappings'] > 0) {
  102 + $notifysuccess = false;
  103 + $notification = get_string('deletestorehasmappings');
  104 + }
  105 +
  106 + if ($notifysuccess) {
  107 + if (!$confirm) {
  108 + $title = get_string('confirmstoredeletion', 'cache');
  109 + $params = array('store' => $store, 'confirm' => 1, 'action' => $action, 'sesskey' => sesskey());
  110 + $url = new moodle_url($PAGE->url, $params);
  111 + $button = new single_button($url, get_string('deletestore', 'cache'));
  112 +
  113 + $PAGE->set_title($title);
  114 + $PAGE->set_heading($SITE->fullname);
  115 + echo $OUTPUT->header();
  116 + echo $OUTPUT->heading($title);
  117 + $confirmation = get_string('deletestoreconfirmation', 'cache', $stores[$store]['name']);
  118 + echo $OUTPUT->confirm($confirmation, $button, $PAGE->url);
  119 + echo $OUTPUT->footer();
  120 + exit;
  121 + } else {
  122 + $writer = cache_config_writer::instance();
  123 + $writer->delete_store_instance($store);
  124 + redirect($PAGE->url, get_string('deletestoresuccess', 'cache'), 5);
  125 + }
  126 + }
  127 + break;
  128 + case 'editdefinitionmapping' : // Edit definition mappings.
  129 + $definition = required_param('definition', PARAM_TEXT);
  130 + $title = get_string('editdefinitionmappings', 'cache', $definition);
  131 + $mform = new cache_definition_mappings_form($PAGE->url, array('definition' => $definition));
  132 + if ($mform->is_cancelled()) {
  133 + redirect($PAGE->url);
  134 + } else if ($data = $mform->get_data()) {
  135 + $writer = cache_config_writer::instance();
  136 + $mappings = array();
  137 + foreach ($data->mappings as $mapping) {
  138 + if (!empty($mapping)) {
  139 + $mappings[] = $mapping;
  140 + }
  141 + }
  142 + $writer->set_definition_mappings($definition, $mappings);
  143 + redirect($PAGE->url);
  144 + }
  145 + break;
  146 + case 'editmodemappings': // Edit default mode mappings.
  147 + $mform = new cache_mode_mappings_form(null, $stores);
  148 + $mform->set_data(array(
  149 + 'mode_'.cache_store::MODE_APPLICATION => key($defaultmodestores[cache_store::MODE_APPLICATION]),
  150 + 'mode_'.cache_store::MODE_SESSION => key($defaultmodestores[cache_store::MODE_SESSION]),
  151 + 'mode_'.cache_store::MODE_REQUEST => key($defaultmodestores[cache_store::MODE_REQUEST]),
  152 + ));
  153 + if ($mform->is_cancelled()) {
  154 + redirect($PAGE->url);
  155 + } else if ($data = $mform->get_data()) {
  156 + $mappings = array(
  157 + cache_store::MODE_APPLICATION => array($data->{'mode_'.cache_store::MODE_APPLICATION}),
  158 + cache_store::MODE_SESSION => array($data->{'mode_'.cache_store::MODE_SESSION}),
  159 + cache_store::MODE_REQUEST => array($data->{'mode_'.cache_store::MODE_REQUEST}),
  160 + );
  161 + $writer = cache_config_writer::instance();
  162 + $writer->set_mode_mappings($mappings);
  163 + redirect($PAGE->url);
  164 + }
  165 + break;
  166 +
  167 + case 'purge': // Purge a store cache.
  168 + $store = required_param('store', PARAM_TEXT);
  169 + cache_helper::purge_store($store);
  170 + redirect($PAGE->url, get_string('purgestoresuccess', 'cache'), 5);
  171 + break;
  172 + }
  173 +}
  174 +
  175 +$PAGE->set_title($title);
  176 +$PAGE->set_heading($SITE->fullname);
  177 +$renderer = $PAGE->get_renderer('core_cache');
  178 +
  179 +echo $renderer->header();
  180 +echo $renderer->heading($title);
  181 +
  182 +if (!is_null($notification)) {
  183 + echo $renderer->notification($notification, ($notifysuccess)?'notifysuccess' : 'notifyproblem');
  184 +}
  185 +
  186 +if ($mform instanceof moodleform) {
  187 + $mform->display();
  188 +} else {
  189 + echo $renderer->store_plugin_summaries($plugins);
  190 + echo $renderer->store_instance_summariers($stores, $plugins);
  191 + echo $renderer->definition_summaries($definitions, cache_administration_helper::get_definition_actions($context));
  192 + echo $renderer->lock_summaries($locks);
  193 +
  194 + $applicationstore = join(', ', $defaultmodestores[cache_store::MODE_APPLICATION]);
  195 + $sessionstore = join(', ', $defaultmodestores[cache_store::MODE_SESSION]);
  196 + $requeststore = join(', ', $defaultmodestores[cache_store::MODE_REQUEST]);
  197 + $editurl = new moodle_url('/cache/admin.php', array('action' => 'editmodemappings', 'sesskey' => sesskey()));
  198 + echo $renderer->mode_mappings($applicationstore, $sessionstore, $requeststore, $editurl);
  199 +}
  200 +
  201 +echo $renderer->footer();
472 cache/classes/config.php
... ... @@ -0,0 +1,472 @@
  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 configuration reader
  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 + * Cache configuration reader.
  33 + *
  34 + * This class is used to interact with the cache's configuration.
  35 + * The configuration is stored in the Moodle data directory.
  36 + *
  37 + * @package core
  38 + * @category cache
  39 + * @copyright 2012 Sam Hemelryk
  40 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41 + */
  42 +class cache_config {
  43 +
  44 + /**
  45 + * The configured stores
  46 + * @var array
  47 + */
  48 + protected $configstores = array();
  49 +
  50 + /**
  51 + * The configured mode mappings
  52 + * @var array
  53 + */
  54 + protected $configmodemappings = array();
  55 +
  56 + /**
  57 + * The configured definitions as picked up from cache.php files
  58 + * @var array
  59 + */
  60 + protected $configdefinitions = array();
  61 +
  62 + /**
  63 + * The definition mappings that have been configured.
  64 + * @var array
  65 + */
  66 + protected $configdefinitionmappings = array();
  67 +
  68 + /**
  69 + * An array of configured cache lock instances.
  70 + * @var array
  71 + */
  72 + protected $configlocks = array();
  73 +
  74 + /**
  75 + * Please use cache_config::instance to get an instance of the cache config that is ready to be used.
  76 + */
  77 + public function __construct() {
  78 + // Nothing to do here but look pretty.
  79 + }
  80 +
  81 + /**
  82 + * Gets an instance of the cache_configuration class.
  83 + *
  84 + * @return cache_config
  85 + */
  86 + public static function instance() {
  87 + $factory = cache_factory::instance();
  88 + return $factory->create_config_instance();
  89 + }
  90 +
  91 + /**
  92 + * Checks if the configuration file exists.
  93 + *
  94 + * @return bool True if it exists
  95 + */
  96 + public static function config_file_exists() {
  97 + // Allow for late static binding.
  98 + return file_exists(self::get_config_file_path());
  99 + }
  100 +
  101 + /**
  102 + * Returns the expected path to the configuration file.
  103 + *
  104 + * @return string The absolute path
  105 + */
  106 + protected static function get_config_file_path() {
  107 + global $CFG;
  108 + if (!empty($CFG->altcacheconfigpath)) {
  109 + $path = $CFG->altcacheconfigpath;
  110 + if (is_dir($path) && is_writable($path)) {
  111 + // Its a writable directory, thats fine.
  112 + return $path.'/cacheconfig.php';
  113 + } else if (is_writable(dirname($path)) && (!file_exists($path) || is_writable($path))) {
  114 + // Its a file, either it doesn't exist and the directory is writable or the file exists and is writable.
  115 + return $path;
  116 + }
  117 + }
  118 + // Return the default location within dataroot.
  119 + return $CFG->dataroot.'/muc/config.php';
  120 + }
  121 +
  122 + /**
  123 + * Loads the configuration file and parses its contents into the expected structure.
  124 + *
  125 + * @return boolean
  126 + */
  127 + public function load() {
  128 + global $CFG;
  129 +
  130 + $configuration = $this->include_configuration();
  131 +
  132 + $this->configstores = array();
  133 + $this->configdefinitions = array();
  134 + $this->configlocks = array();
  135 + $this->configmodemappings = array();
  136 + $this->configdefinitionmappings = array();
  137 + $this->configlockmappings = array();
  138 +
  139 + // Filter the lock instances.
  140 + $defaultlock = null;
  141 + foreach ($configuration['locks'] as $conf) {
  142 + if (!is_array($conf)) {
  143 + // Something is very wrong here.
  144 + continue;
  145 + }
  146 + if (!array_key_exists('name', $conf)) {
  147 + // Not a valid definition configuration.
  148 + continue;
  149 + }
  150 + $name = $conf['name'];
  151 + if (array_key_exists($name, $this->configlocks)) {
  152 + debugging('Duplicate cache lock detected. This should never happen.', DEBUG_DEVELOPER);
  153 + continue;
  154 + }
  155 + $conf['default'] = (!empty($conf['default']));
  156 + if ($defaultlock === null || $conf['default']) {
  157 + $defaultlock = $name;
  158 + }
  159 + $this->configlocks[$name] = $conf;
  160 + }
  161 +
  162 + // Filter the stores.
  163 + $availableplugins = cache_helper::early_get_cache_plugins();
  164 + foreach ($configuration['stores'] as $store) {
  165 + if (!is_array($store) || !array_key_exists('name', $store) || !array_key_exists('plugin', $store)) {
  166 + // Not a valid instance configuration.
  167 + debugging('Invalid cache store in config. Missing name or plugin.', DEBUG_DEVELOPER);
  168 + continue;
  169 + }
  170 + $plugin = $store['plugin'];
  171 + $class = 'cachestore_'.$plugin;
  172 + $exists = array_key_exists($plugin, $availableplugins);
  173 + if (!$exists && (!class_exists($class) || !is_subclass_of($class, 'cache_store'))) {
  174 + // Not a valid plugin, or has been uninstalled, just skip it an carry on.
  175 + debugging('Invalid cache store in config. Not an available plugin.', DEBUG_DEVELOPER);
  176 + continue;
  177 + }
  178 + $file = $CFG->dirroot.'/cache/stores/'.$plugin.'/lib.php';
  179 + if (!class_exists($class) && file_exists($file)) {
  180 + require_once($file);
  181 + }
  182 + if (!class_exists($class)) {
  183 + continue;
  184 + }
  185 + if (!array_key_exists('cache_store', class_implements($class))) {
  186 + continue;
  187 + }
  188 + if (!array_key_exists('configuration', $store) || !is_array($store['configuration'])) {
  189 + $store['configuration'] = array();
  190 + }
  191 + $store['class'] = $class;
  192 + $store['default'] = !empty($store['default']);
  193 + if (!array_key_exists('lock', $store) || !array_key_exists($store['lock'], $this->configlocks)) {
  194 + $store['lock'] = $defaultlock;
  195 + }
  196 +
  197 + $this->configstores[$store['name']] = $store;
  198 + }
  199 +
  200 + // Filter the definitions.
  201 + foreach ($configuration['definitions'] as $id => $conf) {
  202 + if (!is_array($conf)) {
  203 + // Something is very wrong here.
  204 + continue;
  205 + }
  206 + if (!array_key_exists('mode', $conf) || !array_key_exists('component', $conf) || !array_key_exists('area', $conf)) {
  207 + // Not a valid definition configuration.
  208 + continue;
  209 + }
  210 + if (array_key_exists($id, $this->configdefinitions)) {
  211 + debugging('Duplicate cache definition detected. This should never happen.', DEBUG_DEVELOPER);
  212 + continue;
  213 + }
  214 + $conf['mode'] = (int)$conf['mode'];
  215 + if ($conf['mode'] < cache_store::MODE_APPLICATION || $conf['mode'] > cache_store::MODE_REQUEST) {
  216 + // Invalid cache mode used for the definition.
  217 + continue;
  218 + }
  219 + $this->configdefinitions[$id] = $conf;
  220 + }
  221 +
  222 + // Filter the mode mappings.
  223 + foreach ($configuration['modemappings'] as $mapping) {
  224 + if (!is_array($mapping) || !array_key_exists('mode', $mapping) || !array_key_exists('store', $mapping)) {
  225 + // Not a valid mapping configuration.
  226 + debugging('A cache mode mapping entry is invalid.', DEBUG_DEVELOPER);
  227 + continue;
  228 + }
  229 + if (!array_key_exists($mapping['store'], $this->configstores)) {
  230 + // Mapped array instance doesn't exist.
  231 + debugging('A cache mode mapping exists for a mode or store that does not exist.', DEBUG_DEVELOPER);
  232 + continue;
  233 + }
  234 + $mapping['mode'] = (int)$mapping['mode'];
  235 + if ($mapping['mode'] < 0 || $mapping['mode'] > 4) {
  236 + // Invalid cache type used for the mapping.
  237 + continue;
  238 + }
  239 + if (!array_key_exists('sort', $mapping)) {
  240 + $mapping['sort'] = 0;
  241 + }
  242 + $this->configmodemappings[] = $mapping;
  243 + }
  244 +
  245 + // Filter the definition mappings.
  246 + foreach ($configuration['definitionmappings'] as $mapping) {
  247 + if (!is_array($mapping) || !array_key_exists('definition', $mapping) || !array_key_exists('store', $mapping)) {
  248 + // Not a valid mapping configuration.
  249 + continue;
  250 + }
  251 + if (!array_key_exists($mapping['store'], $this->configstores)) {
  252 + // Mapped array instance doesn't exist.
  253 + continue;
  254 + }
  255 + if (!array_key_exists($mapping['definition'], $this->configdefinitions)) {
  256 + // Mapped array instance doesn't exist.
  257 + continue;
  258 + }
  259 + if (!array_key_exists('sort', $mapping)) {
  260 + $mapping['sort'] = 0;
  261 + }
  262 + $this->configdefinitionmappings[] = $mapping;
  263 + }
  264 +
  265 + usort($this->configmodemappings, array($this, 'sort_mappings'));
  266 + usort($this->configdefinitionmappings, array($this, 'sort_mappings'));
  267 +
  268 + return true;
  269 + }
  270 +
  271 + /**
  272 + * Includes the configuration file and makes sure it contains the expected bits.
  273 + *
  274 + * You need to ensure that the config file exists before this is called.
  275 + *
  276 + * @return array
  277 + * @throws cache_exception
  278 + */
  279 + protected function include_configuration() {
  280 + $configuration = array();
  281 + $cachefile = self::get_config_file_path();
  282 +
  283 + if (!file_exists($cachefile)) {
  284 + throw new cache_exception('Default cache config could not be found. It should have already been created by now.');
  285 + }
  286 + include($cachefile);
  287 + if (!is_array($configuration)) {
  288 + throw new cache_exception('Invalid cache configuration file');
  289 + }
  290 + if (!array_key_exists('stores', $configuration) || !is_array($configuration['stores'])) {
  291 + $configuration['stores'] = array();
  292 + }
  293 + if (!array_key_exists('modemappings', $configuration) || !is_array($configuration['modemappings'])) {
  294 + $configuration['modemappings'] = array();
  295 + }
  296 + if (!array_key_exists('definitions', $configuration) || !is_array($configuration['definitions'])) {
  297 + $configuration['definitions'] = array();
  298 + }
  299 + if (!array_key_exists('definitionmappings', $configuration) || !is_array($configuration['definitionmappings'])) {
  300 + $configuration['definitionmappings'] = array();
  301 + }
  302 + if (!array_key_exists('locks', $configuration) || !is_array($configuration['locks'])) {
  303 + $configuration['locks'] = array();
  304 + }
  305 +
  306 + return $configuration;
  307 + }
  308 +
  309 + /**
  310 + * Used to sort cache config arrays based upon a sort key.
  311 + *
  312 + * Highest number at the top.
  313 + *
  314 + * @param array $a
  315 + * @param array $b
  316 + * @return int
  317 + */
  318 + protected function sort_mappings(array $a, array $b) {
  319 + if ($a['sort'] == $b['sort']) {
  320 + return 0;
  321 + }
  322 + return ($a['sort'] < $b['sort']) ? 1 : -1;
  323 + }
  324 +
  325 + /**
  326 + * Gets a definition from the config given its name.
  327 + *
  328 + * @param string $id
  329 + * @return bool
  330 + */
  331 + public function get_definition_by_id($id) {
  332 + if (array_key_exists($id, $this->configdefinitions)) {
  333 + return $this->configdefinitions[$id];
  334 + }
  335 + return false;
  336 + }
  337 +
  338 + /**
  339 + * Returns all the known definitions.
  340 + *
  341 + * @return array
  342 + */
  343 + public function get_definitions() {
  344 + return $this->configdefinitions;
  345 + }
  346 +
  347 + /**
  348 + * Returns all of the stores that are suitable for the given mode and requirements.
  349 + *
  350 + * @param int $mode One of cache_store::MODE_*
  351 + * @param int $requirements The requirements of the cache as a binary flag
  352 + * @return array An array of suitable stores.
  353 + */
  354 + public function get_stores($mode, $requirements = 0) {
  355 + $stores = array();
  356 + foreach ($this->configstores as $name => $store) {
  357 + // If the mode is supported and all of the requirements are provided features.
  358 + if (($store['modes'] & $mode) && ($store['features'] & $requirements) === $requirements) {
  359 + $stores[$name] = $store;
  360 + }
  361 + }
  362 + return $stores;
  363 + }
  364 +
  365 + /**
  366 + * Gets all of the stores that are to be used for the given definition.
  367 + *
  368 + * @param cache_definition $definition
  369 + * @return array
  370 + */
  371 + public function get_stores_for_definition(cache_definition $definition) {
  372 + // Check if MUC has been disabled.
  373 + if (defined('NO_CACHE_STORES') && NO_CACHE_STORES !== false) {
  374 + // Yip its been disabled.
  375 + // To facilitate this we are going to always return an empty array of stores to use.
  376 + // This will force all cache instances to use the cachestore_dummy.
  377 + // MUC will still be used essentially so that code using it will still continue to function but because no cache stores
  378 + // are being used interaction with MUC will be purely based around a static var.
  379 + return array();
  380 + }
  381 +
  382 + $availablestores = $this->get_stores($definition->get_mode(), $definition->get_requirements_bin());
  383 + $stores = array();
  384 + $id = $definition->get_id();
  385 +
  386 + // Now get any mappings and give them priority.
  387 + foreach ($this->configdefinitionmappings as $mapping) {
  388 + if ($mapping['definition'] !== $id) {
  389 + continue;
  390 + }
  391 + $storename = $mapping['store'];
  392 + if (!array_key_exists($storename, $availablestores)) {
  393 + continue;
  394 + }
  395 + if (array_key_exists($storename, $stores)) {
  396 + $store = $stores[$storename];
  397 + unset($stores[$storename]);
  398 + $stores[$storename] = $store;
  399 + } else {
  400 + $stores[$storename] = $availablestores[$storename];
  401 + }
  402 + }
  403 +
  404 + if (empty($stores) && !$definition->is_for_mappings_only()) {
  405 + $mode = $definition->get_mode();
  406 + // Load the default stores.
  407 + foreach ($this->configmodemappings as $mapping) {
  408 + if ($mapping['mode'] === $mode && array_key_exists($mapping['store'], $availablestores)) {
  409 + $store = $availablestores[$mapping['store']];
  410 + if (empty($store['mappingsonly'])) {
  411 + $stores[$mapping['store']] = $store;
  412 + }
  413 + }
  414 + }
  415 + }
  416 +
  417 + return $stores;
  418 + }
  419 +
  420 + /**
  421 + * Returns all of the configured stores
  422 + * @return array
  423 + */
  424 + public function get_all_stores() {
  425 + return $this->configstores;
  426 + }
  427 +
  428 + /**
  429 + * Returns all of the configured mode mappings
  430 + * @return array
  431 + */
  432 + public function get_mode_mappings() {
  433 + return $this->configmodemappings;
  434 + }
  435 +
  436 + /**
  437 + * Returns all of the known definition mappings.
  438 + * @return array
  439 + */
  440 + public function get_definition_mappings() {
  441 + return $this->configdefinitionmappings;
  442 + }
  443 +
  444 + /**
  445 + * Returns an array of the configured locks.
  446 + * @return array Array of name => config
  447 + */
  448 + public function get_locks() {
  449 + return $this->configlocks;
  450 + }
  451 +
  452 + /**
  453 + * Returns the lock store configuration to use with a given store.
  454 + * @param string $storename
  455 + * @return array
  456 + * @throws cache_exception
  457 + */
  458 + public function get_lock_for_store($storename) {
  459 + if (array_key_exists($storename, $this->configstores)) {
  460 + if (array_key_exists($this->configstores[$storename]['lock'], $this->configlocks)) {
  461 + $lock = $this->configstores[$storename]['lock'];
  462 + return $this->configlocks[$lock];
  463 + }
  464 + }
  465 + foreach ($this->configlocks as $lockconf) {
  466 + if (!empty($lockconf['default'])) {
  467 + return $lockconf;
  468 + }
  469 + }
  470 + throw new cache_exception('ex_nodefaultlock');
  471 + }
  472 +}
715 cache/classes/definition.php
... ... @@ -0,0 +1,715 @@
  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 + * + requireidentifiers
  43 + * [array] An array of identifiers that must be provided to the cache when it is created.
  44 + * + requiredataguarantee
  45 + * [bool] If set to true then only stores that can guarantee data will remain available once set will be used.
  46 + * + requiremultipleidentifiers
  47 + * [bool] If set to true then only stores that support multiple identifiers will be used.
  48 + * + requirelockingread
  49 + * [bool] If set to true then a lock will be gained before reading from the cache store. It is recommended not to use
  50 + * this setting unless 100% absolutely positively required. Remember 99.9% of caches will NOT need this setting.
  51 + * This setting will only be used for application caches presently.
  52 + * + requirelockingwrite
  53 + * [bool] If set to true then a lock will be gained before writing to the cache store. As above this is not recommended
  54 + * unless truly needed. Please think about the order of your code and deal with race conditions there first.
  55 + * This setting will only be used for application caches presently.
  56 + * + maxsize
  57 + * [int] If set this will be used as the maximum number of entries within the cache store for this definition.
  58 + * Its important to note that cache stores don't actually have to acknowledge this setting or maintain it as a hard limit.
  59 + * + overrideclass
  60 + * [string] A class to use as the loader for this cache. This is an advanced setting and will allow the developer of the
  61 + * definition to take 100% control of the caching solution.
  62 + * Any class used here must inherit the cache_loader interface and must extend default cache loader for the mode they are
  63 + * using.
  64 + * + overrideclassfile
  65 + * [string] Suplements the above setting indicated the file containing the class to be used. This file is included when
  66 + * required.
  67 + * + datasource
  68 + * [string] A class to use as the data loader for this definition.
  69 + * Any class used here must inherit the cache_data_loader interface.
  70 + * + datasourcefile
  71 + * [string] Suplements the above setting indicated the file containing the class to be used. This file is included when
  72 + * required.
  73 + * + persistent
  74 + * [bool] This setting does two important things. First it tells the cache API to only instantiate the cache structure for
  75 + * this definition once, further requests will be given the original instance.
  76 + * Second the cache loader will keep an array of the items set and retrieved to the cache during the request.
  77 + * This has several advantages including better performance without needing to start passing the cache instance between
  78 + * function calls, the downside is that the cache instance + the items used stay within memory.
  79 + * Consider using this setting when you know that there are going to be many calls to the cache for the same information
  80 + * or when you are converting existing code to the cache and need to access the cache within functions but don't want
  81 + * to add it as an argument to the function.
  82 + * + persistentmaxsize
  83 + * [int] This supplements the above setting by limiting the number of items in the caches persistent array of items.
  84 + * Tweaking this setting lower will allow you to minimise the memory implications above while hopefully still managing to
  85 + * offset calls to the cache store.
  86 + * + ttl
  87 + * [int] A time to live for the data (in seconds). It is strongly recommended that you don't make use of this and
  88 + * instead try to create an event driven invalidation system.
  89 + * Not all cache stores will support this natively and there are undesired performance impacts if the cache store does not.
  90 + * + mappingsonly
  91 + * [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
  92 + * advanced setting and should not be used unless absolutely required. It allows you to avoid the default stores for one
  93 + * reason or another.
  94 + * + invalidationevents
  95 + * [array] An array of events that should cause this cache to invalidate some or all of the items within it.
  96 + *
  97 + * For examples take a look at lib/db/caches.php
  98 + *
  99 + * @package core
  100 + * @category cache
  101 + * @copyright 2012 Sam Hemelryk
  102 + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  103 + */
  104 +class cache_definition {
  105 +
  106 + /**
  107 + * The identifier for the definition
  108 + * @var string
  109 + */
  110 + protected $id;
  111 +
  112 + /**
  113 + * The mode for the defintion. One of cache_store::MODE_*
  114 + * @var int
  115 + */
  116 + protected $mode;
  117 +
  118 + /**
  119 + * The component this definition is associated with.
  120 + * @var string
  121 + */
  122 + protected $component;
  123 +
  124 + /**
  125 + * The area this definition is associated with.
  126 + * @var string
  127 + */
  128 + protected $area;
  129 +
  130 + /**
  131 + * An array of identifiers that must be provided when the definition is used to create a cache.
  132 + * @var array
  133 + */
  134 + protected $requireidentifiers = array();
  135 +
  136 + /**
  137 + * If set to true then only stores that guarantee data may be used with this definition.
  138 + * @var bool
  139 + */
  140 + protected $requiredataguarantee = false;
  141 +
  142 + /**
  143 + * If set to true then only stores that support multple identifiers may be used with this definition.
  144 + * @var bool
  145 + */
  146 + protected $requiremultipleidentifiers = false;
  147 +
  148 + /**
  149 + * If set to true then we know that this definition requires the locking functionality.
  150 + * This gets set during construction based upon the settings requirelockingread and requirelockingwrite.
  151 + * @var bool
  152 + */
  153 + protected $requirelocking = false;
  154 +
  155 + /**
  156 + * Set to true if this definition requires read locking.
  157 + * @var bool
  158 + */
  159 + protected $requirelockingread = false;
  160 +
  161 + /**
  162 + * Gets set to true if this definition requires write locking.
  163 + * @var bool
  164 + */
  165 + protected $requirelockingwrite = false;
  166 +
  167 + /**
  168 + * Sets the maximum number of items that can exist in the cache.
  169 + * 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.
  170 + * @var int
  171 + */
  172 + protected $maxsize = null;
  173 +
  174 + /**
  175 + * The class to use as the cache loader for this definition.
  176 + * @var string
  177 + */
  178 + protected $overrideclass = null;
  179 +
  180 + /**
  181 + * The file in which the override class exists. This will be included if required.
  182 + * @var string Absolute path
  183 + */
  184 + protected $overrideclassfile = null;
  185 +
  186 + /**
  187 + * The data source class to use with this definition.
  188 + * @var string
  189 + */
  190 + protected $datasource = null;
  191 +
  192 + /**
  193 + * The file in which the data source class exists. This will be included if required.
  194 + * @var string
  195 + */
  196 + protected $datasourcefile = null;
  197 +
  198 + /**
  199 + * The data source class aggregate to use. This is a super advanced setting.
  200 + * @var string
  201 + */
  202 + protected $datasourceaggregate = null;
  203 +
  204 + /**
  205 + * Set to true if the definitions cache should be persistent
  206 + * @var bool
  207 + */
  208 + protected $persistent = false;
  209 +
  210 + /**
  211 + * The persistent item array max size.
  212 + * @var int
  213 + */
  214 + protected $persistentmaxsize = false;
  215 +
  216 + /**
  217 + * The TTL for data in this cache. Please don't use this, instead use event driven invalidation.
  218 + * @var int
  219 + */
  220 + protected $ttl = 0;
  221 +
  222 + /**
  223 + * Set to true if this cache should only use mapped cache stores and not the default mode cache store.
  224 + * @var bool
  225 + */
  226 + protected $mappingsonly = false;
  227 +
  228 + /**
  229 + * An array of events that should cause this cache to invalidate.
  230 + * @var array
  231 + */
  232 + protected $invalidationevents = array();
  233 +
  234 + /**
  235 + * An array of identifiers provided to this cache when it was initialised.
  236 + * @var array
  237 + */
  238 + protected $identifiers = array();
  239 +
  240