Skip to content

Commit

Permalink
MDL-56273 cache: Ensure requirements are met for cache stores.
Browse files Browse the repository at this point in the history
Ensure that the cache store requirements are met prior to attempting
to instantiate a class.  Many of the constructors create connections
to external services requiring the installation and availability of
classes that are specified in are_requirements_met().  If they are
not checked properly you end up with PHP Fatal errors rather than
falling back to a different store that is capabable without the
the extra classes loaded.
  • Loading branch information
mr-russ committed Oct 31, 2016
1 parent a169739 commit f9599c7
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 12 deletions.
3 changes: 3 additions & 0 deletions cache/classes/factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ public function create_store_from_config($name, array $details, cache_definition
if (!array_key_exists($name, $this->stores)) {
// Properties: name, plugin, configuration, class.
$class = $details['class'];
if (!$class::are_requirements_met()) {
return false;
}
$store = new $class($details['name'], $details['configuration']);
$this->stores[$name] = $store;
}
Expand Down
9 changes: 6 additions & 3 deletions cache/classes/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -502,15 +502,18 @@ public static function purge_store($storename, cache_config $config = null) {
$store = $stores[$storename];
$class = $store['class'];


// We check are_requirements_met although we expect is_ready is going to check as well.
if (!$class::are_requirements_met()) {
return false;
}
// Found the store: is it ready?
/* @var cache_store $instance */
$instance = new $class($store['name'], $store['configuration']);
// We check are_requirements_met although we expect is_ready is going to check as well.
if (!$instance::are_requirements_met() || !$instance->is_ready()) {
if (!$instance->is_ready()) {
unset($instance);
return false;
}

foreach ($config->get_definitions_by_store($storename) as $id => $definition) {
$definition = cache_definition::load($id, $definition);
$definitioninstance = clone($instance);
Expand Down
21 changes: 12 additions & 9 deletions cache/locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -684,33 +684,36 @@ public static function get_store_instance_summaries() {
$locks = $instance->get_locks();
foreach ($stores as $name => $details) {
$class = $details['class'];
$store = new $class($details['name'], $details['configuration']);
$store = false;
if ($class::are_requirements_met()) {
$store = new $class($details['name'], $details['configuration']);
}
$lock = (isset($details['lock'])) ? $locks[$details['lock']] : $instance->get_default_lock();
$record = array(
'name' => $name,
'plugin' => $details['plugin'],
'default' => $details['default'],
'isready' => $store->is_ready(),
'isready' => $store ? $store->is_ready() : false,
'requirementsmet' => $class::are_requirements_met(),
'mappings' => 0,
'lock' => $lock,
'modes' => array(
cache_store::MODE_APPLICATION =>
($store->get_supported_modes($return) & cache_store::MODE_APPLICATION) == cache_store::MODE_APPLICATION,
($class::get_supported_modes($return) & cache_store::MODE_APPLICATION) == cache_store::MODE_APPLICATION,
cache_store::MODE_SESSION =>
($store->get_supported_modes($return) & cache_store::MODE_SESSION) == cache_store::MODE_SESSION,
($class::get_supported_modes($return) & cache_store::MODE_SESSION) == cache_store::MODE_SESSION,
cache_store::MODE_REQUEST =>
($store->get_supported_modes($return) & cache_store::MODE_REQUEST) == cache_store::MODE_REQUEST,
($class::get_supported_modes($return) & cache_store::MODE_REQUEST) == cache_store::MODE_REQUEST,
),
'supports' => array(
'multipleidentifiers' => $store->supports_multiple_identifiers(),
'dataguarantee' => $store->supports_data_guarantee(),
'nativettl' => $store->supports_native_ttl(),
'multipleidentifiers' => $store ? $store->supports_multiple_identifiers() : false,
'dataguarantee' => $store ? $store->supports_data_guarantee() : false,
'nativettl' => $store ? $store->supports_native_ttl() : false,
'nativelocking' => ($store instanceof cache_is_lockable),
'keyawareness' => ($store instanceof cache_is_key_aware),
'searchable' => ($store instanceof cache_is_searchable)
),
'warnings' => $store->get_warnings()
'warnings' => $store ? $store->get_warnings() : array()
);
if (empty($details['default'])) {
$return[$name] = $record;
Expand Down

0 comments on commit f9599c7

Please sign in to comment.