Merge branch 'MDL-79610-main' of https://github.com/roland04/moodle
[moodle.git] / availability / classes / condition.php
blobef8897246759ec93226f5faa50d0de15c82c9ac9
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * Base class for a single availability condition.
20 * All condition types must extend this class.
22 * @package core_availability
23 * @copyright 2014 The Open University
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27 namespace core_availability;
29 defined('MOODLE_INTERNAL') || die();
31 /**
32 * Base class for a single availability condition.
34 * All condition types must extend this class.
36 * The structure of a condition in JSON input data is:
38 * { type:'date', ... }
40 * where 'date' is the name of the plugin (availability_date in this case) and
41 * ... is arbitrary extra data to be used by the plugin.
43 * Conditions require a constructor with one parameter: $structure. This will
44 * contain all the JSON data for the condition. If the structure of the data
45 * is incorrect (e.g. missing fields) then the constructor may throw a
46 * coding_exception. However, the constructor should cope with all data that
47 * was previously valid (e.g. if the format changes, old data may still be
48 * present in a restore, so there should be a default value for any new fields
49 * and old ones should be handled correctly).
51 * @package core_availability
52 * @copyright 2014 The Open University
53 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
55 abstract class condition extends tree_node {
57 /**
58 * Determines whether a particular item is currently available
59 * according to this availability condition.
61 * If implementations require a course or modinfo, they should use
62 * the get methods in $info.
64 * The $not option is potentially confusing. This option always indicates
65 * the 'real' value of NOT. For example, a condition inside a 'NOT AND'
66 * group will get this called with $not = true, but if you put another
67 * 'NOT OR' group inside the first group, then a condition inside that will
68 * be called with $not = false. We need to use the real values, rather than
69 * the more natural use of the current value at this point inside the tree,
70 * so that the information displayed to users makes sense.
72 * @param bool $not Set true if we are inverting the condition
73 * @param info $info Item we're checking
74 * @param bool $grabthelot Performance hint: if true, caches information
75 * required for all course-modules, to make the front page and similar
76 * pages work more quickly (works only for current user)
77 * @param int $userid User ID to check availability for
78 * @return bool True if available
80 public abstract function is_available($not, info $info, $grabthelot, $userid);
82 public function check_available($not, info $info, $grabthelot, $userid) {
83 // Use is_available, and we always display (at this stage).
84 $allow = $this->is_available($not, $info, $grabthelot, $userid);
85 return new result($allow, $this);
88 public function is_available_for_all($not = false) {
89 // Default is that all conditions may make something unavailable.
90 return false;
93 /**
94 * Display a representation of this condition (used for debugging).
96 * @return string Text representation of condition
98 public function __toString() {
99 return '{' . $this->get_type() . ':' . $this->get_debug_string() . '}';
103 * Gets the type name (e.g. 'date' for availability_date) of plugin.
105 * @return string The type name for this plugin
107 protected function get_type() {
108 return preg_replace('~^availability_(.*?)\\\\condition$~', '$1', get_class($this));
112 * Returns a marker indicating that an activity name should be placed in a description.
114 * Gets placeholder text which will be decoded by info::format_info later when we can safely
115 * display names.
117 * @param int $cmid Course-module id
118 * @return string Placeholder text
119 * @since Moodle 4.0
121 public static function description_cm_name(int $cmid): string {
122 return '<AVAILABILITY_CMNAME_' . $cmid . '/>';
126 * Returns a marker indicating that formatted text should be placed in a description.
128 * Gets placeholder text which will be decoded by info::format_info later when we can safely
129 * call format_string.
131 * @param string $str Text to be processed with format_string
132 * @return string Placeholder text
133 * @since Moodle 4.0
135 public static function description_format_string(string $str): string {
136 return '<AVAILABILITY_FORMAT_STRING>' . htmlspecialchars($str, ENT_NOQUOTES) .
137 '</AVAILABILITY_FORMAT_STRING>';
141 * Returns a marker indicating that some of the description text should be computed at display
142 * time.
144 * This will result in a call to the get_description_callback_value static function within
145 * the condition class.
147 * Gets placeholder text which will be decoded by info::format_info later when we can safely
148 * call most Moodle functions.
150 * @param string[] $params Array of arbitrary parameters
151 * @return string Placeholder text
152 * @since Moodle 4.0
154 public function description_callback(array $params): string {
155 $out = '<AVAILABILITY_CALLBACK type="' . $this->get_type() . '">';
156 $first = true;
157 foreach ($params as $param) {
158 if ($first) {
159 $first = false;
160 } else {
161 $out .= '<P/>';
163 $out .= htmlspecialchars($param, ENT_NOQUOTES);
165 $out .= '</AVAILABILITY_CALLBACK>';
166 return $out;
170 * Obtains a string describing this restriction (whether or not
171 * it actually applies). Used to obtain information that is displayed to
172 * students if the activity is not available to them, and for staff to see
173 * what conditions are.
175 * The $full parameter can be used to distinguish between 'staff' cases
176 * (when displaying all information about the activity) and 'student' cases
177 * (when displaying only conditions they don't meet).
179 * If implementations require a course or modinfo, they should use
180 * the get methods in $info. They should not use any other functions that
181 * might rely on modinfo, such as format_string.
183 * To work around this limitation, use the functions:
185 * description_cm_name()
186 * description_format_string()
187 * description_callback()
189 * These return special markers which will be added to the string and processed
190 * later after modinfo is complete.
192 * @param bool $full Set true if this is the 'full information' view
193 * @param bool $not Set true if we are inverting the condition
194 * @param info $info Item we're checking
195 * @return string Information string (for admin) about all restrictions on
196 * this item
198 public abstract function get_description($full, $not, info $info);
201 * Obtains a string describing this restriction, used when there is only
202 * a single restriction to display. (I.e. this provides a 'short form'
203 * rather than showing in a list.)
205 * Default behaviour sticks the prefix text, normally displayed above
206 * the list, in front of the standard get_description call.
208 * If implementations require a course or modinfo, they should use
209 * the get methods in $info. They should not use any other functions that
210 * might rely on modinfo, such as format_string.
212 * To work around this limitation, use the functions:
214 * description_cm_name()
215 * description_format_string()
216 * description_callback()
218 * These return special markers which will be added to the string and processed
219 * later after modinfo is complete.
221 * @param bool $full Set true if this is the 'full information' view
222 * @param bool $not Set true if we are inverting the condition
223 * @param info $info Item we're checking
224 * @return string Information string (for admin) about all restrictions on
225 * this item
227 public function get_standalone_description($full, $not, info $info) {
228 return get_string('list_root_and', 'availability') . ' ' .
229 $this->get_description($full, $not, $info);
233 * Obtains a representation of the options of this condition as a string,
234 * for debugging.
236 * @return string Text representation of parameters
238 protected abstract function get_debug_string();
240 public function update_dependency_id($table, $oldid, $newid) {
241 // By default, assumes there are no dependent ids.
242 return false;
246 * If the plugin has been configured to rely on a particular activity's
247 * completion value, it should return true here. (This is necessary so that
248 * we know the course page needs to update when that activity becomes
249 * complete.)
251 * Default implementation returns false.
253 * @param \stdClass $course Moodle course object
254 * @param int $cmid ID of activity whose completion value is considered
255 * @return boolean True if the availability of something else may rely on it
257 public static function completion_value_used($course, $cmid) {
258 return false;