MDL-72339 core_availability: Unsafe to use format_string in description

The availability condition get_description method is called while
gathering data for the modinfo object. As such it is not safe to
call other functions which might rely on modinfo, such as format_string
(if using filters which access modinfo).

This change provides a mechanism to call format_string later, and also
a general callback to do other stuff later as well if needed. It uses
the same approach already taken to make activity names work correctly
in the availability_condition class.
This commit is contained in:
sam marshall
2021-10-06 11:27:42 +01:00
parent 278c3dfb4d
commit ca7b088d44
16 changed files with 275 additions and 19 deletions
+20
View File
@@ -746,6 +746,26 @@ abstract class info {
return format_string($cm->get_name(), true, ['context' => $context]);
}
}, $info);
$info = preg_replace_callback('~<AVAILABILITY_FORMAT_STRING>(.*?)</AVAILABILITY_FORMAT_STRING>~s',
function($matches) use ($context) {
$decoded = htmlspecialchars_decode($matches[1], ENT_NOQUOTES);
return format_string($decoded, true, ['context' => $context]);
}, $info);
$info = preg_replace_callback('~<AVAILABILITY_CALLBACK type="([a-z0-9_]+)">(.*?)</AVAILABILITY_CALLBACK>~s',
function($matches) use ($modinfo, $context) {
// Find the class, it must have already been loaded by now.
$fullclassname = 'availability_' . $matches[1] . '\condition';
if (!class_exists($fullclassname, false)) {
return '<!-- Error finding class ' . $fullclassname .' -->';
}
// Load the parameters.
$params = [];
$encodedparams = preg_split('~<P/>~', $matches[2], 0);
foreach ($encodedparams as $encodedparam) {
$params[] = htmlspecialchars_decode($encodedparam, ENT_NOQUOTES);
}
return $fullclassname::get_description_callback_value($modinfo, $context, $params);
}, $info);
return $info;
}