backup MDL-22140 Added conf settings to control the default general backup settings
[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();
145     /**
146      * Returns true if the dependent setting is locked.
147      * @return bool
148      */
149     abstract public function is_locked();
152 /**
153  * A dependency that disables the secondary setting if the primary setting is
154  * equal to the provided value
155  *
156  * @copyright 2010 Sam Hemelryk
157  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
158  */
159 class setting_dependency_disabledif_equals extends setting_dependency {
160     /**
161      * The value to compare to
162      * @var mixed
163      */
164     protected $value;
165     /**
166      * Creates the dependency
167      *
168      * @param base_setting $setting
169      * @param base_setting $dependentsetting
170      * @param mixed $value
171      * @param mixed $defaultvalue
172      */
173     public function __construct(base_setting $setting, base_setting $dependentsetting, $value, $defaultvalue = false) {
174         parent::__construct($setting, $dependentsetting, $defaultvalue);
175         $this->value = ($value)?(string)$value:0;
176     }
177     /**
178      * Returns true if the dependent setting is locked.
179      * @return bool
180      */
181     public function is_locked() {
182         // If the setting is locked or the dependent setting should be locked then return true
183         if ($this->setting->get_status() !== base_setting::NOT_LOCKED || $this->setting->get_value() == $this->value) {
184             return true;
185         }
186         // Else return based upon the dependent settings status
187         return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
188     }
189     /**
190      * Processes a value change in the primary setting
191      * @param mixed $oldvalue
192      * @return bool
193      */
194     protected function process_value_change($oldvalue) {
195         $prevalue = $this->dependentsetting->get_value();
196         // If the setting is the desired value enact the dependency
197         if ($this->setting->get_value() == $this->value) {
198             // The dependent setting needs to be locked by hierachy and set to the
199             // default value.
200             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
201             $this->dependentsetting->set_value($this->defaultvalue);
202         } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
203             // We can unlock the dependent setting
204             $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
205         }
206         // Return true if the value has changed for the dependent setting
207         return ($prevalue != $this->dependentsetting->get_value());
208     }
209     /**
210      * Processes a status change in the primary setting
211      * @param mixed $oldstatus
212      * @return bool
213      */
214     protected function process_status_change($oldstatus) {
215         // Store the dependent status
216         $prevalue = $this->dependentsetting->get_status();
217         // Store the current status
218         $currentstatus = $this->setting->get_status();
219         if ($currentstatus == base_setting::NOT_LOCKED) {
220             if ($prevalue == base_setting::LOCKED_BY_HIERARCHY && $this->setting->get_value() != $this->value) {
221                 // Dependency has changes, is not fine, unlock the dependent setting
222                 $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
223             }
224         } else {
225             // Make sure the dependent setting is also locked, in this case by hierarchy
226             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
227         }
228         // Return true if the dependent setting has changed.
229         return ($prevalue != $this->dependentsetting->get_status());
230     }
231     /**
232      * Enforces the dependency if required.
233      * @return bool True if there were changes
234      */
235     public function enforce() {
236         // This will be set to true if ANYTHING changes
237         $changes = false;
238         // First process any value changes
239         if ($this->process_value_change($this->setting->get_value())) {
240             $changes = true;
241         }
242         // Second process any status changes
243         if ($this->process_status_change($this->setting->get_status())) {
244             $changes = true;
245         }
246         // Finally process visibility changes
247         if ($this->process_visibility_change($this->setting->get_visibility())) {
248             $changes = true;
249         }
250         return $changes;
251     }
252     /**
253      * Returns an array of properties suitable to be used to define a moodleforms
254      * disabled command
255      * @return array
256      */
257     public function get_moodleform_properties() {
258         return array(
259             'setting'=>$this->dependentsetting->get_ui_name(),
260             'dependenton'=>$this->setting->get_ui_name(),
261             'condition'=>'eq',
262             'value'=>$this->value
263         );
264     }
266 /**
267  * A dependency that disables the secondary element if the primary element is
268  * true or checked
269  *
270  * @copyright 2010 Sam Hemelryk
271  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
272  */
273 class setting_dependency_disabledif_checked extends setting_dependency_disabledif_equals {
274     public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
275         parent::__construct($setting, $dependentsetting, true, $defaultvalue);
276         $this->value = true;
277     }
278     /**
279      * Returns an array of properties suitable to be used to define a moodleforms
280      * disabled command
281      * @return array
282      */
283     public function get_moodleform_properties() {
284         return array(
285             'setting'=>$this->dependentsetting->get_ui_name(),
286             'dependenton'=>$this->setting->get_ui_name(),
287             'condition'=>'checked'
288         );
289     }
292 /**
293  * A dependency that disables the secondary element if the primary element is
294  * false or not checked
295  *
296  * @copyright 2010 Sam Hemelryk
297  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
298  */
299 class setting_dependency_disabledif_not_checked extends setting_dependency_disabledif_equals {
300     public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
301         parent::__construct($setting, $dependentsetting, false, $defaultvalue);
302         $this->value = false;
303     }
304     /**
305      * Returns an array of properties suitable to be used to define a moodleforms
306      * disabled command
307      * @return array
308      */
309     public function get_moodleform_properties() {
310         return array(
311             'setting'=>$this->dependentsetting->get_ui_name(),
312             'dependenton'=>$this->setting->get_ui_name(),
313             'condition'=>'notchecked'
314         );
315     }
318 /**
319  * A dependency that disables the secondary setting if the value of the primary setting
320  * is not empty.
321  *
322  * @copyright 2010 Sam Hemelryk
323  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
324  */
325 class setting_dependency_disabledif_not_empty extends setting_dependency_disabledif_equals {
326     public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
327         parent::__construct($setting, $dependentsetting, false, $defaultvalue);
328         $this->value = false;
329     }
330     /**
331      * Returns an array of properties suitable to be used to define a moodleforms
332      * disabled command
333      * @return array
334      */
335     public function get_moodleform_properties() {
336         return array(
337             'setting'=>$this->dependentsetting->get_ui_name(),
338             'dependenton'=>$this->setting->get_ui_name(),
339             'condition'=>'notequal',
340             'value'=>''
341         );
342     }
343     /**
344      * Processes a value change in the primary setting
345      * @param mixed $oldvalue
346      * @return bool
347      */
348     protected function process_value_change($oldvalue) {
349         $prevalue = $this->dependentsetting->get_value();
350         // If the setting is the desired value enact the dependency
351         $value = $this->setting->get_value();
352         if (!empty($value)) {
353             // The dependent setting needs to be locked by hierachy and set to the
354             // default value.
355             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
356             if ($this->defaultvalue === false) {
357                 $this->dependentsetting->set_value($value);
358             } else {
359                 $this->dependentsetting->set_value($this->defaultvalue);
360             }
361         } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
362             // We can unlock the dependent setting
363             $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
364         }
365         // Return true if the value has changed for the dependent setting
366         return ($prevalue != $this->dependentsetting->get_value());
367     }
369     /**
370      * Returns true if the dependent setting is locked.
371      * @return bool
372      */
373     public function is_locked() {
374         // If the setting is locked or the dependent setting should be locked then return true
375         if ($this->setting->get_status() !== base_setting::NOT_LOCKED || !empty($value)) {
376             return true;
377         }
378         // Else return based upon the dependent settings status
379         return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
380     }
383 /**
384  * A dependency that disables the secondary setting if the value of the primary setting
385  * is empty.
386  *
387  * @copyright 2010 Sam Hemelryk
388  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
389  */
390 class setting_dependency_disabledif_empty extends setting_dependency_disabledif_equals {
391     public function __construct(base_setting $setting, base_setting $dependentsetting, $defaultvalue = false) {
392         parent::__construct($setting, $dependentsetting, false, $defaultvalue);
393         $this->value = false;
394     }
395     /**
396      * Returns an array of properties suitable to be used to define a moodleforms
397      * disabled command
398      * @return array
399      */
400     public function get_moodleform_properties() {
401         return array(
402             'setting'=>$this->dependentsetting->get_ui_name(),
403             'dependenton'=>$this->setting->get_ui_name(),
404             'condition'=>'notequal',
405             'value'=>''
406         );
407     }
408     /**
409      * Processes a value change in the primary setting
410      * @param mixed $oldvalue
411      * @return bool
412      */
413     protected function process_value_change($oldvalue) {
414         $prevalue = $this->dependentsetting->get_value();
415         // If the setting is the desired value enact the dependency
416         $value = $this->setting->get_value();
417         if (empty($value)) {
418             // The dependent setting needs to be locked by hierachy and set to the
419             // default value.
420             $this->dependentsetting->set_status(base_setting::LOCKED_BY_HIERARCHY);
421             if ($this->defaultvalue === false) {
422                 $this->dependentsetting->set_value($value);
423             } else {
424                 $this->dependentsetting->set_value($this->defaultvalue);
425             }
426         } else if ($this->dependentsetting->get_status() == base_setting::LOCKED_BY_HIERARCHY) {
427             // We can unlock the dependent setting
428             $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
429         }
430         // Return true if the value has changed for the dependent setting
431         return ($prevalue != $this->dependentsetting->get_value());
432     }
433     /**
434      * Returns true if the dependent setting is locked.
435      * @return bool
436      */
437     public function is_locked() {
438         // If the setting is locked or the dependent setting should be locked then return true
439         if ($this->setting->get_status() !== base_setting::NOT_LOCKED || empty($value)) {
440             return true;
441         }
442         // Else return based upon the dependent settings status
443         return ($this->dependentsetting->get_status() !== base_setting::NOT_LOCKED);
444     }