MDL-48192 tool_monitor: check output buffer and not ignore it.
[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         $label = (string)$label;
143         if ($label === '' || $label !== clean_param($label, PARAM_TEXT)) {
144             throw new base_setting_ui_exception('setting_invalid_ui_label');
145         }
146         $this->label = $label;
147     }
148     /**
149      * Disables the UI for this element
150      */
151     public function disable() {
152        $this->attributes['disabled'] = 'disabled';
153     }
155     /**
156      * Sets the icon to display next to this item
157      *
158      * @param pix_icon $icon
159      */
160     public function set_icon(pix_icon $icon) {
161         $this->icon = $icon;
162     }
164     /**
165      * Returns the icon to display next to this item, or false if there isn't one.
166      *
167      * @return pix_icon|false
168      */
169     public function get_icon() {
170         if (!empty($this->icon)) {
171             return $this->icon;
172         }
173         return false;
174     }
177 /**
178  * Abstract class to represent the user interface backup settings have
179  *
180  * @copyright 2010 Sam Hemelryk
181  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
182  */
183 abstract class backup_setting_ui extends base_setting_ui {
184     /**
185      * An array of options relating to this setting
186      * @var array
187      */
188     protected $options = array();
190     /**
191      * JAC... Just Another Constructor
192      *
193      * @param backup_setting $setting
194      * @param string|null $label The label to display with the setting ui
195      * @param array|null $attributes Array of HTML attributes to apply to the element
196      * @param array|null $options Array of options to apply to the setting ui object
197      */
198     public function __construct(backup_setting $setting, $label = null, array $attributes = null, array $options = null) {
199         parent::__construct($setting);
200         // Improve the inputs name by appending the level to the name
201         switch ($setting->get_level()) {
202             case backup_setting::ROOT_LEVEL :
203                 $this->name = 'root_'.$setting->get_name();
204                 break;
205             case backup_setting::COURSE_LEVEL :
206                 $this->name = 'course_'.$setting->get_name();
207                 break;
208             case backup_setting::SECTION_LEVEL :
209                 $this->name = 'section_'.$setting->get_name();
210                 break;
211             case backup_setting::ACTIVITY_LEVEL :
212                 $this->name = 'activity_'.$setting->get_name();
213                 break;
214         }
215         $this->label = $label;
216         if (is_array($attributes)) {
217             $this->attributes = $attributes;
218         }
219         if (is_array($options)) {
220             $this->options = $options;
221         }
222     }
223     /**
224      * Creates a new backup setting ui based on the setting it is given
225      *
226      * Throws an exception if an invalid type is provided.
227      *
228      * @param backup_setting $setting
229      * @param int $type The backup_setting UI type. One of backup_setting::UI_*;
230      * @param string $label The label to display with the setting ui
231      * @param array $attributes Array of HTML attributes to apply to the element
232      * @param array $options Array of options to apply to the setting ui object
233      *
234      * @return backup_setting_ui_text|backup_setting_ui_checkbox|backup_setting_ui_select|backup_setting_ui_radio
235      */
236     final public static function make(backup_setting $setting, $type, $label, array $attributes = null, array $options=null) {
237         // Base the decision we make on the type that was sent
238         switch ($type) {
239             case backup_setting::UI_HTML_CHECKBOX :
240                 return new backup_setting_ui_checkbox($setting, $label, null, (array)$attributes, (array)$options);
241             case backup_setting::UI_HTML_DROPDOWN :
242                 return new backup_setting_ui_select($setting, $label, null, (array)$attributes, (array)$options);
243             case backup_setting::UI_HTML_RADIOBUTTON :
244                 return new backup_setting_ui_radio($setting, $label, null, null, (array)$attributes, (array)$options);
245             case backup_setting::UI_HTML_TEXTFIELD :
246                 return new backup_setting_ui_text($setting, $label, $attributes, $options);
247             default:
248                 throw new backup_setting_ui_exception('setting_invalid_ui_type');
249         }
250     }
251     /**
252      * Get element properties that can be used to make a quickform element
253      * @return array
254      */
255     abstract public function get_element_properties(base_task $task=null, renderer_base $output=null);
256     /**
257      * Applies config options to a given properties array and then returns it
258      * @param array $properties
259      * @return array
260      */
261     public function apply_options(array $properties) {
262         if (!empty($this->options['size'])) {
263             $properties['attributes']['size'] = $this->options['size'];
264         }
265         return $properties;
266     }
267     /**
268      * Gets the label for this item
269      * @param backup_task|null $task Optional, if provided and the setting is an include
270      *          $task is used to set the setting label
271      * @return string
272      */
273     public function get_label(base_task $task=null) {
274         // If a task has been provided and the label is not already set meaniningfully
275         // we will attempt to improve it.
276         if (!is_null($task) && $this->label == $this->setting->get_name() && strpos($this->setting->get_name(), '_include')!==false) {
277             if ($this->setting->get_level() == backup_setting::SECTION_LEVEL) {
278                 $this->label = get_string('includesection', 'backup', $task->get_name());
279             } else if ($this->setting->get_level() == backup_setting::ACTIVITY_LEVEL) {
280                 $this->label = $task->get_name();
281             }
282         }
283         return $this->label;
284     }
285     /**
286      * Returns true if the setting is changeable.
287      *
288      * A setting is changeable if it meets either of the two following conditions.
289      *
290      * 1. The setting is not locked
291      * 2. The setting is locked but only by settings that are of the same level (same page)
292      *
293      * Condition 2 is really why we have this function
294      *
295      * @return bool
296      */
297     public function is_changeable() {
298         if ($this->setting->get_status() === backup_setting::NOT_LOCKED) {
299             // Its not locked so its chanegable
300             return true;
301         } else if ($this->setting->get_status() !== backup_setting::LOCKED_BY_HIERARCHY) {
302             // Its not changeable because its locked by permission or config
303             return false;
304         } else if ($this->setting->has_dependencies_on_settings()) {
305             foreach ($this->setting->get_settings_depended_on() as $dependency) {
306                 if ($dependency->is_locked() && $dependency->get_setting()->get_level() !== $this->setting->get_level()) {
307                     // Its not changeable because one or more dependancies arn't
308                     // changeable.
309                    return false;
310                 }
311             }
312             // Its changeable because all dependencies are changeable.
313             return true;
314         }
315         // We should never get here but if we do return false to be safe.
316         // The setting would need to be locked by hierarchy and not have any deps
317         return false;
318     }
322 /**
323  * A text input user interface element for backup settings
324  *
325  * @copyright 2010 Sam Hemelryk
326  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
327  */
328 class backup_setting_ui_text extends backup_setting_ui {
329     /**
330      * @var int
331      */
332     protected $type = backup_setting::UI_HTML_TEXTFIELD;
333     /**
334      * Returns an array of properties suitable for generating a quickforms element
335      * @param backup_task|null $task
336      * @return array (element, name, label, attributes)
337      */
338     public function get_element_properties(base_task $task=null, renderer_base $output=null) {
339         // name, label, text, attributes
340         $icon = $this->get_icon();
341         $label = $this->get_label($task);
342         if (!empty($icon)) {
343             $label .= $output->render($icon);
344         }
345         // name, label, attributes
346         return $this->apply_options(array('element'=>'text','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'attributes'=>$this->attributes));
347     }
351 /**
352  * A checkbox user interface element for backup settings (default)
353  *
354  * @copyright 2010 Sam Hemelryk
355  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
356  */
357 class backup_setting_ui_checkbox extends backup_setting_ui {
358     /**
359      * @var int
360      */
361     protected $type = backup_setting::UI_HTML_CHECKBOX;
362     /**
363      * @var bool
364      */
365     protected $changeable = true;
366     /**
367      * The text to show next to the checkbox
368      * @var string
369      */
370     protected $text;
371     /**
372      * Overridden constructor so we can take text argument
373      * @param backup_setting $setting
374      * @param string $label
375      * @param string $text
376      * @param array $attributes
377      * @param array $options
378      */
379     public function __construct(backup_setting $setting, $label = null, $text=null, array $attributes = array(), array $options = array()) {
380         parent::__construct($setting, $label, $attributes, $options);
381         $this->text = $text;
382     }
383     /**
384      * Returns an array of properties suitable for generating a quickforms element
385      * @param backup_task|null $task
386      * @return array (element, name, label, text, attributes);
387      */
388     public function get_element_properties(base_task $task=null, renderer_base $output=null) {
389         // name, label, text, attributes
391         $icon = $this->get_icon();
392         $label = $this->get_label($task);
393         if (!empty($icon)) {
394             $label .= $output->render($icon);
395         }
396         return $this->apply_options(array('element'=>'checkbox','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'text'=>$this->text, 'attributes'=>$this->attributes));
397     }
398     /**
399      * Sets the text for the element
400      * @param string $text
401      */
402     public function set_text($text) {
403         $this->text = $text;
404     }
405     /**
406      * Gets the static value for the element
407      * @global core_renderer $OUTPUT
408      * @return string
409      */
410     public function get_static_value() {
411         global $OUTPUT;
412         // Checkboxes are always yes or no
413         if ($this->get_value()) {
414             return $OUTPUT->pix_icon('i/valid', get_string('yes'));
415         } else {
416             return $OUTPUT->pix_icon('i/invalid', get_string('no'));
417         }
418     }
420     /**
421      * Returns true if the setting is changeable
422      * @return bool
423      */
424     public function is_changeable() {
425         if ($this->changeable===false) {
426             return false;
427         } else {
428             return parent::is_changeable();
429         }
430     }
432     /**
433      * Sets whether the setting is changeable,
434      * Note dependencies can still mark this setting changeable or not
435      * @param bool $newvalue
436      */
437     public function set_changeable($newvalue) {
438         $this->changeable = ($newvalue);
439     }
442 /**
443  * Radio button user interface element for backup settings
444  *
445  * @copyright 2010 Sam Hemelryk
446  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
447  */
448 class backup_setting_ui_radio extends backup_setting_ui {
449     /**
450      * @var int
451      */
452     protected $type = backup_setting::UI_HTML_RADIOBUTTON;
453     /**
454      * The string shown next to the input
455      * @var string
456      */
457     protected $text;
458     /**
459      * The value for the radio input
460      * @var string
461      */
462     protected $value;
463     /**
464      *
465      * @param backup_setting $setting
466      * @param string $label
467      * @param string $text
468      * @param string $value
469      * @param array $attributes
470      * @param array $options
471      */
472     public function __construct(backup_setting $setting, $label = null, $text=null, $value=null, array $attributes = array(), array $options = array()) {
473         parent::__construct($setting, $label, $attributes, $options);
474         $this->text = $text;
475         $this->value = (string)$value;
476     }
477     /**
478      * Returns an array of properties suitable for generating a quickforms element
479      * @param backup_task|null $task
480      * @return array (element, name, label, text, value, attributes)
481      */
482     public function get_element_properties(base_task $task=null, renderer_base $output=null) {
483         // name, label, text, attributes
484         $icon = $this->get_icon();
485         $label = $this->get_label($task);
486         if (!empty($icon)) {
487             $label .= $output->render($icon);
488         }
489         // name, label, text, value, attributes
490         return $this->apply_options(array('element'=>'radio','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'text'=>$this->text, 'value'=>$this->value, 'attributes'=>$this->attributes));
491     }
492     /**
493      * Sets the text next to this input
494      * @param text $text
495      */
496     public function set_text($text) {
497         $this->text = $text;
498     }
499     /**
500      * Sets the value for the input
501      * @param string $value
502      */
503     public function set_value($value) {
504         $this->value = (string)$value;
505     }
506     /**
507      * Gets the static value to show for the element
508      */
509     public function get_static_value() {
510         return $this->value;
511     }
514 /**
515  * A select box, drop down user interface for backup settings
516  *
517  * @copyright 2010 Sam Hemelryk
518  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
519  */
520 class backup_setting_ui_select extends backup_setting_ui {
521     /**
522      * @var int
523      */
524     protected $type = backup_setting::UI_HTML_DROPDOWN;
525     /**
526      * An array of options to display in the select
527      * @var array
528      */
529     protected $values;
530     /**
531      *
532      * @param backup_setting $setting
533      * @param string $label
534      * @param array $values
535      * @param array $attributes
536      * @param array $options
537      */
538     public function __construct(backup_setting $setting, $label = null, $values=null, array $attributes = array(), array $options = array()) {
539         parent::__construct($setting, $label, $attributes, $options);
540         $this->values = $values;
541     }
542     /**
543      * Returns an array of properties suitable for generating a quickforms element
544      * @param backup_task|null $task
545      * @return array (element, name, label, options, attributes)
546      */
547     public function get_element_properties(base_task $task = null, renderer_base $output=null) {
548         // name, label, text, attributes
549         $icon = $this->get_icon();
550         $label = $this->get_label($task);
551         if (!empty($icon)) {
552             $label .= $output->render($icon);
553         }
554         // name, label, options, attributes
555         return $this->apply_options(array('element'=>'select','name'=>self::NAME_PREFIX.$this->name, 'label'=>$label, 'options'=>$this->values, 'attributes'=>$this->attributes));
556     }
557     /**
558      * Sets the options for the select box
559      * @param array $values Associative array of value=>text options
560      */
561     public function set_values(array $values) {
562         $this->values = $values;
563     }
564     /**
565      * Gets the static value for this select element
566      * @return string
567      */
568     public function get_static_value() {
569         return $this->values[$this->get_value()];
570     }
571     /**
572      * Returns true if the setting is changeable, false otherwise
573      *
574      * @return bool
575      */
576     public function is_changeable() {
577         if (count($this->values) == 1) {
578             return false;
579         } else {
580             return parent::is_changeable();
581         }
582     }
585 class backup_setting_ui_dateselector extends backup_setting_ui_text {
586     public function get_element_properties(base_task $task = null, renderer_base $output=null) {
587         if (!array_key_exists('optional', $this->attributes)) {
588             $this->attributes['optional'] = false;
589         }
590         $properties = parent::get_element_properties($task, $output);
591         $properties['element'] = 'date_selector';
592         return $properties;
593     }
594     public function get_static_value() {
595         $value = $this->get_value();
596         if (!empty($value)) {
597             return userdate($value);
598         }
599         return parent::get_static_value();
600     }
603 class base_setting_ui_exception extends base_setting_exception {}
604 class backup_setting_ui_exception extends base_setting_ui_exception {};