MDL-35603 - Backup - Course import selector notice
[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     }
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     }
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      */
142     public function get_dependent_setting() {
143         return $this->dependentsetting;
144     }
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();
155     /**
156      * Returns true if the dependent setting is locked.
157      * @return bool
158      */
159     abstract public function is_locked();
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  */
169 class 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);
185         $this->value = ($value)?(string)$value:0;
186     }
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     }
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) {
213             // We can unlock the dependent setting
214             $this->dependentsetting->set_status(base_setting::NOT_LOCKED);
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     }
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     }
277 /**
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
283 */
284 class 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     }
321 //with array
322 class 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     }
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  */
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);
441         $this->value = true;
442     }
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     }
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  */
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;
468     }
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     }
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  */
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;
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     }
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     }
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  */
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;
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     }
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     }