MDL-35603 - Backup - Course import selector notice
[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 275}
42dffc6f
MN
276
277/**
278* A dependency that disables the secondary setting if the primary setting is
279* not equal to the provided value
280*
281* @copyright 2011 Darko Miletic <dmiletic@moodlerooms.com>
282* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
283*/
284class setting_dependency_disabledif_not_equals extends setting_dependency_disabledif_equals {
285 /**
286 * Enforces the dependency if required.
287 * @return bool True if there were changes
288 */
289 public function enforce() {
290 // This will be set to true if ANYTHING changes
291 $changes = false;
292 // First process any value changes
293 if (!$this->process_value_change($this->setting->get_value())) {
294 $changes = true;
295 }
296 // Second process any status changes
297 if ($this->process_status_change($this->setting->get_status())) {
298 $changes = true;
299 }
300 // Finally process visibility changes
301 if ($this->process_visibility_change($this->setting->get_visibility())) {
302 $changes = true;
303 }
304 return $changes;
305 }
306 /**
307 * Returns an array of properties suitable to be used to define a moodleforms
308 * disabled command
309 * @return array
310 */
311 public function get_moodleform_properties() {
312 return array(
313 'setting'=>$this->dependentsetting->get_ui_name(),
314 'dependenton'=>$this->setting->get_ui_name(),
315 'condition'=>'notequal',
316 'value'=>$this->value
317 );
318 }
319}
320
321//with array
322class setting_dependency_disabledif_equals2 extends setting_dependency {
323 /**
324 * The value to compare to
325 * @var mixed
326 */
327 protected $value;
328 /**
329 * Creates the dependency
330 *
331 * @param base_setting $setting
332 * @param base_setting $dependentsetting
333 * @param mixed $value
334 * @param mixed $defaultvalue
335 */
336 public function __construct(base_setting $setting, base_setting $dependentsetting, array $value, $defaultvalue = false) {
337 parent::__construct($setting, $dependentsetting, $defaultvalue);
338 $this->value = $value;
339 }
340 /**
341 * Returns true if the dependent setting is locked.
342 * @return bool
343 */
344 public function is_locked() {
345 // If the setting is locked or the dependent setting should be locked then return true
346 if ($this->setting->get_status() !== base_setting::NOT_LOCKED || in_array($this->setting->get_value(), $this->value)) {
347 return true;
348 }
349 // Else return based upon the dependent settings status
350 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
351 }
352 /**
353 * Processes a value change in the primary setting
354 * @param mixed $oldvalue
355 * @return bool
356 */
357 protected function process_value_change($oldvalue) {
358 $prevalue = $this->dependentsetting->get_value();
359 // If the setting is the desired value enact the dependency
360 if (in_array($this->setting->get_value(), $this->value)) {
361 // The dependent setting needs to be locked by hierachy and set to the
362 // default value.
363 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
364 $this->dependentsetting->set_value($this->defaultvalue);
365 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
366 // We can unlock the dependent setting
367 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
368 }
369 // Return true if the value has changed for the dependent setting
370 return ($prevalue != $this->dependentsetting->get_value());
371 }
372 /**
373 * Processes a status change in the primary setting
374 * @param mixed $oldstatus
375 * @return bool
376 */
377 protected function process_status_change($oldstatus) {
378 // Store the dependent status
379 $prevalue = $this->dependentsetting->get_status();
380 // Store the current status
381 $currentstatus = $this->setting->get_status();
382 if ($currentstatus == base_setting::NOT_LOCKED) {
383 if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && !in_array($this->setting->get_value(), $this->value)) {
384 // Dependency has changes, is not fine, unlock the dependent setting
385 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
386 }
387 } else {
388 // Make sure the dependent setting is also locked, in this case by hierarchy
389 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
390 }
391 // Return true if the dependent setting has changed.
392 return ($prevalue != $this->dependentsetting->get_status());
393 }
394 /**
395 * Enforces the dependency if required.
396 * @return bool True if there were changes
397 */
398 public function enforce() {
399 // This will be set to true if ANYTHING changes
400 $changes = false;
401 // First process any value changes
402 if ($this->process_value_change($this->setting->get_value())) {
403 $changes = true;
404 }
405 // Second process any status changes
406 if ($this->process_status_change($this->setting->get_status())) {
407 $changes = true;
408 }
409 // Finally process visibility changes
410 if ($this->process_visibility_change($this->setting->get_visibility())) {
411 $changes = true;
412 }
413 return $changes;
414 }
415 /**
416 * Returns an array of properties suitable to be used to define a moodleforms
417 * disabled command
418 * @return array
419 */
420 public function get_moodleform_properties() {
421 return array(
422 'setting'=>$this->dependentsetting->get_ui_name(),
423 'dependenton'=>$this->setting->get_ui_name(),
424 'condition'=>'eq',
425 'value'=>$this->value
426 );
427 }
428}
429
430
1904e9b3
SH
431/**
432 * A dependency that disables the secondary element if the primary element is
433 * true or checked
434 *
435 * @copyright 2010 Sam Hemelryk
436 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
437 */
438class setting_dependency_disabledif_checked extends setting_dependency_disabledif_equals {
84e546e0
SH
439 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
440 parent::__construct($setting, $dependentsetting, true, $defaultvalue);
1904e9b3
SH
441 $this->value = true;
442 }
84e546e0
SH
443 /**
444 * Returns an array of properties suitable to be used to define a moodleforms
445 * disabled command
446 * @return array
447 */
448 public function get_moodleform_properties() {
449 return array(
450 'setting'=>$this->dependentsetting->get_ui_name(),
451 'dependenton'=>$this->setting->get_ui_name(),
452 'condition'=>'checked'
453 );
454 }
1904e9b3
SH
455}
456
457/**
458 * A dependency that disables the secondary element if the primary element is
459 * false or not checked
460 *
461 * @copyright 2010 Sam Hemelryk
462 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
463 */
84e546e0 464class setting_dependency_disabledif_not_checked extends setting_dependency_disabledif_equals {
1904e9b3 465 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
84e546e0 466 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
1904e9b3
SH
467 $this->value = false;
468 }
84e546e0
SH
469 /**
470 * Returns an array of properties suitable to be used to define a moodleforms
471 * disabled command
472 * @return array
473 */
474 public function get_moodleform_properties() {
475 return array(
476 'setting'=>$this->dependentsetting->get_ui_name(),
477 'dependenton'=>$this->setting->get_ui_name(),
478 'condition'=>'notchecked'
479 );
480 }
17f04f53
SH
481}
482
483/**
484 * A dependency that disables the secondary setting if the value of the primary setting
485 * is not empty.
486 *
487 * @copyright 2010 Sam Hemelryk
488 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
489 */
490class setting_dependency_disabledif_not_empty extends setting_dependency_disabledif_equals {
491 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
492 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
493 $this->value = false;
494 }
495 /**
496 * Returns an array of properties suitable to be used to define a moodleforms
497 * disabled command
498 * @return array
499 */
500 public function get_moodleform_properties() {
501 return array(
502 'setting'=>$this->dependentsetting->get_ui_name(),
503 'dependenton'=>$this->setting->get_ui_name(),
504 'condition'=>'notequal',
505 'value'=>''
506 );
507 }
508 /**
509 * Processes a value change in the primary setting
510 * @param mixed $oldvalue
511 * @return bool
512 */
513 protected function process_value_change($oldvalue) {
514 $prevalue = $this->dependentsetting->get_value();
515 // If the setting is the desired value enact the dependency
516 $value = $this->setting->get_value();
517 if (!empty($value)) {
518 // The dependent setting needs to be locked by hierachy and set to the
519 // default value.
520 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
521 if ($this->defaultvalue === false) {
522 $this->dependentsetting->set_value($value);
523 } else {
524 $this->dependentsetting->set_value($this->defaultvalue);
525 }
526 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
527 // We can unlock the dependent setting
528 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
529 }
530 // Return true if the value has changed for the dependent setting
531 return ($prevalue != $this->dependentsetting->get_value());
532 }
61ebef8f
SH
533
534 /**
535 * Returns true if the dependent setting is locked.
536 * @return bool
537 */
538 public function is_locked() {
539 // If the setting is locked or the dependent setting should be locked then return true
540 if ($this->setting->get_status() !== base_setting::NOT_LOCKED || !empty($value)) {
541 return true;
542 }
543 // Else return based upon the dependent settings status
544 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
545 }
17f04f53
SH
546}
547
548/**
549 * A dependency that disables the secondary setting if the value of the primary setting
550 * is empty.
551 *
552 * @copyright 2010 Sam Hemelryk
553 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
554 */
555class setting_dependency_disabledif_empty extends setting_dependency_disabledif_equals {
556 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
557 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
558 $this->value = false;
559 }
560 /**
561 * Returns an array of properties suitable to be used to define a moodleforms
562 * disabled command
563 * @return array
564 */
565 public function get_moodleform_properties() {
566 return array(
567 'setting'=>$this->dependentsetting->get_ui_name(),
568 'dependenton'=>$this->setting->get_ui_name(),
569 'condition'=>'notequal',
570 'value'=>''
571 );
572 }
573 /**
574 * Processes a value change in the primary setting
575 * @param mixed $oldvalue
576 * @return bool
577 */
578 protected function process_value_change($oldvalue) {
579 $prevalue = $this->dependentsetting->get_value();
580 // If the setting is the desired value enact the dependency
581 $value = $this->setting->get_value();
582 if (empty($value)) {
583 // The dependent setting needs to be locked by hierachy and set to the
584 // default value.
585 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
586 if ($this->defaultvalue === false) {
587 $this->dependentsetting->set_value($value);
588 } else {
589 $this->dependentsetting->set_value($this->defaultvalue);
590 }
591 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
592 // We can unlock the dependent setting
593 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
594 }
595 // Return true if the value has changed for the dependent setting
596 return ($prevalue != $this->dependentsetting->get_value());
597 }
61ebef8f
SH
598 /**
599 * Returns true if the dependent setting is locked.
600 * @return bool
601 */
602 public function is_locked() {
603 // If the setting is locked or the dependent setting should be locked then return true
604 if ($this->setting->get_status() !== base_setting::NOT_LOCKED || empty($value)) {
605 return true;
606 }
607 // Else return based upon the dependent settings status
608 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
609 }
287e8040 610}