7c612f356fd78beecf9584f208f171b151c6f6ca
[moodle.git] / backup / util / settings / setting_dependency.class.php
1 <?php
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/>.
18 /**
19  * @package   moodlecore
20  * @copyright 2010 Sam Hemelryk
21  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
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  */
30 abstract class setting_dependency {
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;
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;
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     }
80     /**
81      * Processes a change is setting called by the primary setting
82      * @param int $changetype
83      * @param mixed $oldvalue
84      * @return bool
85      */
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);
95         }
96         // Throw an exception if we get this far
97         throw new backup_ui_exception('unknownchangetype');
98     }
99     /**
100      * Processes a visibility change
101      * @param bool $oldvisibility
102      * @return bool
103      */
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());
111     }
112     /**
113      * All dependencies must define how they would like to deal with a status change
114      * @param int $oldstatus
115      */
116     abstract protected function process_status_change($oldstatus);
117     /**
118      * All dependencies must define how they would like to process a value change
119      */
120     abstract protected function process_value_change($oldvalue);
121     /**
122      * Gets the primary setting
123      * @return backup_setting
124      */
125     public function get_setting() {
126         return $this->setting;
127     }
128     /**
129      * Gets the dependent setting
130      * @return backup_setting
131      */
132     public function get_dependent_setting() {
133         return $this->dependentsetting;
134     }
135     /**
136      * This function enforces the dependency
137      */
138     abstract public function enforce();
139     /**
140      * Returns an array of properties suitable to be used to define a moodleforms
141      * disabled command
142      * @return array
143      */
144     abstract public function get_moodleform_properties();
147 /**
148  * A dependency that disables the secondary setting if the primary setting is
149  * equal to the provided value
150  *
151  * @copyright 2010 Sam Hemelryk
152  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
153  */
154 class setting_dependency_disabledif_equals extends setting_dependency {
155     /**
156      * The value to compare to
157      * @var mixed
158      */
159     protected $value;
160     /**
161      * Creates the dependency
162      *
163      * @param base_setting $setting
164      * @param base_setting $dependentsetting
165      * @param mixed $value
166      * @param mixed $defaultvalue
167      */
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;
171     }
172     /**
173      * Processes a value change in the primary setting
174      * @param mixed $oldvalue
175      * @return bool
176      */
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
182             // default value.
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);
188         }
189         // Return true if the value has changed for the dependent setting
190         return ($prevalue != $this->dependentsetting->get_value());
191     }
192     /**
193      * Processes a status change in the primary setting
194      * @param mixed $oldstatus
195      * @return bool
196      */
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);
206             }
207         } else {
208             // Make sure the dependent setting is also locked, in this case by hierarchy
209             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
210         }
211         // Return true if the dependent setting has changed.
212         return ($prevalue != $this->dependentsetting->get_status());
213     }
214     /**
215      * Enforces the dependency if required.
216      * @return bool True if there were changes
217      */
218     public function enforce() {
219         // This will be set to true if ANYTHING changes
220         $changes = false;
221         // First process any value changes
222         if ($this->process_value_change($this->setting->get_value())) {
223             $changes = true;
224         }
225         // Second process any status changes
226         if ($this->process_status_change($this->setting->get_status())) {
227             $changes = true;
228         }
229         // Finally process visibility changes
230         if ($this->process_visibility_change($this->setting->get_visibility())) {
231             $changes = true;
232         }
233         return $changes;
234     }
235     /**
236      * Returns an array of properties suitable to be used to define a moodleforms
237      * disabled command
238      * @return array
239      */
240     public function get_moodleform_properties() {
241         return array(
242             'setting'=>$this->dependentsetting->get_ui_name(),
243             'dependenton'=>$this->setting->get_ui_name(),
244             'condition'=>'eq',
245             'value'=>$this->value
246         );
247     }
249 /**
250  * A dependency that disables the secondary element if the primary element is
251  * true or checked
252  *
253  * @copyright 2010 Sam Hemelryk
254  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
255  */
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);
259         $this->value = true;
260     }
261     /**
262      * Returns an array of properties suitable to be used to define a moodleforms
263      * disabled command
264      * @return array
265      */
266     public function get_moodleform_properties() {
267         return array(
268             'setting'=>$this->dependentsetting->get_ui_name(),
269             'dependenton'=>$this->setting->get_ui_name(),
270             'condition'=>'checked'
271         );
272     }
275 /**
276  * A dependency that disables the secondary element if the primary element is
277  * false or not checked
278  *
279  * @copyright 2010 Sam Hemelryk
280  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
281  */
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;
286     }
287     /**
288      * Returns an array of properties suitable to be used to define a moodleforms
289      * disabled command
290      * @return array
291      */
292     public function get_moodleform_properties() {
293         return array(
294             'setting'=>$this->dependentsetting->get_ui_name(),
295             'dependenton'=>$this->setting->get_ui_name(),
296             'condition'=>'notchecked'
297         );
298     }
301 /**
302  * A dependency that disables the secondary setting if the value of the primary setting
303  * is not empty.
304  *
305  * @copyright 2010 Sam Hemelryk
306  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
307  */
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;
312     }
313     /**
314      * Returns an array of properties suitable to be used to define a moodleforms
315      * disabled command
316      * @return array
317      */
318     public function get_moodleform_properties() {
319         return array(
320             'setting'=>$this->dependentsetting->get_ui_name(),
321             'dependenton'=>$this->setting->get_ui_name(),
322             'condition'=>'notequal',
323             'value'=>''
324         );
325     }
326     /**
327      * Processes a value change in the primary setting
328      * @param mixed $oldvalue
329      * @return bool
330      */
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
337             // default value.
338             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
339             if ($this->defaultvalue === false) {
340                 $this->dependentsetting->set_value($value);
341             } else {
342                 $this->dependentsetting->set_value($this->defaultvalue);
343             }
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);
347         }
348         // Return true if the value has changed for the dependent setting
349         return ($prevalue != $this->dependentsetting->get_value());
350     }
353 /**
354  * A dependency that disables the secondary setting if the value of the primary setting
355  * is empty.
356  *
357  * @copyright 2010 Sam Hemelryk
358  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
359  */
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;
364     }
365     /**
366      * Returns an array of properties suitable to be used to define a moodleforms
367      * disabled command
368      * @return array
369      */
370     public function get_moodleform_properties() {
371         return array(
372             'setting'=>$this->dependentsetting->get_ui_name(),
373             'dependenton'=>$this->setting->get_ui_name(),
374             'condition'=>'notequal',
375             'value'=>''
376         );
377     }
378     /**
379      * Processes a value change in the primary setting
380      * @param mixed $oldvalue
381      * @return bool
382      */
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();
387         if (empty($value)) {
388             // The dependent setting needs to be locked by hierachy and set to the
389             // default value.
390             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
391             if ($this->defaultvalue === false) {
392                 $this->dependentsetting->set_value($value);
393             } else {
394                 $this->dependentsetting->set_value($this->defaultvalue);
395             }
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);
399         }
400         // Return true if the value has changed for the dependent setting
401         return ($prevalue != $this->dependentsetting->get_value());
402     }