3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
20 * @copyright 2010 Sam Hemelryk
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 * Generic abstract dependency class
27 * @copyright 2010 Sam Hemelryk
28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30 abstract class setting_dependency {
33 * Used to define the type of a dependency.
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.
39 const DISABLED_VALUE = 0;
40 const DISABLED_NOT_VALUE = 1;
41 const DISABLED_TRUE = 2;
42 const DISABLED_FALSE = 3;
43 const DISABLED_CHECKED = 4;
44 const DISABLED_NOT_CHECKED = 5;
45 const DISABLED_EMPTY = 6;
46 const DISABLED_NOT_EMPTY = 7;
49 * The parent setting (primary)
54 * The dependent setting (secondary)
57 protected $dependentsetting;
62 protected $defaultvalue;
64 * The last value the dependent setting had
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
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();
82 * Destroy all circular references. It helps PHP 5.2 a lot!
84 public function destroy() {
85 // No need to destroy anything recursively here, direct reset
86 $this->setting = null;
87 $this->dependentsetting = null;
91 * Processes a change is setting called by the primary setting
92 * @param int $changetype
93 * @param mixed $oldvalue
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);
106 // Throw an exception if we get this far
107 throw new backup_ui_exception('unknownchangetype');
110 * Processes a visibility change
111 * @param bool $oldvisibility
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());
123 * All dependencies must define how they would like to deal with a status change
124 * @param int $oldstatus
126 abstract protected function process_status_change($oldstatus);
128 * All dependencies must define how they would like to process a value change
130 abstract protected function process_value_change($oldvalue);
132 * Gets the primary setting
133 * @return backup_setting
135 public function get_setting() {
136 return $this->setting;
139 * Gets the dependent setting
140 * @return backup_setting
142 public function get_dependent_setting() {
143 return $this->dependentsetting;
146 * This function enforces the dependency
148 abstract public function enforce();
150 * Returns an array of properties suitable to be used to define a moodleforms
154 abstract public function get_moodleform_properties();
156 * Returns true if the dependent setting is locked.
159 abstract public function is_locked();
163 * A dependency that disables the secondary setting if the primary setting is
164 * equal to the provided value
166 * @copyright 2010 Sam Hemelryk
167 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
169 class setting_dependency_disabledif_equals extends setting_dependency {
171 * The value to compare to
176 * Creates the dependency
178 * @param base_setting $setting
179 * @param base_setting $dependentsetting
180 * @param mixed $value
181 * @param mixed $defaultvalue
183 public function __construct(base_setting $setting, base_setting $dependentsetting, $value, $defaultvalue = false) {
184 parent::__construct($setting, $dependentsetting, $defaultvalue);
185 $this->value = ($value)?(string)$value:0;
188 * Returns true if the dependent setting is locked.
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) {
196 // Else return based upon the dependent settings status
197 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
200 * Processes a value change in the primary setting
201 * @param mixed $oldvalue
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
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) {
213 // We can unlock the dependent setting
214 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
216 // Return true if the value has changed for the dependent setting
217 return ($prevalue != $this->dependentsetting->get_value());
220 * Processes a status change in the primary setting
221 * @param mixed $oldstatus
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);
235 // Make sure the dependent setting is also locked, in this case by hierarchy
236 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
238 // Return true if the dependent setting has changed.
239 return ($prevalue != $this->dependentsetting->get_status());
242 * Enforces the dependency if required.
243 * @return bool True if there were changes
245 public function enforce() {
246 // This will be set to true if ANYTHING changes
248 // First process any value changes
249 if ($this->process_value_change($this->setting->get_value())) {
252 // Second process any status changes
253 if ($this->process_status_change($this->setting->get_status())) {
256 // Finally process visibility changes
257 if ($this->process_visibility_change($this->setting->get_visibility())) {
263 * Returns an array of properties suitable to be used to define a moodleforms
267 public function get_moodleform_properties() {
269 'setting'=>$this->dependentsetting->get_ui_name(),
270 'dependenton'=>$this->setting->get_ui_name(),
272 'value'=>$this->value
278 * A dependency that disables the secondary setting if the primary setting is
279 * not equal to the provided value
281 * @copyright 2011 Darko Miletic <dmiletic@moodlerooms.com>
282 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
284 class setting_dependency_disabledif_not_equals extends setting_dependency_disabledif_equals {
286 * Enforces the dependency if required.
287 * @return bool True if there were changes
289 public function enforce() {
290 // This will be set to true if ANYTHING changes
292 // First process any value changes
293 if (!$this->process_value_change($this->setting->get_value())) {
296 // Second process any status changes
297 if ($this->process_status_change($this->setting->get_status())) {
300 // Finally process visibility changes
301 if ($this->process_visibility_change($this->setting->get_visibility())) {
307 * Returns an array of properties suitable to be used to define a moodleforms
311 public function get_moodleform_properties() {
313 'setting'=>$this->dependentsetting->get_ui_name(),
314 'dependenton'=>$this->setting->get_ui_name(),
315 'condition'=>'notequal',
316 'value'=>$this->value
322 class setting_dependency_disabledif_equals2 extends setting_dependency {
324 * The value to compare to
329 * Creates the dependency
331 * @param base_setting $setting
332 * @param base_setting $dependentsetting
333 * @param mixed $value
334 * @param mixed $defaultvalue
336 public function __construct(base_setting $setting, base_setting $dependentsetting, array $value, $defaultvalue = false) {
337 parent::__construct($setting, $dependentsetting, $defaultvalue);
338 $this->value = $value;
341 * Returns true if the dependent setting is locked.
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)) {
349 // Else return based upon the dependent settings status
350 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
353 * Processes a value change in the primary setting
354 * @param mixed $oldvalue
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
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);
369 // Return true if the value has changed for the dependent setting
370 return ($prevalue != $this->dependentsetting->get_value());
373 * Processes a status change in the primary setting
374 * @param mixed $oldstatus
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);
388 // Make sure the dependent setting is also locked, in this case by hierarchy
389 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
391 // Return true if the dependent setting has changed.
392 return ($prevalue != $this->dependentsetting->get_status());
395 * Enforces the dependency if required.
396 * @return bool True if there were changes
398 public function enforce() {
399 // This will be set to true if ANYTHING changes
401 // First process any value changes
402 if ($this->process_value_change($this->setting->get_value())) {
405 // Second process any status changes
406 if ($this->process_status_change($this->setting->get_status())) {
409 // Finally process visibility changes
410 if ($this->process_visibility_change($this->setting->get_visibility())) {
416 * Returns an array of properties suitable to be used to define a moodleforms
420 public function get_moodleform_properties() {
422 'setting'=>$this->dependentsetting->get_ui_name(),
423 'dependenton'=>$this->setting->get_ui_name(),
425 'value'=>$this->value
432 * A dependency that disables the secondary element if the primary element is
435 * @copyright 2010 Sam Hemelryk
436 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
438 class setting_dependency_disabledif_checked extends setting_dependency_disabledif_equals {
439 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
440 parent::__construct($setting, $dependentsetting, true, $defaultvalue);
444 * Returns an array of properties suitable to be used to define a moodleforms
448 public function get_moodleform_properties() {
450 'setting'=>$this->dependentsetting->get_ui_name(),
451 'dependenton'=>$this->setting->get_ui_name(),
452 'condition'=>'checked'
458 * A dependency that disables the secondary element if the primary element is
459 * false or not checked
461 * @copyright 2010 Sam Hemelryk
462 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
464 class setting_dependency_disabledif_not_checked extends setting_dependency_disabledif_equals {
465 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
466 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
467 $this->value = false;
470 * Returns an array of properties suitable to be used to define a moodleforms
474 public function get_moodleform_properties() {
476 'setting'=>$this->dependentsetting->get_ui_name(),
477 'dependenton'=>$this->setting->get_ui_name(),
478 'condition'=>'notchecked'
484 * A dependency that disables the secondary setting if the value of the primary setting
487 * @copyright 2010 Sam Hemelryk
488 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
490 class 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;
496 * Returns an array of properties suitable to be used to define a moodleforms
500 public function get_moodleform_properties() {
502 'setting'=>$this->dependentsetting->get_ui_name(),
503 'dependenton'=>$this->setting->get_ui_name(),
504 'condition'=>'notequal',
509 * Processes a value change in the primary setting
510 * @param mixed $oldvalue
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
520 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
521 if ($this->defaultvalue === false) {
522 $this->dependentsetting->set_value($value);
524 $this->dependentsetting->set_value($this->defaultvalue);
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);
530 // Return true if the value has changed for the dependent setting
531 return ($prevalue != $this->dependentsetting->get_value());
535 * Returns true if the dependent setting is locked.
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)) {
543 // Else return based upon the dependent settings status
544 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
549 * A dependency that disables the secondary setting if the value of the primary setting
552 * @copyright 2010 Sam Hemelryk
553 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
555 class 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;
561 * Returns an array of properties suitable to be used to define a moodleforms
565 public function get_moodleform_properties() {
567 'setting'=>$this->dependentsetting->get_ui_name(),
568 'dependenton'=>$this->setting->get_ui_name(),
569 'condition'=>'notequal',
574 * Processes a value change in the primary setting
575 * @param mixed $oldvalue
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();
583 // The dependent setting needs to be locked by hierachy and set to the
585 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
586 if ($this->defaultvalue === false) {
587 $this->dependentsetting->set_value($value);
589 $this->dependentsetting->set_value($this->defaultvalue);
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);
595 // Return true if the value has changed for the dependent setting
596 return ($prevalue != $this->dependentsetting->get_value());
599 * Returns true if the dependent setting is locked.
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)) {
607 // Else return based upon the dependent settings status
608 return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);