Merge branch 'MDL-22309_master' of git://github.com/dmonllao/moodle
[moodle.git] / backup / util / ui / backup_ui_setting.class.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * This file contains the setting user interface classes that all backup/restore
19  * settings use to represent the UI they have.
20  *
21  * @package   core_backup
22  * @copyright 2010 Sam Hemelryk
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 /**
27  * Abstract class used to represent the user interface that a setting has.
28  *
29  * @todo extend as required for restore
30  * @package core_backup
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;
70     /**
71      * Constructors are sooooo cool
72      * @param base_setting $setting
73      */
74     public function __construct(base_setting $setting) {
75         $this->setting = $setting;
76     }
78     /**
79      * Destroy all circular references. It helps PHP 5.2 a lot!
80      */
81     public function destroy() {
82         // No need to destroy anything recursively here, direct reset.
83         $this->setting = null;
84     }
86     /**
87      * Gets the name of this item including its prefix
88      * @return string
89      */
90     public function get_name() {
91         return self::NAME_PREFIX.$this->name;
92     }
94     /**
95      * Gets the name of this item including its prefix
96      * @return string
97      */
98     public function get_label() {
99         return $this->label;
100     }
102     /**
103      * Gets the type of this element
104      * @return int
105      */
106     public function get_type() {
107         return $this->type;
108     }
110     /**
111      * Gets the HTML attributes for this item
112      * @return array
113      */
114     public function get_attributes() {
115         return $this->attributes;
116     }
118     /**
119      * Gets the value of this setting
120      * @return mixed
121      */
122     public function get_value() {
123         return $this->setting->get_value();
124     }
126     /**
127      * Gets the value to display in a static quickforms element
128      * @return mixed
129      */
130     public function get_static_value() {
131         return $this->setting->get_value();
132     }
134     /**
135      * Gets the the PARAM_XXXX validation to be applied to the setting
136      *
137      * return string The PARAM_XXXX constant of null if the setting type is not defined
138      */
139     public function get_param_validation() {
140         return $this->setting->get_param_validation();
141     }
143     /**
144      * Sets the label.
145      *
146      * @throws base_setting_ui_exception when the label is not valid.
147      * @param string $label
148      */
149     public function set_label($label) {
150         $label = (string)$label;
151         if ($label === '' || $label !== clean_param($label, PARAM_TEXT)) {
152             throw new base_setting_ui_exception('setting_invalid_ui_label');
153         }
154         $this->label = $label;
155     }
157     /**
158      * Disables the UI for this element
159      */
160     public function disable() {
161         $this->attributes['disabled'] = 'disabled';
162     }
164     /**
165      * Sets the icon to display next to this item
166      *
167      * @param pix_icon $icon
168      */
169     public function set_icon(pix_icon $icon) {
170         $this->icon = $icon;
171     }
173     /**
174      * Returns the icon to display next to this item, or false if there isn't one.
175      *
176      * @return pix_icon|false
177      */
178     public function get_icon() {
179         if (!empty($this->icon)) {
180             return $this->icon;
181         }
182         return false;
183     }
186 /**
187  * Abstract class to represent the user interface backup settings have
188  *
189  * @package core_backup
190  * @copyright 2010 Sam Hemelryk
191  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
192  */
193 abstract class backup_setting_ui extends base_setting_ui {
194     /**
195      * An array of options relating to this setting
196      * @var array
197      */
198     protected $options = array();
200     /**
201      * JAC... Just Another Constructor
202      *
203      * @param backup_setting $setting
204      * @param string $label The label to display with the setting ui
205      * @param array $attributes Array of HTML attributes to apply to the element
206      * @param array $options Array of options to apply to the setting ui object
207      */
208     public function __construct(backup_setting $setting, $label = null, array $attributes = null, array $options = null) {
209         parent::__construct($setting);
210         // Improve the inputs name by appending the level to the name.
211         switch ($setting->get_level()) {
212             case backup_setting::ROOT_LEVEL :
213                 $this->name = 'root_'.$setting->get_name();
214                 break;
215             case backup_setting::COURSE_LEVEL :
216                 $this->name = 'course_'.$setting->get_name();
217                 break;
218             case backup_setting::SECTION_LEVEL :
219                 $this->name = 'section_'.$setting->get_name();
220                 break;
221             case backup_setting::ACTIVITY_LEVEL :
222                 $this->name = 'activity_'.$setting->get_name();
223                 break;
224         }
225         $this->label = $label;
226         if (is_array($attributes)) {
227             $this->attributes = $attributes;
228         }
229         if (is_array($options)) {
230             $this->options = $options;
231         }
232     }
234     /**
235      * Creates a new backup setting ui based on the setting it is given
236      *
237      * @throws backup_setting_ui_exception if the setting type is not supported,
238      * @param backup_setting $setting
239      * @param int $type The backup_setting UI type. One of backup_setting::UI_*;
240      * @param string $label The label to display with the setting ui
241      * @param array $attributes Array of HTML attributes to apply to the element
242      * @param array $options Array of options to apply to the setting ui object
243      * @return backup_setting_ui_text|backup_setting_ui_checkbox|backup_setting_ui_select|backup_setting_ui_radio
244      */
245     final public static function make(backup_setting $setting, $type, $label, array $attributes = null, array $options = null) {
246         // Base the decision we make on the type that was sent.
247         switch ($type) {
248             case backup_setting::UI_HTML_CHECKBOX :
249                 return new backup_setting_ui_checkbox($setting, $label, null, (array)$attributes, (array)$options);
250             case backup_setting::UI_HTML_DROPDOWN :
251                 return new backup_setting_ui_select($setting, $label, null, (array)$attributes, (array)$options);
252             case backup_setting::UI_HTML_RADIOBUTTON :
253                 return new backup_setting_ui_radio($setting, $label, null, null, (array)$attributes, (array)$options);
254             case backup_setting::UI_HTML_TEXTFIELD :
255                 return new backup_setting_ui_text($setting, $label, $attributes, $options);
256             default:
257                 throw new backup_setting_ui_exception('setting_invalid_ui_type');
258         }
259     }
261     /**
262      * Get element properties that can be used to make a quickform element
263      *
264      * @param base_task $task
265      * @param renderer_base $output
266      * @return array
267      */
268     abstract public function get_element_properties(base_task $task = null, renderer_base $output = null);
270     /**
271      * Applies config options to a given properties array and then returns it
272      * @param array $properties
273      * @return array
274      */
275     public function apply_options(array $properties) {
276         if (!empty($this->options['size'])) {
277             $properties['attributes']['size'] = $this->options['size'];
278         }
279         return $properties;
280     }
282     /**
283      * Gets the label for this item
284      * @param base_task $task Optional, if provided and the setting is an include
285      *          $task is used to set the setting label
286      * @return string
287      */
288     public function get_label(base_task $task = null) {
289         // If a task has been provided and the label is not already set meaningfully
290         // we will attempt to improve it.
291         if (!is_null($task) && $this->label == $this->setting->get_name() && strpos($this->setting->get_name(), '_include') !== false) {
292             if ($this->setting->get_level() == backup_setting::SECTION_LEVEL) {
293                 $this->label = get_string('includesection', 'backup', $task->get_name());
294             } else if ($this->setting->get_level() == backup_setting::ACTIVITY_LEVEL) {
295                 $this->label = $task->get_name();
296             }
297         }
298         return $this->label;
299     }
301     /**
302      * Returns true if the setting is changeable.
303      *
304      * A setting is changeable if it meets either of the two following conditions.
305      *
306      * 1. The setting is not locked
307      * 2. The setting is locked but only by settings that are of the same level (same page)
308      *
309      * Condition 2 is really why we have this function
310      *
311      * @return bool
312      */
313     public function is_changeable() {
314         if ($this->setting->get_status() === backup_setting::NOT_LOCKED) {
315             // Its not locked so its chanegable.
316             return true;
317         } else if ($this->setting->get_status() !== backup_setting::LOCKED_BY_HIERARCHY) {
318             // Its not changeable because its locked by permission or config.
319             return false;
320         } else if ($this->setting->has_dependencies_on_settings()) {
321             foreach ($this->setting->get_settings_depended_on() as $dependency) {
322                 if ($dependency->is_locked() && $dependency->get_setting()->get_level() !== $this->setting->get_level()) {
323                     // Its not changeable because one or more dependancies arn't changeable.
324                     return false;
325                 }
326             }
327             // Its changeable because all dependencies are changeable.
328             return true;
329         }
330         // We should never get here but if we do return false to be safe.
331         // The setting would need to be locked by hierarchy and not have any deps.
332         return false;
333     }
337 /**
338  * A text input user interface element for backup settings
339  *
340  * @package core_backup
341  * @copyright 2010 Sam Hemelryk
342  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
343  */
344 class backup_setting_ui_text extends backup_setting_ui {
345     /**
346      * @var int
347      */
348     protected $type = backup_setting::UI_HTML_TEXTFIELD;
350     /**
351      * Returns an array of properties suitable for generating a quickforms element
352      * @param base_task $task
353      * @param renderer_base $output
354      * @return array (element, name, label, attributes)
355      */
356     public function get_element_properties(base_task $task = null, renderer_base $output = null) {
357         $icon = $this->get_icon();
358         $label = $this->get_label($task);
359         if (!empty($icon)) {
360             $label .= $output->render($icon);
361         }
362         // Name, label, attributes.
363         return $this->apply_options(array(
364             'element' => 'text',
365             'name' => self::NAME_PREFIX.$this->name,
366             'label' => $label,
367             'attributes' => $this->attributes)
368         );
369     }
373 /**
374  * A checkbox user interface element for backup settings (default)
375  *
376  * @package core_backup
377  * @copyright 2010 Sam Hemelryk
378  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
379  */
380 class backup_setting_ui_checkbox extends backup_setting_ui {
382     /**
383      * @var int
384      */
385     protected $type = backup_setting::UI_HTML_CHECKBOX;
387     /**
388      * @var bool
389      */
390     protected $changeable = true;
392     /**
393      * The text to show next to the checkbox
394      * @var string
395      */
396     protected $text;
398     /**
399      * Overridden constructor so we can take text argument
400      *
401      * @param backup_setting $setting
402      * @param string $label
403      * @param string $text
404      * @param array $attributes
405      * @param array $options
406      */
407     public function __construct(backup_setting $setting, $label = null, $text = null, array $attributes = array(), array $options = array()) {
408         parent::__construct($setting, $label, $attributes, $options);
409         $this->text = $text;
410     }
412     /**
413      * Returns an array of properties suitable for generating a quickforms element
414      * @param base_task $task
415      * @param renderer_base $output
416      * @return array (element, name, label, text, attributes);
417      */
418     public function get_element_properties(base_task $task = null, renderer_base $output = null) {
419         // Name, label, text, attributes.
420         $icon = $this->get_icon();
421         $label = $this->get_label($task);
422         if (!empty($icon)) {
423             $label .= $output->render($icon);
424         }
425         return $this->apply_options(array(
426             'element' => 'checkbox',
427             'name' => self::NAME_PREFIX.$this->name,
428             'label' => $label,
429             'text' => $this->text,
430             'attributes' => $this->attributes
431         ));
432     }
434     /**
435      * Sets the text for the element
436      * @param string $text
437      */
438     public function set_text($text) {
439         $this->text = $text;
440     }
442     /**
443      * Gets the static value for the element
444      * @global core_renderer $OUTPUT
445      * @return string
446      */
447     public function get_static_value() {
448         global $OUTPUT;
449         // Checkboxes are always yes or no.
450         if ($this->get_value()) {
451             return $OUTPUT->pix_icon('i/valid', get_string('yes'));
452         } else {
453             return $OUTPUT->pix_icon('i/invalid', get_string('no'));
454         }
455     }
457     /**
458      * Returns true if the setting is changeable
459      * @return bool
460      */
461     public function is_changeable() {
462         if ($this->changeable === false) {
463             return false;
464         } else {
465             return parent::is_changeable();
466         }
467     }
469     /**
470      * Sets whether the setting is changeable,
471      * Note dependencies can still mark this setting changeable or not
472      * @param bool $newvalue
473      */
474     public function set_changeable($newvalue) {
475         $this->changeable = ($newvalue);
476     }
479 /**
480  * Radio button user interface element for backup settings
481  *
482  * @package core_backup
483  * @copyright 2010 Sam Hemelryk
484  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
485  */
486 class backup_setting_ui_radio extends backup_setting_ui {
487     /**
488      * @var int
489      */
490     protected $type = backup_setting::UI_HTML_RADIOBUTTON;
492     /**
493      * The string shown next to the input
494      * @var string
495      */
496     protected $text;
498     /**
499      * The value for the radio input
500      * @var string
501      */
502     protected $value;
504     /**
505      * Constructor
506      *
507      * @param backup_setting $setting
508      * @param string $label
509      * @param string $text
510      * @param string $value
511      * @param array $attributes
512      * @param array $options
513      */
514     public function __construct(backup_setting $setting, $label = null, $text = null, $value = null, array $attributes = array(), array $options = array()) {
515         parent::__construct($setting, $label, $attributes, $options);
516         $this->text = $text;
517         $this->value = (string)$value;
518     }
520     /**
521      * Returns an array of properties suitable for generating a quickforms element
522      * @param base_task $task
523      * @param renderer_base $output
524      * @return array (element, name, label, text, value, attributes)
525      */
526     public function get_element_properties(base_task $task = null, renderer_base $output = null) {
527         $icon = $this->get_icon();
528         $label = $this->get_label($task);
529         if (!empty($icon)) {
530             $label .= $output->render($icon);
531         }
532         // Name, label, text, value, attributes.
533         return $this->apply_options(array(
534             'element' => 'radio',
535             'name' => self::NAME_PREFIX.$this->name,
536             'label' => $label,
537             'text' => $this->text,
538             'value' => $this->value,
539             'attributes' => $this->attributes
540         ));
541     }
542     /**
543      * Sets the text next to this input
544      * @param text $text
545      */
546     public function set_text($text) {
547         $this->text = $text;
548     }
549     /**
550      * Sets the value for the input
551      * @param string $value
552      */
553     public function set_value($value) {
554         $this->value = (string)$value;
555     }
556     /**
557      * Gets the static value to show for the element
558      */
559     public function get_static_value() {
560         return $this->value;
561     }
564 /**
565  * A select box, drop down user interface for backup settings
566  *
567  * @package core_backup
568  * @copyright 2010 Sam Hemelryk
569  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
570  */
571 class backup_setting_ui_select extends backup_setting_ui {
572     /**
573      * @var int
574      */
575     protected $type = backup_setting::UI_HTML_DROPDOWN;
577     /**
578      * An array of options to display in the select
579      * @var array
580      */
581     protected $values;
583     /**
584      * Constructor
585      *
586      * @param backup_setting $setting
587      * @param string $label
588      * @param array $values
589      * @param array $attributes
590      * @param array $options
591      */
592     public function __construct(backup_setting $setting, $label = null, $values = null, array $attributes = array(), array $options = array()) {
593         parent::__construct($setting, $label, $attributes, $options);
594         $this->values = $values;
595     }
597     /**
598      * Returns an array of properties suitable for generating a quickforms element
599      * @param base_task $task
600      * @param renderer_base $output
601      * @return array (element, name, label, options, attributes)
602      */
603     public function get_element_properties(base_task $task = null, renderer_base $output = null) {
604         $icon = $this->get_icon();
605         $label = $this->get_label($task);
606         if (!empty($icon)) {
607             $label .= $output->render($icon);
608         }
609         // Name, label, options, attributes.
610         return $this->apply_options(array(
611             'element' => 'select',
612             'name' => self::NAME_PREFIX.$this->name,
613             'label' => $label,
614             'options' => $this->values,
615             'attributes' => $this->attributes
616         ));
617     }
619     /**
620      * Sets the options for the select box
621      * @param array $values Associative array of value => text options
622      */
623     public function set_values(array $values) {
624         $this->values = $values;
625     }
627     /**
628      * Gets the static value for this select element
629      * @return string
630      */
631     public function get_static_value() {
632         return $this->values[$this->get_value()];
633     }
635     /**
636      * Returns true if the setting is changeable, false otherwise
637      *
638      * @return bool
639      */
640     public function is_changeable() {
641         if (count($this->values) == 1) {
642             return false;
643         } else {
644             return parent::is_changeable();
645         }
646     }
649 /**
650  * A date selector user interface widget for backup settings.
651  *
652  * @package core_backup
653  * @copyright 2010 Sam Hemelryk
654  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
655  */
656 class backup_setting_ui_dateselector extends backup_setting_ui_text {
658     /**
659      * Returns an array of properties suitable for generating a quickforms element
660      * @param base_task $task
661      * @param renderer_base $output
662      * @return array (element, name, label, options, attributes)
663      */
664     public function get_element_properties(base_task $task = null, renderer_base $output = null) {
665         if (!array_key_exists('optional', $this->attributes)) {
666             $this->attributes['optional'] = false;
667         }
668         $properties = parent::get_element_properties($task, $output);
669         $properties['element'] = 'date_selector';
670         return $properties;
671     }
673     /**
674      * Gets the static value for this select element
675      * @return string
676      */
677     public function get_static_value() {
678         $value = $this->get_value();
679         if (!empty($value)) {
680             return userdate($value);
681         }
682         return parent::get_static_value();
683     }
686 /**
687  * Base setting UI exception class.
688  *
689  * @package core_backup
690  * @copyright 2010 Sam Hemelryk
691  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
692  */
693 class base_setting_ui_exception extends base_setting_exception {}
695 /**
696  * Backup setting UI exception class.
697  *
698  * @package core_backup
699  * @copyright 2010 Sam Hemelryk
700  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
701  */
702 class backup_setting_ui_exception extends base_setting_ui_exception {};