9ef58656a24880df2abe37c064444e2b843c0a93
[moodle.git] / backup / util / ui / backup_ui_setting.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  * This file contains the setting user interface classes that all backup/restore
20  * settings use to represent the UI they have.
21  *
22  * @package   moodlecore
23  * @copyright 2010 Sam Hemelryk
24  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
27 /**
28  * Abstract class used to represent the user interface that a setting has.
29  *
30  * @todo extend as required for restore
31  * @copyright 2010 Sam Hemelryk
32  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33  */
34 class base_setting_ui {
35     /**
36      * Prefix applied to all inputs/selects
37      */
38     const NAME_PREFIX = 'setting_';
39     /**
40      * The name of the setting
41      * @var string
42      */
43     protected $name;
44     /**
45      * The label for the setting
46      * @var string
47      */
48     protected $label;
49     /**
50      * An array of HTML attributes to apply to this setting
51      * @var array
52      */
53     protected $attributes = array();
54     /**
55      * The backup_setting UI type this relates to. One of backup_setting::UI_*;
56      * @var int
57      */
58     protected $type;
59     /**
60      * An icon to display next to this setting in the UI
61      * @var pix_icon
62      */
63     protected $icon = false;
64     /**
65      * The setting this UI belongs to (parent reference)
66      * @var base_setting|backup_setting
67      */
68     protected $setting;
69     /**
70      * Constructors are sooooo cool
71      * @param base_setting $setting
72      */
73     public function __construct(base_setting $setting) {
74         $this->setting = $setting;
75     }
77     /**
78      * Destroy all circular references. It helps PHP 5.2 a lot!
79      */
80     public function destroy() {
81         // No need to destroy anything recursively here, direct reset
82         $this->setting = null;
83     }
85     /**
86      * Gets the name of this item including its prefix
87      * @return string
88      */
89     public function get_name() {
90         return self::NAME_PREFIX.$this->name;
91     }
92     /**
93      * Gets the name of this item including its prefix
94      * @return string
95      */
96     public function get_label() {
97         return $this->label;
98     }
99     /**
100      * Gets the type of this element
101      * @return int
102      */
103     public function get_type() {
104         return $this->type;
105     }
106     /**
107      * Gets the HTML attributes for this item
108      * @return array
109      */
110     public function get_attributes() {
111         return $this->attributes;
112     }
113     /**
114      * Gets the value of this setting
115      * @return mixed
116      */
117     public function get_value() {
118         return $this->setting->get_value();
119     }
120     /**
121      * Gets the value to display in a static quickforms element
122      * @return mixed
123      */
124     public function get_static_value() {
125         return $this->setting->get_value();
126     }
128     /**
129      * Gets the the PARAM_XXXX validation to be applied to the setting
130      *
131      * return string The PARAM_XXXX constant of null if the setting type is not defined
132      */
133     public function get_param_validation() {
134         return $this->setting->get_param_validation();
135     }
137     /**
138      * Sets the label
139      * @param string $label
140      */
141     public function set_label($label) {
142         if ((string)$label === '' || $label !== clean_param($label, PARAM_TEXT)) {
143             throw new base_setting_ui_exception('setting_invalid_ui_label');
144         }
145         $this->label = $label;
146     }
147     /**
148      * Disables the UI for this element
149      */
150     public function disable() {
151        $this->attributes['disabled'] = 'disabled';
152     }
154     /**
155      * Sets the icon to display next to this item
156      *
157      * @param pix_icon $icon
158      */
159     public function set_icon(pix_icon $icon) {
160         $this->icon = $icon;
161     }
163     /**
164      * Returns the icon to display next to this item, or false if there isn't one.
165      *
166      * @return pix_icon|false
167      */
168     public function get_icon() {
169         if (!empty($this->icon)) {
170             return $this->icon;
171         }
172         return false;
173     }
176 /**
177  * Abstract class to represent the user interface backup settings have
178  *
179  * @copyright 2010 Sam Hemelryk
180  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
181  */
182 abstract class backup_setting_ui extends base_setting_ui {
183     /**
184      * An array of options relating to this setting
185      * @var array
186      */
187     protected $options = array();
189     /**
190      * JAC... Just Another Constructor
191      *
192      * @param backup_setting $setting
193      * @param string|null $label The label to display with the setting ui
194      * @param array|null $attributes Array of HTML attributes to apply to the element
195      * @param array|null $options Array of options to apply to the setting ui object
196      */
197     public function __construct(backup_setting $setting, $label = null, array $attributes = null, array $options = null) {
198         parent::__construct($setting);
199         // Improve the inputs name by appending the level to the name
200         switch ($setting->get_level()) {
201             case backup_setting::ROOT_LEVEL :
202                 $this->name = 'root_'.$setting->get_name();
203                 break;
204             case backup_setting::COURSE_LEVEL :
205                 $this->name = 'course_'.$setting->get_name();
206                 break;
207             case backup_setting::SECTION_LEVEL :
208                 $this->name = 'section_'.$setting->get_name();
209                 break;
210             case backup_setting::ACTIVITY_LEVEL :
211                 $this->name = 'activity_'.$setting->get_name();
212                 break;
213         }
214         $this->label = $label;
215         if (is_array($attributes)) {
216             $this->attributes = $attributes;
217         }
218         if (is_array($options)) {
219             $this->options = $options;
220         }
221     }
222     /**
223      * Creates a new backup setting ui based on the setting it is given
224      *
225      * Throws an exception if an invalid type is provided.
226      *
227      * @param backup_setting $setting
228      * @param int $type The backup_setting UI type. One of backup_setting::UI_*;
229      * @param string $label The label to display with the setting ui
230      * @param array $attributes Array of HTML attributes to apply to the element
231      * @param array $options Array of options to apply to the setting ui object
232      *
233      * @return backup_setting_ui_text|backup_setting_ui_checkbox|backup_setting_ui_select|backup_setting_ui_radio
234      */
235     final public static function make(backup_setting $setting, $type, $label, array $attributes = null, array $options=null) {
236         // Base the decision we make on the type that was sent
237         switch ($type) {
238             case backup_setting::UI_HTML_CHECKBOX :
239                 return new backup_setting_ui_checkbox($setting, $label, null, (array)$attributes, (array)$options);
240             case backup_setting::UI_HTML_DROPDOWN :
241                 return new backup_setting_ui_select($setting, $label, null, (array)$attributes, (array)$options);
242             case backup_setting::UI_HTML_RADIOBUTTON :
243                 return new backup_setting_ui_radio($setting, $label, null, null, (array)$attributes, (array)$options);
244             case backup_setting::UI_HTML_TEXTFIELD :
245                 return new backup_setting_ui_text($setting, $label, $attributes, $options);
246             default:
247                 throw new backup_setting_ui_exception('setting_invalid_ui_type');
248         }
249     }
250     /**
251      * Get element properties that can be used to make a quickform element
252      * @return array
253      */
254     abstract public function get_element_properties(base_task $task=null, renderer_base $output=null);
255     /**
256      * Applies config options to a given properties array and then returns it
257      * @param array $properties
258      * @return array
259      */
260     public function apply_options(array $properties) {
261         if (!empty($this->options['size'])) {
262             $properties['attributes']['size'] = $this->options['size'];
263         }
264         return $properties;
265     }
266     /**
267      * Gets the label for this item
268      * @param backup_task|null $task Optional, if provided and the setting is an include
269      *          $task is used to set the setting label
270      * @return string
271      */
272     public function get_label(base_task $task=null) {
273         // If a task has been provided and the label is not already set meaniningfully
274         // we will attempt to improve it.
275         if (!is_null($task) && $this->label == $this->setting->get_name() && strpos($this->setting->get_name(), '_include')!==false) {
276             if ($this->setting->get_level() == backup_setting::SECTION_LEVEL) {
277                 $this->label = get_string('includesection', 'backup', $task->get_name());
278             } else if ($this->setting->get_level() == backup_setting::ACTIVITY_LEVEL) {
279                 $this->label = $task->get_name();
280             }
281         }
282         return $this->label;
283     }
284     /**
285      * Returns true if the setting is changeable.
286      *
287      * A setting is changeable if it meets either of the two following conditions.
288      *
289      * 1. The setting is not locked
290      * 2. The setting is locked but only by settings that are of the same level (same page)
291      *
292      * Condition 2 is really why we have this function
293      *
294      * @return bool
295      */
296     public function is_changeable() {
297         if ($this->setting->get_status() === backup_setting::NOT_LOCKED) {
298             // Its not locked so its chanegable
299             return true;
300         } else if ($this->setting->get_status() !== backup_setting::LOCKED_BY_HIERARCHY) {
301             // Its not changeable because its locked by permission or config
302             return false;
303         } else if ($this->setting->has_dependencies_on_settings()) {
304             foreach ($this->setting->get_settings_depended_on() as $dependency) {
305                 if ($dependency->is_locked() && $dependency->get_setting()->get_level() !== $this->setting->get_level()) {
306                     // Its not changeable because one or more dependancies arn't
307                     // changeable.
308                    return false;
309                 }
310             }
311             // Its changeable because all dependencies are changeable.
312             return true;
313         }
314         // We should never get here but if we do return false to be safe.
315         // The setting would need to be locked by hierarchy and not have any deps
316         return false;
317     }
321 /**
322  * A text input user interface element for backup settings
323  *
324  * @copyright 2010 Sam Hemelryk
325  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
326  */
327 class backup_setting_ui_text extends backup_setting_ui {
328     /**
329      * @var int
330      */
331     protected $type = backup_setting::UI_HTML_TEXTFIELD;
332     /**
333      * Returns an array of properties suitable for generating a quickforms element
334      * @param backup_task|null $task
335      * @return array (element, name, label, attributes)
336      */
337     public function get_element_properties(base_task $task=null, renderer_base $output=null) {
338         // name, label, text, attributes
339         $icon = $this->get_icon();
340         $label = $this->get_label($task);
341         if (!empty($icon)) {
342             $label .= $output->render($icon);
343         }
344         // name, label, attributes
345         return $this->apply_options(array('element'=>'text','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'attributes'=>$this->attributes));
346     }
350 /**
351  * A checkbox user interface element for backup settings (default)
352  *
353  * @copyright 2010 Sam Hemelryk
354  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
355  */
356 class backup_setting_ui_checkbox extends backup_setting_ui {
357     /**
358      * @var int
359      */
360     protected $type = backup_setting::UI_HTML_CHECKBOX;
361     /**
362      * @var bool
363      */
364     protected $changeable = true;
365     /**
366      * The text to show next to the checkbox
367      * @var string
368      */
369     protected $text;
370     /**
371      * Overridden constructor so we can take text argument
372      * @param backup_setting $setting
373      * @param string $label
374      * @param string $text
375      * @param array $attributes
376      * @param array $options
377      */
378     public function __construct(backup_setting $setting, $label = null, $text=null, array $attributes = array(), array $options = array()) {
379         parent::__construct($setting, $label, $attributes, $options);
380         $this->text = $text;
381     }
382     /**
383      * Returns an array of properties suitable for generating a quickforms element
384      * @param backup_task|null $task
385      * @return array (element, name, label, text, attributes);
386      */
387     public function get_element_properties(base_task $task=null, renderer_base $output=null) {
388         // name, label, text, attributes
390         $icon = $this->get_icon();
391         $label = $this->get_label($task);
392         if (!empty($icon)) {
393             $label .= $output->render($icon);
394         }
395         return $this->apply_options(array('element'=>'checkbox','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'text'=>$this->text, 'attributes'=>$this->attributes));
396     }
397     /**
398      * Sets the text for the element
399      * @param string $text
400      */
401     public function set_text($text) {
402         $this->text = $text;
403     }
404     /**
405      * Gets the static value for the element
406      * @global core_renderer $OUTPUT
407      * @return string
408      */
409     public function get_static_value() {
410         global $OUTPUT;
411         // Checkboxes are always yes or no
412         if ($this->get_value()) {
413             return $OUTPUT->pix_icon('i/valid', get_string('yes'));
414         } else {
415             return $OUTPUT->pix_icon('i/invalid', get_string('no'));
416         }
417     }
419     /**
420      * Returns true if the setting is changeable
421      * @return bool
422      */
423     public function is_changeable() {
424         if ($this->changeable===false) {
425             return false;
426         } else {
427             return parent::is_changeable();
428         }
429     }
431     /**
432      * Sets whether the setting is changeable,
433      * Note dependencies can still mark this setting changeable or not
434      * @param bool $newvalue
435      */
436     public function set_changeable($newvalue) {
437         $this->changeable = ($newvalue);
438     }
441 /**
442  * Radio button user interface element for backup settings
443  *
444  * @copyright 2010 Sam Hemelryk
445  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
446  */
447 class backup_setting_ui_radio extends backup_setting_ui {
448     /**
449      * @var int
450      */
451     protected $type = backup_setting::UI_HTML_RADIOBUTTON;
452     /**
453      * The string shown next to the input
454      * @var string
455      */
456     protected $text;
457     /**
458      * The value for the radio input
459      * @var string
460      */
461     protected $value;
462     /**
463      *
464      * @param backup_setting $setting
465      * @param string $label
466      * @param string $text
467      * @param string $value
468      * @param array $attributes
469      * @param array $options
470      */
471     public function __construct(backup_setting $setting, $label = null, $text=null, $value=null, array $attributes = array(), array $options = array()) {
472         parent::__construct($setting, $label, $attributes, $options);
473         $this->text = $text;
474         $this->value = (string)$value;
475     }
476     /**
477      * Returns an array of properties suitable for generating a quickforms element
478      * @param backup_task|null $task
479      * @return array (element, name, label, text, value, attributes)
480      */
481     public function get_element_properties(base_task $task=null, renderer_base $output=null) {
482         // name, label, text, attributes
483         $icon = $this->get_icon();
484         $label = $this->get_label($task);
485         if (!empty($icon)) {
486             $label .= $output->render($icon);
487         }
488         // name, label, text, value, attributes
489         return $this->apply_options(array('element'=>'radio','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'text'=>$this->text, 'value'=>$this->value, 'attributes'=>$this->attributes));
490     }
491     /**
492      * Sets the text next to this input
493      * @param text $text
494      */
495     public function set_text($text) {
496         $this->text = $text;
497     }
498     /**
499      * Sets the value for the input
500      * @param string $value
501      */
502     public function set_value($value) {
503         $this->value = (string)$value;
504     }
505     /**
506      * Gets the static value to show for the element
507      */
508     public function get_static_value() {
509         return $this->value;
510     }
513 /**
514  * A select box, drop down user interface for backup settings
515  *
516  * @copyright 2010 Sam Hemelryk
517  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
518  */
519 class backup_setting_ui_select extends backup_setting_ui {
520     /**
521      * @var int
522      */
523     protected $type = backup_setting::UI_HTML_DROPDOWN;
524     /**
525      * An array of options to display in the select
526      * @var array
527      */
528     protected $values;
529     /**
530      *
531      * @param backup_setting $setting
532      * @param string $label
533      * @param array $values
534      * @param array $attributes
535      * @param array $options
536      */
537     public function __construct(backup_setting $setting, $label = null, $values=null, array $attributes = array(), array $options = array()) {
538         parent::__construct($setting, $label, $attributes, $options);
539         $this->values = $values;
540     }
541     /**
542      * Returns an array of properties suitable for generating a quickforms element
543      * @param backup_task|null $task
544      * @return array (element, name, label, options, attributes)
545      */
546     public function get_element_properties(base_task $task = null, renderer_base $output=null) {
547         // name, label, text, attributes
548         $icon = $this->get_icon();
549         $label = $this->get_label($task);
550         if (!empty($icon)) {
551             $label .= $output->render($icon);
552         }
553         // name, label, options, attributes
554         return $this->apply_options(array('element'=>'select','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'options'=>$this->values, 'attributes'=>$this->attributes));
555     }
556     /**
557      * Sets the options for the select box
558      * @param array $values Associative array of value=>text options
559      */
560     public function set_values(array $values) {
561         $this->values = $values;
562     }
563     /**
564      * Gets the static value for this select element
565      * @return string
566      */
567     public function get_static_value() {
568         return $this->values[$this->get_value()];
569     }
570     /**
571      * Returns true if the setting is changeable, false otherwise
572      *
573      * @return bool
574      */
575     public function is_changeable() {
576         if (count($this->values) == 1) {
577             return false;
578         } else {
579             return parent::is_changeable();
580         }
581     }
584 class backup_setting_ui_dateselector extends backup_setting_ui_text {
585     public function get_element_properties(base_task $task = null, renderer_base $output=null) {
586         if (!array_key_exists('optional', $this->attributes)) {
587             $this->attributes['optional'] = false;
588         }
589         $properties = parent::get_element_properties($task, $output);
590         $properties['element'] = 'date_selector';
591         return $properties;
592     }
593     public function get_static_value() {
594         $value = $this->get_value();
595         if (!empty($value)) {
596             return userdate($value);
597         }
598         return parent::get_static_value();
599     }
602 class base_setting_ui_exception extends base_setting_exception {}
603 class backup_setting_ui_exception extends base_setting_ui_exception {};