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();
81 * Processes a change is setting called by the primary setting
82 * @param int $changetype
83 * @param mixed $oldvalue
86 final public function process_change($changetype, $oldvalue) {
87 // Check the type of change requested
88 switch ($changetype) {
89 // Process a status change
90 case base_setting::CHANGED_STATUS: return $this->process_status_change($oldvalue);
91 // Process a visibility change
92 case base_setting::CHANGED_VISIBILITY: return $this->process_visibility_change($oldvalue);
93 // Process a value change
94 case base_setting::CHANGED_VALUE: return $this->process_value_change($oldvalue);
96 // Throw an exception if we get this far
97 throw new backup_ui_exception('unknownchangetype');
100 * Processes a visibility change
101 * @param bool $oldvisibility
104 protected function process_visibility_change($oldvisibility) {
105 // Store the current dependent settings visibility for comparison
106 $prevalue = $this->dependentsetting->get_visibility();
107 // Set it regardless of whether we need to
108 $this->dependentsetting->set_visibility($this->setting->get_visibility());
109 // Return true if it changed
110 return ($prevalue != $this->dependentsetting->get_visibility());
113 * All dependencies must define how they would like to deal with a status change
114 * @param int $oldstatus
116 abstract protected function process_status_change($oldstatus);
118 * All dependencies must define how they would like to process a value change
120 abstract protected function process_value_change($oldvalue);
122 * Gets the primary setting
123 * @return backup_setting
125 public function get_setting() {
126 return $this->setting;
129 * Gets the dependent setting
130 * @return backup_setting
132 public function get_dependent_setting() {
133 return $this->dependentsetting;
136 * This function enforces the dependency
138 abstract public function enforce();
140 * Returns an array of properties suitable to be used to define a moodleforms
144 abstract public function get_moodleform_properties();
148 * A dependency that disables the secondary setting if the primary setting is
149 * equal to the provided value
151 * @copyright 2010 Sam Hemelryk
152 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
154 class setting_dependency_disabledif_equals extends setting_dependency {
156 * The value to compare to
161 * Creates the dependency
163 * @param base_setting $setting
164 * @param base_setting $dependentsetting
165 * @param mixed $value
166 * @param mixed $defaultvalue
168 public function __construct(base_setting $setting, base_setting $dependentsetting, $value, $defaultvalue = false) {
169 parent::__construct($setting, $dependentsetting, $defaultvalue);
170 $this->value = ($value)?(string)$value:0;
173 * Processes a value change in the primary setting
174 * @param mixed $oldvalue
177 protected function process_value_change($oldvalue) {
178 $prevalue = $this->dependentsetting->get_value();
179 // If the setting is the desired value enact the dependency
180 if ($this->setting->get_value() == $this->value) {
181 // The dependent setting needs to be locked by hierachy and set to the
183 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
184 $this->dependentsetting->set_value($this->defaultvalue);
185 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
186 // We can unlock the dependent setting
187 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
189 // Return true if the value has changed for the dependent setting
190 return ($prevalue != $this->dependentsetting->get_value());
193 * Processes a status change in the primary setting
194 * @param mixed $oldstatus
197 protected function process_status_change($oldstatus) {
198 // Store the dependent status
199 $prevalue = $this->dependentsetting->get_status();
200 // Store the current status
201 $currentstatus = $this->setting->get_status();
202 if ($currentstatus == base_setting::NOT_LOCKED) {
203 if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && $this->setting->get_value() != $this->value) {
204 // Dependency has changes, is not fine, unlock the dependent setting
205 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
208 // Make sure the dependent setting is also locked, in this case by hierarchy
209 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
211 // Return true if the dependent setting has changed.
212 return ($prevalue != $this->dependentsetting->get_status());
215 * Enforces the dependency if required.
216 * @return bool True if there were changes
218 public function enforce() {
219 // This will be set to true if ANYTHING changes
221 // First process any value changes
222 if ($this->process_value_change($this->setting->get_value())) {
225 // Second process any status changes
226 if ($this->process_status_change($this->setting->get_status())) {
229 // Finally process visibility changes
230 if ($this->process_visibility_change($this->setting->get_visibility())) {
236 * Returns an array of properties suitable to be used to define a moodleforms
240 public function get_moodleform_properties() {
242 'setting'=>$this->dependentsetting->get_ui_name(),
243 'dependenton'=>$this->setting->get_ui_name(),
245 'value'=>$this->value
250 * A dependency that disables the secondary element if the primary element is
253 * @copyright 2010 Sam Hemelryk
254 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
256 class setting_dependency_disabledif_checked extends setting_dependency_disabledif_equals {
257 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
258 parent::__construct($setting, $dependentsetting, true, $defaultvalue);
262 * Returns an array of properties suitable to be used to define a moodleforms
266 public function get_moodleform_properties() {
268 'setting'=>$this->dependentsetting->get_ui_name(),
269 'dependenton'=>$this->setting->get_ui_name(),
270 'condition'=>'checked'
276 * A dependency that disables the secondary element if the primary element is
277 * false or not checked
279 * @copyright 2010 Sam Hemelryk
280 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
282 class setting_dependency_disabledif_not_checked extends setting_dependency_disabledif_equals {
283 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
284 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
285 $this->value = false;
288 * Returns an array of properties suitable to be used to define a moodleforms
292 public function get_moodleform_properties() {
294 'setting'=>$this->dependentsetting->get_ui_name(),
295 'dependenton'=>$this->setting->get_ui_name(),
296 'condition'=>'notchecked'
302 * A dependency that disables the secondary setting if the value of the primary setting
305 * @copyright 2010 Sam Hemelryk
306 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
308 class setting_dependency_disabledif_not_empty extends setting_dependency_disabledif_equals {
309 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
310 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
311 $this->value = false;
314 * Returns an array of properties suitable to be used to define a moodleforms
318 public function get_moodleform_properties() {
320 'setting'=>$this->dependentsetting->get_ui_name(),
321 'dependenton'=>$this->setting->get_ui_name(),
322 'condition'=>'notequal',
327 * Processes a value change in the primary setting
328 * @param mixed $oldvalue
331 protected function process_value_change($oldvalue) {
332 $prevalue = $this->dependentsetting->get_value();
333 // If the setting is the desired value enact the dependency
334 $value = $this->setting->get_value();
335 if (!empty($value)) {
336 // The dependent setting needs to be locked by hierachy and set to the
338 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
339 if ($this->defaultvalue === false) {
340 $this->dependentsetting->set_value($value);
342 $this->dependentsetting->set_value($this->defaultvalue);
344 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
345 // We can unlock the dependent setting
346 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
348 // Return true if the value has changed for the dependent setting
349 return ($prevalue != $this->dependentsetting->get_value());
354 * A dependency that disables the secondary setting if the value of the primary setting
357 * @copyright 2010 Sam Hemelryk
358 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
360 class setting_dependency_disabledif_empty extends setting_dependency_disabledif_equals {
361 public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
362 parent::__construct($setting, $dependentsetting, false, $defaultvalue);
363 $this->value = false;
366 * Returns an array of properties suitable to be used to define a moodleforms
370 public function get_moodleform_properties() {
372 'setting'=>$this->dependentsetting->get_ui_name(),
373 'dependenton'=>$this->setting->get_ui_name(),
374 'condition'=>'notequal',
379 * Processes a value change in the primary setting
380 * @param mixed $oldvalue
383 protected function process_value_change($oldvalue) {
384 $prevalue = $this->dependentsetting->get_value();
385 // If the setting is the desired value enact the dependency
386 $value = $this->setting->get_value();
388 // The dependent setting needs to be locked by hierachy and set to the
390 $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
391 if ($this->defaultvalue === false) {
392 $this->dependentsetting->set_value($value);
394 $this->dependentsetting->set_value($this->defaultvalue);
396 } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
397 // We can unlock the dependent setting
398 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
400 // Return true if the value has changed for the dependent setting
401 return ($prevalue != $this->dependentsetting->get_value());