MDL-29793 Advanced grading - do not execute the restore step if the grading.xml is...
[moodle.git] / backup / util / settings / setting_dependency.class.php
CommitLineData
1904e9b3
SH
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * @package moodlecore
20 * @copyright 2010 Sam Hemelryk
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
24/**
25 * Generic abstract dependency class
26 *
27 * @copyright 2010 Sam Hemelryk
28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 */
30abstract class setting_dependency {
31
32 /**
33 * Used to define the type of a dependency.
34 *
35 * Note with these that checked and true, and not checked and false are equal.
36 * This is because the terminology differs but the resulting action is the same.
37 * Reduces code!
38 */
39 const DISABLED_VALUE = 0;
40 const DISABLED_NOT_VALUE = 1;
1904e9b3 41 const DISABLED_TRUE = 2;
1904e9b3 42 const DISABLED_FALSE = 3;
84e546e0
SH
43 const DISABLED_CHECKED = 4;
44 const DISABLED_NOT_CHECKED = 5;
17f04f53
SH
45 const DISABLED_EMPTY = 6;
46 const DISABLED_NOT_EMPTY = 7;
1904e9b3
SH
47
48 /**
49 * The parent setting (primary)
50 * @var base_setting
51 */
52 protected $setting;
53 /**
54 * The dependent setting (secondary)
55 * @var base_setting
56 */
57 protected $dependentsetting;
58 /**
59 * The default setting
60 * @var mixed
61 */
62 protected $defaultvalue;
63 /**
64 * The last value the dependent setting had
65 * @var mixed
66 */
67 protected $lastvalue;
68 /**
69 * Creates the dependency object
70 * @param base_setting $setting The parent setting or the primary setting if you prefer
71 * @param base_setting $dependentsetting The dependent setting
72 * @param mixed $defaultvalue The default value to assign if the dependency is unmet
73 */
74 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
75 $this->setting = $setting;
76 $this->dependentsetting = $dependentsetting;
77 $this->defaultvalue = $defaultvalue;
78 $this->lastvalue = $dependentsetting->get_value();
79 }
287e8040
EL
80
81 /**
82 * Destroy all circular references. It helps PHP 5.2 a lot!
83 */
84 public function destroy() {
85 // No need to destroy anything recursively here, direct reset
86 $this->setting = null;
87 $this->dependentsetting = null;
88 }
89
1904e9b3
SH
90 /**
91 * Processes a change is setting called by the primary setting
92 * @param int $changetype
93 * @param mixed $oldvalue
94 * @return bool
95 */
96 final public function process_change($changetype, $oldvalue) {
97 // Check the type of change requested
98 switch ($changetype) {
99 // Process a status change
100 case base_setting::CHANGED_STATUS: return $this->process_status_change($oldvalue);
101 // Process a visibility change
102 case base_setting::CHANGED_VISIBILITY: return $this->process_visibility_change($oldvalue);
103 // Process a value change
104 case base_setting::CHANGED_VALUE: return $this->process_value_change($oldvalue);
105 }
106 // Throw an exception if we get this far
107 throw new backup_ui_exception('unknownchangetype');
108 }
109 /**
110 * Processes a visibility change
111 * @param bool $oldvisibility
112 * @return bool
113 */
114 protected function process_visibility_change($oldvisibility) {
115 // Store the current dependent settings visibility for comparison
116 $prevalue = $this->dependentsetting->get_visibility();
117 // Set it regardless of whether we need to
118 $this->dependentsetting->set_visibility($this->setting->get_visibility());
119 // Return true if it changed
120 return ($prevalue != $this->dependentsetting->get_visibility());
121 }
122 /**
123 * All dependencies must define how they would like to deal with a status change
124 * @param int $oldstatus
125 */
126 abstract protected function process_status_change($oldstatus);
127 /**
128 * All dependencies must define how they would like to process a value change
129 */
130 abstract protected function process_value_change($oldvalue);
131 /**
132 * Gets the primary setting
133 * @return backup_setting
134 */
135 public function get_setting() {
136 return $this->setting;
137 }
138 /**
139 * Gets the dependent setting
140 * @return backup_setting
141 */
e35fb479 142 public function get_dependent_setting() {
1904e9b3
SH
143 return $this->dependentsetting;
144 }
84e546e0
SH
145 /**
146 * This function enforces the dependency
147 */
148 abstract public function enforce();
149 /**
150 * Returns an array of properties suitable to be used to define a moodleforms
151 * disabled command
152 * @return array
153 */
154 abstract public function get_moodleform_properties();
61ebef8f
SH
155 /**
156 * Returns true if the dependent setting is locked.
157 * @return bool
158 */
159 abstract public function is_locked();
1904e9b3
SH
160}
161
162/**
163 * A dependency that disables the secondary setting if the primary setting is
164 * equal to the provided value
165 *
166 * @copyright 2010 Sam Hemelryk
167 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
168 */
169class setting_dependency_disabledif_equals extends setting_dependency {
170 /**
171 * The value to compare to
172 * @var mixed
173 */
174 protected $value;
175 /**
176 * Creates the dependency
177 *
178 * @param base_setting $setting
179 * @param base_setting $dependentsetting
180 * @param mixed $value
181 * @param mixed $defaultvalue
182 */
183 public function __construct(base_setting $setting, base_setting $dependentsetting, $value, $defaultvalue = false) {
184 parent::__construct($setting, $dependentsetting, $defaultvalue);
84e546e0 185 $this->value = ($value)?(string)$value:0;
1904e9b3 186 }
61ebef8f
SH
187 /**
188 * Returns true if the dependent setting is locked.
189 * @return bool
190 */
191 public function is_locked() {
192 // If the setting is locked or the dependent setting should be locked then return true
193 if ($this->setting->get_status() !== base_setting::NOT_LOCKED || $this->setting->get_value() == $this->value) {
194 return true;
195 }
196 // Else return based upon the dependent settings status
197 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
198 }
1904e9b3
SH
199 /**
200 * Processes a value change in the primary setting
201 * @param mixed $oldvalue
202 * @return bool
203 */
204 protected function process_value_change($oldvalue) {
205 $prevalue = $this->dependentsetting->get_value();
206 // If the setting is the desired value enact the dependency
207 if ($this->setting->get_value() == $this->value) {
208 // The dependent setting needs to be locked by hierachy and set to the
209 // default value.
210 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
211 $this->dependentsetting->set_value($this->defaultvalue);
212 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
84e546e0 213 // We can unlock the dependent setting
1904e9b3 214 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
1904e9b3
SH
215 }
216 // Return true if the value has changed for the dependent setting
217 return ($prevalue != $this->dependentsetting->get_value());
218 }
219 /**
220 * Processes a status change in the primary setting
221 * @param mixed $oldstatus
222 * @return bool
223 */
224 protected function process_status_change($oldstatus) {
225 // Store the dependent status
226 $prevalue = $this->dependentsetting->get_status();
227 // Store the current status
228 $currentstatus = $this->setting->get_status();
229 if ($currentstatus == base_setting::NOT_LOCKED) {
230 if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && $this->setting->get_value() != $this->value) {
231 // Dependency has changes, is not fine, unlock the dependent setting
232 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
233 }
234 } else {
235 // Make sure the dependent setting is also locked, in this case by hierarchy
236 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
237 }
238 // Return true if the dependent setting has changed.
239 return ($prevalue != $this->dependentsetting->get_status());
240 }
241 /**
242 * Enforces the dependency if required.
243 * @return bool True if there were changes
244 */
245 public function enforce() {
246 // This will be set to true if ANYTHING changes
247 $changes = false;
248 // First process any value changes
249 if ($this->process_value_change($this->setting->get_value())) {
250 $changes = true;
251 }
252 // Second process any status changes
253 if ($this->process_status_change($this->setting->get_status())) {
254 $changes = true;
255 }
256 // Finally process visibility changes
257 if ($this->process_visibility_change($this->setting->get_visibility())) {
258 $changes = true;
259 }
260 return $changes;
261 }
84e546e0
SH
262 /**
263 * Returns an array of properties suitable to be used to define a moodleforms
264 * disabled command
265 * @return array
266 */
267 public function get_moodleform_properties() {
268 return array(
269 'setting'=>$this->dependentsetting->get_ui_name(),
270 'dependenton'=>$this->setting->get_ui_name(),
271 'condition'=>'eq',
272 'value'=>$this->value
273 );
274 }
1904e9b3
SH
275}
276/**
277 * A dependency that disables the secondary element if the primary element is
278 * true or checked
279 *
280 * @copyright 2010 Sam Hemelryk
281 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
282 */
283class setting_dependency_disabledif_checked extends setting_dependency_disabledif_equals {
84e546e0
SH
284 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
285 parent::__construct($setting, $dependentsetting, true, $defaultvalue);
1904e9b3
SH
286 $this->value = true;
287 }
84e546e0
SH
288 /**
289 * Returns an array of properties suitable to be used to define a moodleforms
290 * disabled command
291 * @return array
292 */
293 public function get_moodleform_properties() {
294 return array(
295 'setting'=>$this->dependentsetting->get_ui_name(),
296 'dependenton'=>$this->setting->get_ui_name(),
297 'condition'=>'checked'
298 );
299 }
1904e9b3
SH
300}
301
302/**
303 * A dependency that disables the secondary element if the primary element is
304 * false or not checked
305 *
306 * @copyright 2010 Sam Hemelryk
307 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
308 */
84e546e0 309class setting_dependency_disabledif_not_checked extends setting_dependency_disabledif_equals {
1904e9b3 310 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
84e546e0 311 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
1904e9b3
SH
312 $this->value = false;
313 }
84e546e0
SH
314 /**
315 * Returns an array of properties suitable to be used to define a moodleforms
316 * disabled command
317 * @return array
318 */
319 public function get_moodleform_properties() {
320 return array(
321 'setting'=>$this->dependentsetting->get_ui_name(),
322 'dependenton'=>$this->setting->get_ui_name(),
323 'condition'=>'notchecked'
324 );
325 }
17f04f53
SH
326}
327
328/**
329 * A dependency that disables the secondary setting if the value of the primary setting
330 * is not empty.
331 *
332 * @copyright 2010 Sam Hemelryk
333 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
334 */
335class setting_dependency_disabledif_not_empty extends setting_dependency_disabledif_equals {
336 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
337 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
338 $this->value = false;
339 }
340 /**
341 * Returns an array of properties suitable to be used to define a moodleforms
342 * disabled command
343 * @return array
344 */
345 public function get_moodleform_properties() {
346 return array(
347 'setting'=>$this->dependentsetting->get_ui_name(),
348 'dependenton'=>$this->setting->get_ui_name(),
349 'condition'=>'notequal',
350 'value'=>''
351 );
352 }
353 /**
354 * Processes a value change in the primary setting
355 * @param mixed $oldvalue
356 * @return bool
357 */
358 protected function process_value_change($oldvalue) {
359 $prevalue = $this->dependentsetting->get_value();
360 // If the setting is the desired value enact the dependency
361 $value = $this->setting->get_value();
362 if (!empty($value)) {
363 // The dependent setting needs to be locked by hierachy and set to the
364 // default value.
365 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
366 if ($this->defaultvalue === false) {
367 $this->dependentsetting->set_value($value);
368 } else {
369 $this->dependentsetting->set_value($this->defaultvalue);
370 }
371 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
372 // We can unlock the dependent setting
373 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
374 }
375 // Return true if the value has changed for the dependent setting
376 return ($prevalue != $this->dependentsetting->get_value());
377 }
61ebef8f
SH
378
379 /**
380 * Returns true if the dependent setting is locked.
381 * @return bool
382 */
383 public function is_locked() {
384 // If the setting is locked or the dependent setting should be locked then return true
385 if ($this->setting->get_status() !== base_setting::NOT_LOCKED || !empty($value)) {
386 return true;
387 }
388 // Else return based upon the dependent settings status
389 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
390 }
17f04f53
SH
391}
392
393/**
394 * A dependency that disables the secondary setting if the value of the primary setting
395 * is empty.
396 *
397 * @copyright 2010 Sam Hemelryk
398 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
399 */
400class setting_dependency_disabledif_empty extends setting_dependency_disabledif_equals {
401 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
402 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
403 $this->value = false;
404 }
405 /**
406 * Returns an array of properties suitable to be used to define a moodleforms
407 * disabled command
408 * @return array
409 */
410 public function get_moodleform_properties() {
411 return array(
412 'setting'=>$this->dependentsetting->get_ui_name(),
413 'dependenton'=>$this->setting->get_ui_name(),
414 'condition'=>'notequal',
415 'value'=>''
416 );
417 }
418 /**
419 * Processes a value change in the primary setting
420 * @param mixed $oldvalue
421 * @return bool
422 */
423 protected function process_value_change($oldvalue) {
424 $prevalue = $this->dependentsetting->get_value();
425 // If the setting is the desired value enact the dependency
426 $value = $this->setting->get_value();
427 if (empty($value)) {
428 // The dependent setting needs to be locked by hierachy and set to the
429 // default value.
430 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
431 if ($this->defaultvalue === false) {
432 $this->dependentsetting->set_value($value);
433 } else {
434 $this->dependentsetting->set_value($this->defaultvalue);
435 }
436 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
437 // We can unlock the dependent setting
438 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
439 }
440 // Return true if the value has changed for the dependent setting
441 return ($prevalue != $this->dependentsetting->get_value());
442 }
61ebef8f
SH
443 /**
444 * Returns true if the dependent setting is locked.
445 * @return bool
446 */
447 public function is_locked() {
448 // If the setting is locked or the dependent setting should be locked then return true
449 if ($this->setting->get_status() !== base_setting::NOT_LOCKED || empty($value)) {
450 return true;
451 }
452 // Else return based upon the dependent settings status
453 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
454 }
287e8040 455}