MDL-82158 core_cache: Coding style fixes

This commit is contained in:
Andrew Nicols 2024-08-05 09:49:33 +08:00
parent bac9672b7f
commit b92008c92c
No known key found for this signature in database
GPG key ID: 6D1E3157C8CFBF14
53 changed files with 2506 additions and 2081 deletions

8
cache/admin.php vendored
View file

@ -19,14 +19,14 @@
* *
* This file is part of Moodle's cache API, affectionately called MUC. * This file is part of Moodle's cache API, affectionately called MUC.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
require_once('../config.php'); require_once('../config.php');
require_once($CFG->dirroot.'/lib/adminlib.php'); require_once($CFG->dirroot . '/lib/adminlib.php');
// The first time the user visits this page we are going to reparse the definitions. // The first time the user visits this page we are going to reparse the definitions.
// Just ensures that everything is up to date. // Just ensures that everything is up to date.
@ -42,7 +42,7 @@ $action = optional_param('action', null, PARAM_ALPHA);
admin_externalpage_setup('cacheconfig'); admin_externalpage_setup('cacheconfig');
$adminhelper = cache_factory::instance()->get_administration_display_helper(); $adminhelper = cache_factory::instance()->get_administration_display_helper();
$notifications = array(); $notifications = [];
// Empty array to hold any form information returned from actions. // Empty array to hold any form information returned from actions.
$forminfo = []; $forminfo = [];
@ -57,7 +57,7 @@ if (!empty($action)) {
// Add cache store warnings to the list of notifications. // Add cache store warnings to the list of notifications.
// Obviously as these are warnings they are show as failures. // Obviously as these are warnings they are show as failures.
foreach (cache_helper::warnings(core_cache\administration_helper::get_store_instance_summaries()) as $warning) { foreach (cache_helper::warnings(core_cache\administration_helper::get_store_instance_summaries()) as $warning) {
$notifications[] = array($warning, false); $notifications[] = [$warning, false];
} }
// Decide on display mode based on returned forminfo. // Decide on display mode based on returned forminfo.

View file

@ -14,47 +14,33 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Cache administration helper.
*
* This file is part of Moodle's cache API, affectionately called MUC.
* It contains the components that are requried in order to use caching.
*
* @package core
* @category cache
* @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright 2020 Catalyst IT
* @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_cache; namespace core_cache;
defined('MOODLE_INTERNAL') || die(); use core_component;
use cache_helper, cache_store, cache_config, cache_factory, cache_definition; use core\output\pix_icon;
use lang_string;
/** /**
* Administration helper base class. * Administration helper base class.
* *
* Defines abstract methods for a subclass to define the admin page. * Defines abstract methods for a subclass to define the admin page.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @author Peter Burnett <peterburnett@catalyst-au.net> * @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright 2020 Catalyst IT * @copyright 2020 Catalyst IT
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
abstract class administration_helper extends cache_helper { abstract class administration_helper extends helper {
/** /**
* Returns an array containing all of the information about stores a renderer needs. * Returns an array containing all of the information about stores a renderer needs.
* @return array * @return array
*/ */
public static function get_store_instance_summaries(): array { public static function get_store_instance_summaries(): array {
$return = array(); $return = [];
$default = array(); $default = [];
$instance = \cache_config::instance(); $instance = config::instance();
$stores = $instance->get_all_stores(); $stores = $instance->get_all_stores();
$locks = $instance->get_locks(); $locks = $instance->get_locks();
foreach ($stores as $name => $details) { foreach ($stores as $name => $details) {
@ -64,7 +50,7 @@ abstract class administration_helper extends cache_helper {
$store = new $class($details['name'], $details['configuration']); $store = new $class($details['name'], $details['configuration']);
} }
$lock = (isset($details['lock'])) ? $locks[$details['lock']] : $instance->get_default_lock(); $lock = (isset($details['lock'])) ? $locks[$details['lock']] : $instance->get_default_lock();
$record = array( $record = [
'name' => $name, 'name' => $name,
'plugin' => $details['plugin'], 'plugin' => $details['plugin'],
'default' => $details['default'], 'default' => $details['default'],
@ -72,24 +58,24 @@ abstract class administration_helper extends cache_helper {
'requirementsmet' => $class::are_requirements_met(), 'requirementsmet' => $class::are_requirements_met(),
'mappings' => 0, 'mappings' => 0,
'lock' => $lock, 'lock' => $lock,
'modes' => array( 'modes' => [
cache_store::MODE_APPLICATION => store::MODE_APPLICATION =>
($class::get_supported_modes($return) & cache_store::MODE_APPLICATION) == cache_store::MODE_APPLICATION, ($class::get_supported_modes($return) & store::MODE_APPLICATION) == store::MODE_APPLICATION,
cache_store::MODE_SESSION => store::MODE_SESSION =>
($class::get_supported_modes($return) & cache_store::MODE_SESSION) == cache_store::MODE_SESSION, ($class::get_supported_modes($return) & store::MODE_SESSION) == store::MODE_SESSION,
cache_store::MODE_REQUEST => store::MODE_REQUEST =>
($class::get_supported_modes($return) & cache_store::MODE_REQUEST) == cache_store::MODE_REQUEST, ($class::get_supported_modes($return) & store::MODE_REQUEST) == store::MODE_REQUEST,
), ],
'supports' => array( 'supports' => [
'multipleidentifiers' => $store ? $store->supports_multiple_identifiers() : false, 'multipleidentifiers' => $store ? $store->supports_multiple_identifiers() : false,
'dataguarantee' => $store ? $store->supports_data_guarantee() : false, 'dataguarantee' => $store ? $store->supports_data_guarantee() : false,
'nativettl' => $store ? $store->supports_native_ttl() : false, 'nativettl' => $store ? $store->supports_native_ttl() : false,
'nativelocking' => ($store instanceof \cache_is_lockable), 'nativelocking' => ($store instanceof \cache_is_lockable),
'keyawareness' => ($store instanceof \cache_is_key_aware), 'keyawareness' => ($store instanceof \cache_is_key_aware),
'searchable' => ($store instanceof \cache_is_searchable) 'searchable' => ($store instanceof \cache_is_searchable),
), ],
'warnings' => $store ? $store->get_warnings() : array() 'warnings' => $store ? $store->get_warnings() : [],
); ];
if (empty($details['default'])) { if (empty($details['default'])) {
$return[$name] = $record; $return[$name] = $record;
} else { } else {
@ -136,31 +122,31 @@ abstract class administration_helper extends cache_helper {
* See the code below for details * See the code below for details
*/ */
public static function get_store_plugin_summaries(): array { public static function get_store_plugin_summaries(): array {
$return = array(); $return = [];
$plugins = \core_component::get_plugin_list_with_file('cachestore', 'lib.php', true); $plugins = \core_component::get_plugin_list_with_file('cachestore', 'lib.php', true);
foreach ($plugins as $plugin => $path) { foreach ($plugins as $plugin => $path) {
$class = 'cachestore_'.$plugin; $class = 'cachestore_' . $plugin;
$return[$plugin] = array( $return[$plugin] = [
'name' => get_string('pluginname', 'cachestore_'.$plugin), 'name' => get_string('pluginname', 'cachestore_' . $plugin),
'requirementsmet' => $class::are_requirements_met(), 'requirementsmet' => $class::are_requirements_met(),
'instances' => 0, 'instances' => 0,
'modes' => array( 'modes' => [
cache_store::MODE_APPLICATION => ($class::get_supported_modes() & cache_store::MODE_APPLICATION), store::MODE_APPLICATION => ($class::get_supported_modes() & store::MODE_APPLICATION),
cache_store::MODE_SESSION => ($class::get_supported_modes() & cache_store::MODE_SESSION), store::MODE_SESSION => ($class::get_supported_modes() & store::MODE_SESSION),
cache_store::MODE_REQUEST => ($class::get_supported_modes() & cache_store::MODE_REQUEST), store::MODE_REQUEST => ($class::get_supported_modes() & store::MODE_REQUEST),
), ],
'supports' => array( 'supports' => [
'multipleidentifiers' => ($class::get_supported_features() & cache_store::SUPPORTS_MULTIPLE_IDENTIFIERS), 'multipleidentifiers' => ($class::get_supported_features() & store::SUPPORTS_MULTIPLE_IDENTIFIERS),
'dataguarantee' => ($class::get_supported_features() & cache_store::SUPPORTS_DATA_GUARANTEE), 'dataguarantee' => ($class::get_supported_features() & store::SUPPORTS_DATA_GUARANTEE),
'nativettl' => ($class::get_supported_features() & cache_store::SUPPORTS_NATIVE_TTL), 'nativettl' => ($class::get_supported_features() & store::SUPPORTS_NATIVE_TTL),
'nativelocking' => (in_array('cache_is_lockable', class_implements($class))), 'nativelocking' => (in_array(lockable_cache_interface::class, class_implements($class))),
'keyawareness' => (array_key_exists('cache_is_key_aware', class_implements($class))), 'keyawareness' => (array_key_exists(key_aware_cache_interface::class, class_implements($class))),
), ],
'canaddinstance' => ($class::can_add_instance() && $class::are_requirements_met()) 'canaddinstance' => ($class::can_add_instance() && $class::are_requirements_met()),
); ];
} }
$instance = cache_config::instance(); $instance = config::instance();
$stores = $instance->get_all_stores(); $stores = $instance->get_all_stores();
foreach ($stores as $store) { foreach ($stores as $store) {
$plugin = $store['plugin']; $plugin = $store['plugin'];
@ -179,28 +165,28 @@ abstract class administration_helper extends cache_helper {
* See the code below for details * See the code below for details
*/ */
public static function get_definition_summaries(): array { public static function get_definition_summaries(): array {
$factory = cache_factory::instance(); $factory = factory::instance();
$config = $factory->create_config_instance(); $config = $factory->create_config_instance();
$storenames = array(); $storenames = [];
foreach ($config->get_all_stores() as $key => $store) { foreach ($config->get_all_stores() as $key => $store) {
if (!empty($store['default'])) { if (!empty($store['default'])) {
$storenames[$key] = new \lang_string('store_'.$key, 'cache'); $storenames[$key] = new lang_string('store_' . $key, 'cache');
} else { } else {
$storenames[$store['name']] = $store['name']; $storenames[$store['name']] = $store['name'];
} }
} }
/* @var cache_definition[] $definitions */ /* @var definition[] $definitions */
$definitions = []; $definitions = [];
$return = []; $return = [];
foreach ($config->get_definitions() as $key => $definition) { foreach ($config->get_definitions() as $key => $definition) {
$definitions[$key] = cache_definition::load($definition['component'].'/'.$definition['area'], $definition); $definitions[$key] = definition::load($definition['component'] . '/' . $definition['area'], $definition);
} }
foreach ($definitions as $id => $definition) { foreach ($definitions as $id => $definition) {
$mappings = array(); $mappings = [];
foreach (cache_helper::get_stores_suitable_for_definition($definition) as $store) { foreach (helper::get_stores_suitable_for_definition($definition) as $store) {
$mappings[] = $storenames[$store->my_name()]; $mappings[] = $storenames[$store->my_name()];
} }
$return[$id] = array( $return[$id] = [
'id' => $id, 'id' => $id,
'name' => $definition->get_name(), 'name' => $definition->get_name(),
'mode' => $definition->get_mode(), 'mode' => $definition->get_mode(),
@ -210,8 +196,8 @@ abstract class administration_helper extends cache_helper {
'canuselocalstore' => $definition->can_use_localstore(), 'canuselocalstore' => $definition->can_use_localstore(),
'sharingoptions' => self::get_definition_sharing_options($definition->get_sharing_options(), false), 'sharingoptions' => self::get_definition_sharing_options($definition->get_sharing_options(), false),
'selectedsharingoption' => self::get_definition_sharing_options($definition->get_selected_sharing_option(), true), 'selectedsharingoption' => self::get_definition_sharing_options($definition->get_selected_sharing_option(), true),
'userinputsharingkey' => $definition->get_user_input_sharing_key() 'userinputsharingkey' => $definition->get_user_input_sharing_key(),
); ];
} }
return $return; return $return;
} }
@ -223,20 +209,20 @@ abstract class administration_helper extends cache_helper {
*/ */
public static function get_default_mode_stores(): array { public static function get_default_mode_stores(): array {
global $OUTPUT; global $OUTPUT;
$instance = cache_config::instance(); $instance = config::instance();
$adequatestores = cache_helper::get_stores_suitable_for_mode_default(); $adequatestores = helper::get_stores_suitable_for_mode_default();
$icon = new \pix_icon('i/warning', new \lang_string('inadequatestoreformapping', 'cache')); $icon = new pix_icon('i/warning', new lang_string('inadequatestoreformapping', 'cache'));
$storenames = array(); $storenames = [];
foreach ($instance->get_all_stores() as $key => $store) { foreach ($instance->get_all_stores() as $key => $store) {
if (!empty($store['default'])) { if (!empty($store['default'])) {
$storenames[$key] = new \lang_string('store_'.$key, 'cache'); $storenames[$key] = new lang_string('store_' . $key, 'cache');
} }
} }
$modemappings = array( $modemappings = [
cache_store::MODE_APPLICATION => array(), store::MODE_APPLICATION => [],
cache_store::MODE_SESSION => array(), store::MODE_SESSION => [],
cache_store::MODE_REQUEST => array(), store::MODE_REQUEST => [],
); ];
foreach ($instance->get_mode_mappings() as $mapping) { foreach ($instance->get_mode_mappings() as $mapping) {
$mode = $mapping['mode']; $mode = $mapping['mode'];
if (!array_key_exists($mode, $modemappings)) { if (!array_key_exists($mode, $modemappings)) {
@ -249,7 +235,7 @@ abstract class administration_helper extends cache_helper {
$modemappings[$mode][$mapping['store']] = $mapping['store']; $modemappings[$mode][$mapping['store']] = $mapping['store'];
} }
if (!array_key_exists($mapping['store'], $adequatestores)) { if (!array_key_exists($mapping['store'], $adequatestores)) {
$modemappings[$mode][$mapping['store']] = $modemappings[$mode][$mapping['store']].' '.$OUTPUT->render($icon); $modemappings[$mode][$mapping['store']] = $modemappings[$mode][$mapping['store']] . ' ' . $OUTPUT->render($icon);
} }
} }
return $modemappings; return $modemappings;
@ -261,13 +247,13 @@ abstract class administration_helper extends cache_helper {
* @return array array of lock summaries. * @return array array of lock summaries.
*/ */
public static function get_lock_summaries(): array { public static function get_lock_summaries(): array {
$locks = array(); $locks = [];
$instance = cache_config::instance(); $instance = config::instance();
$stores = $instance->get_all_stores(); $stores = $instance->get_all_stores();
foreach ($instance->get_locks() as $lock) { foreach ($instance->get_locks() as $lock) {
$default = !empty($lock['default']); $default = !empty($lock['default']);
if ($default) { if ($default) {
$name = new \lang_string($lock['name'], 'cache'); $name = new lang_string($lock['name'], 'cache');
} else { } else {
$name = $lock['name']; $name = $lock['name'];
} }
@ -277,12 +263,12 @@ abstract class administration_helper extends cache_helper {
$uses++; $uses++;
} }
} }
$lockdata = array( $lockdata = [
'name' => $name, 'name' => $name,
'default' => $default, 'default' => $default,
'uses' => $uses, 'uses' => $uses,
'type' => get_string('pluginname', $lock['type']) 'type' => get_string('pluginname', $lock['type']),
); ];
$locks[$lock['name']] = $lockdata; $locks[$lock['name']] = $lockdata;
} }
return $locks; return $locks;
@ -296,19 +282,19 @@ abstract class administration_helper extends cache_helper {
* @return array An array of lang_string's. * @return array An array of lang_string's.
*/ */
public static function get_definition_sharing_options(int $sharingoption, bool $isselectedoptions = true): array { public static function get_definition_sharing_options(int $sharingoption, bool $isselectedoptions = true): array {
$options = array(); $options = [];
$prefix = ($isselectedoptions) ? 'sharingselected' : 'sharing'; $prefix = ($isselectedoptions) ? 'sharingselected' : 'sharing';
if ($sharingoption & cache_definition::SHARING_ALL) { if ($sharingoption & definition::SHARING_ALL) {
$options[cache_definition::SHARING_ALL] = new \lang_string($prefix.'_all', 'cache'); $options[definition::SHARING_ALL] = new lang_string($prefix . '_all', 'cache');
} }
if ($sharingoption & cache_definition::SHARING_SITEID) { if ($sharingoption & definition::SHARING_SITEID) {
$options[cache_definition::SHARING_SITEID] = new \lang_string($prefix.'_siteid', 'cache'); $options[definition::SHARING_SITEID] = new lang_string($prefix . '_siteid', 'cache');
} }
if ($sharingoption & cache_definition::SHARING_VERSION) { if ($sharingoption & definition::SHARING_VERSION) {
$options[cache_definition::SHARING_VERSION] = new \lang_string($prefix.'_version', 'cache'); $options[definition::SHARING_VERSION] = new lang_string($prefix . '_version', 'cache');
} }
if ($sharingoption & cache_definition::SHARING_INPUT) { if ($sharingoption & definition::SHARING_INPUT) {
$options[cache_definition::SHARING_INPUT] = new \lang_string($prefix.'_input', 'cache'); $options[definition::SHARING_INPUT] = new lang_string($prefix . '_input', 'cache');
} }
return $options; return $options;
} }
@ -324,13 +310,13 @@ abstract class administration_helper extends cache_helper {
* 3. An array of default stores * 3. An array of default stores
*/ */
public static function get_definition_store_options(string $component, string $area): array { public static function get_definition_store_options(string $component, string $area): array {
$factory = cache_factory::instance(); $factory = factory::instance();
$definition = $factory->create_definition($component, $area); $definition = $factory->create_definition($component, $area);
$config = cache_config::instance(); $config = config::instance();
$currentstores = $config->get_stores_for_definition($definition); $currentstores = $config->get_stores_for_definition($definition);
$possiblestores = $config->get_stores($definition->get_mode(), $definition->get_requirements_bin()); $possiblestores = $config->get_stores($definition->get_mode(), $definition->get_requirements_bin());
$defaults = array(); $defaults = [];
foreach ($currentstores as $key => $store) { foreach ($currentstores as $key => $store) {
if (!empty($store['default'])) { if (!empty($store['default'])) {
$defaults[] = $key; $defaults[] = $key;
@ -343,7 +329,7 @@ abstract class administration_helper extends cache_helper {
$possiblestores[$key] = $store; $possiblestores[$key] = $store;
} }
} }
return array($currentstores, $possiblestores, $defaults); return [$currentstores, $possiblestores, $defaults];
} }
/** /**
@ -354,7 +340,7 @@ abstract class administration_helper extends cache_helper {
* @return array array of actions. * @return array array of actions.
*/ */
public function get_store_plugin_actions(string $name, array $plugindetails): array { public function get_store_plugin_actions(string $name, array $plugindetails): array {
return array(); return [];
} }
/** /**
@ -365,7 +351,7 @@ abstract class administration_helper extends cache_helper {
* @return array array of actions. * @return array array of actions.
*/ */
public function get_store_instance_actions(string $name, array $storedetails): array { public function get_store_instance_actions(string $name, array $storedetails): array {
return array(); return [];
} }
/** /**
@ -376,7 +362,7 @@ abstract class administration_helper extends cache_helper {
* @return array array of actions. * @return array array of actions.
*/ */
public function get_definition_actions(\context $context, array $definitionsummary): array { public function get_definition_actions(\context $context, array $definitionsummary): array {
return array(); return [];
} }
/** /**
@ -385,7 +371,7 @@ abstract class administration_helper extends cache_helper {
* @return array array of locks that are addable. * @return array array of locks that are addable.
*/ */
public function get_addable_lock_options(): array { public function get_addable_lock_options(): array {
return array(); return [];
} }
/** /**

View file

@ -14,6 +14,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
use core\exception\moodle_exception;
/** /**
* An application cache. * An application cache.
* *
@ -26,13 +31,12 @@
* *
* @internal don't use me directly. * @internal don't use me directly.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_application extends cache implements cache_loader_with_locking { class application_cache extends cache implements loader_with_locking_interface {
/** /**
* Lock identifier. * Lock identifier.
* This is used to ensure the lock belongs to the cache instance + definition + user. * This is used to ensure the lock belongs to the cache instance + definition + user.
@ -43,7 +47,7 @@ class cache_application extends cache implements cache_loader_with_locking {
/** /**
* Gets set to true if the cache's primary store natively supports locking. * Gets set to true if the cache's primary store natively supports locking.
* If it does then we use that, otherwise we need to instantiate a second store to use for locking. * If it does then we use that, otherwise we need to instantiate a second store to use for locking.
* @var cache_store * @var store
*/ */
protected $nativelocking = null; protected $nativelocking = null;
@ -62,7 +66,7 @@ class cache_application extends cache implements cache_loader_with_locking {
protected $requirelockingbeforewrite = false; protected $requirelockingbeforewrite = false;
/** /**
* Gets set to a cache_store to use for locking if the caches primary store doesn't support locking natively. * Gets set to a store to use for locking if the caches primary store doesn't support locking natively.
* @var cache_lock_interface * @var cache_lock_interface
*/ */
protected $cachelockinstance; protected $cachelockinstance;
@ -78,11 +82,11 @@ class cache_application extends cache implements cache_loader_with_locking {
* *
* You should not call this method from your code, instead you should use the cache::make methods. * You should not call this method from your code, instead you should use the cache::make methods.
* *
* @param cache_definition $definition * @param definition $definition
* @param cache_store $store * @param store $store
* @param cache_loader|cache_data_source $loader * @param loader_interface|data_source_interface $loader
*/ */
public function __construct(cache_definition $definition, cache_store $store, $loader = null) { public function __construct(definition $definition, store $store, $loader = null) {
parent::__construct($definition, $store, $loader); parent::__construct($definition, $store, $loader);
$this->nativelocking = $this->store_supports_native_locking(); $this->nativelocking = $this->store_supports_native_locking();
if ($definition->require_locking()) { if ($definition->require_locking()) {
@ -141,7 +145,7 @@ class cache_application extends cache implements cache_loader_with_locking {
// We need to release this lock later if the lock is not successful. // We need to release this lock later if the lock is not successful.
$releaseparent = true; $releaseparent = true;
} }
$hashedkey = cache_helper::hash_key($key, $this->get_definition()); $hashedkey = helper::hash_key($key, $this->get_definition());
$before = microtime(true); $before = microtime(true);
if ($this->nativelocking) { if ($this->nativelocking) {
$lock = $this->get_store()->acquire_lock($hashedkey, $this->get_identifier()); $lock = $this->get_store()->acquire_lock($hashedkey, $this->get_identifier());
@ -153,14 +157,25 @@ class cache_application extends cache implements cache_loader_with_locking {
if ($lock) { if ($lock) {
$this->locks[$hashedkey] = $lock; $this->locks[$hashedkey] = $lock;
if (MDL_PERF || $this->perfdebug) { if (MDL_PERF || $this->perfdebug) {
\core\lock\timing_wrapper_lock_factory::record_lock_data($after, $before, \core\lock\timing_wrapper_lock_factory::record_lock_data(
$this->get_definition()->get_id(), $hashedkey, $lock, $this->get_identifier() . $hashedkey); $after,
$before,
$this->get_definition()->get_id(),
$hashedkey,
$lock,
$this->get_identifier() . $hashedkey
);
} }
$releaseparent = false; $releaseparent = false;
return true; return true;
} else { } else {
throw new moodle_exception('ex_unabletolock', 'cache', '', null, throw new moodle_exception(
'store: ' . get_class($this->get_store()) . ', lock: ' . $hashedkey); 'ex_unabletolock',
'cache',
'',
null,
'store: ' . get_class($this->get_store()) . ', lock: ' . $hashedkey
);
} }
} finally { } finally {
// Release the parent lock if we acquired it, then threw an exception. // Release the parent lock if we acquired it, then threw an exception.
@ -178,7 +193,7 @@ class cache_application extends cache implements cache_loader_with_locking {
* someone else has the lock. * someone else has the lock.
*/ */
public function check_lock_state($key) { public function check_lock_state($key) {
$key = cache_helper::hash_key($key, $this->get_definition()); $key = helper::hash_key($key, $this->get_definition());
if (!empty($this->locks[$key])) { if (!empty($this->locks[$key])) {
return true; // Shortcut to save having to make a call to the cache store if the lock is held by this process. return true; // Shortcut to save having to make a call to the cache store if the lock is held by this process.
} }
@ -198,7 +213,7 @@ class cache_application extends cache implements cache_loader_with_locking {
*/ */
public function release_lock($key) { public function release_lock($key) {
$loaderkey = $key; $loaderkey = $key;
$key = cache_helper::hash_key($key, $this->get_definition()); $key = helper::hash_key($key, $this->get_definition());
if ($this->nativelocking) { if ($this->nativelocking) {
$released = $this->get_store()->release_lock($key, $this->get_identifier()); $released = $this->get_store()->release_lock($key, $this->get_identifier());
} else { } else {
@ -224,7 +239,7 @@ class cache_application extends cache implements cache_loader_with_locking {
*/ */
protected function ensure_cachelock_available() { protected function ensure_cachelock_available() {
if ($this->cachelockinstance === null) { if ($this->cachelockinstance === null) {
$this->cachelockinstance = cache_helper::get_cachelock_for_store($this->get_store()); $this->cachelockinstance = helper::get_cachelock_for_store($this->get_store());
} }
} }
@ -328,3 +343,8 @@ class cache_application extends cache implements cache_loader_with_locking {
return parent::delete_many($keys, $recurse); return parent::delete_many($keys, $recurse);
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(application_cache::class, \cache_application::class);

View file

@ -14,6 +14,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
use stdClass;
/** /**
* The main cache class. * The main cache class.
* *
@ -21,13 +26,12 @@
* In order to create an instance of a cache that they can work with they must call one of the static make methods belonging * In order to create an instance of a cache that they can work with they must call one of the static make methods belonging
* to this class. * to this class.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache implements cache_loader { class cache implements loader_interface {
/** /**
* @var int Constant for cache entries that do not have a version number * @var int Constant for cache entries that do not have a version number
*/ */
@ -51,13 +55,13 @@ class cache implements cache_loader {
/** /**
* The definition used when loading this cache if there was one. * The definition used when loading this cache if there was one.
* @var cache_definition * @var definition
*/ */
private $definition = false; private $definition = false;
/** /**
* The cache store that this loader will make use of. * The cache store that this loader will make use of.
* @var cache_store * @var store
*/ */
private $store; private $store;
@ -66,14 +70,14 @@ class cache implements cache_loader {
* If a cache request misses for the store belonging to this loader then the loader * If a cache request misses for the store belonging to this loader then the loader
* stored here will be checked next. * stored here will be checked next.
* If there is a loader here then $datasource must be false. * If there is a loader here then $datasource must be false.
* @var cache_loader|false * @var loader_interface|false
*/ */
private $loader = false; private $loader = false;
/** /**
* The data source to use if we need to load data (because if doesn't exist in the cache store). * The data source to use if we need to load data (because if doesn't exist in the cache store).
* If there is a data source here then $loader above must be false. * If there is a data source here then $loader above must be false.
* @var cache_data_source|false * @var data_source_interface|false
*/ */
private $datasource = false; private $datasource = false;
@ -105,7 +109,7 @@ class cache implements cache_loader {
* Items will be stored in this cache as they were provided. This ensure there is no unnecessary processing taking place. * Items will be stored in this cache as they were provided. This ensure there is no unnecessary processing taking place.
* @var array * @var array
*/ */
private $staticaccelerationarray = array(); private $staticaccelerationarray = [];
/** /**
* The number of items in the static acceleration array. Avoids count calls like you wouldn't believe. * The number of items in the static acceleration array. Avoids count calls like you wouldn't believe.
@ -120,7 +124,7 @@ class cache implements cache_loader {
* key that is first on this array. * key that is first on this array.
* @var array * @var array
*/ */
private $staticaccelerationkeys = array(); private $staticaccelerationkeys = [];
/** /**
* The maximum size of the static acceleration array. * The maximum size of the static acceleration array.
@ -168,7 +172,7 @@ class cache implements cache_loader {
/** /**
* Gets set to true if the cache's primary store natively supports locking. * Gets set to true if the cache's primary store natively supports locking.
* If it does then we use that, otherwise we need to instantiate a second store to use for locking. * If it does then we use that, otherwise we need to instantiate a second store to use for locking.
* @var cache_store|null * @var store|null
*/ */
protected $nativelocking = null; protected $nativelocking = null;
@ -179,17 +183,17 @@ class cache implements cache_loader {
* @param string $area The area for the definition * @param string $area The area for the definition
* @param array $identifiers Any additional identifiers that should be provided to the definition. * @param array $identifiers Any additional identifiers that should be provided to the definition.
* @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
* @return cache_application|cache_session|cache_store * @return application_cache|session_cache|store
*/ */
public static function make($component, $area, array $identifiers = array(), $unused = null) { public static function make($component, $area, array $identifiers = [], $unused = null) {
$factory = cache_factory::instance(); $factory = factory::instance();
return $factory->create_cache_from_definition($component, $area, $identifiers); return $factory->create_cache_from_definition($component, $area, $identifiers);
} }
/** /**
* Creates a new cache instance based upon the given params. * Creates a new cache instance based upon the given params.
* *
* @param int $mode One of cache_store::MODE_* * @param int $mode One of store::MODE_*
* @param string $component The component this cache relates to. * @param string $component The component this cache relates to.
* @param string $area The area this cache relates to. * @param string $area The area this cache relates to.
* @param array $identifiers Any additional identifiers that should be provided to the definition. * @param array $identifiers Any additional identifiers that should be provided to the definition.
@ -198,10 +202,10 @@ class cache implements cache_loader {
* - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
* - staticacceleration : If set to true the cache will hold onto data passing through it. * - staticacceleration : If set to true the cache will hold onto data passing through it.
* - staticaccelerationsize : The max size for the static acceleration array. * - staticaccelerationsize : The max size for the static acceleration array.
* @return cache_application|cache_session|cache_request * @return application_cache|session_cache|request_cache
*/ */
public static function make_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) { public static function make_from_params($mode, $component, $area, array $identifiers = [], array $options = []) {
$factory = cache_factory::instance(); $factory = factory::instance();
return $factory->create_cache_from_params($mode, $component, $area, $identifiers, $options); return $factory->create_cache_from_params($mode, $component, $area, $identifiers, $options);
} }
@ -210,25 +214,25 @@ class cache implements cache_loader {
* *
* You should not call this method from your code, instead you should use the cache::make methods. * You should not call this method from your code, instead you should use the cache::make methods.
* *
* This method is public so that the cache_factory is able to instantiate cache instances. * This method is public so that the factory is able to instantiate cache instances.
* Ideally we would make this method protected and expose its construction to the factory method internally somehow. * Ideally we would make this method protected and expose its construction to the factory method internally somehow.
* The factory class is responsible for this in order to centralise the storage of instances once created. This way if needed * The factory class is responsible for this in order to centralise the storage of instances once created. This way if needed
* we can force a reset of the cache API (used during unit testing). * we can force a reset of the cache API (used during unit testing).
* *
* @param cache_definition $definition The definition for the cache instance. * @param definition $definition The definition for the cache instance.
* @param cache_store $store The store that cache should use. * @param store $store The store that cache should use.
* @param cache_loader|cache_data_source $loader The next loader in the chain or the data source if there is one and there * @param loader_interface|data_source_interface $loader The next loader in the chain or the data source if there is one
* are no other cache_loaders in the chain. * and there are no other loader_interfaces in the chain.
*/ */
public function __construct(cache_definition $definition, cache_store $store, $loader = null) { public function __construct(definition $definition, store $store, $loader = null) {
global $CFG; global $CFG;
$this->definition = $definition; $this->definition = $definition;
$this->store = $store; $this->store = $store;
$this->storetype = get_class($store); $this->storetype = get_class($store);
$this->perfdebug = (!empty($CFG->perfdebug) and $CFG->perfdebug > 7); $this->perfdebug = (!empty($CFG->perfdebug) and $CFG->perfdebug > 7);
if ($loader instanceof cache_loader) { if ($loader instanceof loader_interface) {
$this->set_loader($loader); $this->set_loader($loader);
} else if ($loader instanceof cache_data_source) { } else if ($loader instanceof data_source_interface) {
$this->set_data_source($loader); $this->set_data_source($loader);
} }
$this->definition->generate_definition_hash(); $this->definition->generate_definition_hash();
@ -242,9 +246,9 @@ class cache implements cache_loader {
/** /**
* Set the loader for this cache. * Set the loader for this cache.
* *
* @param cache_loader $loader * @param loader_interface $loader
*/ */
protected function set_loader(cache_loader $loader): void { protected function set_loader(loader_interface $loader): void {
$this->loader = $loader; $this->loader = $loader;
// Mark the loader as a sub (chained) loader. // Mark the loader as a sub (chained) loader.
@ -254,9 +258,9 @@ class cache implements cache_loader {
/** /**
* Set the data source for this cache. * Set the data source for this cache.
* *
* @param cache_data_source $datasource * @param data_source_interface $datasource
*/ */
protected function set_data_source(cache_data_source $datasource): void { protected function set_data_source(data_source_interface $datasource): void {
$this->datasource = $datasource; $this->datasource = $datasource;
} }
@ -298,9 +302,9 @@ class cache implements cache_loader {
if ($this->definition->set_identifiers($identifiers)) { if ($this->definition->set_identifiers($identifiers)) {
// As static acceleration uses input keys and not parsed keys // As static acceleration uses input keys and not parsed keys
// it much be cleared when the identifier set is changed. // it much be cleared when the identifier set is changed.
$this->staticaccelerationarray = array(); $this->staticaccelerationarray = [];
if ($this->staticaccelerationsize !== false) { if ($this->staticaccelerationsize !== false) {
$this->staticaccelerationkeys = array(); $this->staticaccelerationkeys = [];
$this->staticaccelerationcount = 0; $this->staticaccelerationcount = 0;
} }
} }
@ -354,7 +358,7 @@ class cache implements cache_loader {
*/ */
$cache = self::make('core', 'eventinvalidation'); $cache = self::make('core', 'eventinvalidation');
$events = $cache->get_many($this->definition->get_invalidation_events()); $events = $cache->get_many($this->definition->get_invalidation_events());
$todelete = array(); $todelete = [];
$purgeall = false; $purgeall = false;
// Iterate the returned data for the events. // Iterate the returned data for the events.
@ -456,7 +460,7 @@ class cache implements cache_loader {
} }
} else { } else {
// If there's no result, obviously it doesn't meet the required version. // If there's no result, obviously it doesn't meet the required version.
if (!cache_helper::result_found($result)) { if (!helper::result_found($result)) {
return false; return false;
} }
if (!($result instanceof \core_cache\version_wrapper)) { if (!($result instanceof \core_cache\version_wrapper)) {
@ -489,7 +493,7 @@ class cache implements cache_loader {
if ($usesstaticacceleration) { if ($usesstaticacceleration) {
$result = $this->static_acceleration_get($key); $result = $this->static_acceleration_get($key);
if (cache_helper::result_found($result) && self::check_version($result, $requiredversion)) { if (helper::result_found($result) && self::check_version($result, $requiredversion)) {
if ($requiredversion === self::VERSION_NONE) { if ($requiredversion === self::VERSION_NONE) {
return $result; return $result;
} else { } else {
@ -504,7 +508,7 @@ class cache implements cache_loader {
// 3. Get it from the store. Obviously wasn't in the static acceleration array. // 3. Get it from the store. Obviously wasn't in the static acceleration array.
$result = $this->store->get($parsedkey); $result = $this->store->get($parsedkey);
if (cache_helper::result_found($result)) { if (helper::result_found($result)) {
// Check the result has at least the required version. // Check the result has at least the required version.
try { try {
$validversion = self::check_version($result, $requiredversion); $validversion = self::check_version($result, $requiredversion);
@ -534,14 +538,14 @@ class cache implements cache_loader {
$this->store->delete($parsedkey); $this->store->delete($parsedkey);
} }
} }
if (cache_helper::result_found($result)) { if (helper::result_found($result)) {
// Look to see if there's a TTL wrapper. It might be inside a version wrapper. // Look to see if there's a TTL wrapper. It might be inside a version wrapper.
if ($requiredversion !== self::VERSION_NONE) { if ($requiredversion !== self::VERSION_NONE) {
$ttlconsider = $result->data; $ttlconsider = $result->data;
} else { } else {
$ttlconsider = $result; $ttlconsider = $result;
} }
if ($ttlconsider instanceof cache_ttl_wrapper) { if ($ttlconsider instanceof ttl_wrapper) {
if ($ttlconsider->has_expired()) { if ($ttlconsider->has_expired()) {
$this->store->delete($parsedkey); $this->store->delete($parsedkey);
$result = false; $result = false;
@ -561,16 +565,16 @@ class cache implements cache_loader {
$actualversion = $result->version; $actualversion = $result->version;
$result = $result->data; $result = $result->data;
} }
if ($result instanceof cache_cached_object) { if ($result instanceof cached_object) {
$result = $result->restore_object(); $result = $result->restore_object();
} }
} }
// 4. Load if from the loader/datasource if we don't already have it. // 4. Load if from the loader/datasource if we don't already have it.
$setaftervalidation = false; $setaftervalidation = false;
if (!cache_helper::result_found($result)) { if (!helper::result_found($result)) {
if ($this->perfdebug) { if ($this->perfdebug) {
cache_helper::record_cache_miss($this->store, $this->definition); helper::record_cache_miss($this->store, $this->definition);
} }
if ($this->loader !== false) { if ($this->loader !== false) {
// We must pass the original (unparsed) key to the next loader in the chain. // We must pass the original (unparsed) key to the next loader in the chain.
@ -585,7 +589,7 @@ class cache implements cache_loader {
if ($requiredversion === self::VERSION_NONE) { if ($requiredversion === self::VERSION_NONE) {
$result = $this->datasource->load_for_cache($key); $result = $this->datasource->load_for_cache($key);
} else { } else {
if (!$this->datasource instanceof cache_data_source_versionable) { if (!$this->datasource instanceof versionable_data_source_interface) {
throw new \coding_exception('Data source is not versionable'); throw new \coding_exception('Data source is not versionable');
} }
$result = $this->datasource->load_for_cache_versioned($key, $requiredversion, $actualversion); $result = $this->datasource->load_for_cache_versioned($key, $requiredversion, $actualversion);
@ -594,13 +598,13 @@ class cache implements cache_loader {
} }
} }
} }
$setaftervalidation = (cache_helper::result_found($result)); $setaftervalidation = (helper::result_found($result));
} else if ($this->perfdebug) { } else if ($this->perfdebug) {
$readbytes = $this->store->get_last_io_bytes(); $readbytes = $this->store->get_last_io_bytes();
cache_helper::record_cache_hit($this->store, $this->definition, 1, $readbytes); helper::record_cache_hit($this->store, $this->definition, 1, $readbytes);
} }
// 5. Validate strictness. // 5. Validate strictness.
if ($strictness === MUST_EXIST && !cache_helper::result_found($result)) { if ($strictness === MUST_EXIST && !helper::result_found($result)) {
throw new coding_exception('Requested key did not exist in any cache stores and could not be loaded.'); throw new coding_exception('Requested key did not exist in any cache stores and could not be loaded.');
} }
// 6. Set it to the store if we got it from the loader/datasource. Only set to this direct // 6. Set it to the store if we got it from the loader/datasource. Only set to this direct
@ -656,12 +660,12 @@ class cache implements cache_loader {
*/ */
public function get_many(array $keys, $strictness = IGNORE_MISSING) { public function get_many(array $keys, $strictness = IGNORE_MISSING) {
$keysparsed = array(); $keysparsed = [];
$parsedkeys = array(); $parsedkeys = [];
$resultpersist = array(); $resultpersist = [];
$resultstore = array(); $resultstore = [];
$keystofind = array(); $keystofind = [];
$readbytes = cache_store::IO_BYTES_NOT_SUPPORTED; $readbytes = store::IO_BYTES_NOT_SUPPORTED;
// First up check the persist cache for each key. // First up check the persist cache for each key.
$isusingpersist = $this->use_static_acceleration(); $isusingpersist = $this->use_static_acceleration();
@ -690,7 +694,7 @@ class cache implements cache_loader {
} }
// Process each item in the result to "unwrap" it. // Process each item in the result to "unwrap" it.
foreach ($resultstore as $key => $value) { foreach ($resultstore as $key => $value) {
if ($value instanceof cache_ttl_wrapper) { if ($value instanceof ttl_wrapper) {
if ($value->has_expired()) { if ($value->has_expired()) {
$value = false; $value = false;
} else { } else {
@ -700,7 +704,7 @@ class cache implements cache_loader {
if ($value !== false && $this->use_static_acceleration()) { if ($value !== false && $this->use_static_acceleration()) {
$this->static_acceleration_set($keystofind[$key], $value); $this->static_acceleration_set($keystofind[$key], $value);
} }
if ($value instanceof cache_cached_object) { if ($value instanceof cached_object) {
$value = $value->restore_object(); $value = $value->restore_object();
} }
$resultstore[$key] = $value; $resultstore[$key] = $value;
@ -716,7 +720,7 @@ class cache implements cache_loader {
$usingloader = ($this->loader !== false); $usingloader = ($this->loader !== false);
$usingsource = (!$usingloader && ($this->datasource !== false)); $usingsource = (!$usingloader && ($this->datasource !== false));
if ($usingloader || $usingsource) { if ($usingloader || $usingsource) {
$missingkeys = array(); $missingkeys = [];
foreach ($result as $key => $value) { foreach ($result as $key => $value) {
if ($value === false) { if ($value === false) {
$missingkeys[] = $parsedkeys[$key]; $missingkeys[] = $parsedkeys[$key];
@ -751,7 +755,7 @@ class cache implements cache_loader {
} }
// Create an array with the original keys and the found values. This will be what we return. // Create an array with the original keys and the found values. This will be what we return.
$fullresult = array(); $fullresult = [];
foreach ($result as $key => $value) { foreach ($result as $key => $value) {
if (!is_scalar($value)) { if (!is_scalar($value)) {
// If data is an object it will be a reference. // If data is an object it will be a reference.
@ -783,8 +787,8 @@ class cache implements cache_loader {
$hits++; $hits++;
} }
} }
cache_helper::record_cache_hit($this->store, $this->definition, $hits, $readbytes); helper::record_cache_hit($this->store, $this->definition, $hits, $readbytes);
cache_helper::record_cache_miss($this->store, $this->definition, $misses); helper::record_cache_miss($this->store, $this->definition, $misses);
} }
// Return the result. Phew! // Return the result. Phew!
@ -858,8 +862,8 @@ class cache implements cache_loader {
} }
$usestaticacceleration = $this->use_static_acceleration(); $usestaticacceleration = $this->use_static_acceleration();
if (is_object($data) && $data instanceof cacheable_object) { if (is_object($data) && $data instanceof cacheable_object_interface) {
$data = new cache_cached_object($data); $data = new cached_object($data);
} else if (!$this->store->supports_dereferencing_objects() && !is_scalar($data)) { } else if (!$this->store->supports_dereferencing_objects() && !is_scalar($data)) {
// If data is an object it will be a reference. // If data is an object it will be a reference.
// If data is an array if may contain references. // If data is an array if may contain references.
@ -878,7 +882,7 @@ class cache implements cache_loader {
} }
if ($this->has_a_ttl() && !$this->store_supports_native_ttl()) { if ($this->has_a_ttl() && !$this->store_supports_native_ttl()) {
$data = new cache_ttl_wrapper($data, $this->definition->get_ttl()); $data = new ttl_wrapper($data, $this->definition->get_ttl());
} }
$parsedkey = $this->parse_key($key); $parsedkey = $this->parse_key($key);
@ -888,8 +892,12 @@ class cache implements cache_loader {
$success = $this->store->set($parsedkey, $data); $success = $this->store->set($parsedkey, $data);
if ($this->perfdebug) { if ($this->perfdebug) {
cache_helper::record_cache_set($this->store, $this->definition, 1, helper::record_cache_set(
$this->store->get_last_io_bytes()); $this->store,
$this->definition,
1,
$this->store->get_last_io_bytes()
);
} }
return $success; return $success;
} }
@ -996,8 +1004,8 @@ class cache implements cache_loader {
$usestaticaccelerationarray = $this->use_static_acceleration(); $usestaticaccelerationarray = $this->use_static_acceleration();
$needsdereferencing = !$this->store->supports_dereferencing_objects(); $needsdereferencing = !$this->store->supports_dereferencing_objects();
foreach ($keyvaluearray as $key => $value) { foreach ($keyvaluearray as $key => $value) {
if (is_object($value) && $value instanceof cacheable_object) { if (is_object($value) && $value instanceof cacheable_object_interface) {
$value = new cache_cached_object($value); $value = new cached_object($value);
} else if ($needsdereferencing && !is_scalar($value)) { } else if ($needsdereferencing && !is_scalar($value)) {
// If data is an object it will be a reference. // If data is an object it will be a reference.
// If data is an array if may contain references. // If data is an array if may contain references.
@ -1009,17 +1017,21 @@ class cache implements cache_loader {
$this->static_acceleration_set($key, $value); $this->static_acceleration_set($key, $value);
} }
if ($simulatettl) { if ($simulatettl) {
$value = new cache_ttl_wrapper($value, $this->definition->get_ttl()); $value = new ttl_wrapper($value, $this->definition->get_ttl());
} }
$data[$key] = array( $data[$key] = [
'key' => $this->parse_key($key), 'key' => $this->parse_key($key),
'value' => $value 'value' => $value,
); ];
} }
$successfullyset = $this->store->set_many($data); $successfullyset = $this->store->set_many($data);
if ($this->perfdebug && $successfullyset) { if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->store, $this->definition, $successfullyset, helper::record_cache_set(
$this->store->get_last_io_bytes()); $this->store,
$this->definition,
$successfullyset,
$this->store->get_last_io_bytes()
);
} }
return $successfullyset; return $successfullyset;
} }
@ -1056,7 +1068,7 @@ class cache implements cache_loader {
// The data has a TTL and the store doesn't support it natively. // The data has a TTL and the store doesn't support it natively.
// We must fetch the data and expect a ttl wrapper. // We must fetch the data and expect a ttl wrapper.
$data = $this->store->get($parsedkey); $data = $this->store->get($parsedkey);
$has = ($data instanceof cache_ttl_wrapper && !$data->has_expired()); $has = ($data instanceof ttl_wrapper && !$data->has_expired());
} else if (!$this->store_supports_key_awareness()) { } else if (!$this->store_supports_key_awareness()) {
// The store doesn't support key awareness, get the data and check it manually... puke. // The store doesn't support key awareness, get the data and check it manually... puke.
// Either no TTL is set of the store supports its handling natively. // Either no TTL is set of the store supports its handling natively.
@ -1103,7 +1115,7 @@ class cache implements cache_loader {
} }
return true; return true;
} }
$parsedkeys = array_map(array($this, 'parse_key'), $keys); $parsedkeys = array_map([$this, 'parse_key'], $keys);
return $this->store->has_all($parsedkeys); return $this->store->has_all($parsedkeys);
} }
@ -1137,7 +1149,7 @@ class cache implements cache_loader {
} }
} }
} }
$parsedkeys = array_map(array($this, 'parse_key'), $keys); $parsedkeys = array_map([$this, 'parse_key'], $keys);
return $this->store->has_any($parsedkeys); return $this->store->has_any($parsedkeys);
} }
@ -1177,7 +1189,7 @@ class cache implements cache_loader {
// Delete from the bottom of the stack first. // Delete from the bottom of the stack first.
$this->loader->delete_many($keys, $recurse); $this->loader->delete_many($keys, $recurse);
} }
$parsedkeys = array_map(array($this, 'parse_key'), $keys); $parsedkeys = array_map([$this, 'parse_key'], $keys);
return $this->store->delete_many($parsedkeys); return $this->store->delete_many($parsedkeys);
} }
@ -1211,8 +1223,8 @@ class cache implements cache_loader {
$result['key'] = $key; $result['key'] = $key;
return $result; return $result;
} }
// If not we need to generate a hash and to for that we use the cache_helper. // If not we need to generate a hash and to for that we use the helper.
return cache_helper::hash_key($key, $this->definition); return helper::hash_key($key, $this->definition);
} }
/** /**
@ -1237,7 +1249,7 @@ class cache implements cache_loader {
/** /**
* Returns the cache definition. * Returns the cache definition.
* *
* @return cache_definition * @return definition
*/ */
protected function get_definition() { protected function get_definition() {
return $this->definition; return $this->definition;
@ -1246,7 +1258,7 @@ class cache implements cache_loader {
/** /**
* Returns the cache store * Returns the cache store
* *
* @return cache_store * @return store
*/ */
protected function get_store() { protected function get_store() {
return $this->store; return $this->store;
@ -1266,7 +1278,7 @@ class cache implements cache_loader {
* Returns the data source associated with this cache. * Returns the data source associated with this cache.
* *
* @since Moodle 2.4.4 * @since Moodle 2.4.4
* @return cache_data_source|false * @return data_source_interface|false
*/ */
protected function get_datasource() { protected function get_datasource() {
return $this->datasource; return $this->datasource;
@ -1279,7 +1291,7 @@ class cache implements cache_loader {
*/ */
protected function store_supports_key_awareness() { protected function store_supports_key_awareness() {
if ($this->supportskeyawareness === null) { if ($this->supportskeyawareness === null) {
$this->supportskeyawareness = ($this->store instanceof cache_is_key_aware); $this->supportskeyawareness = ($this->store instanceof key_aware_cache_interface);
} }
return $this->supportskeyawareness; return $this->supportskeyawareness;
} }
@ -1291,7 +1303,7 @@ class cache implements cache_loader {
*/ */
protected function store_supports_native_locking() { protected function store_supports_native_locking() {
if ($this->nativelocking === null) { if ($this->nativelocking === null) {
$this->nativelocking = ($this->store instanceof cache_is_lockable); $this->nativelocking = ($this->store instanceof lockable_cache_interface);
} }
return $this->nativelocking; return $this->nativelocking;
} }
@ -1359,7 +1371,7 @@ class cache implements cache_loader {
} else { } else {
$data = $this->staticaccelerationarray[$key]['data']; $data = $this->staticaccelerationarray[$key]['data'];
if ($data instanceof cache_cached_object) { if ($data instanceof cached_object) {
$result = $data->restore_object(); $result = $data->restore_object();
} else if ($this->staticaccelerationarray[$key]['serialized']) { } else if ($this->staticaccelerationarray[$key]['serialized']) {
$result = unserialize($data); $result = unserialize($data);
@ -1367,9 +1379,9 @@ class cache implements cache_loader {
$result = $data; $result = $data;
} }
} }
if (cache_helper::result_found($result)) { if (helper::result_found($result)) {
if ($this->perfdebug) { if ($this->perfdebug) {
cache_helper::record_cache_hit(cache_store::STATIC_ACCEL, $this->definition); helper::record_cache_hit(store::STATIC_ACCEL, $this->definition);
} }
if ($this->staticaccelerationsize > 1 && $this->staticaccelerationcount > 1) { if ($this->staticaccelerationsize > 1 && $this->staticaccelerationcount > 1) {
// Check to see if this is the last item on the static acceleration keys array. // Check to see if this is the last item on the static acceleration keys array.
@ -1383,7 +1395,7 @@ class cache implements cache_loader {
return $result; return $result;
} else { } else {
if ($this->perfdebug) { if ($this->perfdebug) {
cache_helper::record_cache_miss(cache_store::STATIC_ACCEL, $this->definition); helper::record_cache_miss(store::STATIC_ACCEL, $this->definition);
} }
return false; return false;
} }
@ -1415,8 +1427,10 @@ class cache implements cache_loader {
// 1. A known scalar safe value. // 1. A known scalar safe value.
// 2. A definition that says it's simpledata. We trust it that it doesn't contain dangerous references. // 2. A definition that says it's simpledata. We trust it that it doesn't contain dangerous references.
// 3. An object that handles dereferencing by itself. // 3. An object that handles dereferencing by itself.
if (is_scalar($data) || $this->definition->uses_simple_data() if (
|| $data instanceof cache_cached_object) { is_scalar($data) || $this->definition->uses_simple_data()
|| $data instanceof cached_object
) {
$this->staticaccelerationarray[$key]['data'] = $data; $this->staticaccelerationarray[$key]['data'] = $data;
$this->staticaccelerationarray[$key]['serialized'] = false; $this->staticaccelerationarray[$key]['serialized'] = false;
} else { } else {
@ -1463,9 +1477,9 @@ class cache implements cache_loader {
* Purge the static acceleration cache. * Purge the static acceleration cache.
*/ */
protected function static_acceleration_purge() { protected function static_acceleration_purge() {
$this->staticaccelerationarray = array(); $this->staticaccelerationarray = [];
if ($this->staticaccelerationsize !== false) { if ($this->staticaccelerationsize !== false) {
$this->staticaccelerationkeys = array(); $this->staticaccelerationkeys = [];
$this->staticaccelerationcount = 0; $this->staticaccelerationcount = 0;
} }
} }
@ -1528,10 +1542,10 @@ class cache implements cache_loader {
} }
// The token for when the cache was last invalidated. // The token for when the cache was last invalidated.
list($atime) = explode('-', "{$tokena}-", 2); [$atime] = explode('-', "{$tokena}-", 2);
// The token for this cache. // The token for this cache.
list($btime) = explode('-', "{$tokenb}-", 2); [$btime] = explode('-', "{$tokenb}-", 2);
if ($atime >= $btime) { if ($atime >= $btime) {
// Token A is newer. // Token A is newer.
@ -1549,3 +1563,8 @@ class cache implements cache_loader {
public function purge_current_user() { public function purge_current_user() {
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cache::class, \cache::class);

View file

@ -14,10 +14,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cache lock interface * Cache lock interface.
* *
* This interface needs to be inherited by all cache lock plugins. * This interface needs to be inherited by all cache lock plugins.
*
* @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_lock_interface { interface cache_lock_interface {
/** /**
@ -26,7 +32,7 @@ interface cache_lock_interface {
* @param string $name The unique name of the lock instance * @param string $name The unique name of the lock instance
* @param array $configuration * @param array $configuration
*/ */
public function __construct($name, array $configuration = array()); public function __construct($name, array $configuration = []);
/** /**
* Acquires a lock on a given key. * Acquires a lock on a given key.
@ -72,3 +78,8 @@ interface cache_lock_interface {
*/ */
public function __destruct(); public function __destruct();
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cache_lock_interface::class, \cache_lock_interface::class);

View file

@ -14,6 +14,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
use ArrayObject;
/** /**
* An array of cacheable objects. * An array of cacheable objects.
* *
@ -41,28 +46,28 @@
* *
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package core_cache
*/ */
class cacheable_object_array extends ArrayObject implements cacheable_object { class cacheable_object_array extends ArrayObject implements cacheable_object_interface {
/** /**
* Constructs a new array object instance. * Constructs a new array object instance.
* @param array $items * @param array $items
*/ */
final public function __construct(array $items = array()) { final public function __construct(array $items = []) {
parent::__construct($items, ArrayObject::STD_PROP_LIST); parent::__construct($items, ArrayObject::STD_PROP_LIST);
} }
/** /**
* Returns the data to cache for this object. * Returns the data to cache for this object.
* *
* @return array An array of cache_cached_object instances. * @return cached_object[] An array of cached_object instances.
* @throws coding_exception * @throws coding_exception
*/ */
final public function prepare_to_cache() { final public function prepare_to_cache() {
$result = array(); $result = [];
foreach ($this as $key => $value) { foreach ($this as $key => $value) {
if ($value instanceof cacheable_object) { if ($value instanceof cacheable_object_interface) {
$value = new cache_cached_object($value); $value = new cached_object($value);
} else { } else {
throw new coding_exception('Only cacheable_object instances can be added to a cacheable_array'); throw new coding_exception('Only cacheable_object instances can be added to a cacheable_array');
} }
@ -75,14 +80,14 @@ class cacheable_object_array extends ArrayObject implements cacheable_object {
* Returns the cacheable_object_array that was originally sent to the cache. * Returns the cacheable_object_array that was originally sent to the cache.
* *
* @param array $data * @param array $data
* @return cacheable_object_array * @return self
* @throws coding_exception * @throws coding_exception
*/ */
final public static function wake_from_cache($data) { final public static function wake_from_cache($data) {
if (!is_array($data)) { if (!is_array($data)) {
throw new coding_exception('Invalid data type when reviving cacheable_array data'); throw new coding_exception('Invalid data type when reviving cacheable_array data');
} }
$result = array(); $result = [];
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$result[$key] = $value->restore_object(); $result[$key] = $value->restore_object();
} }
@ -90,3 +95,8 @@ class cacheable_object_array extends ArrayObject implements cacheable_object {
return new $class($result); return new $class($result);
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cacheable_object_array::class, \cacheable_object_array::class);

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cacheable object. * Cacheable object.
* *
@ -22,9 +24,12 @@
* Think of it like serialisation and the __sleep and __wakeup methods. * Think of it like serialisation and the __sleep and __wakeup methods.
* This is used because cache stores are responsible for how they interact with data and what they do when storing it. This * This is used because cache stores are responsible for how they interact with data and what they do when storing it. This
* interface ensures there is always a guaranteed action. * interface ensures there is always a guaranteed action.
*
* @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cacheable_object { interface cacheable_object_interface {
/** /**
* Prepares the object for caching. Works like the __sleep method. * Prepares the object for caching. Works like the __sleep method.
* *
@ -41,3 +46,8 @@ interface cacheable_object {
*/ */
public static function wake_from_cache($data); public static function wake_from_cache($data);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cacheable_object_interface::class, \cacheable_object::class);

View file

@ -14,18 +14,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* A cached object wrapper. * A cached object wrapper.
* *
* This class gets used when the data is an object that has implemented the cacheable_object interface. * This class gets used when the data is an object that has implemented the cacheable_object_interface interface.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_cached_object { class cached_object {
/** /**
* The class of the cacheable object * The class of the cacheable object
* @var string * @var string
@ -33,22 +34,22 @@ class cache_cached_object {
protected $class; protected $class;
/** /**
* The data returned by the cacheable_object prepare_to_cache method. * The data returned by the cacheable_object_interface prepare_to_cache method.
* @var mixed * @var mixed
*/ */
protected $data; protected $data;
/** /**
* Constructs a cached object wrapper. * Constructs a cached object wrapper.
* @param cacheable_object $obj * @param cacheable_object_interface $obj
*/ */
public function __construct(cacheable_object $obj) { public function __construct(cacheable_object_interface $obj) {
$this->class = get_class($obj); $this->class = get_class($obj);
$this->data = $obj->prepare_to_cache(); $this->data = $obj->prepare_to_cache();
} }
/** /**
* Restores the data as an instance of the cacheable_object class. * Restores the data as an instance of the cacheable_object_interface class.
* @return object * @return object
*/ */
public function restore_object() { public function restore_object() {
@ -56,3 +57,8 @@ class cache_cached_object {
return $class::wake_from_cache($this->data); return $class::wake_from_cache($this->data);
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cached_object::class, \cache_cached_object::class);

View file

@ -14,48 +14,54 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core_cache\exception\cache_exception;
use cache_factory as factory;
use cache_helper as helper;
use cache_store as store;
/** /**
* Cache configuration reader. * Cache configuration reader.
* *
* This class is used to interact with the cache's configuration. * This class is used to interact with the cache's configuration.
* The configuration is stored in the Moodle data directory. * The configuration is stored in the Moodle data directory.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_config { class config {
/** /**
* The configured stores * The configured stores
* @var array * @var array
*/ */
protected $configstores = array(); protected $configstores = [];
/** /**
* The configured mode mappings * The configured mode mappings
* @var array * @var array
*/ */
protected $configmodemappings = array(); protected $configmodemappings = [];
/** /**
* The configured definitions as picked up from cache.php files * The configured definitions as picked up from cache.php files
* @var array * @var array
*/ */
protected $configdefinitions = array(); protected $configdefinitions = [];
/** /**
* The definition mappings that have been configured. * The definition mappings that have been configured.
* @var array * @var array
*/ */
protected $configdefinitionmappings = array(); protected $configdefinitionmappings = [];
/** /**
* An array of configured cache lock instances. * An array of configured cache lock instances.
* @var array * @var array
*/ */
protected $configlocks = array(); protected $configlocks = [];
/** /**
* The site identifier used when the cache config was last saved. * The site identifier used when the cache config was last saved.
@ -71,12 +77,12 @@ class cache_config {
} }
/** /**
* Gets an instance of the cache_configuration class. * Gets an instance of the cache config class.
* *
* @return cache_config * @return self
*/ */
public static function instance() { public static function instance() {
$factory = cache_factory::instance(); $factory = factory::instance();
return $factory->create_config_instance(); return $factory->create_config_instance();
} }
@ -101,14 +107,14 @@ class cache_config {
$path = $CFG->altcacheconfigpath; $path = $CFG->altcacheconfigpath;
if (is_dir($path) && is_writable($path)) { if (is_dir($path) && is_writable($path)) {
// Its a writable directory, thats fine. // Its a writable directory, thats fine.
return $path.'/cacheconfig.php'; return $path . '/cacheconfig.php';
} else if (is_writable(dirname($path)) && (!file_exists($path) || is_writable($path))) { } else if (is_writable(dirname($path)) && (!file_exists($path) || is_writable($path))) {
// Its a file, either it doesn't exist and the directory is writable or the file exists and is writable. // Its a file, either it doesn't exist and the directory is writable or the file exists and is writable.
return $path; return $path;
} }
} }
// Return the default location within dataroot. // Return the default location within dataroot.
return $CFG->dataroot.'/muc/config.php'; return $CFG->dataroot . '/muc/config.php';
} }
/** /**
@ -124,11 +130,11 @@ class cache_config {
$configuration = $this->include_configuration(); $configuration = $this->include_configuration();
} }
$this->configstores = array(); $this->configstores = [];
$this->configdefinitions = array(); $this->configdefinitions = [];
$this->configlocks = array(); $this->configlocks = [];
$this->configmodemappings = array(); $this->configmodemappings = [];
$this->configdefinitionmappings = array(); $this->configdefinitionmappings = [];
$siteidentifier = 'unknown'; $siteidentifier = 'unknown';
if (array_key_exists('siteidentifier', $configuration)) { if (array_key_exists('siteidentifier', $configuration)) {
@ -160,7 +166,7 @@ class cache_config {
} }
// Filter the stores. // Filter the stores.
$availableplugins = cache_helper::early_get_cache_plugins(); $availableplugins = helper::early_get_cache_plugins();
foreach ($configuration['stores'] as $store) { foreach ($configuration['stores'] as $store) {
if (!is_array($store) || !array_key_exists('name', $store) || !array_key_exists('plugin', $store)) { if (!is_array($store) || !array_key_exists('name', $store) || !array_key_exists('plugin', $store)) {
// Not a valid instance configuration. // Not a valid instance configuration.
@ -168,25 +174,25 @@ class cache_config {
continue; continue;
} }
$plugin = $store['plugin']; $plugin = $store['plugin'];
$class = 'cachestore_'.$plugin; $class = 'cachestore_' . $plugin;
$exists = array_key_exists($plugin, $availableplugins); $exists = array_key_exists($plugin, $availableplugins);
if (!$exists) { if (!$exists) {
// Not a valid plugin, or has been uninstalled, just skip it an carry on. // Not a valid plugin, or has been uninstalled, just skip it an carry on.
debugging('Invalid cache store in config. Not an available plugin.', DEBUG_DEVELOPER); debugging('Invalid cache store in config. Not an available plugin.', DEBUG_DEVELOPER);
continue; continue;
} }
$file = $CFG->dirroot.'/cache/stores/'.$plugin.'/lib.php'; $file = $CFG->dirroot . '/cache/stores/' . $plugin . '/lib.php';
if (!class_exists($class) && file_exists($file)) { if (!class_exists($class) && file_exists($file)) {
require_once($file); require_once($file);
} }
if (!class_exists($class)) { if (!class_exists($class)) {
continue; continue;
} }
if (!array_key_exists('cache_store', class_parents($class))) { if (!array_key_exists(store::class, class_parents($class))) {
continue; continue;
} }
if (!array_key_exists('configuration', $store) || !is_array($store['configuration'])) { if (!array_key_exists('configuration', $store) || !is_array($store['configuration'])) {
$store['configuration'] = array(); $store['configuration'] = [];
} }
$store['class'] = $class; $store['class'] = $class;
$store['default'] = !empty($store['default']); $store['default'] = !empty($store['default']);
@ -285,8 +291,8 @@ class cache_config {
$this->configdefinitionmappings[] = $mapping; $this->configdefinitionmappings[] = $mapping;
} }
usort($this->configmodemappings, array($this, 'sort_mappings')); usort($this->configmodemappings, [$this, 'sort_mappings']);
usort($this->configdefinitionmappings, array($this, 'sort_mappings')); usort($this->configdefinitionmappings, [$this, 'sort_mappings']);
return true; return true;
} }
@ -324,19 +330,19 @@ class cache_config {
throw new cache_exception('Invalid cache configuration file'); throw new cache_exception('Invalid cache configuration file');
} }
if (!array_key_exists('stores', $configuration) || !is_array($configuration['stores'])) { if (!array_key_exists('stores', $configuration) || !is_array($configuration['stores'])) {
$configuration['stores'] = array(); $configuration['stores'] = [];
} }
if (!array_key_exists('modemappings', $configuration) || !is_array($configuration['modemappings'])) { if (!array_key_exists('modemappings', $configuration) || !is_array($configuration['modemappings'])) {
$configuration['modemappings'] = array(); $configuration['modemappings'] = [];
} }
if (!array_key_exists('definitions', $configuration) || !is_array($configuration['definitions'])) { if (!array_key_exists('definitions', $configuration) || !is_array($configuration['definitions'])) {
$configuration['definitions'] = array(); $configuration['definitions'] = [];
} }
if (!array_key_exists('definitionmappings', $configuration) || !is_array($configuration['definitionmappings'])) { if (!array_key_exists('definitionmappings', $configuration) || !is_array($configuration['definitionmappings'])) {
$configuration['definitionmappings'] = array(); $configuration['definitionmappings'] = [];
} }
if (!array_key_exists('locks', $configuration) || !is_array($configuration['locks'])) { if (!array_key_exists('locks', $configuration) || !is_array($configuration['locks'])) {
$configuration['locks'] = array(); $configuration['locks'] = [];
} }
return $configuration; return $configuration;
@ -387,7 +393,7 @@ class cache_config {
* @return array Associative array of definitions, id=>definition * @return array Associative array of definitions, id=>definition
*/ */
public function get_definitions_by_store($storename) { public function get_definitions_by_store($storename) {
$definitions = array(); $definitions = [];
// This function was accidentally made static at some stage in the past. // This function was accidentally made static at some stage in the past.
// It was converted to an instance method but to be backwards compatible // It was converted to an instance method but to be backwards compatible
@ -406,18 +412,18 @@ class cache_config {
$defmappings = $config->get_definition_mappings(); $defmappings = $config->get_definition_mappings();
// Create an associative array for the definition mappings. // Create an associative array for the definition mappings.
$thedefmappings = array(); $thedefmappings = [];
foreach ($defmappings as $defmapping) { foreach ($defmappings as $defmapping) {
$thedefmappings[$defmapping['definition']] = $defmapping; $thedefmappings[$defmapping['definition']] = $defmapping;
} }
// Search for matches in default mappings. // Search for matches in default mappings.
$defs = $config->get_definitions(); $defs = $config->get_definitions();
foreach($config->get_mode_mappings() as $modemapping) { foreach ($config->get_mode_mappings() as $modemapping) {
if ($modemapping['store'] !== $storename) { if ($modemapping['store'] !== $storename) {
continue; continue;
} }
foreach($defs as $id => $definition) { foreach ($defs as $id => $definition) {
if ($definition['mode'] !== $modemapping['mode']) { if ($definition['mode'] !== $modemapping['mode']) {
continue; continue;
} }
@ -429,7 +435,7 @@ class cache_config {
} }
} }
// Search for matches in the custom definitions mapping // Search for matches in the custom definitions mapping.
foreach ($defmappings as $defmapping) { foreach ($defmappings as $defmapping) {
if ($defmapping['store'] !== $storename) { if ($defmapping['store'] !== $storename) {
continue; continue;
@ -451,7 +457,7 @@ class cache_config {
* @return array An array of suitable stores. * @return array An array of suitable stores.
*/ */
public function get_stores($mode, $requirements = 0) { public function get_stores($mode, $requirements = 0) {
$stores = array(); $stores = [];
foreach ($this->configstores as $name => $store) { foreach ($this->configstores as $name => $store) {
// If the mode is supported and all of the requirements are provided features. // If the mode is supported and all of the requirements are provided features.
if (($store['modes'] & $mode) && ($store['features'] & $requirements) === $requirements) { if (($store['modes'] & $mode) && ($store['features'] & $requirements) === $requirements) {
@ -469,18 +475,18 @@ class cache_config {
*/ */
public function get_stores_for_definition(definition $definition) { public function get_stores_for_definition(definition $definition) {
// Check if MUC has been disabled. // Check if MUC has been disabled.
$factory = cache_factory::instance(); $factory = factory::instance();
if ($factory->stores_disabled()) { if ($factory->stores_disabled()) {
// Yip its been disabled. // Yip its been disabled.
// To facilitate this we are going to always return an empty array of stores to use. // To facilitate this we are going to always return an empty array of stores to use.
// This will force all cache instances to use the cachestore_dummy. // This will force all cache instances to use the cachestore_dummy.
// MUC will still be used essentially so that code using it will still continue to function but because no cache stores // MUC will still be used essentially so that code using it will still continue to function but because no cache stores
// are being used interaction with MUC will be purely based around a static var. // are being used interaction with MUC will be purely based around a static var.
return array(); return [];
} }
$availablestores = $this->get_stores($definition->get_mode(), $definition->get_requirements_bin()); $availablestores = $this->get_stores($definition->get_mode(), $definition->get_requirements_bin());
$stores = array(); $stores = [];
$id = $definition->get_id(); $id = $definition->get_id();
// Now get any mappings and give them priority. // Now get any mappings and give them priority.
@ -580,3 +586,8 @@ class cache_config {
throw new cache_exception('ex_nodefaultlock'); throw new cache_exception('ex_nodefaultlock');
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(config::class, \cache_config::class);

View file

@ -14,20 +14,29 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
use core_cache\exception\cache_exception;
use cachestore_static;
use cachestore_session;
use cachestore_file;
use core_component;
use ReflectionClass;
/** /**
* Cache configuration writer. * Cache configuration writer.
* *
* This class should only be used when you need to write to the config, all read operations exist within the cache_config. * This class should only be used when you need to write to the config, all read operations exist within the cache_config.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_config_writer extends cache_config { class config_writer extends config {
/** /**
* Switch that gets set to true when ever a cache_config_writer instance is saving the cache configuration file. * Switch that gets set to true when ever a config_writer instance is saving the cache configuration file.
* If this is set to true when save is next called we must avoid the trying to save and instead return the * If this is set to true when save is next called we must avoid the trying to save and instead return the
* generated config so that is may be used instead of the file. * generated config so that is may be used instead of the file.
* @var bool * @var bool
@ -37,10 +46,10 @@ class cache_config_writer extends cache_config {
/** /**
* Returns an instance of the configuration writer. * Returns an instance of the configuration writer.
* *
* @return cache_config_writer * @return config_writer
*/ */
public static function instance() { public static function instance() {
$factory = cache_factory::instance(); $factory = factory::instance();
return $factory->create_config_instance(true); return $factory->create_config_instance(true);
} }
@ -70,7 +79,7 @@ class cache_config_writer extends cache_config {
$configuration = $this->generate_configuration_array(); $configuration = $this->generate_configuration_array();
// Prepare the file content. // Prepare the file content.
$content = "<?php defined('MOODLE_INTERNAL') || die();\n \$configuration = ".var_export($configuration, true).";"; $content = "<?php defined('MOODLE_INTERNAL') || die();\n \$configuration = " . var_export($configuration, true) . ";";
// Do both file content and hash based detection because this might be called // Do both file content and hash based detection because this might be called
// many times within a single request. // many times within a single request.
@ -87,14 +96,14 @@ class cache_config_writer extends cache_config {
if ($lockconf === false) { if ($lockconf === false) {
debugging('Your cache configuration file is out of date and needs to be refreshed.', DEBUG_DEVELOPER); debugging('Your cache configuration file is out of date and needs to be refreshed.', DEBUG_DEVELOPER);
// Use the default // Use the default
$lockconf = array( $lockconf = [
'name' => 'cachelock_file_default', 'name' => 'cachelock_file_default',
'type' => 'cachelock_file', 'type' => 'cachelock_file',
'dir' => 'filelocks', 'dir' => 'filelocks',
'default' => true 'default' => true,
); ];
} }
$factory = cache_factory::instance(); $factory = factory::instance();
$locking = $factory->create_lock_instance($lockconf); $locking = $factory->create_lock_instance($lockconf);
if ($locking->lock('configwrite', 'config', true)) { if ($locking->lock('configwrite', 'config', true)) {
$tempcachefile = "{$cachefile}.tmp"; $tempcachefile = "{$cachefile}.tmp";
@ -118,7 +127,7 @@ class cache_config_writer extends cache_config {
* @return array * @return array
*/ */
protected function generate_configuration_array() { protected function generate_configuration_array() {
$configuration = array(); $configuration = [];
$configuration['siteidentifier'] = $this->siteidentifier; $configuration['siteidentifier'] = $this->siteidentifier;
$configuration['stores'] = $this->configstores; $configuration['stores'] = $this->configstores;
$configuration['modemappings'] = $this->configmodemappings; $configuration['modemappings'] = $this->configmodemappings;
@ -140,11 +149,11 @@ class cache_config_writer extends cache_config {
* @return bool * @return bool
* @throws cache_exception * @throws cache_exception
*/ */
public function add_store_instance($name, $plugin, array $configuration = array()) { public function add_store_instance($name, $plugin, array $configuration = []) {
if (array_key_exists($name, $this->configstores)) { if (array_key_exists($name, $this->configstores)) {
throw new cache_exception('Duplicate name specificed for cache plugin instance. You must provide a unique name.'); throw new cache_exception('Duplicate name specificed for cache plugin instance. You must provide a unique name.');
} }
$class = 'cachestore_'.$plugin; $class = 'cachestore_' . $plugin;
if (!class_exists($class)) { if (!class_exists($class)) {
$plugins = core_component::get_plugin_list_with_file('cachestore', 'lib.php'); $plugins = core_component::get_plugin_list_with_file('cachestore', 'lib.php');
if (!array_key_exists($plugin, $plugins)) { if (!array_key_exists($plugin, $plugins)) {
@ -159,13 +168,13 @@ class cache_config_writer extends cache_config {
} }
} }
$reflection = new ReflectionClass($class); $reflection = new ReflectionClass($class);
if (!$reflection->isSubclassOf('cache_store')) { if (!$reflection->isSubclassOf(store::class)) {
throw new cache_exception('Invalid cache plugin specified. The plugin does not extend the required class.'); throw new cache_exception('Invalid cache plugin specified. The plugin does not extend the required class.');
} }
if (!$class::are_requirements_met()) { if (!$class::are_requirements_met()) {
throw new cache_exception('Unable to add new cache plugin instance. The requested plugin type is not supported.'); throw new cache_exception('Unable to add new cache plugin instance. The requested plugin type is not supported.');
} }
$this->configstores[$name] = array( $this->configstores[$name] = [
'name' => $name, 'name' => $name,
'plugin' => $plugin, 'plugin' => $plugin,
'configuration' => $configuration, 'configuration' => $configuration,
@ -173,8 +182,8 @@ class cache_config_writer extends cache_config {
'modes' => $class::get_supported_modes($configuration), 'modes' => $class::get_supported_modes($configuration),
'mappingsonly' => !empty($configuration['mappingsonly']), 'mappingsonly' => !empty($configuration['mappingsonly']),
'class' => $class, 'class' => $class,
'default' => false 'default' => false,
); ];
if (array_key_exists('lock', $configuration)) { if (array_key_exists('lock', $configuration)) {
$this->configstores[$name]['lock'] = $configuration['lock']; $this->configstores[$name]['lock'] = $configuration['lock'];
unset($this->configstores[$name]['configuration']['lock']); unset($this->configstores[$name]['configuration']['lock']);
@ -195,11 +204,11 @@ class cache_config_writer extends cache_config {
* @param string $configuration Configuration data from the config instance. * @param string $configuration Configuration data from the config instance.
* @throws cache_exception * @throws cache_exception
*/ */
public function add_lock_instance($name, $plugin, $configuration = array()) { public function add_lock_instance($name, $plugin, $configuration = []) {
if (array_key_exists($name, $this->configlocks)) { if (array_key_exists($name, $this->configlocks)) {
throw new cache_exception('Duplicate name specificed for cache lock instance. You must provide a unique name.'); throw new cache_exception('Duplicate name specificed for cache lock instance. You must provide a unique name.');
} }
$class = 'cachelock_'.$plugin; $class = 'cachelock_' . $plugin;
if (!class_exists($class)) { if (!class_exists($class)) {
$plugins = core_component::get_plugin_list_with_file('cachelock', 'lib.php'); $plugins = core_component::get_plugin_list_with_file('cachelock', 'lib.php');
if (!array_key_exists($plugin, $plugins)) { if (!array_key_exists($plugin, $plugins)) {
@ -214,14 +223,14 @@ class cache_config_writer extends cache_config {
} }
} }
$reflection = new ReflectionClass($class); $reflection = new ReflectionClass($class);
if (!$reflection->implementsInterface('cache_lock_interface')) { if (!$reflection->implementsInterface(lockable_cache_interface::class)) {
throw new cache_exception('Invalid lock plugin specified. The plugin does not implement the required interface.'); throw new cache_exception('Invalid lock plugin specified. The plugin does not implement the required interface.');
} }
$this->configlocks[$name] = array_merge($configuration, array( $this->configlocks[$name] = array_merge($configuration, [
'name' => $name, 'name' => $name,
'type' => 'cachelock_'.$plugin, 'type' => 'cachelock_' . $plugin,
'default' => false 'default' => false,
)); ]);
$this->config_save(); $this->config_save();
} }
@ -261,11 +270,11 @@ class cache_config_writer extends cache_config {
* @throws cache_exception * @throws cache_exception
*/ */
public function set_mode_mappings(array $modemappings) { public function set_mode_mappings(array $modemappings) {
$mappings = array( $mappings = [
cache_store::MODE_APPLICATION => array(), store::MODE_APPLICATION => [],
cache_store::MODE_SESSION => array(), store::MODE_SESSION => [],
cache_store::MODE_REQUEST => array(), store::MODE_REQUEST => [],
); ];
foreach ($modemappings as $mode => $stores) { foreach ($modemappings as $mode => $stores) {
if (!array_key_exists($mode, $mappings)) { if (!array_key_exists($mode, $mappings)) {
throw new cache_exception('The cache mode for the new mapping does not exist'); throw new cache_exception('The cache mode for the new mapping does not exist');
@ -278,17 +287,17 @@ class cache_config_writer extends cache_config {
if (array_key_exists($store, $mappings[$mode])) { if (array_key_exists($store, $mappings[$mode])) {
throw new cache_exception('This cache mapping already exists'); throw new cache_exception('This cache mapping already exists');
} }
$mappings[$mode][] = array( $mappings[$mode][] = [
'store' => $store, 'store' => $store,
'mode' => $mode, 'mode' => $mode,
'sort' => $sort++ 'sort' => $sort++,
); ];
} }
} }
$this->configmodemappings = array_merge( $this->configmodemappings = array_merge(
$mappings[cache_store::MODE_APPLICATION], $mappings[store::MODE_APPLICATION],
$mappings[cache_store::MODE_SESSION], $mappings[store::MODE_SESSION],
$mappings[cache_store::MODE_REQUEST] $mappings[store::MODE_REQUEST]
); );
$this->config_save(); $this->config_save();
@ -316,17 +325,19 @@ class cache_config_writer extends cache_config {
if (!array_key_exists($plugin, $plugins)) { if (!array_key_exists($plugin, $plugins)) {
throw new cache_exception('Invalid plugin name specified. The plugin either does not exist or is not valid.'); throw new cache_exception('Invalid plugin name specified. The plugin either does not exist or is not valid.');
} }
$class = 'cachestore_'.$plugin; $class = 'cachestore_' . $plugin;
$file = $plugins[$plugin]; $file = $plugins[$plugin];
if (!class_exists($class)) { if (!class_exists($class)) {
if (file_exists($file)) { if (file_exists($file)) {
require_once($file); require_once($file);
} }
if (!class_exists($class)) { if (!class_exists($class)) {
throw new cache_exception('Invalid cache plugin specified. The plugin does not contain the required class.'.$class); throw new cache_exception(
"Invalid cache plugin specified. The plugin does not contain the required class {$class}",
);
} }
} }
$this->configstores[$name] = array( $this->configstores[$name] = [
'name' => $name, 'name' => $name,
'plugin' => $plugin, 'plugin' => $plugin,
'configuration' => $configuration, 'configuration' => $configuration,
@ -334,8 +345,8 @@ class cache_config_writer extends cache_config {
'modes' => $class::get_supported_modes($configuration), 'modes' => $class::get_supported_modes($configuration),
'mappingsonly' => !empty($configuration['mappingsonly']), 'mappingsonly' => !empty($configuration['mappingsonly']),
'class' => $class, 'class' => $class,
'default' => $this->configstores[$name]['default'] // Can't change the default. 'default' => $this->configstores[$name]['default'], // Can't change the default.
); ];
if (array_key_exists('lock', $configuration)) { if (array_key_exists('lock', $configuration)) {
$this->configstores[$name]['lock'] = $configuration['lock']; $this->configstores[$name]['lock'] = $configuration['lock'];
unset($this->configstores[$name]['configuration']['lock']); unset($this->configstores[$name]['configuration']['lock']);
@ -373,7 +384,7 @@ class cache_config_writer extends cache_config {
} }
// Call instance_deleted() // Call instance_deleted()
$class = 'cachestore_'.$this->configstores[$name]['plugin']; $class = 'cachestore_' . $this->configstores[$name]['plugin'];
$store = new $class($name, $this->configstores[$name]['configuration']); $store = new $class($name, $this->configstores[$name]['configuration']);
$store->instance_deleted(); $store->instance_deleted();
@ -396,42 +407,42 @@ class cache_config_writer extends cache_config {
// HACK ALERT. // HACK ALERT.
// We probably need to come up with a better way to create the default stores, or at least ensure 100% that the // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the
// default store plugins are protected from deletion. // default store plugins are protected from deletion.
$writer = new self; $writer = new self();
$writer->configstores = self::get_default_stores(); $writer->configstores = self::get_default_stores();
$writer->configdefinitions = self::locate_definitions(); $writer->configdefinitions = self::locate_definitions();
$writer->configmodemappings = array( $writer->configmodemappings = [
array( [
'mode' => cache_store::MODE_APPLICATION, 'mode' => store::MODE_APPLICATION,
'store' => 'default_application', 'store' => 'default_application',
'sort' => -1 'sort' => -1,
), ],
array( [
'mode' => cache_store::MODE_SESSION, 'mode' => store::MODE_SESSION,
'store' => 'default_session', 'store' => 'default_session',
'sort' => -1 'sort' => -1,
), ],
array( [
'mode' => cache_store::MODE_REQUEST, 'mode' => store::MODE_REQUEST,
'store' => 'default_request', 'store' => 'default_request',
'sort' => -1 'sort' => -1,
) ],
); ];
$writer->configlocks = array( $writer->configlocks = [
'default_file_lock' => array( 'default_file_lock' => [
'name' => 'cachelock_file_default', 'name' => 'cachelock_file_default',
'type' => 'cachelock_file', 'type' => 'cachelock_file',
'dir' => 'filelocks', 'dir' => 'filelocks',
'default' => true 'default' => true,
) ],
); ];
$factory = cache_factory::instance(); $factory = factory::instance();
// We expect the cache to be initialising presently. If its not then something has gone wrong and likely // We expect the cache to be initialising presently. If its not then something has gone wrong and likely
// we are now in a loop. // we are now in a loop.
if (!$forcesave && $factory->get_state() !== cache_factory::STATE_INITIALISING) { if (!$forcesave && $factory->get_state() !== factory::STATE_INITIALISING) {
return $writer->generate_configuration_array(); return $writer->generate_configuration_array();
} }
$factory->set_state(cache_factory::STATE_SAVING); $factory->set_state(factory::STATE_SAVING);
$writer->config_save(); $writer->config_save();
return true; return true;
} }
@ -444,43 +455,43 @@ class cache_config_writer extends cache_config {
protected static function get_default_stores() { protected static function get_default_stores() {
global $CFG; global $CFG;
require_once($CFG->dirroot.'/cache/stores/file/lib.php'); require_once($CFG->dirroot . '/cache/stores/file/lib.php');
require_once($CFG->dirroot.'/cache/stores/session/lib.php'); require_once($CFG->dirroot . '/cache/stores/session/lib.php');
require_once($CFG->dirroot.'/cache/stores/static/lib.php'); require_once($CFG->dirroot . '/cache/stores/static/lib.php');
return array( return [
'default_application' => array( 'default_application' => [
'name' => 'default_application', 'name' => 'default_application',
'plugin' => 'file', 'plugin' => 'file',
'configuration' => array(), 'configuration' => [],
'features' => cachestore_file::get_supported_features(), 'features' => cachestore_file::get_supported_features(),
'modes' => cachestore_file::get_supported_modes(), 'modes' => cachestore_file::get_supported_modes(),
'default' => true, 'default' => true,
), ],
'default_session' => array( 'default_session' => [
'name' => 'default_session', 'name' => 'default_session',
'plugin' => 'session', 'plugin' => 'session',
'configuration' => array(), 'configuration' => [],
'features' => cachestore_session::get_supported_features(), 'features' => cachestore_session::get_supported_features(),
'modes' => cachestore_session::get_supported_modes(), 'modes' => cachestore_session::get_supported_modes(),
'default' => true, 'default' => true,
), ],
'default_request' => array( 'default_request' => [
'name' => 'default_request', 'name' => 'default_request',
'plugin' => 'static', 'plugin' => 'static',
'configuration' => array(), 'configuration' => [],
'features' => cachestore_static::get_supported_features(), 'features' => cachestore_static::get_supported_features(),
'modes' => cachestore_static::get_supported_modes(), 'modes' => cachestore_static::get_supported_modes(),
'default' => true, 'default' => true,
) ],
); ];
} }
/** /**
* Updates the default stores within the MUC config file. * Updates the default stores within the MUC config file.
*/ */
public static function update_default_config_stores() { public static function update_default_config_stores() {
$factory = cache_factory::instance(); $factory = factory::instance();
$factory->updating_started(); $factory->updating_started();
$config = $factory->create_config_instance(true); $config = $factory->create_config_instance(true);
$config->configstores = array_merge($config->configstores, self::get_default_stores()); $config->configstores = array_merge($config->configstores, self::get_default_stores());
@ -496,7 +507,7 @@ class cache_config_writer extends cache_config {
* @param bool $coreonly If set to true only core definitions will be updated. * @param bool $coreonly If set to true only core definitions will be updated.
*/ */
public static function update_definitions($coreonly = false) { public static function update_definitions($coreonly = false) {
$factory = cache_factory::instance(); $factory = factory::instance();
$factory->updating_started(); $factory->updating_started();
$config = $factory->create_config_instance(true); $config = $factory->create_config_instance(true);
$config->write_definitions_to_cache(self::locate_definitions($coreonly)); $config->write_definitions_to_cache(self::locate_definitions($coreonly));
@ -512,9 +523,9 @@ class cache_config_writer extends cache_config {
protected static function locate_definitions($coreonly = false) { protected static function locate_definitions($coreonly = false) {
global $CFG; global $CFG;
$files = array(); $files = [];
if (file_exists($CFG->dirroot.'/lib/db/caches.php')) { if (file_exists($CFG->dirroot . '/lib/db/caches.php')) {
$files['core'] = $CFG->dirroot.'/lib/db/caches.php'; $files['core'] = $CFG->dirroot . '/lib/db/caches.php';
} }
if (!$coreonly) { if (!$coreonly) {
@ -522,22 +533,22 @@ class cache_config_writer extends cache_config {
foreach ($plugintypes as $type => $location) { foreach ($plugintypes as $type => $location) {
$plugins = core_component::get_plugin_list_with_file($type, 'db/caches.php'); $plugins = core_component::get_plugin_list_with_file($type, 'db/caches.php');
foreach ($plugins as $plugin => $filepath) { foreach ($plugins as $plugin => $filepath) {
$component = clean_param($type.'_'.$plugin, PARAM_COMPONENT); // Standardised plugin name. $component = clean_param($type . '_' . $plugin, PARAM_COMPONENT); // Standardised plugin name.
$files[$component] = $filepath; $files[$component] = $filepath;
} }
} }
} }
$definitions = array(); $definitions = [];
foreach ($files as $component => $file) { foreach ($files as $component => $file) {
$filedefs = self::load_caches_file($file); $filedefs = self::load_caches_file($file);
foreach ($filedefs as $area => $definition) { foreach ($filedefs as $area => $definition) {
$area = clean_param($area, PARAM_AREA); $area = clean_param($area, PARAM_AREA);
$id = $component.'/'.$area; $id = $component . '/' . $area;
$definition['component'] = $component; $definition['component'] = $component;
$definition['area'] = $area; $definition['area'] = $area;
if (array_key_exists($id, $definitions)) { if (array_key_exists($id, $definitions)) {
debugging('Error: duplicate cache definition found with id: '.$id, DEBUG_DEVELOPER); debugging('Error: duplicate cache definition found with id: ' . $id, DEBUG_DEVELOPER);
continue; continue;
} }
$definitions[$id] = $definition; $definitions[$id] = $definition;
@ -582,9 +593,9 @@ class cache_config_writer extends cache_config {
*/ */
private static function load_caches_file($file) { private static function load_caches_file($file) {
if (!file_exists($file)) { if (!file_exists($file)) {
return array(); return [];
} }
$definitions = array(); $definitions = [];
include($file); include($file);
return $definitions; return $definitions;
} }
@ -612,11 +623,11 @@ class cache_config_writer extends cache_config {
} }
$sort = count($mappings); $sort = count($mappings);
foreach ($mappings as $store) { foreach ($mappings as $store) {
$this->configdefinitionmappings[] = array( $this->configdefinitionmappings[] = [
'store' => $store, 'store' => $store,
'definition' => $definition, 'definition' => $definition,
'sort' => $sort 'sort' => $sort,
); ];
$sort--; $sort--;
} }
@ -657,3 +668,8 @@ class cache_config_writer extends cache_config {
$this->config_save(); $this->config_save();
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(config_writer::class, \cache_config_writer::class);

View file

@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use moodleform;
/** /**
* Cache store feature: configurable. * Cache store feature: configurable.
* *
@ -23,9 +27,11 @@
* data for the edit form. * data for the edit form.
* *
* Can be implemented by classes already implementing cache_store. * Can be implemented by classes already implementing cache_store.
* @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_is_configurable { interface configurable_cache_interface {
/** /**
* Given the data from the add instance form this function creates a configuration array. * Given the data from the add instance form this function creates a configuration array.
* *
@ -42,3 +48,8 @@ interface cache_is_configurable {
*/ */
public static function config_set_edit_form_data(moodleform $editform, array $config); public static function config_set_edit_form_data(moodleform $editform, array $config);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(configurable_cache_interface::class, \cache_is_configurable::class);

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cache Data Source. * Cache Data Source.
* *
@ -26,13 +28,12 @@
* *
* Can be implemented by any class. * Can be implemented by any class.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_data_source { interface data_source_interface {
/** /**
* Returns an instance of the data source class that the cache can use for loading data using the other methods * Returns an instance of the data source class that the cache can use for loading data using the other methods
* specified by this interface. * specified by this interface.
@ -58,3 +59,8 @@ interface cache_data_source {
*/ */
public function load_many_for_cache(array $keys); public function load_many_for_cache(array $keys);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(data_source_interface::class, \cache_data_source::class);

View file

@ -14,6 +14,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
use cache_helper as helper;
use cache_store as store;
use lang_string;
/** /**
* The cache definition class. * The cache definition class.
* *
@ -22,7 +29,7 @@
* *
* Required settings: * Required settings:
* + mode * + mode
* [int] Sets the mode for the definition. Must be one of cache_store::MODE_* * [int] Sets the mode for the definition. Must be one of store::MODE_*
* *
* Optional settings: * Optional settings:
* + simplekeys * + simplekeys
@ -89,13 +96,12 @@
* *
* For examples take a look at lib/db/caches.php * For examples take a look at lib/db/caches.php
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_definition { class definition {
/** The cache can be shared with everyone */ /** The cache can be shared with everyone */
const SHARING_ALL = 1; const SHARING_ALL = 1;
/** The cache can be shared with other sites using the same siteid. */ /** The cache can be shared with other sites using the same siteid. */
@ -123,7 +129,7 @@ class cache_definition {
protected $id; protected $id;
/** /**
* The mode for the defintion. One of cache_store::MODE_* * The mode for the defintion. One of store::MODE_*
* @var int * @var int
*/ */
protected $mode; protected $mode;
@ -156,7 +162,7 @@ class cache_definition {
* An array of identifiers that must be provided when the definition is used to create a cache. * An array of identifiers that must be provided when the definition is used to create a cache.
* @var array * @var array
*/ */
protected $requireidentifiers = array(); protected $requireidentifiers = [];
/** /**
* If set to true then only stores that guarantee data may be used with this definition. * If set to true then only stores that guarantee data may be used with this definition.
@ -249,7 +255,7 @@ class cache_definition {
* An array of events that should cause this cache to invalidate. * An array of events that should cause this cache to invalidate.
* @var array * @var array
*/ */
protected $invalidationevents = array(); protected $invalidationevents = [];
/** /**
* An array of identifiers provided to this cache when it was initialised. * An array of identifiers provided to this cache when it was initialised.
@ -305,7 +311,7 @@ class cache_definition {
* @param string $id * @param string $id
* @param array $definition * @param array $definition
* @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
* @return cache_definition * @return definition
* @throws coding_exception * @throws coding_exception
*/ */
public static function load($id, array $definition, $unused = null) { public static function load($id, array $definition, $unused = null) {
@ -327,11 +333,11 @@ class cache_definition {
// Set the defaults. // Set the defaults.
$simplekeys = false; $simplekeys = false;
$simpledata = false; $simpledata = false;
$requireidentifiers = array(); $requireidentifiers = [];
$requiredataguarantee = false; $requiredataguarantee = false;
$requiremultipleidentifiers = false; $requiremultipleidentifiers = false;
$requirelockingbeforewrite = false; $requirelockingbeforewrite = false;
$requiresearchable = ($mode === cache_store::MODE_SESSION) ? true : false; $requiresearchable = ($mode === store::MODE_SESSION) ? true : false;
$maxsize = null; $maxsize = null;
$overrideclass = null; $overrideclass = null;
$overrideclassfile = null; $overrideclassfile = null;
@ -341,7 +347,7 @@ class cache_definition {
$staticaccelerationsize = false; $staticaccelerationsize = false;
$ttl = 0; $ttl = 0;
$mappingsonly = false; $mappingsonly = false;
$invalidationevents = array(); $invalidationevents = [];
$sharingoptions = self::SHARING_DEFAULT; $sharingoptions = self::SHARING_DEFAULT;
$selectedsharingoption = self::SHARING_DEFAULT; $selectedsharingoption = self::SHARING_DEFAULT;
$userinputsharingkey = ''; $userinputsharingkey = '';
@ -364,13 +370,17 @@ class cache_definition {
} }
if (array_key_exists('requirelockingread', $definition)) { if (array_key_exists('requirelockingread', $definition)) {
debugging('The cache option requirelockingread is deprecated and now has no effect.', debugging(
DEBUG_DEVELOPER); 'The cache option requirelockingread is deprecated and now has no effect.',
DEBUG_DEVELOPER
);
} }
if (array_key_exists('requirelockingwrite', $definition)) { if (array_key_exists('requirelockingwrite', $definition)) {
debugging('The cache option requirelockingwrite is deprecated and now has no effect. ' . debugging(
'The cache option requirelockingwrite is deprecated and now has no effect. ' .
"Consider removing the option, or using requirelockingbeforewrite for the $component:$area definition", "Consider removing the option, or using requirelockingbeforewrite for the $component:$area definition",
DEBUG_DEVELOPER); DEBUG_DEVELOPER
);
} }
if (array_key_exists('requirelockingbeforewrite', $definition)) { if (array_key_exists('requirelockingbeforewrite', $definition)) {
$requirelockingbeforewrite = (bool)$definition['requirelockingbeforewrite']; $requirelockingbeforewrite = (bool)$definition['requirelockingbeforewrite'];
@ -451,7 +461,7 @@ class cache_definition {
if (!is_null($overrideclass)) { if (!is_null($overrideclass)) {
if (!is_null($overrideclassfile)) { if (!is_null($overrideclassfile)) {
if (strpos($overrideclassfile, $CFG->dirroot) !== 0) { if (strpos($overrideclassfile, $CFG->dirroot) !== 0) {
$overrideclassfile = $CFG->dirroot.'/'.$overrideclassfile; $overrideclassfile = $CFG->dirroot . '/' . $overrideclassfile;
} }
if (strpos($overrideclassfile, '../') !== false) { if (strpos($overrideclassfile, '../') !== false) {
throw new coding_exception('No path craziness allowed within override class file path.'); throw new coding_exception('No path craziness allowed within override class file path.');
@ -466,7 +476,7 @@ class cache_definition {
} }
// Make sure that the provided class extends the default class for the mode. // Make sure that the provided class extends the default class for the mode.
if (get_parent_class($overrideclass) !== cache_helper::get_class_for_mode($mode)) { if (get_parent_class($overrideclass) !== helper::get_class_for_mode($mode)) {
throw new coding_exception('The override class does not immediately extend the relevant cache class.'); throw new coding_exception('The override class does not immediately extend the relevant cache class.');
} }
} }
@ -474,7 +484,7 @@ class cache_definition {
if (!is_null($datasource)) { if (!is_null($datasource)) {
if (!is_null($datasourcefile)) { if (!is_null($datasourcefile)) {
if (strpos($datasourcefile, $CFG->dirroot) !== 0) { if (strpos($datasourcefile, $CFG->dirroot) !== 0) {
$datasourcefile = $CFG->dirroot.'/'.$datasourcefile; $datasourcefile = $CFG->dirroot . '/' . $datasourcefile;
} }
if (strpos($datasourcefile, '../') !== false) { if (strpos($datasourcefile, '../') !== false) {
throw new coding_exception('No path craziness allowed within data source file path.'); throw new coding_exception('No path craziness allowed within data source file path.');
@ -492,7 +502,7 @@ class cache_definition {
} }
} }
$cachedefinition = new cache_definition(); $cachedefinition = new self();
$cachedefinition->id = $id; $cachedefinition->id = $id;
$cachedefinition->mode = $mode; $cachedefinition->mode = $mode;
$cachedefinition->component = $component; $cachedefinition->component = $component;
@ -529,7 +539,7 @@ class cache_definition {
* Please note that when using an adhoc definition you cannot set any of the optional params. * Please note that when using an adhoc definition you cannot set any of the optional params.
* This is because we cannot guarantee consistent access and we don't want to mislead people into thinking that. * This is because we cannot guarantee consistent access and we don't want to mislead people into thinking that.
* *
* @param int $mode One of cache_store::MODE_* * @param int $mode One of store::MODE_*
* @param string $component The component this definition relates to. * @param string $component The component this definition relates to.
* @param string $area The area this definition relates to. * @param string $area The area this definition relates to.
* @param array $options An array of options, available options are: * @param array $options An array of options, available options are:
@ -538,15 +548,15 @@ class cache_definition {
* - overrideclass : The class to use as the loader. * - overrideclass : The class to use as the loader.
* - staticacceleration : If set to true the cache will hold onto data passing through it. * - staticacceleration : If set to true the cache will hold onto data passing through it.
* - staticaccelerationsize : Set it to an int to limit the size of the staticacceleration cache. * - staticaccelerationsize : Set it to an int to limit the size of the staticacceleration cache.
* @return cache_application|cache_session|cache_request * @return self
*/ */
public static function load_adhoc($mode, $component, $area, array $options = array()) { public static function load_adhoc($mode, $component, $area, array $options = []) {
$id = 'adhoc/'.$component.'_'.$area; $id = 'adhoc/' . $component . '_' . $area;
$definition = array( $definition = [
'mode' => $mode, 'mode' => $mode,
'component' => $component, 'component' => $component,
'area' => $area, 'area' => $area,
); ];
if (!empty($options['simplekeys'])) { if (!empty($options['simplekeys'])) {
$definition['simplekeys'] = $options['simplekeys']; $definition['simplekeys'] = $options['simplekeys'];
} }
@ -580,7 +590,7 @@ class cache_definition {
if (!is_null($this->overrideclass)) { if (!is_null($this->overrideclass)) {
return $this->overrideclass; return $this->overrideclass;
} }
return cache_helper::get_class_for_mode($this->mode); return helper::get_class_for_mode($this->mode);
} }
/** /**
@ -596,7 +606,7 @@ class cache_definition {
* @return string * @return string
*/ */
public function get_name() { public function get_name() {
$identifier = 'cachedef_'.clean_param($this->area, PARAM_STRINGID); $identifier = 'cachedef_' . clean_param($this->area, PARAM_STRINGID);
$component = $this->component; $component = $this->component;
if ($component === 'core') { if ($component === 'core') {
$component = 'cache'; $component = 'cache';
@ -606,7 +616,7 @@ class cache_definition {
/** /**
* Returns the mode of this definition * Returns the mode of this definition
* @return int One more cache_store::MODE_ * @return int One more store::MODE_
*/ */
public function get_mode() { public function get_mode() {
return $this->mode; return $this->mode;
@ -645,7 +655,7 @@ class cache_definition {
*/ */
public function get_identifiers() { public function get_identifiers() {
if (!isset($this->identifiers)) { if (!isset($this->identifiers)) {
return array(); return [];
} }
return $this->identifiers; return $this->identifiers;
} }
@ -743,14 +753,14 @@ class cache_definition {
/** /**
* Returns an instance of the data source class used for this definition. * Returns an instance of the data source class used for this definition.
* *
* @return cache_data_source * @return data_source_interface
* @throws coding_exception * @throws coding_exception
*/ */
public function get_data_source() { public function get_data_source() {
if (!$this->has_data_source()) { if (!$this->has_data_source()) {
throw new coding_exception('This cache does not use a data source.'); throw new coding_exception('This cache does not use a data source.');
} }
return forward_static_call(array($this->datasource, 'get_instance_for_cache'), $this); return forward_static_call([$this->datasource, 'get_instance_for_cache'], $this);
} }
/** /**
@ -760,7 +770,7 @@ class cache_definition {
* @return bool false if no identifiers where changed, true otherwise. * @return bool false if no identifiers where changed, true otherwise.
* @throws coding_exception * @throws coding_exception
*/ */
public function set_identifiers(array $identifiers = array()) { public function set_identifiers(array $identifiers = []) {
if ($this->identifiers !== null) { if ($this->identifiers !== null) {
throw new coding_exception("You can only set identifiers on initial definition creation." . throw new coding_exception("You can only set identifiers on initial definition creation." .
" Define a new cache to set different identifiers."); " Define a new cache to set different identifiers.");
@ -771,11 +781,11 @@ class cache_definition {
foreach ($this->requireidentifiers as $identifier) { foreach ($this->requireidentifiers as $identifier) {
if (!isset($identifiers[$identifier])) { if (!isset($identifiers[$identifier])) {
throw new coding_exception('Identifier required for cache has not been provided: '.$identifier); throw new coding_exception('Identifier required for cache has not been provided: ' . $identifier);
} }
} }
$this->identifiers = array(); $this->identifiers = [];
foreach ($identifiers as $name => $value) { foreach ($identifiers as $name => $value) {
$this->identifiers[$name] = (string)$value; $this->identifiers[$name] = (string)$value;
@ -794,13 +804,13 @@ class cache_definition {
public function get_requirements_bin() { public function get_requirements_bin() {
$requires = 0; $requires = 0;
if ($this->require_data_guarantee()) { if ($this->require_data_guarantee()) {
$requires += cache_store::SUPPORTS_DATA_GUARANTEE; $requires += store::SUPPORTS_DATA_GUARANTEE;
} }
if ($this->require_multiple_identifiers()) { if ($this->require_multiple_identifiers()) {
$requires += cache_store::SUPPORTS_MULTIPLE_IDENTIFIERS; $requires += store::SUPPORTS_MULTIPLE_IDENTIFIERS;
} }
if ($this->require_searchable()) { if ($this->require_searchable()) {
$requires += cache_store::IS_SEARCHABLE; $requires += store::IS_SEARCHABLE;
} }
return $requires; return $requires;
} }
@ -808,11 +818,11 @@ class cache_definition {
/** /**
* Please call {@link cache_definition::use_static_acceleration()} instead. * Please call {@link cache_definition::use_static_acceleration()} instead.
* *
* @see cache_definition::use_static_acceleration() * @see definition::use_static_acceleration()
* @deprecated since 2.6 * @deprecated since 2.6
*/ */
public function should_be_persistent() { public function should_be_persistent() {
throw new coding_exception('cache_definition::should_be_persistent() can not be used anymore.' . throw new coding_exception('definition::should_be_persistent() can not be used anymore.' .
' Please use cache_definition::use_static_acceleration() instead.'); ' Please use cache_definition::use_static_acceleration() instead.');
} }
@ -825,7 +835,7 @@ class cache_definition {
* @return bool * @return bool
*/ */
public function use_static_acceleration() { public function use_static_acceleration() {
if ($this->mode === cache_store::MODE_REQUEST) { if ($this->mode === store::MODE_REQUEST) {
// Request caches should never use static acceleration - it just doesn't make sense. // Request caches should never use static acceleration - it just doesn't make sense.
return false; return false;
} }
@ -869,12 +879,12 @@ class cache_definition {
*/ */
public function generate_single_key_prefix() { public function generate_single_key_prefix() {
if ($this->keyprefixsingle === null) { if ($this->keyprefixsingle === null) {
$this->keyprefixsingle = $this->mode.'/'.$this->component.'/'.$this->area; $this->keyprefixsingle = $this->mode . '/' . $this->component . '/' . $this->area;
$this->keyprefixsingle .= '/'.$this->get_cache_identifier(); $this->keyprefixsingle .= '/' . $this->get_cache_identifier();
$identifiers = $this->get_identifiers(); $identifiers = $this->get_identifiers();
if ($identifiers) { if ($identifiers) {
foreach ($identifiers as $key => $value) { foreach ($identifiers as $key => $value) {
$this->keyprefixsingle .= '/'.$key.'='.$value; $this->keyprefixsingle .= '/' . $key . '=' . $value;
} }
} }
$this->keyprefixsingle = md5($this->keyprefixsingle); $this->keyprefixsingle = md5($this->keyprefixsingle);
@ -889,16 +899,16 @@ class cache_definition {
*/ */
public function generate_multi_key_parts() { public function generate_multi_key_parts() {
if ($this->keyprefixmulti === null) { if ($this->keyprefixmulti === null) {
$this->keyprefixmulti = array( $this->keyprefixmulti = [
'mode' => $this->mode, 'mode' => $this->mode,
'component' => $this->component, 'component' => $this->component,
'area' => $this->area, 'area' => $this->area,
'siteidentifier' => $this->get_cache_identifier() 'siteidentifier' => $this->get_cache_identifier(),
); ];
if (isset($this->identifiers) && !empty($this->identifiers)) { if (isset($this->identifiers) && !empty($this->identifiers)) {
$identifiers = array(); $identifiers = [];
foreach ($this->identifiers as $key => $value) { foreach ($this->identifiers as $key => $value) {
$identifiers[] = htmlentities($key, ENT_QUOTES, 'UTF-8').'='.htmlentities($value, ENT_QUOTES, 'UTF-8'); $identifiers[] = htmlentities($key, ENT_QUOTES, 'UTF-8') . '=' . htmlentities($value, ENT_QUOTES, 'UTF-8');
} }
$this->keyprefixmulti['identifiers'] = join('&', $identifiers); $this->keyprefixmulti['identifiers'] = join('&', $identifiers);
} }
@ -940,15 +950,15 @@ class cache_definition {
* @return string A string to be used as part of keys. * @return string A string to be used as part of keys.
*/ */
protected function get_cache_identifier() { protected function get_cache_identifier() {
$identifiers = array(); $identifiers = [];
if ($this->selectedsharingoption & self::SHARING_ALL) { if ($this->selectedsharingoption & self::SHARING_ALL) {
// Nothing to do here. // Nothing to do here.
} else { } else {
if ($this->selectedsharingoption & self::SHARING_SITEID) { if ($this->selectedsharingoption & self::SHARING_SITEID) {
$identifiers[] = cache_helper::get_site_identifier(); $identifiers[] = helper::get_site_identifier();
} }
if ($this->selectedsharingoption & self::SHARING_VERSION) { if ($this->selectedsharingoption & self::SHARING_VERSION) {
$identifiers[] = cache_helper::get_site_version(); $identifiers[] = helper::get_site_version();
} }
if ($this->selectedsharingoption & self::SHARING_INPUT && !empty($this->userinputsharingkey)) { if ($this->selectedsharingoption & self::SHARING_INPUT && !empty($this->userinputsharingkey)) {
$identifiers[] = $this->userinputsharingkey; $identifiers[] = $this->userinputsharingkey;
@ -993,3 +1003,8 @@ class cache_definition {
return $this->selectedsharingoption; return $this->selectedsharingoption;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(definition::class, \cache_definition::class);

View file

@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
/** /**
* The cache loader class used when the Cache has been disabled. * The cache loader class used when the Cache has been disabled.
* *
@ -21,17 +25,16 @@
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_disabled extends cache implements cache_loader_with_locking { class disabled_cache extends cache implements loader_with_locking_interface {
/** /**
* Constructs the cache. * Constructs the cache.
* *
* @param cache_definition $definition * @param definition $definition
* @param cache_store $store * @param store $store
* @param null $loader Unused. * @param null $loader Unused.
*/ */
public function __construct(cache_definition $definition, cache_store $store, $loader = null) { public function __construct(definition $definition, store $store, $loader = null) {
if ($loader instanceof cache_data_source) { if ($loader instanceof data_source_interface) {
// Set the data source to allow data sources to work when caching is entirely disabled. // Set the data source to allow data sources to work when caching is entirely disabled.
$this->set_data_source($loader); $this->set_data_source($loader);
} }
@ -54,12 +57,12 @@ class cache_disabled extends cache implements cache_loader_with_locking {
if ($requiredversion === cache::VERSION_NONE) { if ($requiredversion === cache::VERSION_NONE) {
return $datasource->load_for_cache($key); return $datasource->load_for_cache($key);
} else { } else {
if (!$datasource instanceof cache_data_source_versionable) { if (!$datasource instanceof versionable_data_source_interface) {
throw new \coding_exception('Data source is not versionable'); throw new coding_exception('Data source is not versionable');
} }
$result = $datasource->load_for_cache_versioned($key, $requiredversion, $actualversion); $result = $datasource->load_for_cache_versioned($key, $requiredversion, $actualversion);
if ($result && $actualversion < $requiredversion) { if ($result && $actualversion < $requiredversion) {
throw new \coding_exception('Data source returned outdated version'); throw new coding_exception('Data source returned outdated version');
} }
return $result; return $result;
} }
@ -213,3 +216,8 @@ class cache_disabled extends cache implements cache_loader_with_locking {
return true; return true;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(disabled_cache::class, \cache_disabled::class);

View file

@ -14,6 +14,14 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
use core_cache\exception\cache_exception;
use cachestore_static;
use cachestore_session;
use cachestore_file;
/** /**
* The cache config class used when the Cache has been disabled. * The cache config class used when the Cache has been disabled.
* *
@ -21,15 +29,14 @@
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_config_disabled extends config_writer { class disabled_config extends config_writer {
/** /**
* Returns an instance of the configuration writer. * Returns an instance of the configuration writer.
* *
* @return cache_config_disabled * @return disabled_config
*/ */
public static function instance() { public static function instance() {
$factory = cache_factory::instance(); $factory = factory::instance();
return $factory->create_config_instance(true); return $factory->create_config_instance(true);
} }
@ -46,7 +53,7 @@ class cache_config_disabled extends config_writer {
* @return array * @return array
*/ */
protected function generate_configuration_array() { protected function generate_configuration_array() {
$configuration = array(); $configuration = [];
$configuration['stores'] = $this->configstores; $configuration['stores'] = $this->configstores;
$configuration['modemappings'] = $this->configmodemappings; $configuration['modemappings'] = $this->configmodemappings;
$configuration['definitions'] = $this->configdefinitions; $configuration['definitions'] = $this->configdefinitions;
@ -64,7 +71,7 @@ class cache_config_disabled extends config_writer {
* @return bool * @return bool
* @throws cache_exception * @throws cache_exception
*/ */
public function add_store_instance($name, $plugin, array $configuration = array()) { public function add_store_instance($name, $plugin, array $configuration = []) {
return false; return false;
} }
@ -115,63 +122,63 @@ class cache_config_disabled extends config_writer {
// HACK ALERT. // HACK ALERT.
// We probably need to come up with a better way to create the default stores, or at least ensure 100% that the // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the
// default store plugins are protected from deletion. // default store plugins are protected from deletion.
require_once($CFG->dirroot.'/cache/stores/file/lib.php'); require_once($CFG->dirroot . '/cache/stores/file/lib.php');
require_once($CFG->dirroot.'/cache/stores/session/lib.php'); require_once($CFG->dirroot . '/cache/stores/session/lib.php');
require_once($CFG->dirroot.'/cache/stores/static/lib.php'); require_once($CFG->dirroot . '/cache/stores/static/lib.php');
$writer = new self; $writer = new self();
$writer->configstores = array( $writer->configstores = [
'default_application' => array( 'default_application' => [
'name' => 'default_application', 'name' => 'default_application',
'plugin' => 'file', 'plugin' => 'file',
'configuration' => array(), 'configuration' => [],
'features' => cachestore_file::get_supported_features(), 'features' => cachestore_file::get_supported_features(),
'modes' => cache_store::MODE_APPLICATION, 'modes' => store::MODE_APPLICATION,
'default' => true, 'default' => true,
), ],
'default_session' => array( 'default_session' => [
'name' => 'default_session', 'name' => 'default_session',
'plugin' => 'session', 'plugin' => 'session',
'configuration' => array(), 'configuration' => [],
'features' => cachestore_session::get_supported_features(), 'features' => cachestore_session::get_supported_features(),
'modes' => cache_store::MODE_SESSION, 'modes' => store::MODE_SESSION,
'default' => true, 'default' => true,
), ],
'default_request' => array( 'default_request' => [
'name' => 'default_request', 'name' => 'default_request',
'plugin' => 'static', 'plugin' => 'static',
'configuration' => array(), 'configuration' => [],
'features' => cachestore_static::get_supported_features(), 'features' => cachestore_static::get_supported_features(),
'modes' => cache_store::MODE_REQUEST, 'modes' => store::MODE_REQUEST,
'default' => true, 'default' => true,
) ],
); ];
$writer->configdefinitions = array(); $writer->configdefinitions = [];
$writer->configmodemappings = array( $writer->configmodemappings = [
array( [
'mode' => cache_store::MODE_APPLICATION, 'mode' => store::MODE_APPLICATION,
'store' => 'default_application', 'store' => 'default_application',
'sort' => -1 'sort' => -1,
), ],
array( [
'mode' => cache_store::MODE_SESSION, 'mode' => store::MODE_SESSION,
'store' => 'default_session', 'store' => 'default_session',
'sort' => -1 'sort' => -1,
), ],
array( [
'mode' => cache_store::MODE_REQUEST, 'mode' => store::MODE_REQUEST,
'store' => 'default_request', 'store' => 'default_request',
'sort' => -1 'sort' => -1,
) ],
); ];
$writer->configlocks = array( $writer->configlocks = [
'default_file_lock' => array( 'default_file_lock' => [
'name' => 'cachelock_file_default', 'name' => 'cachelock_file_default',
'type' => 'cachelock_file', 'type' => 'cachelock_file',
'dir' => 'filelocks', 'dir' => 'filelocks',
'default' => true 'default' => true,
) ],
); ];
return $writer->generate_configuration_array(); return $writer->generate_configuration_array();
} }
@ -192,7 +199,7 @@ class cache_config_disabled extends config_writer {
* @return array * @return array
*/ */
protected static function locate_definitions($coreonly = false) { protected static function locate_definitions($coreonly = false) {
return array(); return [];
} }
/** /**
@ -206,3 +213,8 @@ class cache_config_disabled extends config_writer {
// Nothing to do here. // Nothing to do here.
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(disabled_config::class, \cache_config_disabled::class);

View file

@ -14,6 +14,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use cache_factory as factory;
use cache_store as store;
use core_cache\definition;
use cache_application as application_cache;
use cache_session as session_cache;
use cachestore_static;
use core\exception\coding_exception;
/** /**
* The cache factory class used when the Cache has been disabled. * The cache factory class used when the Cache has been disabled.
* *
@ -21,7 +31,7 @@
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_factory_disabled extends cache_factory { class disabled_factory extends factory {
/** @var array Array of temporary caches in use. */ /** @var array Array of temporary caches in use. */
protected static $tempcaches = []; protected static $tempcaches = [];
@ -29,7 +39,7 @@ class cache_factory_disabled extends cache_factory {
* Returns an instance of the cache_factor method. * Returns an instance of the cache_factor method.
* *
* @param bool $forcereload Unused. * @param bool $forcereload Unused.
* @return cache_factory * @return factory
* @throws coding_exception * @throws coding_exception
*/ */
public static function instance($forcereload = false) { public static function instance($forcereload = false) {
@ -42,7 +52,7 @@ class cache_factory_disabled extends cache_factory {
* @param string $component * @param string $component
* @param string $area * @param string $area
* @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
* @return cache_definition * @return definition
*/ */
public function create_definition($component, $area, $unused = null) { public function create_definition($component, $area, $unused = null) {
$definition = parent::create_definition($component, $area); $definition = parent::create_definition($component, $area);
@ -50,22 +60,22 @@ class cache_factory_disabled extends cache_factory {
return $definition; return $definition;
} }
return cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area); return definition::load_adhoc(store::MODE_REQUEST, $component, $area);
} }
/** /**
* Common public method to create a cache instance given a definition. * Common public method to create a cache instance given a definition.
* *
* @param cache_definition $definition * @param definition $definition
* @return cache_application|cache_session|cache_store * @return application_cache|session_cache|store
* @throws coding_exception * @throws coding_exception
*/ */
public function create_cache(cache_definition $definition) { public function create_cache(definition $definition) {
$loader = null; $loader = null;
if ($definition->has_data_source()) { if ($definition->has_data_source()) {
$loader = $definition->get_data_source(); $loader = $definition->get_data_source();
} }
return new cache_disabled($definition, $this->create_dummy_store($definition), $loader); return new disabled_cache($definition, $this->create_dummy_store($definition), $loader);
} }
/** /**
@ -75,9 +85,9 @@ class cache_factory_disabled extends cache_factory {
* @param string $area * @param string $area
* @param array $identifiers * @param array $identifiers
* @param string $unused Used to be datasourceaggregate but that was removed and this is now unused. * @param string $unused Used to be datasourceaggregate but that was removed and this is now unused.
* @return cache_application|cache_session|request_cache * @return application_cache|session_cache|request_cache
*/ */
public function create_cache_from_definition($component, $area, array $identifiers = array(), $unused = null) { public function create_cache_from_definition($component, $area, array $identifiers = [], $unused = null) {
// Temporary in-memory caches are sometimes allowed when caching is disabled. // Temporary in-memory caches are sometimes allowed when caching is disabled.
if (\core_cache\allow_temporary_caches::is_allowed() && !$identifiers) { if (\core_cache\allow_temporary_caches::is_allowed() && !$identifiers) {
$key = $component . '/' . $area; $key = $component . '/' . $area;
@ -93,7 +103,7 @@ class cache_factory_disabled extends cache_factory {
// or it wouldn't have support for versioning. The cache_application class is used // or it wouldn't have support for versioning. The cache_application class is used
// (rather than cache_request which might make more sense logically) because it // (rather than cache_request which might make more sense logically) because it
// includes support for locking, which might be necessary for some caches. // includes support for locking, which might be necessary for some caches.
$cache = new cache_application($definition, $store); $cache = new application_cache($definition, $store);
self::$tempcaches[$key] = $cache; self::$tempcaches[$key] = $cache;
} }
return $cache; return $cache;
@ -129,13 +139,13 @@ class cache_factory_disabled extends cache_factory {
* - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
* - staticacceleration : If set to true the cache will hold onto all data passing through it. * - staticacceleration : If set to true the cache will hold onto all data passing through it.
* - staticaccelerationsize : Sets the max size of the static acceleration array. * - staticaccelerationsize : Sets the max size of the static acceleration array.
* @return cache_application|cache_session|request_cache * @return application_cache|session_cache|request_cache
*/ */
public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) { public function create_cache_from_params($mode, $component, $area, array $identifiers = [], array $options = []) {
// Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php // Regular cache definitions are cached inside create_definition(). This is not the case for disabledlib.php
// definitions as they use load_adhoc(). They are built as a new object on each call. // definitions as they use load_adhoc(). They are built as a new object on each call.
// We do not need to clone the definition because we know it's new. // We do not need to clone the definition because we know it's new.
$definition = cache_definition::load_adhoc($mode, $component, $area, $options); $definition = definition::load_adhoc($mode, $component, $area, $options);
$definition->set_identifiers($identifiers); $definition->set_identifiers($identifiers);
$cache = $this->create_cache($definition); $cache = $this->create_cache($definition);
return $cache; return $cache;
@ -146,10 +156,10 @@ class cache_factory_disabled extends cache_factory {
* *
* @param string $name Unused. * @param string $name Unused.
* @param array $details Unused. * @param array $details Unused.
* @param cache_definition $definition * @param definition $definition
* @return boolean|cache_store * @return boolean|store
*/ */
public function create_store_from_config($name, array $details, cache_definition $definition) { public function create_store_from_config($name, array $details, definition $definition) {
return $this->create_dummy_store($definition); return $this->create_dummy_store($definition);
} }
@ -157,7 +167,7 @@ class cache_factory_disabled extends cache_factory {
* Creates a cache config instance with the ability to write if required. * Creates a cache config instance with the ability to write if required.
* *
* @param bool $writer Unused. * @param bool $writer Unused.
* @return cache_config_disabled|config_writer * @return disabled_config|config_writer
*/ */
public function create_config_instance($writer = false) { public function create_config_instance($writer = false) {
// We are always going to use the cache_config_disabled class for all regular request. // We are always going to use the cache_config_disabled class for all regular request.
@ -170,10 +180,10 @@ class cache_factory_disabled extends cache_factory {
$class = 'cache_config_writer'; $class = 'cache_config_writer';
} }
if (!array_key_exists($class, $this->configs)) { if (!array_key_exists($class, $this->configs)) {
self::set_state(self::STATE_INITIALISING); self::set_state(factory::STATE_INITIALISING);
if ($class === 'cache_config_disabled') { if ($class === 'cache_config_disabled') {
$configuration = $class::create_default_configuration(); $configuration = $class::create_default_configuration();
$this->configs[$class] = new $class; $this->configs[$class] = new $class();
} else { } else {
$configuration = false; $configuration = false;
// If we need a writer, we should get the classname from the generic factory. // If we need a writer, we should get the classname from the generic factory.
@ -182,7 +192,7 @@ class cache_factory_disabled extends cache_factory {
} }
$this->configs[$class]->load($configuration); $this->configs[$class]->load($configuration);
} }
self::set_state(self::STATE_READY); self::set_state(factory::STATE_READY);
// Return the instance. // Return the instance.
return $this->configs[$class]; return $this->configs[$class];
@ -197,3 +207,7 @@ class cache_factory_disabled extends cache_factory {
return true; return true;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(disabled_factory::class, \cache_factory_disabled::class);

View file

@ -16,31 +16,14 @@
namespace core_cache; namespace core_cache;
/**
* Cache dummy store.
*
* This dummy store is used when a load has no other stores that it can make use of.
* This shouldn't happen in normal operation... I think.
*
* This file is part of Moodle's cache API, affectionately called MUC.
* It contains the components that are requried in order to use caching.
*
* @package core
* @category cache
* @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/** /**
* The cache dummy store. * The cache dummy store.
* *
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package core_cache
*/ */
class cachestore_dummy extends cache_store { class dummy_cachestore extends store {
/** /**
* The name of this store. * The name of this store.
* @var string * @var string
@ -59,7 +42,7 @@ class cachestore_dummy extends cache_store {
* The stored data array * The stored data array
* @var array * @var array
*/ */
protected $store = array(); protected $store = [];
/** /**
* Cache definition * Cache definition
@ -72,7 +55,7 @@ class cachestore_dummy extends cache_store {
* @param string $name * @param string $name
* @param array $configuration * @param array $configuration
*/ */
public function __construct($name = 'Dummy store', array $configuration = array()) { public function __construct($name = 'Dummy store', array $configuration = []) {
$this->name = $name; $this->name = $name;
} }
@ -97,8 +80,8 @@ class cachestore_dummy extends cache_store {
* @param array $configuration * @param array $configuration
* @return int * @return int
*/ */
public static function get_supported_features(array $configuration = array()) { public static function get_supported_features(array $configuration = []) {
return self::SUPPORTS_NATIVE_TTL; return store::SUPPORTS_NATIVE_TTL;
} }
/** /**
@ -106,8 +89,8 @@ class cachestore_dummy extends cache_store {
* @param array $configuration * @param array $configuration
* @return int * @return int
*/ */
public static function get_supported_modes(array $configuration = array()) { public static function get_supported_modes(array $configuration = []) {
return self::MODE_APPLICATION + self::MODE_REQUEST + self::MODE_SESSION; return store::MODE_APPLICATION + store::MODE_REQUEST + store::MODE_SESSION;
} }
/** /**
@ -121,7 +104,7 @@ class cachestore_dummy extends cache_store {
// store things in its static array. // store things in its static array.
// - If the definition is not using static acceleration then the cache loader won't try to store anything // - If the definition is not using static acceleration then the cache loader won't try to store anything
// and we will need to store it here in order to make sure it is accessible. // and we will need to store it here in order to make sure it is accessible.
if ($definition->get_mode() !== self::MODE_APPLICATION) { if ($definition->get_mode() !== store::MODE_APPLICATION) {
// Neither the request cache nor the session cache provide static acceleration. // Neither the request cache nor the session cache provide static acceleration.
$this->persist = true; $this->persist = true;
} else { } else {
@ -166,7 +149,7 @@ class cachestore_dummy extends cache_store {
* @return bool * @return bool
*/ */
public function get_many($keys) { public function get_many($keys) {
$return = array(); $return = [];
foreach ($keys as $key) { foreach ($keys as $key) {
if ($this->persist && array_key_exists($key, $this->store)) { if ($this->persist && array_key_exists($key, $this->store)) {
$return[$key] = $this->store[$key]; $return[$key] = $this->store[$key];
@ -200,7 +183,6 @@ class cachestore_dummy extends cache_store {
foreach ($keyvaluearray as $pair) { foreach ($keyvaluearray as $pair) {
$this->store[$pair['key']] = $pair['value']; $this->store[$pair['key']] = $pair['value'];
} }
} }
return count($keyvaluearray); return count($keyvaluearray);
} }
@ -233,7 +215,7 @@ class cachestore_dummy extends cache_store {
* @return bool * @return bool
*/ */
public function purge() { public function purge() {
$this->store = array(); $this->store = [];
return true; return true;
} }
@ -241,11 +223,13 @@ class cachestore_dummy extends cache_store {
* Performs any necessary clean up when the store instance is being deleted. * Performs any necessary clean up when the store instance is being deleted.
* *
* @deprecated since 3.2 * @deprecated since 3.2
* @see cachestore_dummy::instance_deleted() * @see dummy_cachestore::instance_deleted()
*/ */
public function cleanup() { public function cleanup() {
debugging('cachestore_dummy::cleanup() is deprecated. Please use cachestore_dummy::instance_deleted() instead.', debugging(
DEBUG_DEVELOPER); 'dummy_cachestore::cleanup() is deprecated. Please use dummy_cachestore::instance_deleted() instead.',
DEBUG_DEVELOPER
);
$this->instance_deleted(); $this->instance_deleted();
} }
@ -264,10 +248,10 @@ class cachestore_dummy extends cache_store {
* Generates an instance of the cache store that can be used for testing. * Generates an instance of the cache store that can be used for testing.
* *
* @param definition $definition * @param definition $definition
* @return false * @return self
*/ */
public static function initialise_test_instance(definition $definition) { public static function initialise_test_instance(definition $definition) {
$cache = new cachestore_dummy('Dummy store test'); $cache = new dummy_cachestore('Dummy store test');
if ($cache->is_ready()) { if ($cache->is_ready()) {
$cache->initialise($definition); $cache->initialise($definition);
} }

View file

@ -14,10 +14,14 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache\exception;
use core\exception\moodle_exception;
/** /**
* A cache exception class. Just allows people to catch cache exceptions. * A cache exception class. Just allows people to catch cache exceptions.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -37,3 +41,8 @@ class cache_exception extends moodle_exception {
parent::__construct($errorcode, $module, $link, $a, $debuginfo); parent::__construct($errorcode, $module, $link, $a, $debuginfo);
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cache_exception::class, \cache_exception::class);

View file

@ -14,6 +14,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
use cache_config_testing;
use cache_phpunit_factory;
/** /**
* The cache factory class. * The cache factory class.
* *
@ -23,9 +29,9 @@
* *
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @package core_cache
*/ */
class cache_factory { class factory {
/** The cache has not been initialised yet. */ /** The cache has not been initialised yet. */
const STATE_UNINITIALISED = 0; const STATE_UNINITIALISED = 0;
/** The cache is in the process of initialising itself. */ /** The cache is in the process of initialising itself. */
@ -44,8 +50,8 @@ class cache_factory {
const STATE_STORES_DISABLED = 11; const STATE_STORES_DISABLED = 11;
/** /**
* An instance of the cache_factory class created upon the first request. * An instance of the factory class created upon the first request.
* @var cache_factory * @var factory
*/ */
protected static $instance; protected static $instance;
@ -53,43 +59,43 @@ class cache_factory {
* An array containing caches created for definitions * An array containing caches created for definitions
* @var array * @var array
*/ */
protected $cachesfromdefinitions = array(); protected $cachesfromdefinitions = [];
/** /**
* Array of caches created by parameters, ad-hoc definitions will have been used. * Array of caches created by parameters, ad-hoc definitions will have been used.
* @var array * @var array
*/ */
protected $cachesfromparams = array(); protected $cachesfromparams = [];
/** /**
* An array of stores organised by definitions. * An array of stores organised by definitions.
* @var array * @var array
*/ */
protected $definitionstores = array(); protected $definitionstores = [];
/** /**
* An array of instantiated stores. * An array of instantiated stores.
* @var array * @var array
*/ */
protected $stores = array(); protected $stores = [];
/** /**
* An array of configuration instances * An array of configuration instances
* @var array * @var array
*/ */
protected $configs = array(); protected $configs = [];
/** /**
* An array of initialised definitions * An array of initialised definitions
* @var array * @var array
*/ */
protected $definitions = array(); protected $definitions = [];
/** /**
* An array of lock plugins. * An array of lock plugins.
* @var array * @var array
*/ */
protected $lockplugins = array(); protected $lockplugins = [];
/** /**
* The current state of the cache API. * The current state of the cache API.
@ -104,10 +110,10 @@ class cache_factory {
protected static $displayhelper = null; protected static $displayhelper = null;
/** /**
* Returns an instance of the cache_factory class. * Returns an instance of the factory class.
* *
* @param bool $forcereload If set to true a new cache_factory instance will be created and used. * @param bool $forcereload If set to true a new factory instance will be created and used.
* @return cache_factory * @return factory
*/ */
public static function instance($forcereload = false) { public static function instance($forcereload = false) {
global $CFG; global $CFG;
@ -116,22 +122,21 @@ class cache_factory {
if (defined('CACHE_DISABLE_ALL') && CACHE_DISABLE_ALL !== false) { if (defined('CACHE_DISABLE_ALL') && CACHE_DISABLE_ALL !== false) {
// The cache has been disabled. Load disabledlib and start using the factory designed to handle this // The cache has been disabled. Load disabledlib and start using the factory designed to handle this
// situation. It will use disabled alternatives where available. // situation. It will use disabled alternatives where available.
self::$instance = new cache_factory_disabled(); self::$instance = new disabled_factory();
} else if ((defined('PHPUNIT_TEST') && PHPUNIT_TEST) || defined('BEHAT_SITE_RUNNING')) { } else if ((defined('PHPUNIT_TEST') && PHPUNIT_TEST) || defined('BEHAT_SITE_RUNNING')) {
// We're using the test factory. // We're using the test factory.
require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php'); require_once($CFG->dirroot . '/cache/tests/fixtures/lib.php');
self::$instance = new cache_phpunit_factory(); self::$instance = new cache_phpunit_factory();
if (defined('CACHE_DISABLE_STORES') && CACHE_DISABLE_STORES !== false) { if (defined('CACHE_DISABLE_STORES') && CACHE_DISABLE_STORES !== false) {
// The cache stores have been disabled. // The cache stores have been disabled.
self::$instance->set_state(self::STATE_STORES_DISABLED); self::$instance->set_state(self::STATE_STORES_DISABLED);
} }
} else if (!empty($CFG->alternative_cache_factory_class)) { } else if (!empty($CFG->alternative_cache_factory_class)) {
$factoryclass = $CFG->alternative_cache_factory_class; $factoryclass = $CFG->alternative_cache_factory_class;
self::$instance = new $factoryclass(); self::$instance = new $factoryclass();
} else { } else {
// We're using the regular factory. // We're using the regular factory.
self::$instance = new cache_factory(); self::$instance = new factory();
if (defined('CACHE_DISABLE_STORES') && CACHE_DISABLE_STORES !== false) { if (defined('CACHE_DISABLE_STORES') && CACHE_DISABLE_STORES !== false) {
// The cache stores have been disabled. // The cache stores have been disabled.
self::$instance->set_state(self::STATE_STORES_DISABLED); self::$instance->set_state(self::STATE_STORES_DISABLED);
@ -154,10 +159,10 @@ class cache_factory {
public static function reset() { public static function reset() {
$factory = self::instance(); $factory = self::instance();
$factory->reset_cache_instances(); $factory->reset_cache_instances();
$factory->configs = array(); $factory->configs = [];
$factory->definitions = array(); $factory->definitions = [];
$factory->definitionstores = array(); $factory->definitionstores = [];
$factory->lockplugins = array(); // MUST be null in order to force its regeneration. $factory->lockplugins = []; // MUST be null in order to force its regeneration.
// Reset the state to uninitialised. // Reset the state to uninitialised.
$factory->state = self::STATE_UNINITIALISED; $factory->state = self::STATE_UNINITIALISED;
} }
@ -169,9 +174,9 @@ class cache_factory {
* however all future requests for a cache/store will lead to a new instance being re-initialised. * however all future requests for a cache/store will lead to a new instance being re-initialised.
*/ */
public function reset_cache_instances() { public function reset_cache_instances() {
$this->cachesfromdefinitions = array(); $this->cachesfromdefinitions = [];
$this->cachesfromparams = array(); $this->cachesfromparams = [];
$this->stores = array(); $this->stores = [];
} }
/** /**
@ -183,11 +188,11 @@ class cache_factory {
* @param string $area * @param string $area
* @param array $identifiers * @param array $identifiers
* @param string $unused Used to be data source aggregate however that was removed and this is now unused. * @param string $unused Used to be data source aggregate however that was removed and this is now unused.
* @return cache_application|cache_session|cache_request * @return application_cache|session_cache|request_cache
*/ */
public function create_cache_from_definition($component, $area, array $identifiers = array(), $unused = null) { public function create_cache_from_definition($component, $area, array $identifiers = [], $unused = null) {
$identifierstring = empty($identifiers) ? '' : '/'.http_build_query($identifiers); $identifierstring = empty($identifiers) ? '' : '/' . http_build_query($identifiers);
$definitionname = $component.'/'.$area.$identifierstring; $definitionname = $component . '/' . $area . $identifierstring;
if (isset($this->cachesfromdefinitions[$definitionname])) { if (isset($this->cachesfromdefinitions[$definitionname])) {
$cache = $this->cachesfromdefinitions[$definitionname]; $cache = $this->cachesfromdefinitions[$definitionname];
return $cache; return $cache;
@ -217,10 +222,10 @@ class cache_factory {
* - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars * - simpledata : Set to true if the type of the data you are going to store is scalar, or an array of scalar vars
* - staticacceleration : If set to true the cache will hold onto data passing through it. * - staticacceleration : If set to true the cache will hold onto data passing through it.
* - staticaccelerationsize : The maximum number of items to hold onto for acceleration purposes. * - staticaccelerationsize : The maximum number of items to hold onto for acceleration purposes.
* @return cache_application|cache_session|cache_request * @return application_cache|session_cache|request_cache
*/ */
public function create_cache_from_params($mode, $component, $area, array $identifiers = array(), array $options = array()) { public function create_cache_from_params($mode, $component, $area, array $identifiers = [], array $options = []) {
$identifierstring = empty($identifiers) ? '' : '_'.http_build_query($identifiers); $identifierstring = empty($identifiers) ? '' : '_' . http_build_query($identifiers);
$key = "{$mode}_{$component}_{$area}{$identifierstring}"; $key = "{$mode}_{$component}_{$area}{$identifierstring}";
if (isset($this->cachesfromparams[$key])) { if (isset($this->cachesfromparams[$key])) {
return $this->cachesfromparams[$key]; return $this->cachesfromparams[$key];
@ -228,7 +233,7 @@ class cache_factory {
// Regular cache definitions are cached inside create_definition(). This is not the case for Adhoc definitions // Regular cache definitions are cached inside create_definition(). This is not the case for Adhoc definitions
// using load_adhoc(). They are built as a new object on each call. // using load_adhoc(). They are built as a new object on each call.
// We do not need to clone the definition because we know it's new. // We do not need to clone the definition because we know it's new.
$definition = cache_definition::load_adhoc($mode, $component, $area, $options); $definition = definition::load_adhoc($mode, $component, $area, $options);
$definition->set_identifiers($identifiers); $definition->set_identifiers($identifiers);
$cache = $this->create_cache($definition); $cache = $this->create_cache($definition);
$this->cachesfromparams[$key] = $cache; $this->cachesfromparams[$key] = $cache;
@ -240,13 +245,13 @@ class cache_factory {
* *
* This is used by the static make methods. * This is used by the static make methods.
* *
* @param cache_definition $definition * @param definition $definition
* @return cache_application|cache_session|cache_store * @return application_cache|session_cache|store
* @throws coding_exception * @throws coding_exception
*/ */
public function create_cache(cache_definition $definition) { public function create_cache(definition $definition) {
$class = $definition->get_cache_class(); $class = $definition->get_cache_class();
$stores = cache_helper::get_stores_suitable_for_definition($definition); $stores = helper::get_stores_suitable_for_definition($definition);
foreach ($stores as $key => $store) { foreach ($stores as $key => $store) {
if (!$store::are_requirements_met()) { if (!$store::are_requirements_met()) {
unset($stores[$key]); unset($stores[$key]);
@ -273,10 +278,10 @@ class cache_factory {
* *
* @param string $name The name of the store (must be unique remember) * @param string $name The name of the store (must be unique remember)
* @param array $details * @param array $details
* @param cache_definition $definition The definition to instantiate it for. * @param definition $definition The definition to instantiate it for.
* @return boolean|cache_store * @return boolean|store
*/ */
public function create_store_from_config($name, array $details, cache_definition $definition) { public function create_store_from_config($name, array $details, definition $definition) {
if (!array_key_exists($name, $this->stores)) { if (!array_key_exists($name, $this->stores)) {
// Properties: name, plugin, configuration, class. // Properties: name, plugin, configuration, class.
$class = $details['class']; $class = $details['class'];
@ -286,7 +291,7 @@ class cache_factory {
$store = new $class($details['name'], $details['configuration']); $store = new $class($details['name'], $details['configuration']);
$this->stores[$name] = $store; $this->stores[$name] = $store;
} }
/* @var cache_store $store */ /* @var store $store */
$store = $this->stores[$name]; $store = $this->stores[$name];
// We check are_requirements_met although we expect is_ready is going to check as well. // We check are_requirements_met although we expect is_ready is going to check as well.
if (!$store::are_requirements_met() || !$store->is_ready() || !$store->is_supported_mode($definition->get_mode())) { if (!$store::are_requirements_met() || !$store->is_ready() || !$store->is_supported_mode($definition->get_mode())) {
@ -302,7 +307,7 @@ class cache_factory {
$store->initialise($definition); $store->initialise($definition);
$definitionid = $definition->get_id(); $definitionid = $definition->get_id();
if (!isset($this->definitionstores[$definitionid])) { if (!isset($this->definitionstores[$definitionid])) {
$this->definitionstores[$definitionid] = array(); $this->definitionstores[$definitionid] = [];
} }
$this->definitionstores[$definitionid][] = $store; $this->definitionstores[$definitionid][] = $store;
return $store; return $store;
@ -310,13 +315,13 @@ class cache_factory {
/** /**
* Returns an array of cache stores that have been initialised for use in definitions. * Returns an array of cache stores that have been initialised for use in definitions.
* @param cache_definition $definition * @param definition $definition
* @return array * @return array
*/ */
public function get_store_instances_in_use(cache_definition $definition) { public function get_store_instances_in_use(definition $definition) {
$id = $definition->get_id(); $id = $definition->get_id();
if (!isset($this->definitionstores[$id])) { if (!isset($this->definitionstores[$id])) {
return array(); return [];
} }
return $this->definitionstores[$id]; return $this->definitionstores[$id];
} }
@ -333,7 +338,7 @@ class cache_factory {
/** /**
* Gets all adhoc caches that have been used within this request. * Gets all adhoc caches that have been used within this request.
* *
* @return cache_store[] Caches currently in use * @return store[] Caches currently in use
*/ */
public function get_adhoc_caches_in_use() { public function get_adhoc_caches_in_use() {
return $this->cachesfromparams; return $this->cachesfromparams;
@ -343,23 +348,23 @@ class cache_factory {
* Creates a cache config instance with the ability to write if required. * Creates a cache config instance with the ability to write if required.
* *
* @param bool $writer If set to true an instance that can update the configuration will be returned. * @param bool $writer If set to true an instance that can update the configuration will be returned.
* @return cache_config|cache_config_writer * @return config|config_writer
*/ */
public function create_config_instance($writer = false) { public function create_config_instance($writer = false) {
global $CFG; global $CFG;
// The class to use. // The class to use.
$class = 'cache_config'; $class = config::class;
// Are we running tests of some form? // Are we running tests of some form?
$testing = (defined('PHPUNIT_TEST') && PHPUNIT_TEST) || defined('BEHAT_SITE_RUNNING'); $testing = (defined('PHPUNIT_TEST') && PHPUNIT_TEST) || defined('BEHAT_SITE_RUNNING');
// Check if this is a PHPUnit test and redirect to the phpunit config classes if it is. // Check if this is a PHPUnit test and redirect to the phpunit config classes if it is.
if ($testing) { if ($testing) {
require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php'); require_once($CFG->dirroot . '/cache/tests/fixtures/lib.php');
// We have just a single class for PHP unit tests. We don't care enough about its // We have just a single class for PHP unit tests. We don't care enough about its
// performance to do otherwise and having a single method allows us to inject things into it // performance to do otherwise and having a single method allows us to inject things into it
// while testing. // while testing.
$class = 'cache_config_testing'; $class = cache_config_testing::class;
} }
// Check if we need to create a config file with defaults. // Check if we need to create a config file with defaults.
@ -376,12 +381,12 @@ class cache_factory {
// Create the default configuration. // Create the default configuration.
// Update the state, we are now initialising the cache. // Update the state, we are now initialising the cache.
self::set_state(self::STATE_INITIALISING); self::set_state(self::STATE_INITIALISING);
/** @var cache_config_writer $class */ /** @var config_writer $class */
$configuration = $class::create_default_configuration(); $configuration = $class::create_default_configuration();
if ($configuration !== true) { if ($configuration !== true) {
// Failed to create the default configuration. Disable the cache stores and update the state. // Failed to create the default configuration. Disable the cache stores and update the state.
self::set_state(self::STATE_ERROR_INITIALISING); self::set_state(self::STATE_ERROR_INITIALISING);
$this->configs[$class] = new $class; $this->configs[$class] = new $class();
$this->configs[$class]->load($configuration); $this->configs[$class]->load($configuration);
$error = true; $error = true;
} }
@ -389,7 +394,7 @@ class cache_factory {
if (!array_key_exists($class, $this->configs)) { if (!array_key_exists($class, $this->configs)) {
// Create a new instance and call it to load it. // Create a new instance and call it to load it.
$this->configs[$class] = new $class; $this->configs[$class] = new $class();
$this->configs[$class]->load(); $this->configs[$class]->load();
} }
@ -408,17 +413,17 @@ class cache_factory {
* @param string $area * @param string $area
* @param string $unused This used to be data source aggregate - however that functionality has been removed and * @param string $unused This used to be data source aggregate - however that functionality has been removed and
* this argument is now unused. * this argument is now unused.
* @return cache_definition * @return definition
* @throws coding_exception If the definition cannot be found. * @throws coding_exception If the definition cannot be found.
*/ */
public function create_definition($component, $area, $unused = null) { public function create_definition($component, $area, $unused = null) {
$id = $component.'/'.$area; $id = $component . '/' . $area;
if (!isset($this->definitions[$id])) { if (!isset($this->definitions[$id])) {
// This is the first time this definition has been requested. // This is the first time this definition has been requested.
if ($this->is_initialising()) { if ($this->is_initialising()) {
// We're initialising the cache right now. Don't try to create another config instance. // We're initialising the cache right now. Don't try to create another config instance.
// We'll just use an ad-hoc cache for the time being. // We'll just use an ad-hoc cache for the time being.
$definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area); $definition = definition::load_adhoc(store::MODE_REQUEST, $component, $area);
} else { } else {
// Load all the known definitions and find the desired one. // Load all the known definitions and find the desired one.
$instance = $this->create_config_instance(); $instance = $this->create_config_instance();
@ -433,7 +438,7 @@ class cache_factory {
// This means that the cache initialisation has requested something from a cache (I had recursive nightmares about this). // This means that the cache initialisation has requested something from a cache (I had recursive nightmares about this).
// To serve this purpose and avoid errors we are going to make use of an ad-hoc cache rather than // To serve this purpose and avoid errors we are going to make use of an ad-hoc cache rather than
// search for the definition which would possibly cause an infitite loop trying to initialise the cache. // search for the definition which would possibly cause an infitite loop trying to initialise the cache.
$definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area); $definition = definition::load_adhoc(store::MODE_REQUEST, $component, $area);
} else { } else {
// Either a typo of the developer has just created the definition and is using it for the first time. // Either a typo of the developer has just created the definition and is using it for the first time.
$this->reset(); $this->reset();
@ -441,16 +446,16 @@ class cache_factory {
$instance->update_definitions(); $instance->update_definitions();
$definition = $instance->get_definition_by_id($id); $definition = $instance->get_definition_by_id($id);
if (!$definition) { if (!$definition) {
throw new coding_exception('The requested cache definition does not exist.'. $id, $id); throw new coding_exception('The requested cache definition does not exist.' . $id, $id);
} }
if (!$this->is_disabled()) { if (!$this->is_disabled()) {
debugging('Cache definitions reparsed causing cache reset in order to locate definition. debugging('Cache definitions reparsed causing cache reset in order to locate definition.
You should bump the version number to ensure definitions are reprocessed.', DEBUG_DEVELOPER); You should bump the version number to ensure definitions are reprocessed.', DEBUG_DEVELOPER);
} }
$definition = cache_definition::load($id, $definition); $definition = definition::load($id, $definition);
} }
} else { } else {
$definition = cache_definition::load($id, $definition); $definition = definition::load($id, $definition);
} }
} }
$this->definitions[$id] = $definition; $this->definitions[$id] = $definition;
@ -464,8 +469,8 @@ class cache_factory {
* @param definition $definition * @param definition $definition
* @return dummy_cachestore * @return dummy_cachestore
*/ */
protected function create_dummy_store(cache_definition $definition) { protected function create_dummy_store(definition $definition) {
$store = new cachestore_dummy(); $store = new dummy_cachestore();
$store->initialise($definition); $store->initialise($definition);
return $store; return $store;
} }
@ -474,7 +479,7 @@ class cache_factory {
* Returns a lock instance ready for use. * Returns a lock instance ready for use.
* *
* @param array $config * @param array $config
* @return cache_lock_interface * @return lockable_cache_interface
*/ */
public function create_lock_instance(array $config) { public function create_lock_instance(array $config) {
global $CFG; global $CFG;
@ -488,7 +493,7 @@ class cache_factory {
if (!isset($this->lockplugins[$type])) { if (!isset($this->lockplugins[$type])) {
$pluginname = substr($type, 10); $pluginname = substr($type, 10);
$file = $CFG->dirroot."/cache/locks/{$pluginname}/lib.php"; $file = $CFG->dirroot . "/cache/locks/{$pluginname}/lib.php";
if (file_exists($file) && is_readable($file)) { if (file_exists($file) && is_readable($file)) {
require_once($file); require_once($file);
} }
@ -592,7 +597,7 @@ class cache_factory {
* MUC it was decided that this was just to risky and abusable. * MUC it was decided that this was just to risky and abusable.
*/ */
protected static function disable() { protected static function disable() {
self::$instance = new cache_factory_disabled(); self::$instance = new disabled_factory();
} }
/** /**
@ -614,9 +619,9 @@ class cache_factory {
* In order to re-enable the cache you must call the cache factories static reset method: * In order to re-enable the cache you must call the cache factories static reset method:
* <code> * <code>
* // Disable the cache factory. * // Disable the cache factory.
* cache_factory::disable_stores(); * factory::disable_stores();
* // Re-enable the cache factory by resetting it. * // Re-enable the cache factory by resetting it.
* cache_factory::reset(); * factory::reset();
* </code> * </code>
*/ */
public static function disable_stores() { public static function disable_stores() {
@ -629,9 +634,9 @@ class cache_factory {
/** /**
* Returns an instance of the current display_helper. * Returns an instance of the current display_helper.
* *
* @return core_cache\administration_helper * @return administration_helper
*/ */
public static function get_administration_display_helper(): core_cache\administration_helper { public static function get_administration_display_helper(): administration_helper {
if (is_null(self::$displayhelper)) { if (is_null(self::$displayhelper)) {
self::$displayhelper = new \core_cache\local\administration_display_helper(); self::$displayhelper = new \core_cache\local\administration_display_helper();
} }
@ -639,12 +644,12 @@ class cache_factory {
} }
/** /**
* Gets the cache_config_writer to use when caching is disabled. * Gets the config_writer to use when caching is disabled.
* This should only be called from cache_factory_disabled. * This should only be called from disabled_factory.
* *
* @return cache_config_writer * @return config_writer
*/ */
public static function get_disabled_writer(): cache_config_writer { public static function get_disabled_writer(): config_writer {
global $CFG; global $CFG;
// Figure out if we are in a recursive loop using late static binding. // Figure out if we are in a recursive loop using late static binding.
@ -659,14 +664,19 @@ class cache_factory {
$factoryinstance = new $CFG->alternative_cache_factory_class(); $factoryinstance = new $CFG->alternative_cache_factory_class();
return $factoryinstance::get_disabled_writer(); return $factoryinstance::get_disabled_writer();
} else { } else {
// We got here from cache_factory_disabled. // We got here from disabled_factory.
// We should use the default writer here. // We should use the default writer here.
// Make sure we have a default config if needed. // Make sure we have a default config if needed.
if (!cache_config::config_file_exists()) { if (!config::config_file_exists()) {
cache_config_writer::create_default_configuration(true); config_writer::create_default_configuration(true);
} }
return new cache_config_writer(); return new config_writer();
} }
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(factory::class, \cache_factory::class);

View file

@ -14,10 +14,17 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache\form;
use core_cache\administration_helper;
use cache_store as store;
use html_writer;
use moodleform;
/** /**
* Form to set definition mappings * Form to set definition mappings
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -32,11 +39,11 @@ class cache_definition_mappings_form extends moodleform {
$definition = $this->_customdata['definition']; $definition = $this->_customdata['definition'];
$form = $this->_form; $form = $this->_form;
list($component, $area) = explode('/', $definition, 2); [$component, $area] = explode('/', $definition, 2);
list($currentstores, $storeoptions, $defaults) = [$currentstores, $storeoptions, $defaults] =
core_cache\administration_helper::get_definition_store_options($component, $area); administration_helper::get_definition_store_options($component, $area);
$storedata = core_cache\administration_helper::get_definition_summaries(); $storedata = administration_helper::get_definition_summaries();
if ($storedata[$definition]['mode'] != store::MODE_REQUEST) { if ($storedata[$definition]['mode'] != store::MODE_REQUEST) {
if (isset($storedata[$definition]['canuselocalstore']) && $storedata[$definition]['canuselocalstore']) { if (isset($storedata[$definition]['canuselocalstore']) && $storedata[$definition]['canuselocalstore']) {
$form->addElement('html', $OUTPUT->notification(get_string('localstorenotification', 'cache'), 'notifymessage')); $form->addElement('html', $OUTPUT->notification(get_string('localstorenotification', 'cache'), 'notifymessage'));
@ -49,14 +56,14 @@ class cache_definition_mappings_form extends moodleform {
$form->addElement('hidden', 'action', 'editdefinitionmapping'); $form->addElement('hidden', 'action', 'editdefinitionmapping');
$form->setType('action', PARAM_ALPHA); $form->setType('action', PARAM_ALPHA);
$requiredoptions = max(3, count($currentstores)+1); $requiredoptions = max(3, count($currentstores) + 1);
$requiredoptions = min($requiredoptions, count($storeoptions)); $requiredoptions = min($requiredoptions, count($storeoptions));
$options = array('' => get_string('none')); $options = ['' => get_string('none')];
foreach ($storeoptions as $option => $def) { foreach ($storeoptions as $option => $def) {
$options[$option] = $option; $options[$option] = $option;
if ($def['default']) { if ($def['default']) {
$options[$option] .= ' '.get_string('mappingdefault', 'cache'); $options[$option] .= ' ' . get_string('mappingdefault', 'cache');
} }
} }
@ -64,23 +71,32 @@ class cache_definition_mappings_form extends moodleform {
$title = '...'; $title = '...';
if ($i === 0) { if ($i === 0) {
$title = get_string('mappingprimary', 'cache'); $title = get_string('mappingprimary', 'cache');
} else if ($i === $requiredoptions-1) { } else if ($i === $requiredoptions - 1) {
$title = get_string('mappingfinal', 'cache'); $title = get_string('mappingfinal', 'cache');
} }
$form->addElement('select', 'mappings['.$i.']', $title, $options); $form->addElement('select', 'mappings[' . $i . ']', $title, $options);
} }
$i = 0; $i = 0;
foreach ($currentstores as $store => $def) { foreach ($currentstores as $store => $def) {
$form->setDefault('mappings['.$i.']', $store); $form->setDefault('mappings[' . $i . ']', $store);
$i++; $i++;
} }
if (!empty($defaults)) { if (!empty($defaults)) {
$form->addElement('static', 'defaults', get_string('defaultmappings', 'cache'), $form->addElement(
html_writer::tag('strong', join(', ', $defaults))); 'static',
'defaults',
get_string('defaultmappings', 'cache'),
html_writer::tag('strong', join(', ', $defaults))
);
$form->addHelpButton('defaults', 'defaultmappings', 'cache'); $form->addHelpButton('defaults', 'defaultmappings', 'cache');
} }
$this->add_action_buttons(); $this->add_action_buttons();
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cache_definition_mappings_form::class, \cache_definition_mappings_form::class);

View file

@ -14,10 +14,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache\form;
use core_cache\administration_helper;
use core_cache\definition;
use moodleform;
/** /**
* Form to set definition sharing option * Form to set definition sharing option
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2013 Sam Hemelryk * @copyright 2013 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -38,7 +44,7 @@ class cache_definition_sharing_form extends moodleform {
// We use a group here for validation. // We use a group here for validation.
$count = 0; $count = 0;
$group = array(); $group = [];
foreach ($sharingoptions as $value => $text) { foreach ($sharingoptions as $value => $text) {
$count++; $count++;
$group[] = $form->createElement('checkbox', $value, null, $text); $group[] = $form->createElement('checkbox', $value, null, $text);
@ -48,16 +54,16 @@ class cache_definition_sharing_form extends moodleform {
$form->addElement('text', 'userinputsharingkey', get_string('userinputsharingkey', 'cache')); $form->addElement('text', 'userinputsharingkey', get_string('userinputsharingkey', 'cache'));
$form->addHelpButton('userinputsharingkey', 'userinputsharingkey', 'cache'); $form->addHelpButton('userinputsharingkey', 'userinputsharingkey', 'cache');
$form->disabledIf('userinputsharingkey', 'sharing['.\core_cache\definition::SHARING_INPUT.']', 'notchecked'); $form->disabledIf('userinputsharingkey', 'sharing[' . definition::SHARING_INPUT . ']', 'notchecked');
$form->setType('userinputsharingkey', PARAM_ALPHANUMEXT); $form->setType('userinputsharingkey', PARAM_ALPHANUMEXT);
$values = array_keys($sharingoptions); $values = array_keys($sharingoptions);
if (in_array(\core_cache\definition::SHARING_ALL, $values)) { if (in_array(definition::SHARING_ALL, $values)) {
// If you share with all thenthe other options don't really make sense. // If you share with all thenthe other options don't really make sense.
foreach ($values as $value) { foreach ($values as $value) {
$form->disabledIf('sharing['.$value.']', 'sharing['.\core_cache\definition::SHARING_ALL.']', 'checked'); $form->disabledIf('sharing[' . $value . ']', 'sharing[' . definition::SHARING_ALL . ']', 'checked');
} }
$form->disabledIf('userinputsharingkey', 'sharing['.\core_cache\definition::SHARING_ALL.']', 'checked'); $form->disabledIf('userinputsharingkey', 'sharing[' . definition::SHARING_ALL . ']', 'checked');
} }
$this->add_action_buttons(); $this->add_action_buttons();
@ -71,7 +77,7 @@ class cache_definition_sharing_form extends moodleform {
public function set_data($data) { public function set_data($data) {
if (!isset($data['sharing'])) { if (!isset($data['sharing'])) {
// Set the default value here. mforms doesn't handle defaults very nicely. // Set the default value here. mforms doesn't handle defaults very nicely.
$data['sharing'] = core_cache\administration_helper::get_definition_sharing_options(\core_cache\definition::SHARING_DEFAULT); $data['sharing'] = administration_helper::get_definition_sharing_options(definition::SHARING_DEFAULT);
} }
parent::set_data($data); parent::set_data($data);
} }
@ -92,3 +98,8 @@ class cache_definition_sharing_form extends moodleform {
return $errors; return $errors;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cache_definition_sharing_form::class, \cache_definition_sharing_form::class);

View file

@ -14,19 +14,23 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache\form;
use cache_config;
use moodleform;
/** /**
* Form to add a cache lock instance. * Form to add a cache lock instance.
* *
* All cache lock plugins that wish to have custom configuration should override * All cache lock plugins that wish to have custom configuration should override
* this form, and more explicitly the plugin_definition and plugin_validation methods. * this form, and more explicitly the plugin_definition and plugin_validation methods.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2013 Sam Hemelryk * @copyright 2013 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_lock_form extends moodleform { class cache_lock_form extends moodleform {
/** /**
* Defines this form. * Defines this form.
*/ */
@ -85,3 +89,8 @@ class cache_lock_form extends moodleform {
return $errors; return $errors;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cache_lock_form::class, \cache_lock_form::class);

View file

@ -14,10 +14,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache\form;
use cache_store as store;
use moodleform;
/** /**
* Form to set the mappings for a mode. * Form to set the mappings for a mode.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -30,18 +35,18 @@ class cache_mode_mappings_form extends moodleform {
$form = $this->_form; $form = $this->_form;
$stores = $this->_customdata; $stores = $this->_customdata;
$options = array( $options = [
store::MODE_APPLICATION => array(), store::MODE_APPLICATION => [],
store::MODE_SESSION => array(), store::MODE_SESSION => [],
store::MODE_REQUEST => array() store::MODE_REQUEST => [],
); ];
foreach ($stores as $storename => $store) { foreach ($stores as $storename => $store) {
foreach ($store['modes'] as $mode => $enabled) { foreach ($store['modes'] as $mode => $enabled) {
if ($enabled && ($mode !== store::MODE_SESSION || $store['supports']['searchable'])) { if ($enabled && ($mode !== store::MODE_SESSION || $store['supports']['searchable'])) {
if (empty($store['default'])) { if (empty($store['default'])) {
$options[$mode][$storename] = $store['name']; $options[$mode][$storename] = $store['name'];
} else { } else {
$options[$mode][$storename] = get_string('store_'.$store['name'], 'cache'); $options[$mode][$storename] = get_string('store_' . $store['name'], 'cache');
} }
} }
} }
@ -50,9 +55,14 @@ class cache_mode_mappings_form extends moodleform {
$form->addElement('hidden', 'action', 'editmodemappings'); $form->addElement('hidden', 'action', 'editmodemappings');
$form->setType('action', PARAM_ALPHA); $form->setType('action', PARAM_ALPHA);
foreach ($options as $mode => $optionset) { foreach ($options as $mode => $optionset) {
$form->addElement('select', 'mode_'.$mode, get_string('mode_'.$mode, 'cache'), $optionset); $form->addElement('select', 'mode_' . $mode, get_string('mode_' . $mode, 'cache'), $optionset);
} }
$this->add_action_buttons(); $this->add_action_buttons();
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cache_mode_mappings_form::class, \cache_mode_mappings_form::class);

View file

@ -14,19 +14,21 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache\form;
use core_cache\administration_helper;
use moodleform;
/** /**
* Add store instance form. * Add store instance form.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cachestore_addinstance_form extends moodleform { class cachestore_addinstance_form extends moodleform {
#[\Override]
/**
* The definition of the add instance form
*/
final protected function definition() { final protected function definition() {
$form = $this->_form; $form = $this->_form;
$store = $this->_customdata['store']; $store = $this->_customdata['store'];
@ -56,8 +58,12 @@ class cachestore_addinstance_form extends moodleform {
} else { } else {
$form->addElement('hidden', 'lock', ''); $form->addElement('hidden', 'lock', '');
$form->setType('lock', PARAM_ALPHANUMEXT); $form->setType('lock', PARAM_ALPHANUMEXT);
$form->addElement('static', 'lock-value', get_string('locking', 'cache'), $form->addElement(
'<em>'.get_string('nativelocking', 'cache').'</em>'); 'static',
'lock-value',
get_string('locking', 'cache'),
'<em>' . get_string('nativelocking', 'cache') . '</em>'
);
} }
if (method_exists($this, 'configuration_definition')) { if (method_exists($this, 'configuration_definition')) {
@ -68,13 +74,7 @@ class cachestore_addinstance_form extends moodleform {
$this->add_action_buttons(); $this->add_action_buttons();
} }
/** #[\Override]
* Validates the add instance form data
*
* @param array $data
* @param array $files
* @return array
*/
public function validation($data, $files) { public function validation($data, $files) {
$errors = parent::validation($data, $files); $errors = parent::validation($data, $files);
@ -82,7 +82,7 @@ class cachestore_addinstance_form extends moodleform {
if (!preg_match('#^[a-zA-Z0-9\-_ ]+$#', $data['name'])) { if (!preg_match('#^[a-zA-Z0-9\-_ ]+$#', $data['name'])) {
$errors['name'] = get_string('storenameinvalid', 'cache'); $errors['name'] = get_string('storenameinvalid', 'cache');
} else if (empty($this->_customdata['store'])) { } else if (empty($this->_customdata['store'])) {
$stores = core_cache\administration_helper::get_store_instance_summaries(); $stores = administration_helper::get_store_instance_summaries();
if (array_key_exists($data['name'], $stores)) { if (array_key_exists($data['name'], $stores)) {
$errors['name'] = get_string('storenamealreadyused', 'cache'); $errors['name'] = get_string('storenamealreadyused', 'cache');
} }
@ -91,7 +91,7 @@ class cachestore_addinstance_form extends moodleform {
if (method_exists($this, 'configuration_validation')) { if (method_exists($this, 'configuration_validation')) {
$newerrors = $this->configuration_validation($data, $files, $errors); $newerrors = $this->configuration_validation($data, $files, $errors);
// We need to selectiviliy merge here // We need to selectiviliy merge here.
foreach ($newerrors as $element => $error) { foreach ($newerrors as $element => $error) {
if (!array_key_exists($element, $errors)) { if (!array_key_exists($element, $errors)) {
$errors[$element] = $error; $errors[$element] = $error;
@ -102,3 +102,8 @@ class cachestore_addinstance_form extends moodleform {
return $errors; return $errors;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(cachestore_addinstance_form::class, \cachestore_addinstance_form::class);

View file

@ -14,29 +14,34 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core_cache\administration_helper;
use core\exception\coding_exception;
use DirectoryIterator;
/** /**
* The cache helper class. * The cache helper class.
* *
* The cache helper class provides common functionality to the cache API and is useful to developers within to interact with * The cache helper class provides common functionality to the cache API and is useful to developers within to interact with
* the cache API in a general way. * the cache API in a general way.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_helper { class helper {
/** /**
* Statistics gathered by the cache API during its operation will be used here. * Statistics gathered by the cache API during its operation will be used here.
* @static * @static
* @var array * @var array
*/ */
protected static $stats = array(); protected static $stats = [];
/** /**
* The instance of the cache helper. * The instance of the cache helper.
* @var cache_helper * @var self
*/ */
protected static $instance; protected static $instance;
@ -56,25 +61,25 @@ class cache_helper {
* @return bool * @return bool
*/ */
public static function ready_for_early_init() { public static function ready_for_early_init() {
return cache_config::config_file_exists(); return config::config_file_exists();
} }
/** /**
* Returns an instance of the cache_helper. * Returns an instance of the helper.
* *
* This is designed for internal use only and acts as a static store. * This is designed for internal use only and acts as a static store.
* @staticvar null $instance * @staticvar null $instance
* @return cache_helper * @return self
*/ */
protected static function instance() { protected static function instance() {
if (is_null(self::$instance)) { if (is_null(self::$instance)) {
self::$instance = new cache_helper(); self::$instance = new self();
} }
return self::$instance; return self::$instance;
} }
/** /**
* Constructs an instance of the cache_helper class. Again for internal use only. * Constructs an instance of the helper class. Again for internal use only.
*/ */
protected function __construct() { protected function __construct() {
// Nothing to do here, just making sure you can't get an instance of this. // Nothing to do here, just making sure you can't get an instance of this.
@ -84,41 +89,41 @@ class cache_helper {
* Used as a data store for initialised definitions. * Used as a data store for initialised definitions.
* @var array * @var array
*/ */
protected $definitions = array(); protected $definitions = [];
/** /**
* Used as a data store for initialised cache stores * Used as a data store for initialised cache stores
* We use this because we want to avoid establishing multiple instances of a single store. * We use this because we want to avoid establishing multiple instances of a single store.
* @var array * @var array
*/ */
protected $stores = array(); protected $stores = [];
/** /**
* Returns the class for use as a cache loader for the given mode. * Returns the class for use as a cache loader for the given mode.
* *
* @param int $mode One of cache_store::MODE_ * @param int $mode One of store::MODE_
* @return string * @return string
* @throws coding_exception * @throws coding_exception
*/ */
public static function get_class_for_mode($mode) { public static function get_class_for_mode($mode) {
switch ($mode) { switch ($mode) {
case cache_store::MODE_APPLICATION : case store::MODE_APPLICATION:
return 'cache_application'; return application_cache::class;
case cache_store::MODE_REQUEST : case store::MODE_REQUEST:
return 'cache_request'; return request_cache::class;
case cache_store::MODE_SESSION : case store::MODE_SESSION:
return 'cache_session'; return session_cache::class;
} }
throw new coding_exception('Unknown cache mode passed. Must be one of cache_store::MODE_*'); throw new coding_exception('Unknown cache mode passed. Must be one of store::MODE_*');
} }
/** /**
* Returns the cache stores to be used with the given definition. * Returns the cache stores to be used with the given definition.
* @param cache_definition $definition * @param definition $definition
* @return array * @return array
*/ */
public static function get_cache_stores(cache_definition $definition) { public static function get_cache_stores(definition $definition) {
$instance = cache_config::instance(); $instance = config::instance();
$stores = $instance->get_stores_for_definition($definition); $stores = $instance->get_stores_for_definition($definition);
$stores = self::initialise_cachestore_instances($stores, $definition); $stores = self::initialise_cachestore_instances($stores, $definition);
return $stores; return $stores;
@ -128,12 +133,12 @@ class cache_helper {
* Internal function for initialising an array of stores against a given cache definition. * Internal function for initialising an array of stores against a given cache definition.
* *
* @param array $stores * @param array $stores
* @param cache_definition $definition * @param definition $definition
* @return cache_store[] * @return store[]
*/ */
protected static function initialise_cachestore_instances(array $stores, cache_definition $definition) { protected static function initialise_cachestore_instances(array $stores, definition $definition) {
$return = array(); $return = [];
$factory = cache_factory::instance(); $factory = factory::instance();
foreach ($stores as $name => $details) { foreach ($stores as $name => $details) {
$store = $factory->create_store_from_config($name, $details, $definition); $store = $factory->create_store_from_config($name, $details, $definition);
if ($store !== false) { if ($store !== false) {
@ -146,13 +151,13 @@ class cache_helper {
/** /**
* Returns a cache_lock instance suitable for use with the store. * Returns a cache_lock instance suitable for use with the store.
* *
* @param cache_store $store * @param store $store
* @return cache_lock_interface * @return lockable_cache_interface
*/ */
public static function get_cachelock_for_store(cache_store $store) { public static function get_cachelock_for_store(store $store) {
$instance = cache_config::instance(); $instance = config::instance();
$lockconf = $instance->get_lock_for_store($store->my_name()); $lockconf = $instance->get_lock_for_store($store->my_name());
$factory = cache_factory::instance(); $factory = factory::instance();
return $factory->create_lock_instance($lockconf); return $factory->create_lock_instance($lockconf);
} }
@ -166,9 +171,9 @@ class cache_helper {
*/ */
public static function early_get_cache_plugins() { public static function early_get_cache_plugins() {
global $CFG; global $CFG;
$result = array(); $result = [];
$ignored = array('CVS', '_vti_cnf', 'simpletest', 'db', 'yui', 'tests'); $ignored = ['CVS', '_vti_cnf', 'simpletest', 'db', 'yui', 'tests'];
$fulldir = $CFG->dirroot.'/cache/stores'; $fulldir = $CFG->dirroot . '/cache/stores';
$items = new DirectoryIterator($fulldir); $items = new DirectoryIterator($fulldir);
foreach ($items as $item) { foreach ($items as $item) {
if ($item->isDot() or !$item->isDir()) { if ($item->isDot() or !$item->isDir()) {
@ -182,7 +187,7 @@ class cache_helper {
// Better ignore plugins with problematic names here. // Better ignore plugins with problematic names here.
continue; continue;
} }
$result[$pluginname] = $fulldir.'/'.$pluginname; $result[$pluginname] = $fulldir . '/' . $pluginname;
unset($item); unset($item);
} }
unset($items); unset($items);
@ -201,14 +206,14 @@ class cache_helper {
* @return boolean * @return boolean
* @throws coding_exception * @throws coding_exception
*/ */
public static function invalidate_by_definition($component, $area, array $identifiers = array(), $keys = array()) { public static function invalidate_by_definition($component, $area, array $identifiers = [], $keys = []) {
$cache = cache::make($component, $area, $identifiers); $cache = cache::make($component, $area, $identifiers);
if (is_array($keys)) { if (is_array($keys)) {
$cache->delete_many($keys); $cache->delete_many($keys);
} else if (is_scalar($keys)) { } else if (is_scalar($keys)) {
$cache->delete($keys); $cache->delete($keys);
} else { } else {
throw new coding_exception('cache_helper::invalidate_by_definition only accepts $keys as array, or scalar.'); throw new coding_exception('helper::invalidate_by_definition only accepts $keys as array, or scalar.');
} }
return true; return true;
} }
@ -223,17 +228,17 @@ class cache_helper {
* @param array $keys * @param array $keys
*/ */
public static function invalidate_by_event($event, array $keys) { public static function invalidate_by_event($event, array $keys) {
$instance = cache_config::instance(); $instance = config::instance();
$invalidationeventset = false; $invalidationeventset = false;
$factory = cache_factory::instance(); $factory = factory::instance();
$inuse = $factory->get_caches_in_use(); $inuse = $factory->get_caches_in_use();
$purgetoken = null; $purgetoken = null;
foreach ($instance->get_definitions() as $name => $definitionarr) { foreach ($instance->get_definitions() as $name => $definitionarr) {
$definition = cache_definition::load($name, $definitionarr); $definition = definition::load($name, $definitionarr);
if ($definition->invalidates_on_event($event)) { if ($definition->invalidates_on_event($event)) {
// First up check if there is a cache loader for this definition already. // First up check if there is a cache loader for this definition already.
// If there is we need to invalidate the keys from there. // If there is we need to invalidate the keys from there.
$definitionkey = $definition->get_component().'/'.$definition->get_area(); $definitionkey = $definition->get_component() . '/' . $definition->get_area();
if (isset($inuse[$definitionkey])) { if (isset($inuse[$definitionkey])) {
$inuse[$definitionkey]->delete_many($keys); $inuse[$definitionkey]->delete_many($keys);
} }
@ -242,7 +247,7 @@ class cache_helper {
// Request caches shouldn't have events as all data is lost at the end of the request. // Request caches shouldn't have events as all data is lost at the end of the request.
// Events should only be logged once of course and likely several definitions are watching so we // Events should only be logged once of course and likely several definitions are watching so we
// track its logging with $invalidationeventset. // track its logging with $invalidationeventset.
$logevent = ($invalidationeventset === false && $definition->get_mode() !== cache_store::MODE_REQUEST); $logevent = ($invalidationeventset === false && $definition->get_mode() !== store::MODE_REQUEST);
if ($logevent) { if ($logevent) {
// Get the event invalidation cache. // Get the event invalidation cache.
@ -251,7 +256,7 @@ class cache_helper {
$data = $cache->get($event); $data = $cache->get($event);
if ($data === false) { if ($data === false) {
// There are none. // There are none.
$data = array(); $data = [];
} }
// Add our keys to them with the current cache timestamp. // Add our keys to them with the current cache timestamp.
if (null === $purgetoken) { if (null === $purgetoken) {
@ -277,12 +282,12 @@ class cache_helper {
* @param array $identifiers * @param array $identifiers
* @return bool * @return bool
*/ */
public static function purge_by_definition($component, $area, array $identifiers = array()) { public static function purge_by_definition($component, $area, array $identifiers = []) {
// Create the cache. // Create the cache.
$cache = cache::make($component, $area, $identifiers); $cache = cache::make($component, $area, $identifiers);
// Initialise, in case of a store. // Initialise, in case of a store.
if ($cache instanceof cache_store) { if ($cache instanceof store) {
$factory = cache_factory::instance(); $factory = factory::instance();
$definition = $factory->create_definition($component, $area, null); $definition = $factory->create_definition($component, $area, null);
$cacheddefinition = clone $definition; $cacheddefinition = clone $definition;
$cacheddefinition->set_identifiers($identifiers); $cacheddefinition->set_identifiers($identifiers);
@ -302,17 +307,17 @@ class cache_helper {
* @param string $event * @param string $event
*/ */
public static function purge_by_event($event) { public static function purge_by_event($event) {
$instance = cache_config::instance(); $instance = config::instance();
$invalidationeventset = false; $invalidationeventset = false;
$factory = cache_factory::instance(); $factory = factory::instance();
$inuse = $factory->get_caches_in_use(); $inuse = $factory->get_caches_in_use();
$purgetoken = null; $purgetoken = null;
foreach ($instance->get_definitions() as $name => $definitionarr) { foreach ($instance->get_definitions() as $name => $definitionarr) {
$definition = cache_definition::load($name, $definitionarr); $definition = definition::load($name, $definitionarr);
if ($definition->invalidates_on_event($event)) { if ($definition->invalidates_on_event($event)) {
// First up check if there is a cache loader for this definition already. // First up check if there is a cache loader for this definition already.
// If there is we need to invalidate the keys from there. // If there is we need to invalidate the keys from there.
$definitionkey = $definition->get_component().'/'.$definition->get_area(); $definitionkey = $definition->get_component() . '/' . $definition->get_area();
if (isset($inuse[$definitionkey])) { if (isset($inuse[$definitionkey])) {
$inuse[$definitionkey]->purge(); $inuse[$definitionkey]->purge();
} else { } else {
@ -323,7 +328,7 @@ class cache_helper {
// Request caches shouldn't have events as all data is lost at the end of the request. // Request caches shouldn't have events as all data is lost at the end of the request.
// Events should only be logged once of course and likely several definitions are watching so we // Events should only be logged once of course and likely several definitions are watching so we
// track its logging with $invalidationeventset. // track its logging with $invalidationeventset.
$logevent = ($invalidationeventset === false && $definition->get_mode() !== cache_store::MODE_REQUEST); $logevent = ($invalidationeventset === false && $definition->get_mode() !== store::MODE_REQUEST);
// We need to flag the event in the "Event invalidation" cache if it hasn't already happened. // We need to flag the event in the "Event invalidation" cache if it hasn't already happened.
if ($logevent && $invalidationeventset === false) { if ($logevent && $invalidationeventset === false) {
@ -333,9 +338,9 @@ class cache_helper {
if (null === $purgetoken) { if (null === $purgetoken) {
$purgetoken = cache::get_purge_token(true); $purgetoken = cache::get_purge_token(true);
} }
$data = array( $data = [
'purged' => $purgetoken, 'purged' => $purgetoken,
); ];
// Set that data back to the cache. // Set that data back to the cache.
$cache->set($event, $data); $cache->set($event, $data);
// This only needs to occur once. // This only needs to occur once.
@ -350,9 +355,9 @@ class cache_helper {
* @param string $store * @param string $store
* @param string $storeclass * @param string $storeclass
* @param string $definition A string that identifies the definition. * @param string $definition A string that identifies the definition.
* @param int $mode One of cache_store::MODE_*. Since 2.9. * @param int $mode One of store::MODE_*. Since 2.9.
*/ */
protected static function ensure_ready_for_stats($store, $storeclass, $definition, $mode = cache_store::MODE_APPLICATION) { protected static function ensure_ready_for_stats($store, $storeclass, $definition, $mode = store::MODE_APPLICATION) {
// This function is performance-sensitive, so exit as quickly as possible // This function is performance-sensitive, so exit as quickly as possible
// if we do not need to do anything. // if we do not need to do anything.
if (isset(self::$stats[$definition]['stores'][$store])) { if (isset(self::$stats[$definition]['stores'][$store])) {
@ -360,28 +365,28 @@ class cache_helper {
} }
if (!array_key_exists($definition, self::$stats)) { if (!array_key_exists($definition, self::$stats)) {
self::$stats[$definition] = array( self::$stats[$definition] = [
'mode' => $mode, 'mode' => $mode,
'stores' => array( 'stores' => [
$store => array( $store => [
'class' => $storeclass, 'class' => $storeclass,
'hits' => 0, 'hits' => 0,
'misses' => 0, 'misses' => 0,
'sets' => 0, 'sets' => 0,
'iobytes' => cache_store::IO_BYTES_NOT_SUPPORTED, 'iobytes' => store::IO_BYTES_NOT_SUPPORTED,
'locks' => 0, 'locks' => 0,
) ],
) ],
); ];
} else if (!array_key_exists($store, self::$stats[$definition]['stores'])) { } else if (!array_key_exists($store, self::$stats[$definition]['stores'])) {
self::$stats[$definition]['stores'][$store] = array( self::$stats[$definition]['stores'][$store] = [
'class' => $storeclass, 'class' => $storeclass,
'hits' => 0, 'hits' => 0,
'misses' => 0, 'misses' => 0,
'sets' => 0, 'sets' => 0,
'iobytes' => cache_store::IO_BYTES_NOT_SUPPORTED, 'iobytes' => store::IO_BYTES_NOT_SUPPORTED,
'locks' => 0, 'locks' => 0,
); ];
} }
} }
@ -392,47 +397,52 @@ class cache_helper {
* It is backwards compatible when a string is passed but is not accurate. * It is backwards compatible when a string is passed but is not accurate.
* *
* @since 2.9 * @since 2.9
* @param cache_definition|string $definition * @param definition|string $definition
* @return string * @return string
*/ */
protected static function get_definition_stat_id_and_mode($definition) { protected static function get_definition_stat_id_and_mode($definition) {
if (!($definition instanceof cache_definition)) { if (!($definition instanceof definition)) {
// All core calls to this method have been updated, this is the legacy state. // All core calls to this method have been updated, this is the legacy state.
// We'll use application as the default as that is the most common, really this is not accurate of course but // We'll use application as the default as that is the most common, really this is not accurate of course but
// at this point we can only guess and as it only affects calls to cache stat outside of core (of which there should // at this point we can only guess and as it only affects calls to cache stat outside of core (of which there should
// be none) I think that is fine. // be none) I think that is fine.
debugging('Please update you cache stat calls to pass the definition rather than just its ID.', DEBUG_DEVELOPER); debugging('Please update you cache stat calls to pass the definition rather than just its ID.', DEBUG_DEVELOPER);
return array((string)$definition, cache_store::MODE_APPLICATION); return [(string)$definition, store::MODE_APPLICATION];
} }
return array($definition->get_id(), $definition->get_mode()); return [$definition->get_id(), $definition->get_mode()];
} }
/** /**
* Record a cache hit in the stats for the given store and definition. * Record a cache hit in the stats for the given store and definition.
* *
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a * In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance. * definition instance. It is preferable to pass a cache definition instance.
* *
* In Moodle 3.9 the first argument changed to also accept a cache_store. * In Moodle 3.9 the first argument changed to also accept a store.
* *
* @internal * @internal
* @param string|cache_store $store * @param string|store $store
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the * @param definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now. * actual definition object now.
* @param int $hits The number of hits to record (by default 1) * @param int $hits The number of hits to record (by default 1)
* @param int $readbytes Number of bytes read from the cache or cache_store::IO_BYTES_NOT_SUPPORTED * @param int $readbytes Number of bytes read from the cache or store::IO_BYTES_NOT_SUPPORTED
*/ */
public static function record_cache_hit($store, $definition, int $hits = 1, int $readbytes = cache_store::IO_BYTES_NOT_SUPPORTED): void { public static function record_cache_hit(
$store,
$definition,
int $hits = 1,
int $readbytes = store::IO_BYTES_NOT_SUPPORTED,
): void {
$storeclass = ''; $storeclass = '';
if ($store instanceof cache_store) { if ($store instanceof store) {
$storeclass = get_class($store); $storeclass = get_class($store);
$store = $store->my_name(); $store = $store->my_name();
} }
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition); [$definitionstr, $mode] = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode); self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['hits'] += $hits; self::$stats[$definitionstr]['stores'][$store]['hits'] += $hits;
if ($readbytes !== cache_store::IO_BYTES_NOT_SUPPORTED) { if ($readbytes !== store::IO_BYTES_NOT_SUPPORTED) {
if (self::$stats[$definitionstr]['stores'][$store]['iobytes'] === cache_store::IO_BYTES_NOT_SUPPORTED) { if (self::$stats[$definitionstr]['stores'][$store]['iobytes'] === store::IO_BYTES_NOT_SUPPORTED) {
self::$stats[$definitionstr]['stores'][$store]['iobytes'] = $readbytes; self::$stats[$definitionstr]['stores'][$store]['iobytes'] = $readbytes;
} else { } else {
self::$stats[$definitionstr]['stores'][$store]['iobytes'] += $readbytes; self::$stats[$definitionstr]['stores'][$store]['iobytes'] += $readbytes;
@ -444,23 +454,23 @@ class cache_helper {
* Record a cache miss in the stats for the given store and definition. * Record a cache miss in the stats for the given store and definition.
* *
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a * In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance. * definition instance. It is preferable to pass a cache definition instance.
* *
* In Moodle 3.9 the first argument changed to also accept a cache_store. * In Moodle 3.9 the first argument changed to also accept a store.
* *
* @internal * @internal
* @param string|cache_store $store * @param string|store $store
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the * @param definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now. * actual definition object now.
* @param int $misses The number of misses to record (by default 1) * @param int $misses The number of misses to record (by default 1)
*/ */
public static function record_cache_miss($store, $definition, $misses = 1) { public static function record_cache_miss($store, $definition, $misses = 1) {
$storeclass = ''; $storeclass = '';
if ($store instanceof cache_store) { if ($store instanceof store) {
$storeclass = get_class($store); $storeclass = get_class($store);
$store = $store->my_name(); $store = $store->my_name();
} }
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition); [$definitionstr, $mode] = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode); self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['misses'] += $misses; self::$stats[$definitionstr]['stores'][$store]['misses'] += $misses;
} }
@ -469,29 +479,33 @@ class cache_helper {
* Record a cache set in the stats for the given store and definition. * Record a cache set in the stats for the given store and definition.
* *
* In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a * In Moodle 2.9 the $definition argument changed from accepting only a string to accepting a string or a
* cache_definition instance. It is preferable to pass a cache definition instance. * definition instance. It is preferable to pass a cache definition instance.
* *
* In Moodle 3.9 the first argument changed to also accept a cache_store. * In Moodle 3.9 the first argument changed to also accept a store.
* *
* @internal * @internal
* @param string|cache_store $store * @param string|store $store
* @param cache_definition $definition You used to be able to pass a string here, however that is deprecated please pass the * @param definition $definition You used to be able to pass a string here, however that is deprecated please pass the
* actual cache_definition object now. * actual definition object now.
* @param int $sets The number of sets to record (by default 1) * @param int $sets The number of sets to record (by default 1)
* @param int $writebytes Number of bytes written to the cache or cache_store::IO_BYTES_NOT_SUPPORTED * @param int $writebytes Number of bytes written to the cache or store::IO_BYTES_NOT_SUPPORTED
*/ */
public static function record_cache_set($store, $definition, int $sets = 1, public static function record_cache_set(
int $writebytes = cache_store::IO_BYTES_NOT_SUPPORTED) { $store,
$definition,
int $sets = 1,
int $writebytes = store::IO_BYTES_NOT_SUPPORTED
) {
$storeclass = ''; $storeclass = '';
if ($store instanceof cache_store) { if ($store instanceof store) {
$storeclass = get_class($store); $storeclass = get_class($store);
$store = $store->my_name(); $store = $store->my_name();
} }
list($definitionstr, $mode) = self::get_definition_stat_id_and_mode($definition); [$definitionstr, $mode] = self::get_definition_stat_id_and_mode($definition);
self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode); self::ensure_ready_for_stats($store, $storeclass, $definitionstr, $mode);
self::$stats[$definitionstr]['stores'][$store]['sets'] += $sets; self::$stats[$definitionstr]['stores'][$store]['sets'] += $sets;
if ($writebytes !== cache_store::IO_BYTES_NOT_SUPPORTED) { if ($writebytes !== store::IO_BYTES_NOT_SUPPORTED) {
if (self::$stats[$definitionstr]['stores'][$store]['iobytes'] === cache_store::IO_BYTES_NOT_SUPPORTED) { if (self::$stats[$definitionstr]['stores'][$store]['iobytes'] === store::IO_BYTES_NOT_SUPPORTED) {
self::$stats[$definitionstr]['stores'][$store]['iobytes'] = $writebytes; self::$stats[$definitionstr]['stores'][$store]['iobytes'] = $writebytes;
} else { } else {
self::$stats[$definitionstr]['stores'][$store]['iobytes'] += $writebytes; self::$stats[$definitionstr]['stores'][$store]['iobytes'] += $writebytes;
@ -514,13 +528,13 @@ class cache_helper {
* anything. This will involve full setup of the cache + the purge operation. On a site using caching heavily this WILL be * anything. This will involve full setup of the cache + the purge operation. On a site using caching heavily this WILL be
* painful. * painful.
* *
* @param bool $usewriter If set to true the cache_config_writer class is used. This class is special as it avoids * @param bool $usewriter If set to true the config_writer class is used. This class is special as it avoids
* it is still usable when caches have been disabled. * it is still usable when caches have been disabled.
* Please use this option only if you really must. It's purpose is to allow the cache to be purged when it would be * Please use this option only if you really must. It's purpose is to allow the cache to be purged when it would be
* otherwise impossible. * otherwise impossible.
*/ */
public static function purge_all($usewriter = false) { public static function purge_all($usewriter = false) {
$factory = cache_factory::instance(); $factory = factory::instance();
$config = $factory->create_config_instance($usewriter); $config = $factory->create_config_instance($usewriter);
foreach ($config->get_all_stores() as $store) { foreach ($config->get_all_stores() as $store) {
self::purge_store($store['name'], $config); self::purge_store($store['name'], $config);
@ -534,12 +548,12 @@ class cache_helper {
* Purges a store given its name. * Purges a store given its name.
* *
* @param string $storename * @param string $storename
* @param cache_config $config * @param config|null $config
* @return bool * @return bool
*/ */
public static function purge_store($storename, cache_config $config = null) { public static function purge_store($storename, ?config $config = null) {
if ($config === null) { if ($config === null) {
$config = cache_config::instance(); $config = config::instance();
} }
$stores = $config->get_all_stores(); $stores = $config->get_all_stores();
@ -557,14 +571,14 @@ class cache_helper {
return false; return false;
} }
// Found the store: is it ready? // Found the store: is it ready?
/* @var cache_store $instance */ /* @var store $instance */
$instance = new $class($store['name'], $store['configuration']); $instance = new $class($store['name'], $store['configuration']);
if (!$instance->is_ready()) { if (!$instance->is_ready()) {
unset($instance); unset($instance);
return false; return false;
} }
foreach ($config->get_definitions_by_store($storename) as $id => $definition) { foreach ($config->get_definitions_by_store($storename) as $id => $definition) {
$definition = cache_definition::load($id, $definition); $definition = definition::load($id, $definition);
$definitioninstance = clone($instance); $definitioninstance = clone($instance);
$definitioninstance->initialise($definition); $definitioninstance->initialise($definition);
$definitioninstance->purge(); $definitioninstance->purge();
@ -577,7 +591,7 @@ class cache_helper {
/** /**
* Purges all of the stores used by a definition. * Purges all of the stores used by a definition.
* *
* Unlike cache_helper::purge_by_definition this purges all of the data from the stores not * Unlike helper::purge_by_definition this purges all of the data from the stores not
* just the data relating to the definition. * just the data relating to the definition.
* This function is useful when you must purge a definition that requires setup but you don't * This function is useful when you must purge a definition that requires setup but you don't
* want to set it up. * want to set it up.
@ -586,7 +600,7 @@ class cache_helper {
* @param string $area * @param string $area
*/ */
public static function purge_stores_used_by_definition($component, $area) { public static function purge_stores_used_by_definition($component, $area) {
$factory = cache_factory::instance(); $factory = factory::instance();
$config = $factory->create_config_instance(); $config = $factory->create_config_instance();
$definition = $factory->create_definition($component, $area); $definition = $factory->create_definition($component, $area);
$stores = $config->get_stores_for_definition($definition); $stores = $config->get_stores_for_definition($definition);
@ -598,14 +612,14 @@ class cache_helper {
/** /**
* Returns the translated name of the definition. * Returns the translated name of the definition.
* *
* @param cache_definition $definition * @param definition $definition
* @return lang_string * @return lang_string
*/ */
public static function get_definition_name($definition) { public static function get_definition_name($definition) {
if ($definition instanceof cache_definition) { if ($definition instanceof definition) {
return $definition->get_name(); return $definition->get_name();
} }
$identifier = 'cachedef_'.clean_param($definition['area'], PARAM_STRINGID); $identifier = 'cachedef_' . clean_param($definition['area'], PARAM_STRINGID);
$component = $definition['component']; $component = $definition['component'];
if ($component === 'core') { if ($component === 'core') {
$component = 'cache'; $component = 'cache';
@ -616,13 +630,16 @@ class cache_helper {
/** /**
* Hashes a descriptive key to make it shorter and still unique. * Hashes a descriptive key to make it shorter and still unique.
* @param string|int $key * @param string|int $key
* @param cache_definition $definition * @param definition $definition
* @return string * @return string
*/ */
public static function hash_key($key, cache_definition $definition) { public static function hash_key($key, definition $definition) {
if ($definition->uses_simple_keys()) { if ($definition->uses_simple_keys()) {
if (debugging() && preg_match('#[^a-zA-Z0-9_]#', $key ?? '')) { if (debugging() && preg_match('#[^a-zA-Z0-9_]#', $key ?? '')) {
throw new coding_exception('Cache definition '.$definition->get_id().' requires simple keys. Invalid key provided.', $key); throw new coding_exception(
'Cache definition ' . $definition->get_id() . ' requires simple keys. Invalid key provided.',
$key,
);
} }
// We put the key first so that we can be sure the start of the key changes. // We put the key first so that we can be sure the start of the key changes.
return (string)$key . '-' . $definition->generate_single_key_prefix(); return (string)$key . '-' . $definition->generate_single_key_prefix();
@ -638,9 +655,9 @@ class cache_helper {
*/ */
public static function update_definitions($coreonly = false) { public static function update_definitions($coreonly = false) {
// First update definitions // First update definitions
cache_config_writer::update_definitions($coreonly); config_writer::update_definitions($coreonly);
// Second reset anything we have already initialised to ensure we're all up to date. // Second reset anything we have already initialised to ensure we're all up to date.
cache_factory::reset(); factory::reset();
} }
/** /**
@ -650,12 +667,12 @@ class cache_helper {
* @return string The new site identifier. * @return string The new site identifier.
*/ */
public static function update_site_identifier($siteidentifier) { public static function update_site_identifier($siteidentifier) {
$factory = cache_factory::instance(); $factory = factory::instance();
$factory->updating_started(); $factory->updating_started();
$config = $factory->create_config_instance(true); $config = $factory->create_config_instance(true);
$siteidentifier = $config->update_site_identifier($siteidentifier); $siteidentifier = $config->update_site_identifier($siteidentifier);
$factory->updating_finished(); $factory->updating_finished();
cache_factory::reset(); factory::reset();
return $siteidentifier; return $siteidentifier;
} }
@ -670,7 +687,7 @@ class cache_helper {
return self::$siteidentifier; return self::$siteidentifier;
} }
// If site identifier hasn't been collected yet attempt to get it from the cache config. // If site identifier hasn't been collected yet attempt to get it from the cache config.
$factory = cache_factory::instance(); $factory = factory::instance();
// If the factory is initialising then we don't want to try to get it from the config or we risk // If the factory is initialising then we don't want to try to get it from the config or we risk
// causing the cache to enter an infinite initialisation loop. // causing the cache to enter an infinite initialisation loop.
if (!$factory->is_initialising()) { if (!$factory->is_initialising()) {
@ -719,13 +736,13 @@ class cache_helper {
if ($output) { if ($output) {
mtrace('Cleaning up stale session data from cache stores.'); mtrace('Cleaning up stale session data from cache stores.');
} }
$factory = cache_factory::instance(); $factory = factory::instance();
$config = $factory->create_config_instance(); $config = $factory->create_config_instance();
$definitions = $config->get_definitions(); $definitions = $config->get_definitions();
$purgetime = time() - $CFG->sessiontimeout; $purgetime = time() - $CFG->sessiontimeout;
foreach ($definitions as $definitionarray) { foreach ($definitions as $definitionarray) {
// We are only interested in session caches. // We are only interested in session caches.
if (!($definitionarray['mode'] & cache_store::MODE_SESSION)) { if (!($definitionarray['mode'] & store::MODE_SESSION)) {
continue; continue;
} }
$definition = $factory->create_definition($definitionarray['component'], $definitionarray['area']); $definition = $factory->create_definition($definitionarray['component'], $definitionarray['area']);
@ -735,18 +752,18 @@ class cache_helper {
// Initialise all of the stores used for that definition. // Initialise all of the stores used for that definition.
foreach ($stores as $store) { foreach ($stores as $store) {
// If the store doesn't support searching we can skip it. // If the store doesn't support searching we can skip it.
if (!($store instanceof cache_is_searchable)) { if (!($store instanceof searchable_cache_interface)) {
debugging('Cache stores used for session definitions should ideally be searchable.', DEBUG_DEVELOPER); debugging('Cache stores used for session definitions should ideally be searchable.', DEBUG_DEVELOPER);
continue; continue;
} }
// Get all of the last access keys. // Get all of the last access keys.
$keys = $store->find_by_prefix(cache_session::LASTACCESS); $keys = $store->find_by_prefix(session_cache::LASTACCESS);
$todelete = []; $todelete = [];
foreach ($store->get_many($keys) as $key => $value) { foreach ($store->get_many($keys) as $key => $value) {
$expiresvalue = 0; $expiresvalue = 0;
if ($value instanceof cache_ttl_wrapper) { if ($value instanceof cache_ttl_wrapper) {
$expiresvalue = $value->data; $expiresvalue = $value->data;
} else if ($value instanceof cache_cached_object) { } else if ($value instanceof cached_object) {
$expiresvalue = $value->restore_object(); $expiresvalue = $value->restore_object();
} else { } else {
$expiresvalue = $value; $expiresvalue = $value;
@ -754,13 +771,13 @@ class cache_helper {
$expires = (int) $expiresvalue; $expires = (int) $expiresvalue;
if ($expires > 0 && $expires < $purgetime) { if ($expires > 0 && $expires < $purgetime) {
$prefix = substr($key, strlen(cache_session::LASTACCESS)); $prefix = substr($key, strlen(session_cache::LASTACCESS));
$foundbyprefix = $store->find_by_prefix($prefix); $foundbyprefix = $store->find_by_prefix($prefix);
$todelete = array_merge($todelete, [$key], $foundbyprefix); $todelete = array_merge($todelete, [$key], $foundbyprefix);
} }
} }
if ($todelete) { if ($todelete) {
$outcome = (int)$store->delete_many($todelete); $outcome = (int) store->delete_many($todelete);
if ($output) { if ($output) {
$strdef = s($definition->get_id()); $strdef = s($definition->get_id());
$strstore = s($store->my_name()); $strstore = s($store->my_name());
@ -779,14 +796,14 @@ class cache_helper {
* @return array[] An array of stores, keys are the store names. * @return array[] An array of stores, keys are the store names.
*/ */
public static function get_stores_suitable_for_mode_default() { public static function get_stores_suitable_for_mode_default() {
$factory = cache_factory::instance(); $factory = factory::instance();
$config = $factory->create_config_instance(); $config = $factory->create_config_instance();
$requirements = 0; $requirements = 0;
foreach ($config->get_definitions() as $definition) { foreach ($config->get_definitions() as $definition) {
$definition = cache_definition::load($definition['component'].'/'.$definition['area'], $definition); $definition = definition::load($definition['component'] . '/' . $definition['area'], $definition);
$requirements = $requirements | $definition->get_requirements_bin(); $requirements = $requirements | $definition->get_requirements_bin();
} }
$stores = array(); $stores = [];
foreach ($config->get_all_stores() as $name => $store) { foreach ($config->get_all_stores() as $name => $store) {
if (!empty($store['features']) && ($store['features'] & $requirements)) { if (!empty($store['features']) && ($store['features'] & $requirements)) {
$stores[$name] = $store; $stores[$name] = $store;
@ -798,12 +815,12 @@ class cache_helper {
/** /**
* Returns stores suitable for use with a given definition. * Returns stores suitable for use with a given definition.
* *
* @param cache_definition $definition * @param definition $definition
* @return cache_store[] * @return store[]
*/ */
public static function get_stores_suitable_for_definition(cache_definition $definition) { public static function get_stores_suitable_for_definition(definition $definition) {
$factory = cache_factory::instance(); $factory = factory::instance();
$stores = array(); $stores = [];
if ($factory->is_initialising() || $factory->stores_disabled()) { if ($factory->is_initialising() || $factory->stores_disabled()) {
// No suitable stores here. // No suitable stores here.
return $stores; return $stores;
@ -838,10 +855,9 @@ class cache_helper {
*/ */
public static function warnings(array $stores = null) { public static function warnings(array $stores = null) {
if ($stores === null) { if ($stores === null) {
$stores = administration_helper::get_store_instance_summaries();
$stores = core_cache\administration_helper::get_store_instance_summaries();
} }
$warnings = array(); $warnings = [];
foreach ($stores as $store) { foreach ($stores as $store) {
if (!empty($store['warnings'])) { if (!empty($store['warnings'])) {
$warnings = array_merge($warnings, $store['warnings']); $warnings = array_merge($warnings, $store['warnings']);
@ -871,3 +887,8 @@ class cache_helper {
return class_exists('RedisCluster'); return class_exists('RedisCluster');
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(helper::class, \cache_helper::class);

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cache store feature: key awareness. * Cache store feature: key awareness.
* *
@ -26,9 +28,12 @@
* means of performing these tests than the handling that would otherwise take place in the cache_loader. * means of performing these tests than the handling that would otherwise take place in the cache_loader.
* *
* Can be implemented by classes already implementing cache_store. * Can be implemented by classes already implementing cache_store.
*
* @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_is_key_aware { interface key_aware_cache_interface {
/** /**
* Test is a cache has a key. * Test is a cache has a key.
* *
@ -80,3 +85,8 @@ interface cache_is_key_aware {
*/ */
public function has_all(array $keys); public function has_all(array $keys);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(key_aware_cache_interface::class, \cache_is_key_aware::class);

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cache Loader. * Cache Loader.
* *
@ -21,9 +23,11 @@
* means of accessing and interacting with a cache. * means of accessing and interacting with a cache.
* *
* Can be implemented by any class wishing to be a cache loader. * Can be implemented by any class wishing to be a cache loader.
* @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_loader { interface loader_interface {
/** /**
* Retrieves the value for the given key from the cache. * Retrieves the value for the given key from the cache.
* *
@ -215,3 +219,8 @@ interface cache_loader {
*/ */
public function delete_many(array $keys, $recurse = true); public function delete_many(array $keys, $recurse = true);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(loader_interface::class, \cache_loader::class);

View file

@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\moodle_exception;
/** /**
* Cache Loader supporting locking. * Cache Loader supporting locking.
* *
@ -21,8 +25,11 @@
* It outlines the required structure for utilising locking functionality when using a cache. * It outlines the required structure for utilising locking functionality when using a cache.
* *
* Can be implemented by any class already implementing the cache_loader interface. * Can be implemented by any class already implementing the cache_loader interface.
* @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_loader_with_locking { interface loader_with_locking_interface {
/** /**
* Acquires a lock for the given key. * Acquires a lock for the given key.
* *
@ -67,3 +74,8 @@ interface cache_loader_with_locking {
*/ */
public function release_lock($key); public function release_lock($key);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(loader_with_locking_interface::class, \cache_loader_with_locking::class);

View file

@ -20,7 +20,7 @@
* This file is part of Moodle's cache API, affectionately called MUC. * This file is part of Moodle's cache API, affectionately called MUC.
* It contains the components that are requried in order to use caching. * It contains the components that are requried in order to use caching.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @author Peter Burnett <peterburnett@catalyst-au.net> * @author Peter Burnett <peterburnett@catalyst-au.net>
* @copyright 2020 Catalyst IT * @copyright 2020 Catalyst IT
@ -30,8 +30,30 @@
namespace core_cache\local; namespace core_cache\local;
use cache_store, cache_factory, cache_config_writer, cache_helper; use cache_store as store;
use cache_config_writer as config_writer;
use cache_factory as factory;
use cache_helper;
use core_cache\cache;
use core_cache\config;
use core_cache\configurable_cache_interface;
use core_cache\exception\cache_exception;
use core_cache\form\cache_lock_form;
use core_cache\form\cache_mode_mappings_form;
use core_cache\form\cache_definition_sharing_form;
use core_cache\form\cache_definition_mappings_form;
use core_cache\form\cachestore_addinstance_form;
use core_cache\lockable_cache_interface;
use core_component;
use core\context;
use core\context\system as context_system;
use core\exception\coding_exception;
use core\exception\moodle_exception;
use core\output\notification; use core\output\notification;
use core\output\single_button;
use core\url;
use html_writer;
use stdClass;
/** /**
* A cache helper for administration tasks * A cache helper for administration tasks
@ -42,9 +64,8 @@ use core\output\notification;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class administration_display_helper extends \core_cache\administration_helper { class administration_display_helper extends \core_cache\administration_helper {
/** /**
* Please do not call constructor directly. Use cache_factory::get_administration_display_helper() instead. * Please do not call constructor directly. Use factory::get_administration_display_helper() instead.
*/ */
public function __construct() { public function __construct() {
// Nothing to do here. // Nothing to do here.
@ -59,33 +80,33 @@ class administration_display_helper extends \core_cache\administration_helper {
* element is used. * element is used.
* @return array of actions. Each action is an action_url. * @return array of actions. Each action is an action_url.
*/ */
public function get_definition_actions(\context $context, array $definitionsummary): array { public function get_definition_actions(context $context, array $definitionsummary): array {
global $OUTPUT; global $OUTPUT;
if (has_capability('moodle/site:config', $context)) { if (has_capability('moodle/site:config', $context)) {
$actions = array(); $actions = [];
// Edit mappings. // Edit mappings.
$actions[] = $OUTPUT->action_link( $actions[] = $OUTPUT->action_link(
new \moodle_url('/cache/admin.php', array('action' => 'editdefinitionmapping', new url('/cache/admin.php', ['action' => 'editdefinitionmapping',
'definition' => $definitionsummary['id'])), 'definition' => $definitionsummary['id'], ]),
get_string('editmappings', 'cache') get_string('editmappings', 'cache')
); );
// Edit sharing. // Edit sharing.
if (count($definitionsummary['sharingoptions']) > 1) { if (count($definitionsummary['sharingoptions']) > 1) {
$actions[] = $OUTPUT->action_link( $actions[] = $OUTPUT->action_link(
new \moodle_url('/cache/admin.php', array('action' => 'editdefinitionsharing', new url('/cache/admin.php', ['action' => 'editdefinitionsharing',
'definition' => $definitionsummary['id'])), 'definition' => $definitionsummary['id'], ]),
get_string('editsharing', 'cache') get_string('editsharing', 'cache')
); );
} }
// Purge. // Purge.
$actions[] = $OUTPUT->action_link( $actions[] = $OUTPUT->action_link(
new \moodle_url('/cache/admin.php', array('action' => 'purgedefinition', new url('/cache/admin.php', ['action' => 'purgedefinition',
'definition' => $definitionsummary['id'], 'sesskey' => sesskey())), 'definition' => $definitionsummary['id'], 'sesskey' => sesskey(), ]),
get_string('purge', 'cache') get_string('purge', 'cache')
); );
return $actions; return $actions;
} }
return array(); return [];
} }
/** /**
@ -98,24 +119,24 @@ class administration_display_helper extends \core_cache\administration_helper {
*/ */
public function get_store_instance_actions(string $name, array $storedetails): array { public function get_store_instance_actions(string $name, array $storedetails): array {
global $OUTPUT; global $OUTPUT;
$actions = array(); $actions = [];
if (has_capability('moodle/site:config', \context_system::instance())) { if (has_capability('moodle/site:config', context_system::instance())) {
$baseurl = new \moodle_url('/cache/admin.php', array('store' => $name)); $baseurl = new url('/cache/admin.php', ['store' => $name]);
if (empty($storedetails['default'])) { if (empty($storedetails['default'])) {
// Edit store. // Edit store.
$actions[] = $OUTPUT->action_link( $actions[] = $OUTPUT->action_link(
new \moodle_url($baseurl, array('action' => 'editstore', 'plugin' => $storedetails['plugin'])), new url($baseurl, ['action' => 'editstore', 'plugin' => $storedetails['plugin']]),
get_string('editstore', 'cache') get_string('editstore', 'cache')
); );
// Delete store. // Delete store.
$actions[] = $OUTPUT->action_link( $actions[] = $OUTPUT->action_link(
new \moodle_url($baseurl, array('action' => 'deletestore')), new url($baseurl, ['action' => 'deletestore']),
get_string('deletestore', 'cache') get_string('deletestore', 'cache')
); );
} }
// Purge store. // Purge store.
$actions[] = $OUTPUT->action_link( $actions[] = $OUTPUT->action_link(
new \moodle_url($baseurl, array('action' => 'purgestore', 'sesskey' => sesskey())), new url($baseurl, ['action' => 'purgestore', 'sesskey' => sesskey()]),
get_string('purge', 'cache') get_string('purge', 'cache')
); );
} }
@ -132,11 +153,13 @@ class administration_display_helper extends \core_cache\administration_helper {
*/ */
public function get_store_plugin_actions(string $name, array $plugindetails): array { public function get_store_plugin_actions(string $name, array $plugindetails): array {
global $OUTPUT; global $OUTPUT;
$actions = array(); $actions = [];
if (has_capability('moodle/site:config', \context_system::instance())) { if (has_capability('moodle/site:config', context_system::instance())) {
if (!empty($plugindetails['canaddinstance'])) { if (!empty($plugindetails['canaddinstance'])) {
$url = new \moodle_url('/cache/admin.php', $url = new url(
array('action' => 'addstore', 'plugin' => $name)); '/cache/admin.php',
['action' => 'addstore', 'plugin' => $name]
);
$actions[] = $OUTPUT->action_link( $actions[] = $OUTPUT->action_link(
$url, $url,
get_string('addinstance', 'cache') get_string('addinstance', 'cache')
@ -153,28 +176,28 @@ class administration_display_helper extends \core_cache\administration_helper {
* @return cachestore_addinstance_form * @return cachestore_addinstance_form
* @throws coding_exception * @throws coding_exception
*/ */
public function get_add_store_form(string $plugin): \cachestore_addinstance_form { public function get_add_store_form(string $plugin): cachestore_addinstance_form {
global $CFG; // Needed for includes. global $CFG; // Needed for includes.
$plugins = \core_component::get_plugin_list('cachestore'); $plugins = core_component::get_plugin_list('cachestore');
if (!array_key_exists($plugin, $plugins)) { if (!array_key_exists($plugin, $plugins)) {
throw new \coding_exception('Invalid cache plugin used when trying to create an edit form.'); throw new coding_exception('Invalid cache plugin used when trying to create an edit form.');
} }
$plugindir = $plugins[$plugin]; $plugindir = $plugins[$plugin];
$class = 'cachestore_addinstance_form'; $class = 'cachestore_addinstance_form';
if (file_exists($plugindir.'/addinstanceform.php')) { if (file_exists($plugindir . '/addinstanceform.php')) {
require_once($plugindir.'/addinstanceform.php'); require_once($plugindir . '/addinstanceform.php');
if (class_exists('cachestore_'.$plugin.'_addinstance_form')) { if (class_exists('cachestore_' . $plugin . '_addinstance_form')) {
$class = 'cachestore_'.$plugin.'_addinstance_form'; $class = 'cachestore_' . $plugin . '_addinstance_form';
if (!array_key_exists('cachestore_addinstance_form', class_parents($class))) { if (!array_key_exists(cachestore_addinstance_form::class, class_parents($class))) {
throw new \coding_exception('Cache plugin add instance forms must extend cachestore_addinstance_form'); throw new coding_exception('Cache plugin add instance forms must extend cachestore_addinstance_form');
} }
} }
} }
$locks = $this->get_possible_locks_for_stores($plugindir, $plugin); $locks = $this->get_possible_locks_for_stores($plugindir, $plugin);
$url = new \moodle_url('/cache/admin.php', array('action' => 'addstore')); $url = new url('/cache/admin.php', ['action' => 'addstore']);
return new $class($url, array('plugin' => $plugin, 'store' => null, 'locks' => $locks)); return new $class($url, ['plugin' => $plugin, 'store' => null, 'locks' => $locks]);
} }
/** /**
@ -185,43 +208,45 @@ class administration_display_helper extends \core_cache\administration_helper {
* @return cachestore_addinstance_form * @return cachestore_addinstance_form
* @throws coding_exception * @throws coding_exception
*/ */
public function get_edit_store_form(string $plugin, string $store): \cachestore_addinstance_form { public function get_edit_store_form(string $plugin, string $store): cachestore_addinstance_form {
global $CFG; // Needed for includes. global $CFG; // Needed for includes.
$plugins = \core_component::get_plugin_list('cachestore'); $plugins = core_component::get_plugin_list('cachestore');
if (!array_key_exists($plugin, $plugins)) { if (!array_key_exists($plugin, $plugins)) {
throw new \coding_exception('Invalid cache plugin used when trying to create an edit form.'); throw new coding_exception('Invalid cache plugin used when trying to create an edit form.');
} }
$factory = \cache_factory::instance(); $factory = factory::instance();
$config = $factory->create_config_instance(); $config = $factory->create_config_instance();
$stores = $config->get_all_stores(); $stores = $config->get_all_stores();
if (!array_key_exists($store, $stores)) { if (!array_key_exists($store, $stores)) {
throw new \coding_exception('Invalid store name given when trying to create an edit form.'); throw new coding_exception('Invalid store name given when trying to create an edit form.');
} }
$plugindir = $plugins[$plugin]; $plugindir = $plugins[$plugin];
$class = 'cachestore_addinstance_form'; $class = 'cachestore_addinstance_form';
if (file_exists($plugindir.'/addinstanceform.php')) { if (file_exists($plugindir . '/addinstanceform.php')) {
require_once($plugindir.'/addinstanceform.php'); require_once($plugindir . '/addinstanceform.php');
if (class_exists('cachestore_'.$plugin.'_addinstance_form')) { if (class_exists('cachestore_' . $plugin . '_addinstance_form')) {
$class = 'cachestore_'.$plugin.'_addinstance_form'; $class = 'cachestore_' . $plugin . '_addinstance_form';
if (!array_key_exists('cachestore_addinstance_form', class_parents($class))) { if (!array_key_exists(cachestore_addinstance_form::class, class_parents($class))) {
throw new \coding_exception('Cache plugin add instance forms must extend cachestore_addinstance_form'); throw new coding_exception('Cache plugin add instance forms must extend cachestore_addinstance_form');
} }
} }
} }
$locks = $this->get_possible_locks_for_stores($plugindir, $plugin); $locks = $this->get_possible_locks_for_stores($plugindir, $plugin);
$url = new \moodle_url('/cache/admin.php', array('action' => 'editstore', 'plugin' => $plugin, 'store' => $store)); $url = new url('/cache/admin.php', ['action' => 'editstore', 'plugin' => $plugin, 'store' => $store]);
$editform = new $class($url, array('plugin' => $plugin, 'store' => $store, 'locks' => $locks)); $editform = new $class($url, ['plugin' => $plugin, 'store' => $store, 'locks' => $locks]);
if (isset($stores[$store]['lock'])) { if (isset($stores[$store]['lock'])) {
$editform->set_data(array('lock' => $stores[$store]['lock'])); $editform->set_data(['lock' => $stores[$store]['lock']]);
} }
// See if the cachestore is going to want to load data for the form. // See if the cachestore is going to want to load data for the form.
// If it has a customised add instance form then it is going to want to. // If it has a customised add instance form then it is going to want to.
$storeclass = 'cachestore_'.$plugin; $storeclass = 'cachestore_' . $plugin;
$storedata = $stores[$store]; $storedata = $stores[$store];
if (array_key_exists('configuration', $storedata) && if (
array_key_exists('cache_is_configurable', class_implements($storeclass))) { array_key_exists('configuration', $storedata) &&
array_key_exists(configurable_cache_interface::class, class_implements($storeclass))
) {
$storeclass::config_set_edit_form_data($editform, $storedata['configuration']); $storeclass::config_set_edit_form_data($editform, $storedata['configuration']);
} }
return $editform; return $editform;
@ -237,17 +262,17 @@ class administration_display_helper extends \core_cache\administration_helper {
protected function get_possible_locks_for_stores(string $plugindir, string $plugin) { protected function get_possible_locks_for_stores(string $plugindir, string $plugin) {
global $CFG; // Needed for includes. global $CFG; // Needed for includes.
$supportsnativelocking = false; $supportsnativelocking = false;
if (file_exists($plugindir.'/lib.php')) { if (file_exists($plugindir . '/lib.php')) {
require_once($plugindir.'/lib.php'); require_once($plugindir . '/lib.php');
$pluginclass = 'cachestore_'.$plugin; $pluginclass = 'cachestore_' . $plugin;
if (class_exists($pluginclass)) { if (class_exists($pluginclass)) {
$supportsnativelocking = array_key_exists('cache_is_lockable', class_implements($pluginclass)); $supportsnativelocking = array_key_exists(lockable_cache_interface::class, class_implements($pluginclass));
} }
} }
if (!$supportsnativelocking) { if (!$supportsnativelocking) {
$config = \cache_config::instance(); $config = config::instance();
$locks = array(); $locks = [];
foreach ($config->get_locks() as $lock => $conf) { foreach ($config->get_locks() as $lock => $conf) {
if (!empty($conf['default'])) { if (!empty($conf['default'])) {
$name = get_string($lock, 'cache'); $name = get_string($lock, 'cache');
@ -271,21 +296,21 @@ class administration_display_helper extends \core_cache\administration_helper {
* @return array * @return array
* @throws coding_exception * @throws coding_exception
*/ */
public function get_store_configuration_from_data(\stdClass $data): array { public function get_store_configuration_from_data(stClass $data): array {
global $CFG; global $CFG;
$file = $CFG->dirroot.'/cache/stores/'.$data->plugin.'/lib.php'; $file = $CFG->dirroot . '/cache/stores/' . $data->plugin . '/lib.php';
if (!file_exists($file)) { if (!file_exists($file)) {
throw new \coding_exception('Invalid cache plugin provided. '.$file); throw new coding_exception('Invalid cache plugin provided. ' . $file);
} }
require_once($file); require_once($file);
$class = 'cachestore_'.$data->plugin; $class = 'cachestore_' . $data->plugin;
if (!class_exists($class)) { if (!class_exists($class)) {
throw new \coding_exception('Invalid cache plugin provided.'); throw new coding_exception('Invalid cache plugin provided.');
} }
if (array_key_exists('cache_is_configurable', class_implements($class))) { if (array_key_exists(configurable_cache_interface::class, class_implements($class))) {
return $class::config_get_configuration_array($data); return $class::config_get_configuration_array($data);
} }
return array(); return [];
} }
/** /**
@ -296,8 +321,8 @@ class administration_display_helper extends \core_cache\administration_helper {
* @return array * @return array
*/ */
public function get_addable_lock_options(): array { public function get_addable_lock_options(): array {
$plugins = \core_component::get_plugin_list_with_class('cachelock', '', 'lib.php'); $plugins = core_component::get_plugin_list_with_class('cachelock', '', 'lib.php');
$options = array(); $options = [];
$len = strlen('cachelock_'); $len = strlen('cachelock_');
foreach ($plugins as $plugin => $class) { foreach ($plugins as $plugin => $class) {
$method = "$class::can_add_instance"; $method = "$class::can_add_instance";
@ -314,28 +339,28 @@ class administration_display_helper extends \core_cache\administration_helper {
* Gets the form to use when adding a lock instance. * Gets the form to use when adding a lock instance.
* *
* @param string $plugin * @param string $plugin
* @param array $lockplugin * @param array|null $lockplugin
* @return cache_lock_form * @return cache_lock_form
* @throws coding_exception * @throws coding_exception
*/ */
public function get_add_lock_form(string $plugin, array $lockplugin = null): \cache_lock_form { public function get_add_lock_form(string $plugin, ?array $lockplugin = null): cache_lock_form {
global $CFG; // Needed for includes. global $CFG; // Needed for includes.
$plugins = \core_component::get_plugin_list('cachelock'); $plugins = core_component::get_plugin_list('cachelock');
if (!array_key_exists($plugin, $plugins)) { if (!array_key_exists($plugin, $plugins)) {
throw new \coding_exception('Invalid cache lock plugin requested when trying to create a form.'); throw new coding_exception('Invalid cache lock plugin requested when trying to create a form.');
} }
$plugindir = $plugins[$plugin]; $plugindir = $plugins[$plugin];
$class = 'cache_lock_form'; $class = 'cache_lock_form';
if (file_exists($plugindir.'/addinstanceform.php') && in_array('cache_is_configurable', class_implements($class))) { if (file_exists($plugindir . '/addinstanceform.php') && in_array(configurable_cache_interface::class, class_implements($class))) {
require_once($plugindir.'/addinstanceform.php'); require_once($plugindir . '/addinstanceform.php');
if (class_exists('cachelock_'.$plugin.'_addinstance_form')) { if (class_exists('cachelock_' . $plugin . '_addinstance_form')) {
$class = 'cachelock_'.$plugin.'_addinstance_form'; $class = 'cachelock_' . $plugin . '_addinstance_form';
if (!array_key_exists('cache_lock_form', class_parents($class))) { if (!array_key_exists(cache_lock_form::class, class_parents($class))) {
throw new \coding_exception('Cache lock plugin add instance forms must extend cache_lock_form'); throw new coding_exception('Cache lock plugin add instance forms must extend cache_lock_form');
} }
} }
} }
return new $class(null, array('lock' => $plugin)); return new $class(null, ['lock' => $plugin]);
} }
/** /**
@ -346,21 +371,21 @@ class administration_display_helper extends \core_cache\administration_helper {
* @return array * @return array
* @throws coding_exception * @throws coding_exception
*/ */
public function get_lock_configuration_from_data(string $plugin, \stdClass $data): array { public function get_lock_configuration_from_data(string $plugin, stClass $data): array {
global $CFG; global $CFG;
$file = $CFG->dirroot.'/cache/locks/'.$plugin.'/lib.php'; $file = $CFG->dirroot . '/cache/locks/' . $plugin . '/lib.php';
if (!file_exists($file)) { if (!file_exists($file)) {
throw new \coding_exception('Invalid cache plugin provided. '.$file); throw new coding_exception('Invalid cache plugin provided. ' . $file);
} }
require_once($file); require_once($file);
$class = 'cachelock_'.$plugin; $class = 'cachelock_' . $plugin;
if (!class_exists($class)) { if (!class_exists($class)) {
throw new \coding_exception('Invalid cache plugin provided.'); throw new coding_exception('Invalid cache plugin provided.');
} }
if (array_key_exists('cache_is_configurable', class_implements($class))) { if (array_key_exists(configurable_cache_interface::class, class_implements($class))) {
return $class::config_get_configuration_array($data); return $class::config_get_configuration_array($data);
} }
return array(); return [];
} }
/** /**
@ -372,27 +397,27 @@ class administration_display_helper extends \core_cache\administration_helper {
*/ */
public function perform_cache_actions(string $action, array $forminfo): array { public function perform_cache_actions(string $action, array $forminfo): array {
switch ($action) { switch ($action) {
case 'rescandefinitions' : // Rescan definitions. case 'rescandefinitions': // Rescan definitions.
$this->action_rescan_definition(); $this->action_rescan_definition();
break; break;
case 'addstore' : // Add the requested store. case 'addstore': // Add the requested store.
$forminfo = $this->action_addstore(); $forminfo = $this->action_addstore();
break; break;
case 'editstore' : // Edit the requested store. case 'editstore': // Edit the requested store.
$forminfo = $this->action_editstore(); $forminfo = $this->action_editstore();
break; break;
case 'deletestore' : // Delete a given store. case 'deletestore': // Delete a given store.
$this->action_deletestore($action); $this->action_deletestore($action);
break; break;
case 'editdefinitionmapping' : // Edit definition mappings. case 'editdefinitionmapping': // Edit definition mappings.
$forminfo = $this->action_editdefinitionmapping(); $forminfo = $this->action_editdefinitionmapping();
break; break;
case 'editdefinitionsharing' : // Edit definition sharing. case 'editdefinitionsharing': // Edit definition sharing.
$forminfo = $this->action_editdefinitionsharing(); $forminfo = $this->action_editdefinitionsharing();
break; break;
@ -431,7 +456,7 @@ class administration_display_helper extends \core_cache\administration_helper {
global $PAGE; global $PAGE;
require_sesskey(); require_sesskey();
\cache_config_writer::update_definitions(); config_writer::update_definitions();
redirect($PAGE->url); redirect($PAGE->url);
} }
@ -446,7 +471,7 @@ class administration_display_helper extends \core_cache\administration_helper {
$plugin = required_param('plugin', PARAM_PLUGIN); $plugin = required_param('plugin', PARAM_PLUGIN);
if (!$storepluginsummaries[$plugin]['canaddinstance']) { if (!$storepluginsummaries[$plugin]['canaddinstance']) {
throw new \moodle_exception('ex_unmetstorerequirements', 'cache'); throw new moodle_exception('ex_unmetstorerequirements', 'cache');
} }
$mform = $this->get_add_store_form($plugin); $mform = $this->get_add_store_form($plugin);
$title = get_string('addstore', 'cache', $storepluginsummaries[$plugin]['name']); $title = get_string('addstore', 'cache', $storepluginsummaries[$plugin]['name']);
@ -454,7 +479,7 @@ class administration_display_helper extends \core_cache\administration_helper {
redirect($PAGE->url); redirect($PAGE->url);
} else if ($data = $mform->get_data()) { } else if ($data = $mform->get_data()) {
$config = $this->get_store_configuration_from_data($data); $config = $this->get_store_configuration_from_data($data);
$writer = \cache_config_writer::instance(); $writer = config_writer::instance();
unset($config['lock']); unset($config['lock']);
foreach ($writer->get_locks() as $lock => $lockconfig) { foreach ($writer->get_locks() as $lock => $lockconfig) {
if ($lock == $data->lock) { if ($lock == $data->lock) {
@ -466,7 +491,7 @@ class administration_display_helper extends \core_cache\administration_helper {
} }
$PAGE->navbar->add(get_string('addstore', 'cache', 'cache'), $PAGE->url); $PAGE->navbar->add(get_string('addstore', 'cache', 'cache'), $PAGE->url);
return array('form' => $mform, 'title' => $title); return ['form' => $mform, 'title' => $title];
} }
/** /**
@ -486,7 +511,7 @@ class administration_display_helper extends \core_cache\administration_helper {
redirect($PAGE->url); redirect($PAGE->url);
} else if ($data = $mform->get_data()) { } else if ($data = $mform->get_data()) {
$config = $this->get_store_configuration_from_data($data); $config = $this->get_store_configuration_from_data($data);
$writer = \cache_config_writer::instance(); $writer = config_writer::instance();
unset($config['lock']); unset($config['lock']);
foreach ($writer->get_locks() as $lock => $lockconfig) { foreach ($writer->get_locks() as $lock => $lockconfig) {
@ -498,7 +523,7 @@ class administration_display_helper extends \core_cache\administration_helper {
redirect($PAGE->url, get_string('editstoresuccess', 'cache', $storepluginsummaries[$plugin]['name']), 5); redirect($PAGE->url, get_string('editstoresuccess', 'cache', $storepluginsummaries[$plugin]['name']), 5);
} }
return array('form' => $mform, 'title' => $title); return ['form' => $mform, 'title' => $title];
} }
/** /**
@ -525,9 +550,9 @@ class administration_display_helper extends \core_cache\administration_helper {
if ($notifysuccess) { if ($notifysuccess) {
if (!$confirm) { if (!$confirm) {
$title = get_string('confirmstoredeletion', 'cache'); $title = get_string('confirmstoredeletion', 'cache');
$params = array('store' => $store, 'confirm' => 1, 'action' => $action, 'sesskey' => sesskey()); $params = ['store' => $store, 'confirm' => 1, 'action' => $action, 'sesskey' => sesskey()];
$url = new \moodle_url($PAGE->url, $params); $url = new url($PAGE->url, $params);
$button = new \single_button($url, get_string('deletestore', 'cache')); $button = new single_button($url, get_string('deletestore', 'cache'));
$PAGE->set_title($title); $PAGE->set_title($title);
$PAGE->set_heading($SITE->fullname); $PAGE->set_heading($SITE->fullname);
@ -539,7 +564,7 @@ class administration_display_helper extends \core_cache\administration_helper {
exit; exit;
} else { } else {
require_sesskey(); require_sesskey();
$writer = \cache_config_writer::instance(); $writer = config_writer::instance();
$writer->delete_store_instance($store); $writer->delete_store_instance($store);
redirect($PAGE->url, get_string('deletestoresuccess', 'cache'), 5); redirect($PAGE->url, get_string('deletestoresuccess', 'cache'), 5);
} }
@ -560,15 +585,15 @@ class administration_display_helper extends \core_cache\administration_helper {
$definition = required_param('definition', PARAM_SAFEPATH); $definition = required_param('definition', PARAM_SAFEPATH);
if (!array_key_exists($definition, $definitionsummaries)) { if (!array_key_exists($definition, $definitionsummaries)) {
throw new \cache_exception('Invalid cache definition requested'); throw new cache_exception('Invalid cache definition requested');
} }
$title = get_string('editdefinitionmappings', 'cache', $definition); $title = get_string('editdefinitionmappings', 'cache', $definition);
$mform = new \cache_definition_mappings_form($PAGE->url, array('definition' => $definition)); $mform = new cache_definition_mappings_form($PAGE->url, ['definition' => $definition]);
if ($mform->is_cancelled()) { if ($mform->is_cancelled()) {
redirect($PAGE->url); redirect($PAGE->url);
} else if ($data = $mform->get_data()) { } else if ($data = $mform->get_data()) {
$writer = \cache_config_writer::instance(); $writer = config_writer::instance();
$mappings = array(); $mappings = [];
foreach ($data->mappings as $mapping) { foreach ($data->mappings as $mapping) {
if (!empty($mapping)) { if (!empty($mapping)) {
$mappings[] = $mapping; $mappings[] = $mapping;
@ -579,7 +604,7 @@ class administration_display_helper extends \core_cache\administration_helper {
} }
$PAGE->navbar->add(get_string('updatedefinitionmapping', 'cache'), $PAGE->url); $PAGE->navbar->add(get_string('updatedefinitionmapping', 'cache'), $PAGE->url);
return array('form' => $mform, 'title' => $title); return ['form' => $mform, 'title' => $title];
} }
/** /**
@ -593,24 +618,24 @@ class administration_display_helper extends \core_cache\administration_helper {
$definition = required_param('definition', PARAM_SAFEPATH); $definition = required_param('definition', PARAM_SAFEPATH);
if (!array_key_exists($definition, $definitionsummaries)) { if (!array_key_exists($definition, $definitionsummaries)) {
throw new \cache_exception('Invalid cache definition requested'); throw new cache_exception('Invalid cache definition requested');
} }
$title = get_string('editdefinitionsharing', 'cache', $definition); $title = get_string('editdefinitionsharing', 'cache', $definition);
$sharingoptions = $definitionsummaries[$definition]['sharingoptions']; $sharingoptions = $definitionsummaries[$definition]['sharingoptions'];
$customdata = array('definition' => $definition, 'sharingoptions' => $sharingoptions); $customdata = ['definition' => $definition, 'sharingoptions' => $sharingoptions];
$mform = new \cache_definition_sharing_form($PAGE->url, $customdata); $mform = new cache_definition_sharing_form($PAGE->url, $customdata);
$mform->set_data(array( $mform->set_data([
'sharing' => $definitionsummaries[$definition]['selectedsharingoption'], 'sharing' => $definitionsummaries[$definition]['selectedsharingoption'],
'userinputsharingkey' => $definitionsummaries[$definition]['userinputsharingkey'] 'userinputsharingkey' => $definitionsummaries[$definition]['userinputsharingkey'],
)); ]);
if ($mform->is_cancelled()) { if ($mform->is_cancelled()) {
redirect($PAGE->url); redirect($PAGE->url);
} else if ($data = $mform->get_data()) { } else if ($data = $mform->get_data()) {
$component = $definitionsummaries[$definition]['component']; $component = $definitionsummaries[$definition]['component'];
$area = $definitionsummaries[$definition]['area']; $area = $definitionsummaries[$definition]['area'];
// Purge the stores removing stale data before we alter the sharing option. // Purge the stores removing stale data before we alter the sharing option.
\cache_helper::purge_stores_used_by_definition($component, $area); cache_helper::purge_stores_used_by_definition($component, $area);
$writer = \cache_config_writer::instance(); $writer = config_writer::instance();
$sharing = array_sum(array_keys($data->sharing)); $sharing = array_sum(array_keys($data->sharing));
$userinputsharingkey = $data->userinputsharingkey; $userinputsharingkey = $data->userinputsharingkey;
$writer->set_definition_sharing($definition, $sharing, $userinputsharingkey); $writer->set_definition_sharing($definition, $sharing, $userinputsharingkey);
@ -618,7 +643,7 @@ class administration_display_helper extends \core_cache\administration_helper {
} }
$PAGE->navbar->add(get_string('updatedefinitionsharing', 'cache'), $PAGE->url); $PAGE->navbar->add(get_string('updatedefinitionsharing', 'cache'), $PAGE->url);
return array('form' => $mform, 'title' => $title); return ['form' => $mform, 'title' => $title];
} }
/** /**
@ -631,26 +656,26 @@ class administration_display_helper extends \core_cache\administration_helper {
$storeinstancesummaries = $this->get_store_instance_summaries(); $storeinstancesummaries = $this->get_store_instance_summaries();
$defaultmodestores = $this->get_default_mode_stores(); $defaultmodestores = $this->get_default_mode_stores();
$mform = new \cache_mode_mappings_form(null, $storeinstancesummaries); $mform = new cache_mode_mappings_form(null, $storeinstancesummaries);
$mform->set_data(array( $mform->set_data([
'mode_'.cache_store::MODE_APPLICATION => key($defaultmodestores[cache_store::MODE_APPLICATION]), 'mode_' . store::MODE_APPLICATION => key($defaultmodestores[store::MODE_APPLICATION]),
'mode_'.cache_store::MODE_SESSION => key($defaultmodestores[cache_store::MODE_SESSION]), 'mode_' . store::MODE_SESSION => key($defaultmodestores[store::MODE_SESSION]),
'mode_'.cache_store::MODE_REQUEST => key($defaultmodestores[cache_store::MODE_REQUEST]), 'mode_' . store::MODE_REQUEST => key($defaultmodestores[store::MODE_REQUEST]),
)); ]);
if ($mform->is_cancelled()) { if ($mform->is_cancelled()) {
redirect($PAGE->url); redirect($PAGE->url);
} else if ($data = $mform->get_data()) { } else if ($data = $mform->get_data()) {
$mappings = array( $mappings = [
cache_store::MODE_APPLICATION => array($data->{'mode_'.cache_store::MODE_APPLICATION}), store::MODE_APPLICATION => [$data->{'mode_' . store::MODE_APPLICATION}],
cache_store::MODE_SESSION => array($data->{'mode_'.cache_store::MODE_SESSION}), store::MODE_SESSION => [$data->{'mode_' . store::MODE_SESSION}],
cache_store::MODE_REQUEST => array($data->{'mode_'.cache_store::MODE_REQUEST}), store::MODE_REQUEST => [$data->{'mode_' . store::MODE_REQUEST}],
); ];
$writer = cache_config_writer::instance(); $writer = config_writer::instance();
$writer->set_mode_mappings($mappings); $writer->set_mode_mappings($mappings);
redirect($PAGE->url); redirect($PAGE->url);
} }
return array('form' => $mform); return ['form' => $mform];
} }
/** /**
@ -663,8 +688,8 @@ class administration_display_helper extends \core_cache\administration_helper {
require_sesskey(); require_sesskey();
$id = required_param('definition', PARAM_SAFEPATH); $id = required_param('definition', PARAM_SAFEPATH);
list($component, $area) = explode('/', $id, 2); [$component, $area] = explode('/', $id, 2);
$factory = cache_factory::instance(); $factory = factory::instance();
$definition = $factory->create_definition($component, $area); $definition = $factory->create_definition($component, $area);
if ($definition->has_required_identifiers()) { if ($definition->has_required_identifiers()) {
// We will have to purge the stores used by this definition. // We will have to purge the stores used by this definition.
@ -679,9 +704,11 @@ class administration_display_helper extends \core_cache\administration_helper {
'component' => $component, 'component' => $component,
'area' => $area, 'area' => $area,
]); ]);
$purgeagainlink = \html_writer::link(new \moodle_url('/cache/admin.php', [ $purgeagainlink = html_writer::link(
'action' => 'purgedefinition', 'sesskey' => sesskey(), 'definition' => $id]), new url('/cache/admin.php', [
get_string('purgeagain', 'cache')); 'action' => 'purgedefinition', 'sesskey' => sesskey(), 'definition' => $id, ]),
get_string('purgeagain', 'cache')
);
redirect($PAGE->url, $message . ' ' . $purgeagainlink, 5); redirect($PAGE->url, $message . ' ' . $purgeagainlink, 5);
} }
@ -697,9 +724,11 @@ class administration_display_helper extends \core_cache\administration_helper {
$store = required_param('store', PARAM_TEXT); $store = required_param('store', PARAM_TEXT);
cache_helper::purge_store($store); cache_helper::purge_store($store);
$message = get_string('purgexstoresuccess', 'cache', ['store' => $store]); $message = get_string('purgexstoresuccess', 'cache', ['store' => $store]);
$purgeagainlink = \html_writer::link(new \moodle_url('/cache/admin.php', [ $purgeagainlink = html_writer::link(
'action' => 'purgestore', 'sesskey' => sesskey(), 'store' => $store]), new url('/cache/admin.php', [
get_string('purgeagain', 'cache')); 'action' => 'purgestore', 'sesskey' => sesskey(), 'store' => $store, ]),
get_string('purgeagain', 'cache')
);
redirect($PAGE->url, $message . ' ' . $purgeagainlink, 5); redirect($PAGE->url, $message . ' ' . $purgeagainlink, 5);
} }
@ -717,7 +746,7 @@ class administration_display_helper extends \core_cache\administration_helper {
if ($mform->is_cancelled()) { if ($mform->is_cancelled()) {
redirect($PAGE->url); redirect($PAGE->url);
} else if ($data = $mform->get_data()) { } else if ($data = $mform->get_data()) {
$factory = cache_factory::instance(); $factory = factory::instance();
$config = $factory->create_config_instance(true); $config = $factory->create_config_instance(true);
$name = $data->name; $name = $data->name;
$data = $this->get_lock_configuration_from_data($lock, $data); $data = $this->get_lock_configuration_from_data($lock, $data);
@ -725,7 +754,7 @@ class administration_display_helper extends \core_cache\administration_helper {
redirect($PAGE->url, get_string('addlocksuccess', 'cache', $name), 5); redirect($PAGE->url, get_string('addlocksuccess', 'cache', $name), 5);
} }
return array('form' => $mform); return ['form' => $mform];
} }
/** /**
@ -750,9 +779,9 @@ class administration_display_helper extends \core_cache\administration_helper {
if ($notifysuccess) { if ($notifysuccess) {
if (!$confirm) { if (!$confirm) {
$title = get_string('confirmlockdeletion', 'cache'); $title = get_string('confirmlockdeletion', 'cache');
$params = array('lock' => $lock, 'confirm' => 1, 'action' => $action, 'sesskey' => sesskey()); $params = ['lock' => $lock, 'confirm' => 1, 'action' => $action, 'sesskey' => sesskey()];
$url = new \moodle_url($PAGE->url, $params); $url = new url($PAGE->url, $params);
$button = new \single_button($url, get_string('deletelock', 'cache')); $button = new single_button($url, get_string('deletelock', 'cache'));
$PAGE->set_title($title); $PAGE->set_title($title);
$PAGE->set_heading($SITE->fullname); $PAGE->set_heading($SITE->fullname);
@ -764,7 +793,7 @@ class administration_display_helper extends \core_cache\administration_helper {
exit; exit;
} else { } else {
require_sesskey(); require_sesskey();
$writer = cache_config_writer::instance(); $writer = config_writer::instance();
$writer->delete_lock_instance($lock); $writer->delete_lock_instance($lock);
redirect($PAGE->url, get_string('deletelocksuccess', 'cache'), 5); redirect($PAGE->url, get_string('deletelocksuccess', 'cache'), 5);
} }
@ -780,7 +809,7 @@ class administration_display_helper extends \core_cache\administration_helper {
* @return string the HTML for the admin page. * @return string the HTML for the admin page.
*/ */
public function generate_admin_page(\core_cache\output\renderer $renderer): string { public function generate_admin_page(\core_cache\output\renderer $renderer): string {
$context = \context_system::instance(); $context = context_system::instance();
$html = ''; $html = '';
$storepluginsummaries = $this->get_store_plugin_summaries(); $storepluginsummaries = $this->get_store_plugin_summaries();
@ -795,10 +824,10 @@ class administration_display_helper extends \core_cache\administration_helper {
$html .= $renderer->lock_summaries($locks); $html .= $renderer->lock_summaries($locks);
$html .= $renderer->additional_lock_actions(); $html .= $renderer->additional_lock_actions();
$applicationstore = join(', ', $defaultmodestores[cache_store::MODE_APPLICATION]); $applicationstore = join(', ', $defaultmodestores[store::MODE_APPLICATION]);
$sessionstore = join(', ', $defaultmodestores[cache_store::MODE_SESSION]); $sessionstore = join(', ', $defaultmodestores[store::MODE_SESSION]);
$requeststore = join(', ', $defaultmodestores[cache_store::MODE_REQUEST]); $requeststore = join(', ', $defaultmodestores[store::MODE_REQUEST]);
$editurl = new \moodle_url('/cache/admin.php', array('action' => 'editmodemappings')); $editurl = new url('/cache/admin.php', ['action' => 'editmodemappings']);
$html .= $renderer->mode_mappings($applicationstore, $sessionstore, $requeststore, $editurl); $html .= $renderer->mode_mappings($applicationstore, $sessionstore, $requeststore, $editurl);
return $html; return $html;
@ -829,7 +858,7 @@ class administration_display_helper extends \core_cache\administration_helper {
public function get_usage(int $samplekeys): array { public function get_usage(int $samplekeys): array {
$results = []; $results = [];
$factory = cache_factory::instance(); $factory = factory::instance();
// Check the caches we already have an instance of, so we don't make another one... // Check the caches we already have an instance of, so we don't make another one...
$got = $factory->get_caches_in_use(); $got = $factory->get_caches_in_use();
@ -849,7 +878,7 @@ class administration_display_helper extends \core_cache\administration_helper {
// Where possible (if it doesn't need identifiers), make an instance of the cache, otherwise // Where possible (if it doesn't need identifiers), make an instance of the cache, otherwise
// we can't get the store instances for it (and it won't show up in the list). // we can't get the store instances for it (and it won't show up in the list).
if (empty($configdetails['requireidentifiers'])) { if (empty($configdetails['requireidentifiers'])) {
\cache::make($configdetails['component'], $configdetails['area']); cache::make($configdetails['component'], $configdetails['area']);
} }
} }
$definition = $factory->create_definition($configdetails['component'], $configdetails['area']); $definition = $factory->create_definition($configdetails['component'], $configdetails['area']);
@ -859,7 +888,7 @@ class administration_display_helper extends \core_cache\administration_helper {
$currentresult = (object)['cacheid' => $definition->get_id(), 'stores' => []]; $currentresult = (object)['cacheid' => $definition->get_id(), 'stores' => []];
$results[$currentresult->cacheid] = $currentresult; $results[$currentresult->cacheid] = $currentresult;
/** @var cache_store $store */ /** @var store $store */
foreach ($stores as $store) { foreach ($stores as $store) {
// Skip static cache. // Skip static cache.
if ($store instanceof \cachestore_static) { if ($store instanceof \cachestore_static) {

View file

@ -14,16 +14,20 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cache store feature: locking * Cache store feature: locking.
* *
* This is a feature that cache stores can implement if they wish to support locking themselves rather * This is a feature that cache stores can implement if they wish to support locking themselves rather
* than having the cache loader handle it for them. * than having the cache loader handle it for them.
* *
* Can be implemented by classes already implementing cache_store. * Can be implemented by classes already implementing cache_store.
* @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_is_lockable { interface lockable_cache_interface {
/** /**
* Acquires a lock on the given key for the given identifier. * Acquires a lock on the given key for the given identifier.
* *
@ -54,3 +58,8 @@ interface cache_is_lockable {
*/ */
public function release_lock($key, $ownerid); public function release_lock($key, $ownerid);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(lockable_cache_interface::class, \cache_is_lockable::class);

View file

@ -36,7 +36,6 @@ use single_select;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class renderer extends \plugin_renderer_base { class renderer extends \plugin_renderer_base {
/** /**
* Displays store summaries. * Displays store summaries.
* *
@ -48,7 +47,7 @@ class renderer extends \plugin_renderer_base {
*/ */
public function store_instance_summariers(array $storeinstancesummaries, array $storepluginsummaries) { public function store_instance_summariers(array $storeinstancesummaries, array $storepluginsummaries) {
$table = new html_table(); $table = new html_table();
$table->head = array( $table->head = [
get_string('storename', 'cache'), get_string('storename', 'cache'),
get_string('plugin', 'cache'), get_string('plugin', 'cache'),
get_string('storeready', 'cache'), get_string('storeready', 'cache'),
@ -57,8 +56,8 @@ class renderer extends \plugin_renderer_base {
get_string('supports', 'cache'), get_string('supports', 'cache'),
get_string('locking', 'cache') . ' ' . $this->output->help_icon('locking', 'cache'), get_string('locking', 'cache') . ' ' . $this->output->help_icon('locking', 'cache'),
get_string('actions', 'cache'), get_string('actions', 'cache'),
); ];
$table->colclasses = array( $table->colclasses = [
'storename', 'storename',
'plugin', 'plugin',
'storeready', 'storeready',
@ -66,42 +65,42 @@ class renderer extends \plugin_renderer_base {
'modes', 'modes',
'supports', 'supports',
'locking', 'locking',
'actions' 'actions',
); ];
$table->data = array(); $table->data = [];
$defaultstoreactions = get_string('defaultstoreactions', 'cache'); $defaultstoreactions = get_string('defaultstoreactions', 'cache');
foreach ($storeinstancesummaries as $name => $storesummary) { foreach ($storeinstancesummaries as $name => $storesummary) {
$htmlactions = cache_factory::get_administration_display_helper()->get_store_instance_actions($name, $storesummary); $htmlactions = cache_factory::get_administration_display_helper()->get_store_instance_actions($name, $storesummary);
$modes = array(); $modes = [];
foreach ($storesummary['modes'] as $mode => $enabled) { foreach ($storesummary['modes'] as $mode => $enabled) {
if ($enabled) { if ($enabled) {
$modes[] = get_string('mode_'.$mode, 'cache'); $modes[] = get_string('mode_' . $mode, 'cache');
} }
} }
$supports = array(); $supports = [];
foreach ($storesummary['supports'] as $support => $enabled) { foreach ($storesummary['supports'] as $support => $enabled) {
if ($enabled) { if ($enabled) {
$supports[] = get_string('supports_'.$support, 'cache'); $supports[] = get_string('supports_' . $support, 'cache');
} }
} }
$info = ''; $info = '';
if (!empty($storesummary['default'])) { if (!empty($storesummary['default'])) {
$info = $this->output->pix_icon('i/info', $defaultstoreactions, '', array('class' => 'icon')); $info = $this->output->pix_icon('i/info', $defaultstoreactions, '', ['class' => 'icon']);
} }
$isready = $storesummary['isready'] && $storesummary['requirementsmet']; $isready = $storesummary['isready'] && $storesummary['requirementsmet'];
$readycell = new html_table_cell; $readycell = new html_table_cell();
if ($isready) { if ($isready) {
$readycell->text = $this->output->pix_icon('i/valid', '1'); $readycell->text = $this->output->pix_icon('i/valid', '1');
} }
$storename = $storesummary['name']; $storename = $storesummary['name'];
if (!empty($storesummary['default'])) { if (!empty($storesummary['default'])) {
$storename = get_string('store_'.$storesummary['name'], 'cache'); $storename = get_string('store_' . $storesummary['name'], 'cache');
} }
if (!$isready && (int)$storesummary['mappings'] > 0) { if (!$isready && (int)$storesummary['mappings'] > 0) {
$readycell->text = $this->output->help_icon('storerequiresattention', 'cache'); $readycell->text = $this->output->help_icon('storerequiresattention', 'cache');
@ -113,24 +112,24 @@ class renderer extends \plugin_renderer_base {
$lock = get_string($storesummary['lock']['name'], 'cache'); $lock = get_string($storesummary['lock']['name'], 'cache');
} }
$row = new html_table_row(array( $row = new html_table_row([
$storename, $storename,
get_string('pluginname', 'cachestore_'.$storesummary['plugin']), get_string('pluginname', 'cachestore_' . $storesummary['plugin']),
$readycell, $readycell,
$storesummary['mappings'], $storesummary['mappings'],
join(', ', $modes), join(', ', $modes),
join(', ', $supports), join(', ', $supports),
$lock, $lock,
$info.join(', ', $htmlactions) $info . join(', ', $htmlactions),
)); ]);
$row->attributes['class'] = 'store-'.$name; $row->attributes['class'] = 'store-' . $name;
if ($storesummary['default']) { if ($storesummary['default']) {
$row->attributes['class'] .= ' default-store'; $row->attributes['class'] .= ' default-store';
} }
$table->data[] = $row; $table->data[] = $row;
} }
$html = html_writer::start_tag('div', array('id' => 'core-cache-store-summaries')); $html = html_writer::start_tag('div', ['id' => 'core-cache-store-summaries']);
$html .= $this->output->heading(get_string('storesummaries', 'cache'), 3); $html .= $this->output->heading(get_string('storesummaries', 'cache'), 3);
$html .= html_writer::table($table); $html .= html_writer::table($table);
$html .= html_writer::end_tag('div'); $html .= html_writer::end_tag('div');
@ -146,55 +145,55 @@ class renderer extends \plugin_renderer_base {
*/ */
public function store_plugin_summaries(array $storepluginsummaries) { public function store_plugin_summaries(array $storepluginsummaries) {
$table = new html_table(); $table = new html_table();
$table->head = array( $table->head = [
get_string('plugin', 'cache'), get_string('plugin', 'cache'),
get_string('storeready', 'cache'), get_string('storeready', 'cache'),
get_string('stores', 'cache'), get_string('stores', 'cache'),
get_string('modes', 'cache'), get_string('modes', 'cache'),
get_string('supports', 'cache'), get_string('supports', 'cache'),
get_string('actions', 'cache'), get_string('actions', 'cache'),
); ];
$table->colclasses = array( $table->colclasses = [
'plugin', 'plugin',
'storeready', 'storeready',
'stores', 'stores',
'modes', 'modes',
'supports', 'supports',
'actions' 'actions',
); ];
$table->data = array(); $table->data = [];
foreach ($storepluginsummaries as $name => $plugin) { foreach ($storepluginsummaries as $name => $plugin) {
$htmlactions = cache_factory::get_administration_display_helper()->get_store_plugin_actions($name, $plugin); $htmlactions = cache_factory::get_administration_display_helper()->get_store_plugin_actions($name, $plugin);
$modes = array(); $modes = [];
foreach ($plugin['modes'] as $mode => $enabled) { foreach ($plugin['modes'] as $mode => $enabled) {
if ($enabled) { if ($enabled) {
$modes[] = get_string('mode_'.$mode, 'cache'); $modes[] = get_string('mode_' . $mode, 'cache');
} }
} }
$supports = array(); $supports = [];
foreach ($plugin['supports'] as $support => $enabled) { foreach ($plugin['supports'] as $support => $enabled) {
if ($enabled) { if ($enabled) {
$supports[] = get_string('supports_'.$support, 'cache'); $supports[] = get_string('supports_' . $support, 'cache');
} }
} }
$row = new html_table_row(array( $row = new html_table_row([
$plugin['name'], $plugin['name'],
($plugin['requirementsmet']) ? $this->output->pix_icon('i/valid', '1') : '', ($plugin['requirementsmet']) ? $this->output->pix_icon('i/valid', '1') : '',
$plugin['instances'], $plugin['instances'],
join(', ', $modes), join(', ', $modes),
join(', ', $supports), join(', ', $supports),
join(', ', $htmlactions) join(', ', $htmlactions),
)); ]);
$row->attributes['class'] = 'plugin-'.$name; $row->attributes['class'] = 'plugin-' . $name;
$table->data[] = $row; $table->data[] = $row;
} }
$html = html_writer::start_tag('div', array('id' => 'core-cache-plugin-summaries')); $html = html_writer::start_tag('div', ['id' => 'core-cache-plugin-summaries']);
$html .= $this->output->heading(get_string('pluginsummaries', 'cache'), 3); $html .= $this->output->heading(get_string('pluginsummaries', 'cache'), 3);
$html .= html_writer::table($table); $html .= html_writer::table($table);
$html .= html_writer::end_tag('div'); $html .= html_writer::end_tag('div');
@ -212,7 +211,7 @@ class renderer extends \plugin_renderer_base {
*/ */
public function definition_summaries(array $definitionsummaries, context $context) { public function definition_summaries(array $definitionsummaries, context $context) {
$table = new html_table(); $table = new html_table();
$table->head = array( $table->head = [
get_string('definition', 'cache'), get_string('definition', 'cache'),
get_string('mode', 'cache'), get_string('mode', 'cache'),
get_string('component', 'cache'), get_string('component', 'cache'),
@ -220,9 +219,9 @@ class renderer extends \plugin_renderer_base {
get_string('mappings', 'cache'), get_string('mappings', 'cache'),
get_string('sharing', 'cache'), get_string('sharing', 'cache'),
get_string('canuselocalstore', 'cache'), get_string('canuselocalstore', 'cache'),
get_string('actions', 'cache') get_string('actions', 'cache'),
); ];
$table->colclasses = array( $table->colclasses = [
'definition', 'definition',
'mode', 'mode',
'component', 'component',
@ -230,9 +229,9 @@ class renderer extends \plugin_renderer_base {
'mappings', 'mappings',
'sharing', 'sharing',
'canuselocalstore', 'canuselocalstore',
'actions' 'actions',
); ];
$table->data = array(); $table->data = [];
core_collator::asort_array_of_arrays_by_key($definitionsummaries, 'name'); core_collator::asort_array_of_arrays_by_key($definitionsummaries, 'name');
@ -242,7 +241,7 @@ class renderer extends \plugin_renderer_base {
if (!empty($definition['mappings'])) { if (!empty($definition['mappings'])) {
$mapping = join(', ', $definition['mappings']); $mapping = join(', ', $definition['mappings']);
} else { } else {
$mapping = '<em>'.$none.'</em>'; $mapping = '<em>' . $none . '</em>';
} }
$uselocalcachecol = get_string('no'); $uselocalcachecol = get_string('no');
@ -252,27 +251,27 @@ class renderer extends \plugin_renderer_base {
} }
} }
$row = new html_table_row(array( $row = new html_table_row([
$definition['name'], $definition['name'],
get_string('mode_'.$definition['mode'], 'cache'), get_string('mode_' . $definition['mode'], 'cache'),
$definition['component'], $definition['component'],
$definition['area'], $definition['area'],
$mapping, $mapping,
join(', ', $definition['selectedsharingoption']), join(', ', $definition['selectedsharingoption']),
$uselocalcachecol, $uselocalcachecol,
join(', ', $htmlactions) join(', ', $htmlactions),
)); ]);
$row->attributes['class'] = 'definition-'.$definition['component'].'-'.$definition['area']; $row->attributes['class'] = 'definition-' . $definition['component'] . '-' . $definition['area'];
$table->data[] = $row; $table->data[] = $row;
} }
$html = html_writer::start_tag('div', array('id' => 'core-cache-definition-summaries')); $html = html_writer::start_tag('div', ['id' => 'core-cache-definition-summaries']);
$html .= $this->output->heading(get_string('definitionsummaries', 'cache'), 3); $html .= $this->output->heading(get_string('definitionsummaries', 'cache'), 3);
$html .= html_writer::table($table); $html .= html_writer::table($table);
$url = new moodle_url('/cache/admin.php', array('action' => 'rescandefinitions', 'sesskey' => sesskey())); $url = new moodle_url('/cache/admin.php', ['action' => 'rescandefinitions', 'sesskey' => sesskey()]);
$link = html_writer::link($url, get_string('rescandefinitions', 'cache')); $link = html_writer::link($url, get_string('rescandefinitions', 'cache'));
$html .= html_writer::tag('div', $link, array('id' => 'core-cache-rescan-definitions')); $html .= html_writer::tag('div', $link, ['id' => 'core-cache-rescan-definitions']);
$html .= html_writer::end_tag('div'); $html .= html_writer::end_tag('div');
return $html; return $html;
@ -289,30 +288,30 @@ class renderer extends \plugin_renderer_base {
*/ */
public function mode_mappings($applicationstore, $sessionstore, $requeststore, moodle_url $editurl) { public function mode_mappings($applicationstore, $sessionstore, $requeststore, moodle_url $editurl) {
$table = new html_table(); $table = new html_table();
$table->colclasses = array( $table->colclasses = [
'mode', 'mode',
'mapping', 'mapping',
); ];
$table->rowclasses = array( $table->rowclasses = [
'mode_application', 'mode_application',
'mode_session', 'mode_session',
'mode_request' 'mode_request',
); ];
$table->head = array( $table->head = [
get_string('mode', 'cache'), get_string('mode', 'cache'),
get_string('mappings', 'cache'), get_string('mappings', 'cache'),
); ];
$table->data = array( $table->data = [
array(get_string('mode_'.cache_store::MODE_APPLICATION, 'cache'), $applicationstore), [get_string('mode_' . cache_store::MODE_APPLICATION, 'cache'), $applicationstore],
array(get_string('mode_'.cache_store::MODE_SESSION, 'cache'), $sessionstore), [get_string('mode_' . cache_store::MODE_SESSION, 'cache'), $sessionstore],
array(get_string('mode_'.cache_store::MODE_REQUEST, 'cache'), $requeststore) [get_string('mode_' . cache_store::MODE_REQUEST, 'cache'), $requeststore],
); ];
$html = html_writer::start_tag('div', array('id' => 'core-cache-mode-mappings')); $html = html_writer::start_tag('div', ['id' => 'core-cache-mode-mappings']);
$html .= $this->output->heading(get_string('defaultmappings', 'cache'), 3); $html .= $this->output->heading(get_string('defaultmappings', 'cache'), 3);
$html .= html_writer::table($table); $html .= html_writer::table($table);
$link = html_writer::link($editurl, get_string('editmappings', 'cache')); $link = html_writer::link($editurl, get_string('editmappings', 'cache'));
$html .= html_writer::tag('div', $link, array('class' => 'edit-link')); $html .= html_writer::tag('div', $link, ['class' => 'edit-link']);
$html .= html_writer::end_tag('div'); $html .= html_writer::end_tag('div');
return $html; return $html;
} }
@ -327,45 +326,45 @@ class renderer extends \plugin_renderer_base {
*/ */
public function lock_summaries(array $locks) { public function lock_summaries(array $locks) {
$table = new html_table(); $table = new html_table();
$table->colclasses = array( $table->colclasses = [
'name', 'name',
'type', 'type',
'default', 'default',
'uses', 'uses',
'actions' 'actions',
); ];
$table->rowclasses = array( $table->rowclasses = [
'lock_name', 'lock_name',
'lock_type', 'lock_type',
'lock_default', 'lock_default',
'lock_uses', 'lock_uses',
'lock_actions', 'lock_actions',
); ];
$table->head = array( $table->head = [
get_string('lockname', 'cache'), get_string('lockname', 'cache'),
get_string('locktype', 'cache'), get_string('locktype', 'cache'),
get_string('lockdefault', 'cache'), get_string('lockdefault', 'cache'),
get_string('lockuses', 'cache'), get_string('lockuses', 'cache'),
get_string('actions', 'cache') get_string('actions', 'cache'),
); ];
$table->data = array(); $table->data = [];
$tick = $this->output->pix_icon('i/valid', ''); $tick = $this->output->pix_icon('i/valid', '');
foreach ($locks as $lock) { foreach ($locks as $lock) {
$actions = array(); $actions = [];
if ($lock['uses'] === 0 && !$lock['default']) { if ($lock['uses'] === 0 && !$lock['default']) {
$url = new moodle_url('/cache/admin.php', array('lock' => $lock['name'], 'action' => 'deletelock')); $url = new moodle_url('/cache/admin.php', ['lock' => $lock['name'], 'action' => 'deletelock']);
$actions[] = html_writer::link($url, get_string('delete', 'cache')); $actions[] = html_writer::link($url, get_string('delete', 'cache'));
} }
$table->data[] = new html_table_row(array( $table->data[] = new html_table_row([
new html_table_cell($lock['name']), new html_table_cell($lock['name']),
new html_table_cell($lock['type']), new html_table_cell($lock['type']),
new html_table_cell($lock['default'] ? $tick : ''), new html_table_cell($lock['default'] ? $tick : ''),
new html_table_cell($lock['uses']), new html_table_cell($lock['uses']),
new html_table_cell(join(' ', $actions)) new html_table_cell(join(' ', $actions)),
)); ]);
} }
$html = html_writer::start_tag('div', array('id' => 'core-cache-lock-summary')); $html = html_writer::start_tag('div', ['id' => 'core-cache-lock-summary']);
$html .= $this->output->heading(get_string('locksummary', 'cache'), 3); $html .= $this->output->heading(get_string('locksummary', 'cache'), 3);
$html .= html_writer::table($table); $html .= html_writer::table($table);
$html .= html_writer::end_tag('div'); $html .= html_writer::end_tag('div');
@ -378,12 +377,12 @@ class renderer extends \plugin_renderer_base {
* @return string * @return string
*/ */
public function additional_lock_actions(): string { public function additional_lock_actions(): string {
$url = new moodle_url('/cache/admin.php', array('action' => 'newlockinstance')); $url = new moodle_url('/cache/admin.php', ['action' => 'newlockinstance']);
$select = new single_select($url, 'lock', cache_factory::get_administration_display_helper()->get_addable_lock_options()); $select = new single_select($url, 'lock', cache_factory::get_administration_display_helper()->get_addable_lock_options());
$select->label = get_string('addnewlockinstance', 'cache'); $select->label = get_string('addnewlockinstance', 'cache');
$html = html_writer::start_tag('div', array('id' => 'core-cache-lock-additional-actions')); $html = html_writer::start_tag('div', ['id' => 'core-cache-lock-additional-actions']);
$html .= html_writer::tag('div', $this->output->render($select), array('class' => 'new-instance')); $html .= html_writer::tag('div', $this->output->render($select), ['class' => 'new-instance']);
$html .= html_writer::end_tag('div'); $html .= html_writer::end_tag('div');
return $html; return $html;
} }
@ -400,14 +399,14 @@ class renderer extends \plugin_renderer_base {
* @param array $notifications * @param array $notifications
* @return string * @return string
*/ */
public function notifications(array $notifications = array()) { public function notifications(array $notifications = []) {
if (count($notifications) === 0) { if (count($notifications) === 0) {
// There are no notifications to render. // There are no notifications to render.
return ''; return '';
} }
$html = html_writer::start_div('notifications'); $html = html_writer::start_div('notifications');
foreach ($notifications as $notification) { foreach ($notifications as $notification) {
list($message, $notifysuccess) = $notification; [$message, $notifysuccess] = $notification;
$html .= $this->notification($message, ($notifysuccess) ? 'notifysuccess' : 'notifyproblem'); $html .= $this->notification($message, ($notifysuccess) ? 'notifysuccess' : 'notifyproblem');
} }
$html .= html_writer::end_div(); $html .= html_writer::end_div();
@ -432,10 +431,10 @@ class renderer extends \plugin_renderer_base {
get_string('usage_mean', 'cache'), get_string('usage_mean', 'cache'),
get_string('usage_sd', 'cache'), get_string('usage_sd', 'cache'),
get_string('usage_total', 'cache'), get_string('usage_total', 'cache'),
get_string('usage_totalmargin', 'cache')]; get_string('usage_totalmargin', 'cache'), ];
$table->align = [ $table->align = [
'left', 'left', 'left', 'left', 'left', 'left',
'right', 'right', 'right', 'right', 'right' 'right', 'right', 'right', 'right', 'right',
]; ];
$table->data = []; $table->data = [];
@ -445,7 +444,7 @@ class renderer extends \plugin_renderer_base {
get_string('storename', 'cache'), get_string('storename', 'cache'),
get_string('plugin', 'cache'), get_string('plugin', 'cache'),
get_string('usage_total', 'cache'), get_string('usage_total', 'cache'),
get_string('usage_realtotal', 'cache') get_string('usage_realtotal', 'cache'),
]; ];
$summarytable->align = [ $summarytable->align = [
'left', 'left', 'left', 'left',
@ -542,7 +541,7 @@ class renderer extends \plugin_renderer_base {
$data = [ $data = [
'maintable' => \html_writer::table($maintable), 'maintable' => \html_writer::table($maintable),
'summarytable' => \html_writer::table($summarytable), 'summarytable' => \html_writer::table($summarytable),
'samplesform' => $samplesform->render() 'samplesform' => $samplesform->render(),
]; ];
return $this->render_from_template('core_cache/usage', $data); return $this->render_from_template('core_cache/usage', $data);

View file

@ -24,9 +24,7 @@
namespace core_cache\privacy; namespace core_cache\privacy;
defined('MOODLE_INTERNAL') || die(); use core_privacy\local\metadata\collection;
use \core_privacy\local\metadata\collection;
/** /**
* Privacy Subsystem implementation for core_cache. * Privacy Subsystem implementation for core_cache.
@ -41,8 +39,7 @@ class provider implements
// The cache subsystem stores data on behalf of other components. // The cache subsystem stores data on behalf of other components.
\core_privacy\local\request\subsystem\plugin_provider, \core_privacy\local\request\subsystem\plugin_provider,
\core_privacy\local\request\shared_userlist_provider \core_privacy\local\request\shared_userlist_provider
{ {
/** /**
* Returns meta data about this system. * Returns meta data about this system.
* *

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* An request cache. * An request cache.
* *
@ -25,11 +27,16 @@
* *
* @internal don't use me directly. * @internal don't use me directly.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_request extends cache { class request_cache extends cache {
// This comment appeases code pre-checker ;) ! // This comment appeases code pre-checker ;) !
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(request_cache::class, \cache_request::class);

View file

@ -14,15 +14,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cache store feature: keys are searchable. * Cache store feature: keys are searchable.
* *
* Cache stores can choose to implement this interface. * Cache stores can choose to implement this interface.
* In order for a store to be usable as a session cache it must implement this interface. * In order for a store to be usable as a session cache it must implement this interface.
* *
* @since Moodle 2.4.4 * @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_is_searchable { interface searchable_cache_interface {
/** /**
* Finds all of the keys being used by the cache store. * Finds all of the keys being used by the cache store.
* *
@ -37,3 +41,8 @@ interface cache_is_searchable {
*/ */
public function find_by_prefix($prefix); public function find_by_prefix($prefix);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(searchable_cache_interface::class, \cache_is_searchable::class);

View file

@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
use core\exception\coding_exception;
/** /**
* A session cache. * A session cache.
* *
@ -27,7 +31,7 @@
* Along with this we embed a lastaccessed time with the data. This way we can * Along with this we embed a lastaccessed time with the data. This way we can
* check sessions for a last access time. * check sessions for a last access time.
* 3. Session stores are required to support key searching and must * 3. Session stores are required to support key searching and must
* implement cache_is_searchable. This ensures stores used for the cache can be * implement searchable_cache_interface. This ensures stores used for the cache can be
* targetted for garbage collection of session data. * targetted for garbage collection of session data.
* *
* This cache class should never be interacted with directly. Instead you should always use the cache::make methods. * This cache class should never be interacted with directly. Instead you should always use the cache::make methods.
@ -37,14 +41,15 @@
* @todo we should support locking in the session as well. Should be pretty simple to set up. * @todo we should support locking in the session as well. Should be pretty simple to set up.
* *
* @internal don't use me directly. * @internal don't use me directly.
* @method cache_store|cache_is_searchable get_store() Returns the cache store which must implement both cache_is_searchable. * @method store|searchable_cache_interface get_store() Returns the cache store which must implement
* both searchable_cache_interface.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_session extends cache { class session_cache extends cache {
/** /**
* The user the session has been established for. * The user the session has been established for.
* @var int * @var int
@ -89,11 +94,11 @@ class cache_session extends cache {
* *
* You should not call this method from your code, instead you should use the cache::make methods. * You should not call this method from your code, instead you should use the cache::make methods.
* *
* @param cache_definition $definition * @param definition $definition
* @param cache_store $store * @param store $store
* @param cache_loader|cache_data_source $loader * @param loader_interface|data_source_interface $loader
*/ */
public function __construct(cache_definition $definition, cache_store $store, $loader = null) { public function __construct(definition $definition, store $store, $loader = null) {
// First up copy the loadeduserid to the current user id. // First up copy the loadeduserid to the current user id.
$this->currentuserid = self::$loadeduserid; $this->currentuserid = self::$loadeduserid;
$this->set_session_id(); $this->set_session_id();
@ -117,7 +122,7 @@ class cache_session extends cache {
* @return string * @return string
*/ */
protected function get_key_prefix() { protected function get_key_prefix() {
return 'u'.$this->currentuserid.'_'.$this->sessionid; return 'u' . $this->currentuserid . '_' . $this->sessionid;
} }
/** /**
@ -134,9 +139,9 @@ class cache_session extends cache {
protected function parse_key($key) { protected function parse_key($key) {
$prefix = $this->get_key_prefix(); $prefix = $this->get_key_prefix();
if ($key === self::LASTACCESS) { if ($key === self::LASTACCESS) {
return $key.$prefix; return $key . $prefix;
} }
return $prefix.'_'.parent::parse_key($key); return $prefix . '_' . parent::parse_key($key);
} }
/** /**
@ -219,8 +224,8 @@ class cache_session extends cache {
// We have to let the loader do its own parsing of data as it may be unique. // We have to let the loader do its own parsing of data as it may be unique.
$loader->set($key, $data); $loader->set($key, $data);
} }
if (is_object($data) && $data instanceof cacheable_object) { if (is_object($data) && $data instanceof cacheable_object_interface) {
$data = new cache_cached_object($data); $data = new cached_object($data);
} else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($data)) { } else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($data)) {
// If data is an object it will be a reference. // If data is an object it will be a reference.
// If data is an array if may contain references. // If data is an array if may contain references.
@ -230,12 +235,16 @@ class cache_session extends cache {
} }
// We dont' support native TTL here as we consolidate data for sessions. // We dont' support native TTL here as we consolidate data for sessions.
if ($this->has_a_ttl() && !$this->store_supports_native_ttl()) { if ($this->has_a_ttl() && !$this->store_supports_native_ttl()) {
$data = new cache_ttl_wrapper($data, $this->get_definition()->get_ttl()); $data = new ttl_wrapper($data, $this->get_definition()->get_ttl());
} }
$success = $this->get_store()->set($this->parse_key($key), $data); $success = $this->get_store()->set($this->parse_key($key), $data);
if ($this->perfdebug) { if ($this->perfdebug) {
cache_helper::record_cache_set($this->get_store(), $this->get_definition(), 1, helper::record_cache_set(
$this->get_store()->get_last_io_bytes()); $this->get_store(),
$this->get_definition(),
1,
$this->get_store()->get_last_io_bytes()
);
} }
return $success; return $success;
} }
@ -277,8 +286,8 @@ class cache_session extends cache {
*/ */
public function get_many(array $keys, $strictness = IGNORE_MISSING) { public function get_many(array $keys, $strictness = IGNORE_MISSING) {
$this->check_tracked_user(); $this->check_tracked_user();
$parsedkeys = array(); $parsedkeys = [];
$keymap = array(); $keymap = [];
foreach ($keys as $key) { foreach ($keys as $key) {
$parsedkey = $this->parse_key($key); $parsedkey = $this->parse_key($key);
$parsedkeys[$key] = $parsedkey; $parsedkeys[$key] = $parsedkey;
@ -288,13 +297,13 @@ class cache_session extends cache {
if ($this->perfdebug) { if ($this->perfdebug) {
$readbytes = $this->get_store()->get_last_io_bytes(); $readbytes = $this->get_store()->get_last_io_bytes();
} }
$return = array(); $return = [];
$missingkeys = array(); $missingkeys = [];
$hasmissingkeys = false; $hasmissingkeys = false;
foreach ($result as $parsedkey => $value) { foreach ($result as $parsedkey => $value) {
$key = $keymap[$parsedkey]; $key = $keymap[$parsedkey];
if ($value instanceof cache_ttl_wrapper) { if ($value instanceof ttl_wrapper) {
/* @var cache_ttl_wrapper $value */ /* @var ttl_wrapper $value */
if ($value->has_expired()) { if ($value->has_expired()) {
$this->delete($keymap[$parsedkey]); $this->delete($keymap[$parsedkey]);
$value = false; $value = false;
@ -302,8 +311,8 @@ class cache_session extends cache {
$value = $value->data; $value = $value->data;
} }
} }
if ($value instanceof cache_cached_object) { if ($value instanceof cached_object) {
/* @var cache_cached_object $value */ /* @var cached_object $value */
$value = $value->restore_object(); $value = $value->restore_object();
} else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($value)) { } else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($value)) {
// If data is an object it will be a reference. // If data is an object it will be a reference.
@ -355,11 +364,10 @@ class cache_session extends cache {
$hits++; $hits++;
} }
} }
cache_helper::record_cache_hit($this->get_store(), $this->get_definition(), $hits, $readbytes); helper::record_cache_hit($this->get_store(), $this->get_definition(), $hits, $readbytes);
cache_helper::record_cache_miss($this->get_store(), $this->get_definition(), $misses); helper::record_cache_miss($this->get_store(), $this->get_definition(), $misses);
} }
return $return; return $return;
} }
/** /**
@ -371,7 +379,7 @@ class cache_session extends cache {
* @return int The number of items successfully deleted. * @return int The number of items successfully deleted.
*/ */
public function delete_many(array $keys, $recurse = true) { public function delete_many(array $keys, $recurse = true) {
$parsedkeys = array_map(array($this, 'parse_key'), $keys); $parsedkeys = array_map([$this, 'parse_key'], $keys);
if ($recurse && $this->get_loader() !== false) { if ($recurse && $this->get_loader() !== false) {
// Delete from the bottom of the stack first. // Delete from the bottom of the stack first.
$this->get_loader()->delete_many($keys, $recurse); $this->get_loader()->delete_many($keys, $recurse);
@ -410,12 +418,12 @@ class cache_session extends cache {
// We have to let the loader do its own parsing of data as it may be unique. // We have to let the loader do its own parsing of data as it may be unique.
$loader->set_many($keyvaluearray); $loader->set_many($keyvaluearray);
} }
$data = array(); $data = [];
$definitionid = $this->get_definition()->get_ttl(); $definitionid = $this->get_definition()->get_ttl();
$simulatettl = $this->has_a_ttl() && !$this->store_supports_native_ttl(); $simulatettl = $this->has_a_ttl() && !$this->store_supports_native_ttl();
foreach ($keyvaluearray as $key => $value) { foreach ($keyvaluearray as $key => $value) {
if (is_object($value) && $value instanceof cacheable_object) { if (is_object($value) && $value instanceof cacheable_object_interface) {
$value = new cache_cached_object($value); $value = new cached_object($value);
} else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($value)) { } else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($value)) {
// If data is an object it will be a reference. // If data is an object it will be a reference.
// If data is an array if may contain references. // If data is an array if may contain references.
@ -424,17 +432,21 @@ class cache_session extends cache {
$value = $this->unref($value); $value = $this->unref($value);
} }
if ($simulatettl) { if ($simulatettl) {
$value = new cache_ttl_wrapper($value, $definitionid); $value = new ttl_wrapper($value, $definitionid);
} }
$data[$key] = array( $data[$key] = [
'key' => $this->parse_key($key), 'key' => $this->parse_key($key),
'value' => $value 'value' => $value,
); ];
} }
$successfullyset = $this->get_store()->set_many($data); $successfullyset = $this->get_store()->set_many($data);
if ($this->perfdebug && $successfullyset) { if ($this->perfdebug && $successfullyset) {
cache_helper::record_cache_set($this->get_store(), $this->get_definition(), $successfullyset, helper::record_cache_set(
$this->get_store()->get_last_io_bytes()); $this->get_store(),
$this->get_definition(),
$successfullyset,
$this->get_store()->get_last_io_bytes()
);
} }
return $successfullyset; return $successfullyset;
} }
@ -481,7 +493,7 @@ class cache_session extends cache {
// The data has a TTL and the store doesn't support it natively. // The data has a TTL and the store doesn't support it natively.
// We must fetch the data and expect a ttl wrapper. // We must fetch the data and expect a ttl wrapper.
$data = $store->get($parsedkey); $data = $store->get($parsedkey);
$has = ($data instanceof cache_ttl_wrapper && !$data->has_expired()); $has = ($data instanceof ttl_wrapper && !$data->has_expired());
} else if (!$this->store_supports_key_awareness()) { } else if (!$this->store_supports_key_awareness()) {
// The store doesn't support key awareness, get the data and check it manually... puke. // The store doesn't support key awareness, get the data and check it manually... puke.
// Either no TTL is set of the store supports its handling natively. // Either no TTL is set of the store supports its handling natively.
@ -490,7 +502,7 @@ class cache_session extends cache {
} else { } else {
// The store supports key awareness, this is easy! // The store supports key awareness, this is easy!
// Either no TTL is set of the store supports its handling natively. // Either no TTL is set of the store supports its handling natively.
/* @var cache_store|cache_is_key_aware $store */ /* @var store|key_aware_cache_interface $store */
$has = $store->has($parsedkey); $has = $store->has($parsedkey);
} }
if (!$has && $tryloadifpossible) { if (!$has && $tryloadifpossible) {
@ -532,9 +544,9 @@ class cache_session extends cache {
return true; return true;
} }
// The cache must be key aware and if support native ttl if it a ttl is set. // The cache must be key aware and if support native ttl if it a ttl is set.
/* @var cache_store|cache_is_key_aware $store */ /* @var store|key_aware_cache_interface $store */
$store = $this->get_store(); $store = $this->get_store();
return $store->has_all(array_map(array($this, 'parse_key'), $keys)); return $store->has_all(array_map([$this, 'parse_key'], $keys));
} }
/** /**
@ -559,9 +571,9 @@ class cache_session extends cache {
} }
return false; return false;
} }
/* @var cache_store|cache_is_key_aware $store */ /* @var store|key_aware_cache_interface $store */
$store = $this->get_store(); $store = $this->get_store();
return $store->has_any(array_map(array($this, 'parse_key'), $keys)); return $store->has_any(array_map([$this, 'parse_key'], $keys));
} }
/** /**
@ -574,3 +586,8 @@ class cache_session extends cache {
return false; return false;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(session_cache::class, \cache_session::class);

View file

@ -14,17 +14,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/** namespace core_cache;
* Cache store - base class
* use core\exception\coding_exception;
* This file is part of Moodle's cache API, affectionately called MUC. use stdClass;
* It contains the components that are required in order to use caching.
*
* @package core
* @category cache
* @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/** /**
* Abstract cache store class. * Abstract cache store class.
@ -33,13 +26,12 @@
* It lays down the foundation for what is required of a cache store plugin. * It lays down the foundation for what is required of a cache store plugin.
* *
* @since Moodle 2.4 * @since Moodle 2.4
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
abstract class cache_store implements cache_store_interface { abstract class store implements store_interface {
// Constants for features a cache store can support // Constants for features a cache store can support
/** /**
@ -109,7 +101,7 @@ abstract class cache_store implements cache_store_interface {
* @param string $name The name of the cache store * @param string $name The name of the cache store
* @param array $configuration The configuration for this store instance. * @param array $configuration The configuration for this store instance.
*/ */
abstract public function __construct($name, array $configuration = array()); abstract public function __construct($name, array $configuration = []);
/** /**
* Returns the name of this store instance. * Returns the name of this store instance.
@ -127,9 +119,9 @@ abstract class cache_store implements cache_store_interface {
* If there are setup tasks that may fail they should be done within the __construct method * If there are setup tasks that may fail they should be done within the __construct method
* and should they fail is_ready should return false. * and should they fail is_ready should return false.
* *
* @param cache_definition $definition * @param definition $definition
*/ */
abstract public function initialise(cache_definition $definition); abstract public function initialise(definition $definition);
/** /**
* Returns true if this cache store instance has been initialised. * Returns true if this cache store instance has been initialised.
@ -142,7 +134,7 @@ abstract class cache_store implements cache_store_interface {
* @return bool * @return bool
*/ */
public function is_ready() { public function is_ready() {
return forward_static_call(array($this, 'are_requirements_met')); return forward_static_call([$this, 'are_requirements_met']);
} }
/** /**
@ -208,11 +200,11 @@ abstract class cache_store implements cache_store_interface {
/** /**
* @deprecated since 2.5 * @deprecated since 2.5
* @see \cache_store::instance_deleted() * @see store::instance_deleted()
*/ */
public function cleanup() { public function cleanup() {
throw new coding_exception('cache_store::cleanup() can not be used anymore.' . throw new coding_exception('store::cleanup() can not be used anymore.' .
' Please use cache_store::instance_deleted() instead.'); ' Please use store::instance_deleted() instead.');
} }
/** /**
@ -282,7 +274,7 @@ abstract class cache_store implements cache_store_interface {
* @return bool * @return bool
*/ */
public function is_searchable() { public function is_searchable() {
return in_array('cache_is_searchable', class_implements($this)); return in_array(searchable_cache_interface::class, class_implements($this));
} }
/** /**
@ -304,9 +296,9 @@ abstract class cache_store implements cache_store_interface {
* you can override this method to handle any situations you want before cloning. * you can override this method to handle any situations you want before cloning.
* *
* @param array $details An array containing the details of the store from the cache config. * @param array $details An array containing the details of the store from the cache config.
* @return cache_store * @return store
*/ */
public function create_clone(array $details = array()) { public function create_clone(array $details = []) {
// By default we just run clone. // By default we just run clone.
// Any stores that have an issue with this will need to override the create_clone method. // Any stores that have an issue with this will need to override the create_clone method.
return clone($this); return clone($this);
@ -321,7 +313,7 @@ abstract class cache_store implements cache_store_interface {
* @return string[] An array of warning strings from the store instance. * @return string[] An array of warning strings from the store instance.
*/ */
public function get_warnings() { public function get_warnings() {
return array(); return [];
} }
/** /**
@ -384,7 +376,7 @@ abstract class cache_store implements cache_store_interface {
'items' => 0, 'items' => 0,
'mean' => 0, 'mean' => 0,
'sd' => 0, 'sd' => 0,
'margin' => 0 'margin' => 0,
]; ];
// If this cache isn't searchable, we don't know the answer. // If this cache isn't searchable, we don't know the answer.
@ -472,3 +464,8 @@ abstract class cache_store implements cache_store_interface {
return self::IO_BYTES_NOT_SUPPORTED; return self::IO_BYTES_NOT_SUPPORTED;
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(store::class, \cache_store::class);

View file

@ -14,18 +14,20 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Cache store interface. * Cache store interface.
* *
* This interface defines the static methods that must be implemented by every cache store plugin. * This interface defines the static methods that must be implemented by every cache store plugin.
* To ensure plugins implement this class the abstract cache_store class implements this interface. * To ensure plugins implement this class the abstract cache_store class implements this interface.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_store_interface { interface store_interface {
/** /**
* Static method to check if the store requirements are met. * Static method to check if the store requirements are met.
* *
@ -46,7 +48,7 @@ interface cache_store_interface {
* @param array $configuration The configuration of a store to consider specifically. * @param array $configuration The configuration of a store to consider specifically.
* @return int The supported features. * @return int The supported features.
*/ */
public static function get_supported_features(array $configuration = array()); public static function get_supported_features(array $configuration = []);
/** /**
* Returns the supported modes as a binary flag. * Returns the supported modes as a binary flag.
@ -54,17 +56,17 @@ interface cache_store_interface {
* @param array $configuration The configuration of a store to consider specifically. * @param array $configuration The configuration of a store to consider specifically.
* @return int The supported modes. * @return int The supported modes.
*/ */
public static function get_supported_modes(array $configuration = array()); public static function get_supported_modes(array $configuration = []);
/** /**
* Generates an instance of the cache store that can be used for testing. * Generates an instance of the cache store that can be used for testing.
* *
* Returns an instance of the cache store, or false if one cannot be created. * Returns an instance of the cache store, or false if one cannot be created.
* *
* @param cache_definition $definition * @param definition $definition
* @return cache_store|false * @return store_interface|false
*/ */
public static function initialise_test_instance(cache_definition $definition); public static function initialise_test_instance(definition $definition);
/** /**
* Generates the appropriate configuration required for unit testing. * Generates the appropriate configuration required for unit testing.
@ -73,3 +75,8 @@ interface cache_store_interface {
*/ */
public static function unit_test_configuration(); public static function unit_test_configuration();
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(store_interface::class, \cache_store_interface::class);

View file

@ -14,18 +14,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* A wrapper class used to handle ttl when the cache store doesn't natively support it. * A wrapper class used to handle ttl when the cache store doesn't natively support it.
* *
* This class is exactly why you should use event driving invalidation of cache data rather than relying on ttl. * This class is exactly why you should use event driving invalidation of cache data rather than relying on ttl.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_ttl_wrapper { class ttl_wrapper {
/** /**
* The data being stored. * The data being stored.
* @var mixed * @var mixed
@ -57,3 +58,8 @@ class cache_ttl_wrapper {
return ($this->expires < cache::now()); return ($this->expires < cache::now());
} }
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(ttl_wrapper::class, \cache_ttl_wrapper::class);

View file

@ -24,7 +24,6 @@ namespace core_cache;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class version_wrapper { class version_wrapper {
/** /**
* The data being stored. * The data being stored.
* @var mixed * @var mixed

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_cache;
/** /**
* Versionable cache data source. * Versionable cache data source.
* *
@ -21,8 +23,10 @@
* the data source is to be used for a versioned cache. * the data source is to be used for a versioned cache.
* *
* @package core_cache * @package core_cache
* @copyright Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
interface cache_data_source_versionable extends cache_data_source { interface versionable_data_source_interface extends cache_data_source {
/** /**
* Loads the data for the key provided ready formatted for caching. * Loads the data for the key provided ready formatted for caching.
* *
@ -39,3 +43,8 @@ interface cache_data_source_versionable extends cache_data_source {
*/ */
public function load_for_cache_versioned($key, int $requiredversion, &$actualversion); public function load_for_cache_versioned($key, int $requiredversion, &$actualversion);
} }
// Alias this class to the old name.
// This file will be autoloaded by the legacyclasses autoload system.
// In future all uses of this class will be corrected and the legacy references will be removed.
class_alias(versionable_data_source_interface::class, \cache_data_source_versionable::class);

View file

@ -17,14 +17,14 @@
/** /**
* Store performance test run + output script. * Store performance test run + output script.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
require_once('../config.php'); require_once('../config.php');
require_once($CFG->dirroot.'/lib/adminlib.php'); require_once($CFG->dirroot . '/lib/adminlib.php');
$count = optional_param('count', 100, PARAM_INT); $count = optional_param('count', 100, PARAM_INT);
$count = min($count, 100000); $count = min($count, 100000);
@ -33,15 +33,15 @@ $count = max($count, 0);
admin_externalpage_setup('cachetestperformance'); admin_externalpage_setup('cachetestperformance');
$applicationtable = new html_table(); $applicationtable = new html_table();
$applicationtable->head = array( $applicationtable->head = [
get_string('plugin', 'cache'), get_string('plugin', 'cache'),
get_string('result', 'cache'), get_string('result', 'cache'),
get_string('set', 'cache'), get_string('set', 'cache'),
get_string('gethit', 'cache'), get_string('gethit', 'cache'),
get_string('getmiss', 'cache'), get_string('getmiss', 'cache'),
get_string('delete', 'cache'), get_string('delete', 'cache'),
); ];
$applicationtable->data = array(); $applicationtable->data = [];
$sessiontable = clone($applicationtable); $sessiontable = clone($applicationtable);
$requesttable = clone($applicationtable); $requesttable = clone($applicationtable);
@ -57,48 +57,47 @@ $strtested = new lang_string('tested', 'cache');
$strnotready = new lang_string('storenotready', 'cache'); $strnotready = new lang_string('storenotready', 'cache');
foreach (core_component::get_plugin_list_with_file('cachestore', 'lib.php', true) as $plugin => $path) { foreach (core_component::get_plugin_list_with_file('cachestore', 'lib.php', true) as $plugin => $path) {
$class = 'cachestore_' . $plugin;
$class = 'cachestore_'.$plugin; $plugin = get_string('pluginname', 'cachestore_' . $plugin);
$plugin = get_string('pluginname', 'cachestore_'.$plugin);
if (!class_exists($class) || !method_exists($class, 'initialise_test_instance') || !$class::are_requirements_met()) { if (!class_exists($class) || !method_exists($class, 'initialise_test_instance') || !$class::are_requirements_met()) {
$applicationtable->data[] = array($plugin, $strinvalidplugin, '-', '-', '-', '-'); $applicationtable->data[] = [$plugin, $strinvalidplugin, '-', '-', '-', '-'];
$sessiontable->data[] = array($plugin, $strinvalidplugin, '-', '-', '-', '-'); $sessiontable->data[] = [$plugin, $strinvalidplugin, '-', '-', '-', '-'];
$requesttable->data[] = array($plugin, $strinvalidplugin, '-', '-', '-', '-'); $requesttable->data[] = [$plugin, $strinvalidplugin, '-', '-', '-', '-'];
continue; continue;
} }
if (!$class::is_supported_mode(cache_store::MODE_APPLICATION)) { if (!$class::is_supported_mode(cache_store::MODE_APPLICATION)) {
$applicationtable->data[] = array($plugin, $strunsupportedmode, '-', '-', '-', '-'); $applicationtable->data[] = [$plugin, $strunsupportedmode, '-', '-', '-', '-'];
} else { } else {
$store = $class::initialise_test_instance($application); $store = $class::initialise_test_instance($application);
if ($store === false) { if ($store === false) {
$applicationtable->data[] = array($plugin, $struntestable, '-', '-', '-', '-'); $applicationtable->data[] = [$plugin, $struntestable, '-', '-', '-', '-'];
} else if (!$store->is_ready()) { } else if (!$store->is_ready()) {
$applicationtable->data[] = array($plugin, $strnotready, '-', '-', '-', '-'); $applicationtable->data[] = [$plugin, $strnotready, '-', '-', '-', '-'];
} else { } else {
$result = array($plugin, $strtested, 0, 0, 0); $result = [$plugin, $strtested, 0, 0, 0];
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->set('key'.$i, 'test data '.$i); $store->set('key' . $i, 'test data ' . $i);
} }
$result[2] = sprintf('%01.4f', microtime(true) - $start); $result[2] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->get('key'.$i); $store->get('key' . $i);
} }
$result[3] = sprintf('%01.4f', microtime(true) - $start); $result[3] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->get('fake'.$i); $store->get('fake' . $i);
} }
$result[4] = sprintf('%01.4f', microtime(true) - $start); $result[4] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->delete('key'.$i); $store->delete('key' . $i);
} }
$result[5] = sprintf('%01.4f', microtime(true) - $start); $result[5] = sprintf('%01.4f', microtime(true) - $start);
$applicationtable->data[] = $result; $applicationtable->data[] = $result;
@ -107,36 +106,36 @@ foreach (core_component::get_plugin_list_with_file('cachestore', 'lib.php', true
} }
if (!$class::is_supported_mode(cache_store::MODE_SESSION)) { if (!$class::is_supported_mode(cache_store::MODE_SESSION)) {
$sessiontable->data[] = array($plugin, $strunsupportedmode, '-', '-', '-', '-'); $sessiontable->data[] = [$plugin, $strunsupportedmode, '-', '-', '-', '-'];
} else { } else {
$store = $class::initialise_test_instance($session); $store = $class::initialise_test_instance($session);
if ($store === false) { if ($store === false) {
$sessiontable->data[] = array($plugin, $struntestable, '-', '-', '-', '-'); $sessiontable->data[] = [$plugin, $struntestable, '-', '-', '-', '-'];
} else if (!$store->is_ready()) { } else if (!$store->is_ready()) {
$sessiontable->data[] = array($plugin, $strnotready, '-', '-', '-', '-'); $sessiontable->data[] = [$plugin, $strnotready, '-', '-', '-', '-'];
} else { } else {
$result = array($plugin, $strtested, 0, 0, 0); $result = [$plugin, $strtested, 0, 0, 0];
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->set('key'.$i, 'test data '.$i); $store->set('key' . $i, 'test data ' . $i);
} }
$result[2] = sprintf('%01.4f', microtime(true) - $start); $result[2] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->get('key'.$i); $store->get('key' . $i);
} }
$result[3] = sprintf('%01.4f', microtime(true) - $start); $result[3] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->get('fake'.$i); $store->get('fake' . $i);
} }
$result[4] = sprintf('%01.4f', microtime(true) - $start); $result[4] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->delete('key'.$i); $store->delete('key' . $i);
} }
$result[5] = sprintf('%01.4f', microtime(true) - $start); $result[5] = sprintf('%01.4f', microtime(true) - $start);
$sessiontable->data[] = $result; $sessiontable->data[] = $result;
@ -145,52 +144,51 @@ foreach (core_component::get_plugin_list_with_file('cachestore', 'lib.php', true
} }
if (!$class::is_supported_mode(cache_store::MODE_REQUEST)) { if (!$class::is_supported_mode(cache_store::MODE_REQUEST)) {
$requesttable->data[] = array($plugin, $strunsupportedmode, '-', '-', '-', '-'); $requesttable->data[] = [$plugin, $strunsupportedmode, '-', '-', '-', '-'];
} else { } else {
$store = $class::initialise_test_instance($request); $store = $class::initialise_test_instance($request);
if ($store === false) { if ($store === false) {
$requesttable->data[] = array($plugin, $struntestable, '-', '-', '-', '-'); $requesttable->data[] = [$plugin, $struntestable, '-', '-', '-', '-'];
} else if (!$store->is_ready()) { } else if (!$store->is_ready()) {
$requesttable->data[] = array($plugin, $strnotready, '-', '-', '-', '-'); $requesttable->data[] = [$plugin, $strnotready, '-', '-', '-', '-'];
} else { } else {
$result = array($plugin, $strtested, 0, 0, 0); $result = [$plugin, $strtested, 0, 0, 0];
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->set('key'.$i, 'test data '.$i); $store->set('key' . $i, 'test data ' . $i);
} }
$result[2] = sprintf('%01.4f', microtime(true) - $start); $result[2] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->get('key'.$i); $store->get('key' . $i);
} }
$result[3] = sprintf('%01.4f', microtime(true) - $start); $result[3] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->get('fake'.$i); $store->get('fake' . $i);
} }
$result[4] = sprintf('%01.4f', microtime(true) - $start); $result[4] = sprintf('%01.4f', microtime(true) - $start);
$start = microtime(true); $start = microtime(true);
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
$store->delete('key'.$i); $store->delete('key' . $i);
} }
$result[5] = sprintf('%01.4f', microtime(true) - $start); $result[5] = sprintf('%01.4f', microtime(true) - $start);
$requesttable->data[] = $result; $requesttable->data[] = $result;
$store->instance_deleted(); $store->instance_deleted();
} }
} }
} }
echo $OUTPUT->header(); echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('storeperformance', 'cache', $count)); echo $OUTPUT->heading(get_string('storeperformance', 'cache', $count));
$possiblecounts = array(1, 10, 100, 500, 1000, 5000, 10000, 50000, 100000); $possiblecounts = [1, 10, 100, 500, 1000, 5000, 10000, 50000, 100000];
$links = array(); $links = [];
foreach ($possiblecounts as $pcount) { foreach ($possiblecounts as $pcount) {
$links[] = html_writer::link(new moodle_url($PAGE->url, array('count' => $pcount)), $pcount); $links[] = html_writer::link(new moodle_url($PAGE->url, ['count' => $pcount]), $pcount);
} }
echo $OUTPUT->box_start('generalbox performance-test-counts'); echo $OUTPUT->box_start('generalbox performance-test-counts');
echo get_string('requestcount', 'cache', join(', ', $links)); echo get_string('requestcount', 'cache', join(', ', $links));

View file

@ -17,18 +17,6 @@
namespace core_cache; namespace core_cache;
use cache_config_testing; use cache_config_testing;
use cache_config_writer;
use cache_factory;
use cache_helper;
use cache_store;
defined('MOODLE_INTERNAL') || die();
// Include the necessary evils.
global $CFG;
require_once($CFG->dirroot.'/cache/locallib.php');
require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php');
/** /**
* PHPunit tests for the cache API and in particular the core_cache\administration_helper * PHPunit tests for the cache API and in particular the core_cache\administration_helper
@ -37,24 +25,34 @@ require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php');
* @category test * @category test
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_cache\administration_helper
*/ */
class administration_helper_test extends \advanced_testcase { final class administration_helper_test extends \advanced_testcase {
/** /**
* Set things back to the default before each test. * Set things back to the default before each test.
*/ */
public function setUp(): void { public function setUp(): void {
parent::setUp(); parent::setUp();
cache_factory::reset(); factory::reset();
cache_config_testing::create_default_configuration(); cache_config_testing::create_default_configuration();
} }
/**
* Require all test dependencies not auto-loadable.
*/
public static function setUpBeforeClass(): void {
global $CFG;
parent::setUpBeforeClass();
require_once($CFG->dirroot . '/cache/tests/fixtures/lib.php');
}
/** /**
* Final task is to reset the cache system * Final task is to reset the cache system
*/ */
public static function tearDownAfterClass(): void { public static function tearDownAfterClass(): void {
parent::tearDownAfterClass(); parent::tearDownAfterClass();
cache_factory::reset(); factory::reset();
} }
/** /**
@ -62,20 +60,20 @@ class administration_helper_test extends \advanced_testcase {
*/ */
public function test_get_summaries(): void { public function test_get_summaries(): void {
// First the preparation. // First the preparation.
$config = cache_config_writer::instance(); $config = config_writer::instance();
$this->assertTrue($config->add_store_instance('summariesstore', 'file')); $this->assertTrue($config->add_store_instance('summariesstore', 'file'));
$config->set_definition_mappings('core/eventinvalidation', array('summariesstore')); $config->set_definition_mappings('core/eventinvalidation', ['summariesstore']);
$this->assertTrue($config->set_mode_mappings(array( $this->assertTrue($config->set_mode_mappings([
cache_store::MODE_APPLICATION => array('summariesstore'), store::MODE_APPLICATION => ['summariesstore'],
cache_store::MODE_SESSION => array('default_session'), store::MODE_SESSION => ['default_session'],
cache_store::MODE_REQUEST => array('default_request'), store::MODE_REQUEST => ['default_request'],
))); ]));
$storesummaries = administration_helper::get_store_instance_summaries(); $storesummaries = administration_helper::get_store_instance_summaries();
$this->assertIsArray($storesummaries); $this->assertIsArray($storesummaries);
$this->assertArrayHasKey('summariesstore', $storesummaries); $this->assertArrayHasKey('summariesstore', $storesummaries);
$summary = $storesummaries['summariesstore']; $summary = $storesummaries['summariesstore'];
// Check the keys // Check the keys.
$this->assertArrayHasKey('name', $summary); $this->assertArrayHasKey('name', $summary);
$this->assertArrayHasKey('plugin', $summary); $this->assertArrayHasKey('plugin', $summary);
$this->assertArrayHasKey('default', $summary); $this->assertArrayHasKey('default', $summary);
@ -84,7 +82,7 @@ class administration_helper_test extends \advanced_testcase {
$this->assertArrayHasKey('mappings', $summary); $this->assertArrayHasKey('mappings', $summary);
$this->assertArrayHasKey('modes', $summary); $this->assertArrayHasKey('modes', $summary);
$this->assertArrayHasKey('supports', $summary); $this->assertArrayHasKey('supports', $summary);
// Check the important/known values // Check the important/known values.
$this->assertEquals('summariesstore', $summary['name']); $this->assertEquals('summariesstore', $summary['name']);
$this->assertEquals('file', $summary['plugin']); $this->assertEquals('file', $summary['plugin']);
$this->assertEquals(0, $summary['default']); $this->assertEquals(0, $summary['default']);
@ -92,8 +90,8 @@ class administration_helper_test extends \advanced_testcase {
$this->assertEquals(1, $summary['requirementsmet']); $this->assertEquals(1, $summary['requirementsmet']);
// Find the number of mappings to sessionstore. // Find the number of mappings to sessionstore.
$mappingcount = count(array_filter($config->get_definitions(), function($element) { $mappingcount = count(array_filter($config->get_definitions(), function ($element) {
return $element['mode'] === cache_store::MODE_APPLICATION; return $element['mode'] === store::MODE_APPLICATION;
})); }));
$this->assertEquals($mappingcount, $summary['mappings']); $this->assertEquals($mappingcount, $summary['mappings']);
@ -101,17 +99,17 @@ class administration_helper_test extends \advanced_testcase {
$this->assertIsArray($definitionsummaries); $this->assertIsArray($definitionsummaries);
$this->assertArrayHasKey('core/eventinvalidation', $definitionsummaries); $this->assertArrayHasKey('core/eventinvalidation', $definitionsummaries);
$summary = $definitionsummaries['core/eventinvalidation']; $summary = $definitionsummaries['core/eventinvalidation'];
// Check the keys // Check the keys.
$this->assertArrayHasKey('id', $summary); $this->assertArrayHasKey('id', $summary);
$this->assertArrayHasKey('name', $summary); $this->assertArrayHasKey('name', $summary);
$this->assertArrayHasKey('mode', $summary); $this->assertArrayHasKey('mode', $summary);
$this->assertArrayHasKey('component', $summary); $this->assertArrayHasKey('component', $summary);
$this->assertArrayHasKey('area', $summary); $this->assertArrayHasKey('area', $summary);
$this->assertArrayHasKey('mappings', $summary); $this->assertArrayHasKey('mappings', $summary);
// Check the important/known values // Check the important/known values.
$this->assertEquals('core/eventinvalidation', $summary['id']); $this->assertEquals('core/eventinvalidation', $summary['id']);
$this->assertInstanceOf('lang_string', $summary['name']); $this->assertInstanceOf('lang_string', $summary['name']);
$this->assertEquals(cache_store::MODE_APPLICATION, $summary['mode']); $this->assertEquals(store::MODE_APPLICATION, $summary['mode']);
$this->assertEquals('core', $summary['component']); $this->assertEquals('core', $summary['component']);
$this->assertEquals('eventinvalidation', $summary['area']); $this->assertEquals('eventinvalidation', $summary['area']);
$this->assertIsArray($summary['mappings']); $this->assertIsArray($summary['mappings']);
@ -121,7 +119,7 @@ class administration_helper_test extends \advanced_testcase {
$this->assertIsArray($pluginsummaries); $this->assertIsArray($pluginsummaries);
$this->assertArrayHasKey('file', $pluginsummaries); $this->assertArrayHasKey('file', $pluginsummaries);
$summary = $pluginsummaries['file']; $summary = $pluginsummaries['file'];
// Check the keys // Check the keys.
$this->assertArrayHasKey('name', $summary); $this->assertArrayHasKey('name', $summary);
$this->assertArrayHasKey('requirementsmet', $summary); $this->assertArrayHasKey('requirementsmet', $summary);
$this->assertArrayHasKey('instances', $summary); $this->assertArrayHasKey('instances', $summary);
@ -136,12 +134,12 @@ class administration_helper_test extends \advanced_testcase {
$mappings = administration_helper::get_default_mode_stores(); $mappings = administration_helper::get_default_mode_stores();
$this->assertIsArray($mappings); $this->assertIsArray($mappings);
$this->assertCount(3, $mappings); $this->assertCount(3, $mappings);
$this->assertArrayHasKey(cache_store::MODE_APPLICATION, $mappings); $this->assertArrayHasKey(store::MODE_APPLICATION, $mappings);
$this->assertIsArray($mappings[cache_store::MODE_APPLICATION]); $this->assertIsArray($mappings[store::MODE_APPLICATION]);
$this->assertContains('summariesstore', $mappings[cache_store::MODE_APPLICATION]); $this->assertContains('summariesstore', $mappings[store::MODE_APPLICATION]);
$potentials = administration_helper::get_definition_store_options('core', 'eventinvalidation'); $potentials = administration_helper::get_definition_store_options('core', 'eventinvalidation');
$this->assertIsArray($potentials); // Currently used, suitable, default $this->assertIsArray($potentials); // Currently used, suitable, default.
$this->assertCount(3, $potentials); $this->assertCount(3, $potentials);
$this->assertArrayHasKey('summariesstore', $potentials[0]); $this->assertArrayHasKey('summariesstore', $potentials[0]);
$this->assertArrayHasKey('summariesstore', $potentials[1]); $this->assertArrayHasKey('summariesstore', $potentials[1]);
@ -152,14 +150,14 @@ class administration_helper_test extends \advanced_testcase {
* Test instantiating an add store form. * Test instantiating an add store form.
*/ */
public function test_get_add_store_form(): void { public function test_get_add_store_form(): void {
$form = cache_factory::get_administration_display_helper()->get_add_store_form('file'); $form = factory::get_administration_display_helper()->get_add_store_form('file');
$this->assertInstanceOf('moodleform', $form); $this->assertInstanceOf('moodleform', $form);
try { try {
$form = cache_factory::get_administration_display_helper()->get_add_store_form('somethingstupid'); $form = factory::get_administration_display_helper()->get_add_store_form('somethingstupid');
$this->fail('You should not be able to create an add form for a store plugin that does not exist.'); $this->fail('You should not be able to create an add form for a store plugin that does not exist.');
} catch (\moodle_exception $e) { } catch (\moodle_exception $e) {
$this->assertInstanceOf('coding_exception', $e, 'Needs to be: ' .get_class($e)." ::: ".$e->getMessage()); $this->assertInstanceOf('coding_exception', $e, 'Needs to be: ' . get_class($e) . " ::: " . $e->getMessage());
} }
} }
@ -168,8 +166,8 @@ class administration_helper_test extends \advanced_testcase {
*/ */
public function test_get_edit_store_form(): void { public function test_get_edit_store_form(): void {
// Always instantiate a new core display helper here. // Always instantiate a new core display helper here.
$administrationhelper = new local\administration_display_helper; $administrationhelper = new local\administration_display_helper();
$config = cache_config_writer::instance(); $config = config_writer::instance();
$this->assertTrue($config->add_store_instance('test_get_edit_store_form', 'file')); $this->assertTrue($config->add_store_instance('test_get_edit_store_form', 'file'));
$form = $administrationhelper->get_edit_store_form('file', 'test_get_edit_store_form'); $form = $administrationhelper->get_edit_store_form('file', 'test_get_edit_store_form');
@ -197,41 +195,41 @@ class administration_helper_test extends \advanced_testcase {
$this->resetAfterTest(); $this->resetAfterTest();
set_debugging(DEBUG_ALL); set_debugging(DEBUG_ALL);
// First with simplekeys // First with simplekeys.
$instance = cache_config_testing::instance(true); $instance = cache_config_testing::instance(true);
$instance->phpunit_add_definition('phpunit/hashtest', array( $instance->phpunit_add_definition('phpunit/hashtest', [
'mode' => cache_store::MODE_APPLICATION, 'mode' => store::MODE_APPLICATION,
'component' => 'phpunit', 'component' => 'phpunit',
'area' => 'hashtest', 'area' => 'hashtest',
'simplekeys' => true 'simplekeys' => true,
)); ]);
$factory = cache_factory::instance(); $factory = factory::instance();
$definition = $factory->create_definition('phpunit', 'hashtest'); $definition = $factory->create_definition('phpunit', 'hashtest');
$result = cache_helper::hash_key('test', $definition); $result = helper::hash_key('test', $definition);
$this->assertEquals('test-'.$definition->generate_single_key_prefix(), $result); $this->assertEquals('test-' . $definition->generate_single_key_prefix(), $result);
try { try {
cache_helper::hash_key('test/test', $definition); helper::hash_key('test/test', $definition);
$this->fail('Invalid key was allowed, you should see this.'); $this->fail('Invalid key was allowed, you should see this.');
} catch (\coding_exception $e) { } catch (\coding_exception $e) {
$this->assertEquals('test/test', $e->debuginfo); $this->assertEquals('test/test', $e->debuginfo);
} }
// Second without simple keys // Second without simple keys.
$instance->phpunit_add_definition('phpunit/hashtest2', array( $instance->phpunit_add_definition('phpunit/hashtest2', [
'mode' => cache_store::MODE_APPLICATION, 'mode' => store::MODE_APPLICATION,
'component' => 'phpunit', 'component' => 'phpunit',
'area' => 'hashtest2', 'area' => 'hashtest2',
'simplekeys' => false 'simplekeys' => false,
)); ]);
$definition = $factory->create_definition('phpunit', 'hashtest2'); $definition = $factory->create_definition('phpunit', 'hashtest2');
$result = cache_helper::hash_key('test', $definition); $result = helper::hash_key('test', $definition);
$this->assertEquals(sha1($definition->generate_single_key_prefix().'-test'), $result); $this->assertEquals(sha1($definition->generate_single_key_prefix() . '-test'), $result);
$result = cache_helper::hash_key('test/test', $definition); $result = helper::hash_key('test/test', $definition);
$this->assertEquals(sha1($definition->generate_single_key_prefix().'-test/test'), $result); $this->assertEquals(sha1($definition->generate_single_key_prefix() . '-test/test'), $result);
} }
/** /**
@ -241,17 +239,17 @@ class administration_helper_test extends \advanced_testcase {
// Create a test cache definition and put items in it. // Create a test cache definition and put items in it.
$instance = cache_config_testing::instance(true); $instance = cache_config_testing::instance(true);
$instance->phpunit_add_definition('phpunit/test', [ $instance->phpunit_add_definition('phpunit/test', [
'mode' => cache_store::MODE_APPLICATION, 'mode' => store::MODE_APPLICATION,
'component' => 'phpunit', 'component' => 'phpunit',
'area' => 'test', 'area' => 'test',
'simplekeys' => true 'simplekeys' => true,
]); ]);
$cache = \cache::make('phpunit', 'test'); $cache = \cache::make('phpunit', 'test');
for ($i = 0; $i < 100; $i++) { for ($i = 0; $i < 100; $i++) {
$cache->set('key' . $i, str_repeat('x', $i)); $cache->set('key' . $i, str_repeat('x', $i));
} }
$factory = cache_factory::instance(); $factory = factory::instance();
$adminhelper = $factory->get_administration_display_helper(); $adminhelper = $factory->get_administration_display_helper();
$usage = $adminhelper->get_usage(10)['phpunit/test']; $usage = $adminhelper->get_usage(10)['phpunit/test'];

View file

@ -25,8 +25,7 @@ namespace core_cache;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_cache\allow_temporary_caches * @covers \core_cache\allow_temporary_caches
*/ */
class allow_temporary_caches_test extends \advanced_testcase { final class allow_temporary_caches_test extends \advanced_testcase {
/** /**
* Tests whether temporary caches are allowed. * Tests whether temporary caches are allowed.
*/ */
@ -92,8 +91,8 @@ class allow_temporary_caches_test extends \advanced_testcase {
get_fast_modinfo($course); get_fast_modinfo($course);
} finally { } finally {
// You have to do this after phpunit_disable or it breaks later tests. // You have to do this after phpunit_disable or it breaks later tests.
\cache_factory::reset(); factory::reset();
\cache_factory::instance(true); factory::instance(true);
} }
} }
} }

View file

@ -19,23 +19,22 @@ namespace core_cache;
/** /**
* PHPunit tests for the cache_helper class. * PHPunit tests for the cache_helper class.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk> * @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @coversDefaultClass \cache_helper * @covers \core_cache\helper
*/ */
class cache_helper_test extends \advanced_testcase { final class cache_helper_test extends \advanced_testcase {
/** /**
* Test the result_found method. * Test the result_found method.
* *
* @param mixed $value * @param mixed $value
* @param bool $expected * @param bool $expected
* @dataProvider result_found_provider * @dataProvider result_found_provider
* @covers ::result_found
*/ */
public function test_result_found($value, bool $expected): void { public function test_result_found($value, bool $expected): void {
$this->assertEquals($expected, \cache_helper::result_found($value)); $this->assertEquals($expected, helper::result_found($value));
} }
/** /**
@ -43,7 +42,7 @@ class cache_helper_test extends \advanced_testcase {
* *
* @return array * @return array
*/ */
public function result_found_provider(): array { public static function result_found_provider(): array {
return [ return [
// Only false values are considered as not found. // Only false values are considered as not found.
[false, false], [false, false],

File diff suppressed because it is too large Load diff

View file

@ -17,16 +17,6 @@
namespace core_cache; namespace core_cache;
use cache_config_testing; use cache_config_testing;
use cache_config_writer;
use cache_factory;
use cache_store;
defined('MOODLE_INTERNAL') || die();
// Include the necessary evils.
global $CFG;
require_once($CFG->dirroot.'/cache/locallib.php');
require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php');
/** /**
* PHPunit tests for the cache API and in particular the cache config writer. * PHPunit tests for the cache API and in particular the cache config writer.
@ -35,15 +25,25 @@ require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php');
* @category test * @category test
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_cache\config_writer
*/ */
class config_writer_test extends \advanced_testcase { final class config_writer_test extends \advanced_testcase {
/**
* Load required libraries and fixtures.
*/
public static function setUpBeforeClass(): void {
global $CFG;
require_once($CFG->dirroot . '/cache/tests/fixtures/lib.php');
parent::setUpBeforeClass();
}
/** /**
* Set things back to the default before each test. * Set things back to the default before each test.
*/ */
public function setUp(): void { public function setUp(): void {
parent::setUp(); parent::setUp();
cache_factory::reset(); factory::reset();
cache_config_testing::create_default_configuration(); cache_config_testing::create_default_configuration();
} }
@ -52,22 +52,22 @@ class config_writer_test extends \advanced_testcase {
*/ */
public static function tearDownAfterClass(): void { public static function tearDownAfterClass(): void {
parent::tearDownAfterClass(); parent::tearDownAfterClass();
cache_factory::reset(); factory::reset();
} }
/** /**
* Test getting an instance. Pretty basic. * Test getting an instance. Pretty basic.
*/ */
public function test_instance(): void { public function test_instance(): void {
$config = cache_config_writer::instance(); $config = config_writer::instance();
$this->assertInstanceOf('cache_config_writer', $config); $this->assertInstanceOf(config_writer::class, $config);
} }
/** /**
* Test the default configuration. * Test the default configuration.
*/ */
public function test_default_configuration(): void { public function test_default_configuration(): void {
$config = cache_config_writer::instance(); $config = config_writer::instance();
// First check stores. // First check stores.
$stores = $config->get_all_stores(); $stores = $config->get_all_stores();
@ -82,13 +82,13 @@ class config_writer_test extends \advanced_testcase {
$this->assertArrayHasKey('default', $store); $this->assertArrayHasKey('default', $store);
// Check the mode, we need at least one default store of each mode. // Check the mode, we need at least one default store of each mode.
if (!empty($store['default'])) { if (!empty($store['default'])) {
if ($store['modes'] & cache_store::MODE_APPLICATION) { if ($store['modes'] & store::MODE_APPLICATION) {
$hasapplication = true; $hasapplication = true;
} }
if ($store['modes'] & cache_store::MODE_SESSION) { if ($store['modes'] & store::MODE_SESSION) {
$hassession = true; $hassession = true;
} }
if ($store['modes'] & cache_store::MODE_REQUEST) { if ($store['modes'] & store::MODE_REQUEST) {
$hasrequest = true; $hasrequest = true;
} }
} }
@ -111,7 +111,7 @@ class config_writer_test extends \advanced_testcase {
} }
$this->assertTrue($eventinvalidation, 'Missing the event invalidation definition.'); $this->assertTrue($eventinvalidation, 'Missing the event invalidation definition.');
// Next mode mappings // Next mode mappings.
$mappings = $config->get_mode_mappings(); $mappings = $config->get_mode_mappings();
$hasapplication = false; $hasapplication = false;
$hassession = false; $hassession = false;
@ -121,13 +121,13 @@ class config_writer_test extends \advanced_testcase {
$this->assertArrayHasKey('mode', $mode); $this->assertArrayHasKey('mode', $mode);
$this->assertArrayHasKey('store', $mode); $this->assertArrayHasKey('store', $mode);
if ($mode['mode'] === cache_store::MODE_APPLICATION) { if ($mode['mode'] === store::MODE_APPLICATION) {
$hasapplication = true; $hasapplication = true;
} }
if ($mode['mode'] === cache_store::MODE_SESSION) { if ($mode['mode'] === store::MODE_SESSION) {
$hassession = true; $hassession = true;
} }
if ($mode['mode'] === cache_store::MODE_REQUEST) { if ($mode['mode'] === store::MODE_REQUEST) {
$hasrequest = true; $hasrequest = true;
} }
} }
@ -135,7 +135,7 @@ class config_writer_test extends \advanced_testcase {
$this->assertTrue($hassession, 'There is no mapping for the session mode.'); $this->assertTrue($hassession, 'There is no mapping for the session mode.');
$this->assertTrue($hasrequest, 'There is no mapping for the request mode.'); $this->assertTrue($hasrequest, 'There is no mapping for the request mode.');
// Finally check config locks // Finally check config locks.
$locks = $config->get_locks(); $locks = $config->get_locks();
foreach ($locks as $lock) { foreach ($locks as $lock) {
$this->assertArrayHasKey('name', $lock); $this->assertArrayHasKey('name', $lock);
@ -150,14 +150,14 @@ class config_writer_test extends \advanced_testcase {
* Test updating the definitions. * Test updating the definitions.
*/ */
public function test_update_definitions(): void { public function test_update_definitions(): void {
$config = cache_config_writer::instance(); $config = config_writer::instance();
// Remove the definition. // Remove the definition.
$config->phpunit_remove_definition('core/string'); $config->phpunit_remove_definition('core/string');
$definitions = $config->get_definitions(); $definitions = $config->get_definitions();
// Check it is gone. // Check it is gone.
$this->assertFalse(array_key_exists('core/string', $definitions)); $this->assertFalse(array_key_exists('core/string', $definitions));
// Update definitions. This should re-add it. // Update definitions. This should re-add it.
cache_config_writer::update_definitions(); config_writer::update_definitions();
$definitions = $config->get_definitions(); $definitions = $config->get_definitions();
// Check it is back again. // Check it is back again.
$this->assertTrue(array_key_exists('core/string', $definitions)); $this->assertTrue(array_key_exists('core/string', $definitions));
@ -167,18 +167,18 @@ class config_writer_test extends \advanced_testcase {
* Test adding/editing/deleting store instances. * Test adding/editing/deleting store instances.
*/ */
public function test_add_edit_delete_plugin_instance(): void { public function test_add_edit_delete_plugin_instance(): void {
$config = cache_config_writer::instance(); $config = config_writer::instance();
$this->assertArrayNotHasKey('addplugintest', $config->get_all_stores()); $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
$this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores()); $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
// Add a default file instance. // Add a default file instance.
$config->add_store_instance('addplugintest', 'file'); $config->add_store_instance('addplugintest', 'file');
cache_factory::reset(); factory::reset();
$config = cache_config_writer::instance(); $config = config_writer::instance();
$this->assertArrayHasKey('addplugintest', $config->get_all_stores()); $this->assertArrayHasKey('addplugintest', $config->get_all_stores());
// Add a store with a lock described. // Add a store with a lock described.
$config->add_store_instance('addplugintestwlock', 'file', array('lock' => 'default_file_lock')); $config->add_store_instance('addplugintestwlock', 'file', ['lock' => 'default_file_lock']);
$this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores()); $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores());
$config->delete_store_instance('addplugintest'); $config->delete_store_instance('addplugintest');
@ -190,7 +190,7 @@ class config_writer_test extends \advanced_testcase {
$this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores()); $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
// Add a default file instance. // Add a default file instance.
$config->add_store_instance('storeconfigtest', 'file', array('test' => 'a', 'one' => 'two')); $config->add_store_instance('storeconfigtest', 'file', ['test' => 'a', 'one' => 'two']);
$stores = $config->get_all_stores(); $stores = $config->get_all_stores();
$this->assertArrayHasKey('storeconfigtest', $stores); $this->assertArrayHasKey('storeconfigtest', $stores);
$this->assertArrayHasKey('configuration', $stores['storeconfigtest']); $this->assertArrayHasKey('configuration', $stores['storeconfigtest']);
@ -199,7 +199,7 @@ class config_writer_test extends \advanced_testcase {
$this->assertEquals('a', $stores['storeconfigtest']['configuration']['test']); $this->assertEquals('a', $stores['storeconfigtest']['configuration']['test']);
$this->assertEquals('two', $stores['storeconfigtest']['configuration']['one']); $this->assertEquals('two', $stores['storeconfigtest']['configuration']['one']);
$config->edit_store_instance('storeconfigtest', 'file', array('test' => 'b', 'one' => 'three')); $config->edit_store_instance('storeconfigtest', 'file', ['test' => 'b', 'one' => 'three']);
$stores = $config->get_all_stores(); $stores = $config->get_all_stores();
$this->assertArrayHasKey('storeconfigtest', $stores); $this->assertArrayHasKey('storeconfigtest', $stores);
$this->assertArrayHasKey('configuration', $stores['storeconfigtest']); $this->assertArrayHasKey('configuration', $stores['storeconfigtest']);
@ -214,22 +214,22 @@ class config_writer_test extends \advanced_testcase {
$config->delete_store_instance('default_application'); $config->delete_store_instance('default_application');
$this->fail('Default store deleted. This should not be possible!'); $this->fail('Default store deleted. This should not be possible!');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->assertInstanceOf('cache_exception', $e); $this->assertInstanceOf(\core_cache\exception\cache_exception::class, $e);
} }
try { try {
$config->delete_store_instance('some_crazy_store'); $config->delete_store_instance('some_crazy_store');
$this->fail('You should not be able to delete a store that does not exist.'); $this->fail('You should not be able to delete a store that does not exist.');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->assertInstanceOf('cache_exception', $e); $this->assertInstanceOf(\core_cache\exception\cache_exception::class, $e);
} }
try { try {
// Try with a plugin that does not exist. // Try with a plugin that does not exist.
$config->add_store_instance('storeconfigtest', 'shallowfail', array('test' => 'a', 'one' => 'two')); $config->add_store_instance('storeconfigtest', 'shallowfail', ['test' => 'a', 'one' => 'two']);
$this->fail('You should not be able to add an instance of a store that does not exist.'); $this->fail('You should not be able to add an instance of a store that does not exist.');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->assertInstanceOf('cache_exception', $e); $this->assertInstanceOf(\core_cache\exception\cache_exception::class, $e);
} }
} }
@ -237,17 +237,17 @@ class config_writer_test extends \advanced_testcase {
* Test setting some mode mappings. * Test setting some mode mappings.
*/ */
public function test_set_mode_mappings(): void { public function test_set_mode_mappings(): void {
$config = cache_config_writer::instance(); $config = config_writer::instance();
$this->assertTrue($config->add_store_instance('setmodetest', 'file')); $this->assertTrue($config->add_store_instance('setmodetest', 'file'));
$this->assertTrue($config->set_mode_mappings(array( $this->assertTrue($config->set_mode_mappings([
cache_store::MODE_APPLICATION => array('setmodetest', 'default_application'), store::MODE_APPLICATION => ['setmodetest', 'default_application'],
cache_store::MODE_SESSION => array('default_session'), store::MODE_SESSION => ['default_session'],
cache_store::MODE_REQUEST => array('default_request'), store::MODE_REQUEST => ['default_request'],
))); ]));
$mappings = $config->get_mode_mappings(); $mappings = $config->get_mode_mappings();
$setmodetestfound = false; $setmodetestfound = false;
foreach ($mappings as $mapping) { foreach ($mappings as $mapping) {
if ($mapping['store'] == 'setmodetest' && $mapping['mode'] == cache_store::MODE_APPLICATION) { if ($mapping['store'] == 'setmodetest' && $mapping['mode'] == store::MODE_APPLICATION) {
$setmodetestfound = true; $setmodetestfound = true;
} }
} }
@ -258,30 +258,30 @@ class config_writer_test extends \advanced_testcase {
* Test setting some definition mappings. * Test setting some definition mappings.
*/ */
public function test_set_definition_mappings(): void { public function test_set_definition_mappings(): void {
$config = cache_config_testing::instance(true); $config = cache_config_testing::instance();
$config->phpunit_add_definition('phpunit/testdefinition', array( $config->phpunit_add_definition('phpunit/testdefinition', [
'mode' => cache_store::MODE_APPLICATION, 'mode' => store::MODE_APPLICATION,
'component' => 'phpunit', 'component' => 'phpunit',
'area' => 'testdefinition' 'area' => 'testdefinition',
)); ]);
$config = cache_config_writer::instance(); $config = config_writer::instance();
$this->assertTrue($config->add_store_instance('setdefinitiontest', 'file')); $this->assertTrue($config->add_store_instance('setdefinitiontest', 'file'));
$this->assertIsArray($config->get_definition_by_id('phpunit/testdefinition')); $this->assertIsArray($config->get_definition_by_id('phpunit/testdefinition'));
$config->set_definition_mappings('phpunit/testdefinition', array('setdefinitiontest', 'default_application')); $config->set_definition_mappings('phpunit/testdefinition', ['setdefinitiontest', 'default_application']);
try { try {
$config->set_definition_mappings('phpunit/testdefinition', array('something that does not exist')); $config->set_definition_mappings('phpunit/testdefinition', ['something that does not exist']);
$this->fail('You should not be able to set a mapping for a store that does not exist.'); $this->fail('You should not be able to set a mapping for a store that does not exist.');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->assertInstanceOf('coding_exception', $e); $this->assertInstanceOf(\core\exception\coding_exception::class, $e);
} }
try { try {
$config->set_definition_mappings('something/crazy', array('setdefinitiontest')); $config->set_definition_mappings('something/crazy', ['setdefinitiontest']);
$this->fail('You should not be able to set a mapping for a definition that does not exist.'); $this->fail('You should not be able to set a mapping for a definition that does not exist.');
} catch (\Exception $e) { } catch (\Exception $e) {
$this->assertInstanceOf('coding_exception', $e); $this->assertInstanceOf(\core\exception\coding_exception::class, $e);
} }
} }
} }

View file

@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
use core_cache\versionable_data_source_interface;
/** /**
* A dummy datasource which supports versioning. * A dummy datasource which supports versioning.
* *
@ -21,8 +23,9 @@
* @copyright 2021 The Open University * @copyright 2021 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_phpunit_dummy_datasource_versionable extends cache_phpunit_dummy_datasource class cache_phpunit_dummy_datasource_versionable extends cache_phpunit_dummy_datasource implements
implements cache_data_source_versionable { versionable_data_source_interface
{
/** @var array Data in cache */ /** @var array Data in cache */
protected $data = []; protected $data = [];
@ -35,8 +38,7 @@ class cache_phpunit_dummy_datasource_versionable extends cache_phpunit_dummy_dat
* @param cache_definition $definition * @param cache_definition $definition
* @return cache_phpunit_dummy_datasource New object * @return cache_phpunit_dummy_datasource New object
*/ */
public static function get_instance_for_cache(cache_definition $definition): public static function get_instance_for_cache(cache_definition $definition): cache_phpunit_dummy_datasource_versionable {
cache_phpunit_dummy_datasource_versionable {
self::$lastinstance = new cache_phpunit_dummy_datasource_versionable(); self::$lastinstance = new cache_phpunit_dummy_datasource_versionable();
return self::$lastinstance; return self::$lastinstance;
} }
@ -81,4 +83,3 @@ class cache_phpunit_dummy_datasource_versionable extends cache_phpunit_dummy_dat
return $value->data; return $value->data;
} }
} }

View file

@ -30,8 +30,7 @@ class cachestore_file_with_ttl_wrappers extends cachestore_file {
* @param array $configuration Configuration * @param array $configuration Configuration
* @return int Supported features * @return int Supported features
*/ */
public static function get_supported_features(array $configuration = array()) { public static function get_supported_features(array $configuration = []) {
return parent::get_supported_features($configuration) - self::SUPPORTS_NATIVE_TTL; return parent::get_supported_features($configuration) - self::SUPPORTS_NATIVE_TTL;
} }
} }

View file

@ -20,7 +20,7 @@
* This file is part of Moodle's cache API, affectionately called MUC. * This file is part of Moodle's cache API, affectionately called MUC.
* It contains the components that are requried in order to use caching. * It contains the components that are requried in order to use caching.
* *
* @package core * @package core_cache
* @category cache * @category cache
* @copyright 2012 Sam Hemelryk * @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -28,6 +28,8 @@
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
use core_cache\store;
/** /**
* Override the default cache configuration for our own maniacal purposes. * Override the default cache configuration for our own maniacal purposes.
* *
@ -39,7 +41,6 @@ defined('MOODLE_INTERNAL') || die();
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_config_testing extends cache_config_writer { class cache_config_testing extends cache_config_writer {
/** /**
* Creates the default configuration and saves it. * Creates the default configuration and saves it.
* *
@ -55,7 +56,7 @@ class cache_config_testing extends cache_config_writer {
// HACK ALERT. // HACK ALERT.
// We probably need to come up with a better way to create the default stores, or at least ensure 100% that the // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the
// default store plugins are protected from deletion. // default store plugins are protected from deletion.
$writer = new self; $writer = new self();
$writer->configstores = self::get_default_stores(); $writer->configstores = self::get_default_stores();
$writer->configdefinitions = self::locate_definitions(); $writer->configdefinitions = self::locate_definitions();
$defaultapplication = 'default_application'; $defaultapplication = 'default_application';
@ -63,50 +64,50 @@ class cache_config_testing extends cache_config_writer {
$appdefine = defined('TEST_CACHE_USING_APPLICATION_STORE') ? TEST_CACHE_USING_APPLICATION_STORE : false; $appdefine = defined('TEST_CACHE_USING_APPLICATION_STORE') ? TEST_CACHE_USING_APPLICATION_STORE : false;
if ($appdefine !== false && preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/', $appdefine)) { if ($appdefine !== false && preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/', $appdefine)) {
$expectedstore = $appdefine; $expectedstore = $appdefine;
$file = $CFG->dirroot.'/cache/stores/'.$appdefine.'/lib.php'; $file = $CFG->dirroot . '/cache/stores/' . $appdefine . '/lib.php';
$class = 'cachestore_'.$appdefine; $class = 'cachestore_' . $appdefine;
if (file_exists($file)) { if (file_exists($file)) {
require_once($file); require_once($file);
} }
if (class_exists($class) && $class::ready_to_be_used_for_testing()) { if (class_exists($class) && $class::ready_to_be_used_for_testing()) {
/* @var cache_store $class */ /* @var store $class */
$writer->configstores['test_application'] = array( $writer->configstores['test_application'] = [
'name' => 'test_application', 'name' => 'test_application',
'plugin' => $expectedstore, 'plugin' => $expectedstore,
'modes' => $class::get_supported_modes(), 'modes' => $class::get_supported_modes(),
'features' => $class::get_supported_features(), 'features' => $class::get_supported_features(),
'configuration' => $class::unit_test_configuration() 'configuration' => $class::unit_test_configuration(),
); ];
$defaultapplication = 'test_application'; $defaultapplication = 'test_application';
} }
} }
$writer->configmodemappings = array( $writer->configmodemappings = [
array( [
'mode' => cache_store::MODE_APPLICATION, 'mode' => store::MODE_APPLICATION,
'store' => $defaultapplication, 'store' => $defaultapplication,
'sort' => -1 'sort' => -1,
), ],
array( [
'mode' => cache_store::MODE_SESSION, 'mode' => store::MODE_SESSION,
'store' => 'default_session', 'store' => 'default_session',
'sort' => -1 'sort' => -1,
), ],
array( [
'mode' => cache_store::MODE_REQUEST, 'mode' => store::MODE_REQUEST,
'store' => 'default_request', 'store' => 'default_request',
'sort' => -1 'sort' => -1,
) ],
); ];
$writer->configlocks = array( $writer->configlocks = [
'default_file_lock' => array( 'default_file_lock' => [
'name' => 'cachelock_file_default', 'name' => 'cachelock_file_default',
'type' => 'cachelock_file', 'type' => 'cachelock_file',
'dir' => 'filelocks', 'dir' => 'filelocks',
'default' => true 'default' => true,
) ],
); ];
$factory = cache_factory::instance(); $factory = cache_factory::instance();
// We expect the cache to be initialising presently. If its not then something has gone wrong and likely // We expect the cache to be initialising presently. If its not then something has gone wrong and likely
@ -133,10 +134,9 @@ class cache_config_testing extends cache_config_writer {
protected static function get_config_file_path() { protected static function get_config_file_path() {
global $CFG; global $CFG;
// We always use this path. // We always use this path.
$configpath = $CFG->dataroot.'/muc/config.php'; $configpath = $CFG->dataroot . '/muc/config.php';
if (!empty($CFG->altcacheconfigpath)) { if (!empty($CFG->altcacheconfigpath)) {
// No need to check we are within a test here, this is the cache config class that gets used // No need to check we are within a test here, this is the cache config class that gets used
// only when one of those is true. // only when one of those is true.
if (!defined('TEST_CACHE_USING_ALT_CACHE_CONFIG_PATH') || !TEST_CACHE_USING_ALT_CACHE_CONFIG_PATH) { if (!defined('TEST_CACHE_USING_ALT_CACHE_CONFIG_PATH') || !TEST_CACHE_USING_ALT_CACHE_CONFIG_PATH) {
@ -147,7 +147,7 @@ class cache_config_testing extends cache_config_writer {
$path = $CFG->altcacheconfigpath; $path = $CFG->altcacheconfigpath;
if (is_dir($path) && is_writable($path)) { if (is_dir($path) && is_writable($path)) {
// Its a writable directory, thats fine. Convert it to a file. // Its a writable directory, thats fine. Convert it to a file.
$path = $CFG->altcacheconfigpath.'/cacheconfig.php'; $path = $CFG->altcacheconfigpath . '/cacheconfig.php';
} }
if (is_readable($path)) { if (is_readable($path)) {
$directory = dirname($configpath); $directory = dirname($configpath);
@ -178,13 +178,13 @@ class cache_config_testing extends cache_config_writer {
public function phpunit_add_definition($area, array $properties, $addmapping = true) { public function phpunit_add_definition($area, array $properties, $addmapping = true) {
if (!array_key_exists('overrideclass', $properties)) { if (!array_key_exists('overrideclass', $properties)) {
switch ($properties['mode']) { switch ($properties['mode']) {
case cache_store::MODE_APPLICATION: case store::MODE_APPLICATION:
$properties['overrideclass'] = 'cache_phpunit_application'; $properties['overrideclass'] = 'cache_phpunit_application';
break; break;
case cache_store::MODE_SESSION: case store::MODE_SESSION:
$properties['overrideclass'] = 'cache_phpunit_session'; $properties['overrideclass'] = 'cache_phpunit_session';
break; break;
case cache_store::MODE_REQUEST: case store::MODE_REQUEST:
$properties['overrideclass'] = 'cache_phpunit_request'; $properties['overrideclass'] = 'cache_phpunit_request';
break; break;
} }
@ -192,13 +192,13 @@ class cache_config_testing extends cache_config_writer {
$this->configdefinitions[$area] = $properties; $this->configdefinitions[$area] = $properties;
if ($addmapping) { if ($addmapping) {
switch ($properties['mode']) { switch ($properties['mode']) {
case cache_store::MODE_APPLICATION: case store::MODE_APPLICATION:
$this->phpunit_add_definition_mapping($area, 'default_application', 0); $this->phpunit_add_definition_mapping($area, 'default_application', 0);
break; break;
case cache_store::MODE_SESSION: case store::MODE_SESSION:
$this->phpunit_add_definition_mapping($area, 'default_session', 0); $this->phpunit_add_definition_mapping($area, 'default_session', 0);
break; break;
case cache_store::MODE_REQUEST: case store::MODE_REQUEST:
$this->phpunit_add_definition_mapping($area, 'default_request', 0); $this->phpunit_add_definition_mapping($area, 'default_request', 0);
break; break;
} }
@ -217,7 +217,7 @@ class cache_config_testing extends cache_config_writer {
* Removes the configured stores so that there are none available. * Removes the configured stores so that there are none available.
*/ */
public function phpunit_remove_stores() { public function phpunit_remove_stores() {
$this->configstores = array(); $this->configstores = [];
} }
/** /**
@ -232,19 +232,19 @@ class cache_config_testing extends cache_config_writer {
if (!$nativettl) { if (!$nativettl) {
require_once(__DIR__ . '/cachestore_file_with_ttl_wrappers.php'); require_once(__DIR__ . '/cachestore_file_with_ttl_wrappers.php');
} }
$this->configstores[$name] = array( $this->configstores[$name] = [
'name' => $name, 'name' => $name,
'plugin' => 'file', 'plugin' => 'file',
'configuration' => array( 'configuration' => [
'path' => '' 'path' => '',
), ],
'features' => 6, 'features' => 6,
'modes' => 3, 'modes' => 3,
'mappingsonly' => false, 'mappingsonly' => false,
'class' => $nativettl ? 'cachestore_file' : 'cachestore_file_with_ttl_wrappers', 'class' => $nativettl ? 'cachestore_file' : 'cachestore_file_with_ttl_wrappers',
'default' => false, 'default' => false,
'lock' => 'cachelock_file_default' 'lock' => 'cachelock_file_default',
); ];
} }
/** /**
@ -265,16 +265,16 @@ class cache_config_testing extends cache_config_writer {
* @param string $name * @param string $name
*/ */
public function phpunit_add_session_store($name) { public function phpunit_add_session_store($name) {
$this->configstores[$name] = array( $this->configstores[$name] = [
'name' => $name, 'name' => $name,
'plugin' => 'session', 'plugin' => 'session',
'configuration' => array(), 'configuration' => [],
'features' => 14, 'features' => 14,
'modes' => 2, 'modes' => 2,
'default' => true, 'default' => true,
'class' => 'cachestore_session', 'class' => 'cachestore_session',
'lock' => 'cachelock_file_default', 'lock' => 'cachelock_file_default',
); ];
} }
/** /**
@ -288,11 +288,11 @@ class cache_config_testing extends cache_config_writer {
* @param int $sort * @param int $sort
*/ */
public function phpunit_add_definition_mapping($definition, $store, $sort) { public function phpunit_add_definition_mapping($definition, $store, $sort) {
$this->configdefinitionmappings[] = array( $this->configdefinitionmappings[] = [
'store' => $store, 'store' => $store,
'definition' => $definition, 'definition' => $definition,
'sort' => (int)$sort 'sort' => (int)$sort,
); ];
} }
/** /**
@ -302,7 +302,7 @@ class cache_config_testing extends cache_config_writer {
*/ */
public function get_site_identifier() { public function get_site_identifier() {
global $CFG; global $CFG;
return $CFG->wwwroot.'phpunit'; return $CFG->wwwroot . 'phpunit';
} }
/** /**
@ -361,7 +361,7 @@ class cache_phpunit_dummy_object extends stdClass implements cacheable_object {
* @return array * @return array
*/ */
public function prepare_to_cache() { public function prepare_to_cache() {
return array($this->property1.'_ptc', $this->property2.'_ptc', $this->propertytime); return [$this->property1 . '_ptc', $this->property2 . '_ptc', $this->propertytime];
} }
/** /**
* Returns this object from the cache * Returns this object from the cache
@ -375,9 +375,8 @@ class cache_phpunit_dummy_object extends stdClass implements cacheable_object {
do { do {
$time = microtime(true); $time = microtime(true);
} while ($time == $data[2]); } while ($time == $data[2]);
} }
return new cache_phpunit_dummy_object(array_shift($data).'_wfc', array_shift($data).'_wfc', $time); return new cache_phpunit_dummy_object(array_shift($data) . '_wfc', array_shift($data) . '_wfc', $time);
} }
} }
@ -405,7 +404,7 @@ class cache_phpunit_dummy_datasource implements cache_data_source {
* @return string * @return string
*/ */
public function load_for_cache($key) { public function load_for_cache($key) {
return $key.' has no value really.'; return $key . ' has no value really.';
} }
/** /**
@ -415,9 +414,9 @@ class cache_phpunit_dummy_datasource implements cache_data_source {
* @return array * @return array
*/ */
public function load_many_for_cache(array $keys) { public function load_many_for_cache(array $keys) {
$return = array(); $return = [];
foreach ($keys as $key) { foreach ($keys as $key) {
$return[$key] = $key.' has no value really.'; $return[$key] = $key . ' has no value really.';
} }
return $return; return $return;
} }
@ -432,6 +431,10 @@ class cache_phpunit_dummy_datasource implements cache_data_source {
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_phpunit_application extends cache_application { class cache_phpunit_application extends cache_application {
#[\Override]
public function get_store() {
return parent::get_store();
}
/** /**
* Returns the class of the store immediately associated with this cache. * Returns the class of the store immediately associated with this cache.
@ -480,10 +483,14 @@ class cache_phpunit_application extends cache_application {
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_phpunit_session extends cache_session { class cache_phpunit_session extends cache_session {
/** @var Static member used for emulating the behaviour of session_id() during the tests. */ /** @var Static member used for emulating the behaviour of session_id() during the tests. */
protected static $sessionidmockup = 'phpunitmockupsessionid'; protected static $sessionidmockup = 'phpunitmockupsessionid';
#[\Override]
public function get_store() {
return parent::get_store();
}
/** /**
* Returns the class of the store immediately associated with this cache. * Returns the class of the store immediately associated with this cache.
* @return string * @return string
@ -535,6 +542,10 @@ class cache_phpunit_session extends cache_session {
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
class cache_phpunit_request extends cache_request { class cache_phpunit_request extends cache_request {
#[\Override]
public function get_store() {
return parent::get_store();
}
/** /**
* Returns the class of the store immediately associated with this cache. * Returns the class of the store immediately associated with this cache.

View file

@ -14,17 +14,6 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Cache store test fixtures.
*
* @package core
* @category cache
* @copyright 2013 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/** /**
* An abstract class to make writing unit tests for cache stores very easy. * An abstract class to make writing unit tests for cache stores very easy.
* *
@ -34,7 +23,6 @@ defined('MOODLE_INTERNAL') || die();
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
abstract class cachestore_tests extends advanced_testcase { abstract class cachestore_tests extends advanced_testcase {
/** /**
* Returns the class name for the store. * Returns the class name for the store.
* *
@ -49,7 +37,7 @@ abstract class cachestore_tests extends advanced_testcase {
public function setUp(): void { public function setUp(): void {
$class = $this->get_class_name(); $class = $this->get_class_name();
if (!class_exists($class) || !$class::are_requirements_met()) { if (!class_exists($class) || !$class::are_requirements_met()) {
$this->markTestSkipped('Could not test '.$class.'. Requirements are not met.'); $this->markTestSkipped('Could not test ' . $class . '. Requirements are not met.');
} }
parent::setUp(); parent::setUp();
} }
@ -62,10 +50,10 @@ abstract class cachestore_tests extends advanced_testcase {
$modes = $class::get_supported_modes(); $modes = $class::get_supported_modes();
if ($modes & cache_store::MODE_APPLICATION) { if ($modes & cache_store::MODE_APPLICATION) {
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, $class, 'phpunit_test'); $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, $class, 'phpunit_test');
$instance = new $class($class.'_test', $class::unit_test_configuration()); $instance = new $class($class . '_test', $class::unit_test_configuration());
if (!$instance->is_ready()) { if (!$instance->is_ready()) {
$this->markTestSkipped('Could not test '.$class.'. No test instance configured for application caches.'); $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for application caches.');
} else { } else {
$instance->initialise($definition); $instance->initialise($definition);
$this->run_tests($instance); $this->run_tests($instance);
@ -73,10 +61,10 @@ abstract class cachestore_tests extends advanced_testcase {
} }
if ($modes & cache_store::MODE_SESSION) { if ($modes & cache_store::MODE_SESSION) {
$definition = cache_definition::load_adhoc(cache_store::MODE_SESSION, $class, 'phpunit_test'); $definition = cache_definition::load_adhoc(cache_store::MODE_SESSION, $class, 'phpunit_test');
$instance = new $class($class.'_test', $class::unit_test_configuration()); $instance = new $class($class . '_test', $class::unit_test_configuration());
if (!$instance->is_ready()) { if (!$instance->is_ready()) {
$this->markTestSkipped('Could not test '.$class.'. No test instance configured for session caches.'); $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for session caches.');
} else { } else {
$instance->initialise($definition); $instance->initialise($definition);
$this->run_tests($instance); $this->run_tests($instance);
@ -84,10 +72,10 @@ abstract class cachestore_tests extends advanced_testcase {
} }
if ($modes & cache_store::MODE_REQUEST) { if ($modes & cache_store::MODE_REQUEST) {
$definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $class, 'phpunit_test'); $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $class, 'phpunit_test');
$instance = new $class($class.'_test', $class::unit_test_configuration()); $instance = new $class($class . '_test', $class::unit_test_configuration());
if (!$instance->is_ready()) { if (!$instance->is_ready()) {
$this->markTestSkipped('Could not test '.$class.'. No test instance configured for request caches.'); $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for request caches.');
} else { } else {
$instance->initialise($definition); $instance->initialise($definition);
$this->run_tests($instance); $this->run_tests($instance);
@ -99,7 +87,7 @@ abstract class cachestore_tests extends advanced_testcase {
* Test the store for basic functionality. * Test the store for basic functionality.
*/ */
public function run_tests(cache_store $instance) { public function run_tests(cache_store $instance) {
$object = new stdClass; $object = new stdClass();
$object->data = 1; $object->data = 1;
// Test set with a string. // Test set with a string.
@ -163,31 +151,31 @@ abstract class cachestore_tests extends advanced_testcase {
$this->assertFalse($instance->get('test2')); $this->assertFalse($instance->get('test2'));
// Test set_many. // Test set_many.
$outcome = $instance->set_many(array( $outcome = $instance->set_many([
array('key' => 'many1', 'value' => 'many1'), ['key' => 'many1', 'value' => 'many1'],
array('key' => 'many2', 'value' => 'many2'), ['key' => 'many2', 'value' => 'many2'],
array('key' => 'many3', 'value' => 'many3'), ['key' => 'many3', 'value' => 'many3'],
array('key' => 'many4', 'value' => 'many4'), ['key' => 'many4', 'value' => 'many4'],
array('key' => 'many5', 'value' => 'many5') ['key' => 'many5', 'value' => 'many5'],
)); ]);
$this->assertSame(5, $outcome); $this->assertSame(5, $outcome);
$this->assertSame('many1', $instance->get('many1')); $this->assertSame('many1', $instance->get('many1'));
$this->assertSame('many5', $instance->get('many5')); $this->assertSame('many5', $instance->get('many5'));
$this->assertFalse($instance->get('many6')); $this->assertFalse($instance->get('many6'));
// Test get_many. // Test get_many.
$result = $instance->get_many(array('many1', 'many3', 'many5', 'many6')); $result = $instance->get_many(['many1', 'many3', 'many5', 'many6']);
$this->assertIsArray($result); $this->assertIsArray($result);
$this->assertCount(4, $result); $this->assertCount(4, $result);
$this->assertSame(array( $this->assertSame([
'many1' => 'many1', 'many1' => 'many1',
'many3' => 'many3', 'many3' => 'many3',
'many5' => 'many5', 'many5' => 'many5',
'many6' => false, 'many6' => false,
), $result); ], $result);
// Test delete_many. // Test delete_many.
$this->assertSame(3, $instance->delete_many(array('many2', 'many3', 'many4'))); $this->assertSame(3, $instance->delete_many(['many2', 'many3', 'many4']));
$this->assertSame(2, $instance->delete_many(array('many1', 'many5', 'many6'))); $this->assertSame(2, $instance->delete_many(['many1', 'many5', 'many6']));
} }
} }

View file

@ -17,14 +17,14 @@
namespace core_cache; namespace core_cache;
/** /**
* Unit tests for cache_store functionality. * Unit tests for \core_cache\store functionality.
* *
* @package core_cache * @package core_cache
* @copyright 2021 The Open University * @copyright 2021 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \core_cache\store
*/ */
class store_test extends \advanced_testcase { final class store_test extends \advanced_testcase {
/** /**
* Tests the default implementation of cache_size_details, which does some * Tests the default implementation of cache_size_details, which does some
* complicated statistics. * complicated statistics.
@ -67,11 +67,11 @@ class store_test extends \advanced_testcase {
protected static function create_static_store(): \cachestore_static { protected static function create_static_store(): \cachestore_static {
require_once(__DIR__ . '/../stores/static/lib.php'); require_once(__DIR__ . '/../stores/static/lib.php');
$store = new \cachestore_static('frog'); $store = new \cachestore_static('frog');
$definition = \cache_definition::load('zombie', [ $definition = definition::load('zombie', [
'mode' => \cache_store::MODE_REQUEST, 'mode' => store::MODE_REQUEST,
'component' => 'phpunit', 'component' => 'phpunit',
'area' => 'store_test', 'area' => 'store_test',
'simplekeys' => true 'simplekeys' => true,
]); ]);
$store->initialise($definition); $store->initialise($definition);
return $store; return $store;

View file

@ -51,40 +51,142 @@ $legacyclasses = [
\webservice_parameter_exception::class => 'exception/webservice_parameter_exception.php', \webservice_parameter_exception::class => 'exception/webservice_parameter_exception.php',
// Cache API. // Cache API.
\cache::class => 'cache.php', \cache::class => [
\cache_application::class => 'application_cache.php', 'core_cache',
\cache_definition::class => 'definition.php', 'cache.php',
\cache_request::class => 'request_cache.php', ],
\cache_session::class => 'session_cache.php', \cache_application::class => [
\cache_cached_object::class => 'cached_object.php', 'core_cache',
\cache_config::class => 'config.php', 'application_cache.php',
\cache_config_writer::class => 'config_writer.php', ],
\cache_config_disabled::class => 'disabled_config.php', \cache_definition::class => [
\cache_disabled::class => 'disabled_cache.php', 'core_cache',
\config_writer::class => 'config_writer.php', 'definition.php',
\cache_data_source::class => 'data_source_interface.php', ],
\cache_data_source_versionable::class => 'versionable_data_source_interface.php', \cache_request::class => [
\cache_exception::class => 'exception/cache_exception.php', 'core_cache',
\cache_factory::class => 'factory.php', 'request_cache.php',
\cache_factory_disabled::class => 'disabled_factory.php', ],
\cache_helper::class => 'helper.php', \cache_session::class => [
\cache_is_key_aware::class => 'key_aware_cache_interface.php', 'core_cache',
\cache_is_lockable::class => 'lockable_cache_interface.php', 'session_cache.php',
\cache_is_searchable::class => 'searchable_cache_interface.php', ],
\cache_is_configurable::class => 'configurable_cache_interface.php', \cache_cached_object::class => [
\cache_loader::class => 'loader_interface.php', 'core_cache',
\cache_loader_with_locking::class => 'loader_with_locking_interface.php', 'cached_object.php',
\cache_lock_interface::class => 'cache_lock_interface.php', ],
\cache_store::class => 'store.php', \cache_config::class => [
\cache_store_interface::class => 'store_interface.php', 'core_cache',
\cache_ttl_wrapper::class => 'ttl_wrapper.php', 'config.php',
\cacheable_object::class => 'cacheable_object_interface.php', ],
\cacheable_object_array::class => 'cacheable_object_array.php', \cache_config_writer::class => [
\cache_definition_mappings_form::class => 'form/cache_definition_mappings_form.php', 'core_cache',
\cache_definition_sharing_form::class => 'form/cache_definition_sharing_form.php', 'config_writer.php',
\cache_lock_form::class => 'form/cache_lock_form.php', ],
\cache_mode_mappings_form::class => 'form/cache_mode_mappings_form.php', \cache_config_disabled::class => [
'core_cache',
'disabled_config.php',
],
\cache_disabled::class => [
'core_cache',
'disabled_cache.php',
],
\config_writer::class => [
'core_cache',
'config_writer.php',
],
\cache_data_source::class => [
'core_cache',
'data_source_interface.php',
],
\cache_data_source_versionable::class => [
'core_cache',
'versionable_data_source_interface.php',
],
\cache_exception::class => [
'core_cache',
'exception/cache_exception.php',
],
\cache_factory::class => [
'core_cache',
'factory.php',
],
\cache_factory_disabled::class => [
'core_cache',
'disabled_factory.php',
],
\cache_helper::class => [
'core_cache',
'helper.php',
],
\cache_is_key_aware::class => [
'core_cache',
'key_aware_cache_interface.php',
],
\cache_is_lockable::class => [
'core_cache',
'lockable_cache_interface.php',
],
\cache_is_searchable::class => [
'core_cache',
'searchable_cache_interface.php',
],
\cache_is_configurable::class => [
'core_cache',
'configurable_cache_interface.php',
],
\cache_loader::class => [
'core_cache',
'loader_interface.php',
],
\cache_loader_with_locking::class => [
'core_cache',
'loader_with_locking_interface.php',
],
\cache_lock_interface::class => [
'core_cache',
'cache_lock_interface.php',
],
\cache_store::class => [
'core_cache',
'store.php',
],
\cache_store_interface::class => [
'core_cache',
'store_interface.php',
],
\cache_ttl_wrapper::class => [
'core_cache',
'ttl_wrapper.php',
],
\cacheable_object::class => [
'core_cache',
'cacheable_object_interface.php',
],
\cacheable_object_array::class => [
'core_cache',
'cacheable_object_array.php',
],
\cache_definition_mappings_form::class => [
'core_cache',
'form/cache_definition_mappings_form.php',
],
\cache_definition_sharing_form::class => [
'core_cache',
'form/cache_definition_sharing_form.php',
],
\cache_lock_form::class => [
'core_cache',
'form/cache_lock_form.php',
],
\cache_mode_mappings_form::class => [
'core_cache',
'form/cache_mode_mappings_form.php',
],
\cachestore_addinstance_form::class => [
'core_cache',
'form/cachestore_addinstance_form.php',
],
// Output API. // Output API.
\theme_config::class => 'output/theme_config.php', \theme_config::class => 'output/theme_config.php',

View file

@ -313,7 +313,7 @@ if (!defined('CACHE_DISABLE_ALL')) {
} }
// When set to true MUC (Moodle caching) will not use any of the defined or default stores. // When set to true MUC (Moodle caching) will not use any of the defined or default stores.
// The Cache API will continue to function however this will force the use of the cachestore_dummy so all requests // The Cache API will continue to function however this will force the use of the dummy_cachestore so all requests
// will be interacting with a static property and will never go to the proper cache stores. // will be interacting with a static property and will never go to the proper cache stores.
// Useful if you need to avoid the stores for one reason or another. // Useful if you need to avoid the stores for one reason or another.
if (!defined('CACHE_DISABLE_STORES')) { if (!defined('CACHE_DISABLE_STORES')) {