MDL-32705 backup ui: add select all/none JavaScript on schema screens
[moodle.git] / backup / util / ui / base_moodleform.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 generic moodleform bridge for the backup user interface
20  * as well as the individual forms that relate to the different stages the user
21  * interface can exist within.
22  *
23  * @package   moodlecore
24  * @copyright 2010 Sam Hemelryk
25  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26  */
28 defined('MOODLE_INTERNAL') || die();
30 require_once($CFG->libdir . '/formslib.php');
32 /**
33  * Backup moodleform bridge
34  *
35  * Ahhh the mighty moodleform bridge! Strong enough to take the weight of 682 full
36  * grown african swallows all of whom have been carring coconuts for several days.
37  * EWWWWW!!!!!!!!!!!!!!!!!!!!!!!!
38  *
39  * @copyright 2010 Sam Hemelryk
40  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  */
42 abstract class base_moodleform extends moodleform {
43     /**
44      * The stage this form belongs to
45      * @var base_ui_stage
46      */
47     protected $uistage = null;
48     /**
49      * True if we have a course div open, false otherwise
50      * @var bool
51      */
52     protected $coursediv = false;
53     /**
54      * True if we have a section div open, false otherwise
55      * @var bool
56      */
57     protected $sectiondiv = false;
58     /**
59      * True if we have an activity div open, false otherwise
60      * @var bool
61      */
62     protected $activitydiv = false;
63     /**
64      * Creates the form
65      *
66      * @param backup_ui_stage $uistage
67      * @param moodle_url|string $action
68      * @param mixed $customdata
69      * @param string $method get|post
70      * @param string $target
71      * @param array $attributes
72      * @param bool $editable
73      */
74     function __construct(base_ui_stage $uistage, $action=null, $customdata=null, $method='post', $target='', $attributes=null, $editable=true) {
75         $this->uistage = $uistage;
76         parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
77     }
78     /**
79      * The standard form definition... obviously not much here
80      */
81     function definition() {
82         $ui = $this->uistage->get_ui();
83         $mform = $this->_form;
84         $stage = $mform->addElement('hidden', 'stage', $this->uistage->get_stage());
85         $stage = $mform->addElement('hidden', $ui->get_name(), $ui->get_uniqueid());
86         $params = $this->uistage->get_params();
87         if (is_array($params) && count($params) > 0) {
88             foreach ($params as $name=>$value) {
89                 $stage = $mform->addElement('hidden', $name, $value);
90             }
91         }
92     }
93     /**
94      * Definition applied after the data is organised.. why's it here? because I want
95      * to add elements on the fly.
96      * @global moodle_page $PAGE
97      */
98     function definition_after_data() {
99         $buttonarray=array();
100         $buttonarray[] = $this->_form->createElement('submit', 'submitbutton', get_string($this->uistage->get_ui()->get_name().'stage'.$this->uistage->get_stage().'action', 'backup'), array('class'=>'proceedbutton'));
101         if (!$this->uistage->is_first_stage()) {
102             $buttonarray[] = $this->_form->createElement('submit', 'previous', get_string('previousstage','backup'));
103         }
104         $buttonarray[] = $this->_form->createElement('cancel', 'cancel', get_string('cancel'), array('class'=>'confirmcancel'));
105         $this->_form->addGroup($buttonarray, 'buttonar', '', array(' '), false);
106         $this->_form->closeHeaderBefore('buttonar');
108         $this->_definition_finalized = true;
109     }
111     /**
112      * Closes any open divs
113      */
114     function close_task_divs() {
115         if ($this->activitydiv) {
116             $this->_form->addElement('html', html_writer::end_tag('div'));
117             $this->activitydiv = false;
118         }
119         if ($this->sectiondiv) {
120             $this->_form->addElement('html', html_writer::end_tag('div'));
121             $this->sectiondiv = false;
122         }
123         if ($this->coursediv) {
124             $this->_form->addElement('html', html_writer::end_tag('div'));
125             $this->coursediv = false;
126         }
127     }
128     /**
129      * Adds the backup_setting as a element to the form
130      * @param backup_setting $setting
131      * @return bool
132      */
133     function add_setting(backup_setting $setting, base_task $task=null) {
134         return $this->add_settings(array(array($setting, $task)));
135     }
136     /**
137      * Adds multiple backup_settings as elements to the form
138      * @param array $settingstasks Consists of array($setting, $task) elements
139      * @return bool
140      */
141     public function add_settings(array $settingstasks) {
142         global $OUTPUT;
144         $defaults = array();
145         foreach ($settingstasks as $st) {
146             list($setting, $task) = $st;
147             // If the setting cant be changed or isn't visible then add it as a fixed setting.
148             if (!$setting->get_ui()->is_changeable() || $setting->get_visibility() != backup_setting::VISIBLE) {
149                 $this->add_fixed_setting($setting, $task);
150                 continue;
151             }
153             // First add the formatting for this setting
154             $this->add_html_formatting($setting);
156             // Then call the add method with the get_element_properties array
157             call_user_func_array(array($this->_form, 'addElement'), $setting->get_ui()->get_element_properties($task, $OUTPUT));
158             $defaults[$setting->get_ui_name()] = $setting->get_value();
159             if ($setting->has_help()) {
160                 list($identifier, $component) = $setting->get_help();
161                 $this->_form->addHelpButton($setting->get_ui_name(), $identifier, $component);
162             }
163             $this->_form->addElement('html', html_writer::end_tag('div'));
164         }
165         $this->_form->setDefaults($defaults);
166         return true;
167     }
168     /**
169      * Adds a heading to the form
170      * @param string $name
171      * @param string $text
172      */
173     function add_heading($name , $text) {
174         $this->_form->addElement('header', $name, $text);
175     }
176     /**
177      * Adds HTML formatting for the given backup setting, needed to group/segment
178      * correctly.
179      * @param backup_setting $setting
180      */
181     protected function add_html_formatting(backup_setting $setting) {
182         $mform = $this->_form;
183         $isincludesetting = (strpos($setting->get_name(), '_include')!==false);
184         if ($isincludesetting && $setting->get_level() != backup_setting::ROOT_LEVEL)  {
185             switch ($setting->get_level()) {
186                 case backup_setting::COURSE_LEVEL:
187                     if ($this->activitydiv) {
188                         $this->_form->addElement('html', html_writer::end_tag('div'));
189                         $this->activitydiv = false;
190                     }
191                     if ($this->sectiondiv) {
192                         $this->_form->addElement('html', html_writer::end_tag('div'));
193                         $this->sectiondiv = false;
194                     }
195                     if ($this->coursediv) {
196                         $this->_form->addElement('html', html_writer::end_tag('div'));
197                     }
198                     $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings course_level')));
199                     $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting course_level')));
200                     $this->coursediv = true;
201                     break;
202                 case backup_setting::SECTION_LEVEL:
203                     if ($this->activitydiv) {
204                         $this->_form->addElement('html', html_writer::end_tag('div'));
205                         $this->activitydiv = false;
206                     }
207                     if ($this->sectiondiv) {
208                         $this->_form->addElement('html', html_writer::end_tag('div'));
209                     }
210                     $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings section_level')));
211                     $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting section_level')));
212                     $this->sectiondiv = true;
213                     break;
214                 case backup_setting::ACTIVITY_LEVEL:
215                     if ($this->activitydiv) {
216                         $this->_form->addElement('html', html_writer::end_tag('div'));
217                     }
218                     $mform->addElement('html', html_writer::start_tag('div', array('class'=>'grouped_settings activity_level')));
219                     $mform->addElement('html', html_writer::start_tag('div', array('class'=>'include_setting activity_level')));
220                     $this->activitydiv = true;
221                     break;
222                 default:
223                     $mform->addElement('html', html_writer::start_tag('div', array('class'=>'normal_setting')));
224                     break;
225             }
226         } else if ($setting->get_level() == backup_setting::ROOT_LEVEL) {
227             $mform->addElement('html', html_writer::start_tag('div', array('class'=>'root_setting')));
228         } else {
229             $mform->addElement('html', html_writer::start_tag('div', array('class'=>'normal_setting')));
230         }
231     }
232     /**
233      * Adds a fixed or static setting to the form
234      * @param backup_setting $setting
235      */
236     function add_fixed_setting(backup_setting $setting, base_task $task) {
237         global $OUTPUT;
238         $settingui = $setting->get_ui();
239         if ($setting->get_visibility() == backup_setting::VISIBLE) {
240             $this->add_html_formatting($setting);
241             switch ($setting->get_status()) {
242                 case backup_setting::LOCKED_BY_PERMISSION:
243                     $icon = ' '.$OUTPUT->pix_icon('i/permissionlock', get_string('lockedbypermission', 'backup'), 'moodle', array('class'=>'smallicon lockedicon permissionlock'));
244                     break;
245                 case backup_setting::LOCKED_BY_CONFIG:
246                     $icon = ' '.$OUTPUT->pix_icon('i/configlock', get_string('lockedbyconfig', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
247                     break;
248                 case backup_setting::LOCKED_BY_HIERARCHY:
249                     $icon = ' '.$OUTPUT->pix_icon('i/hierarchylock', get_string('lockedbyhierarchy', 'backup'), 'moodle', array('class'=>'smallicon lockedicon configlock'));
250                     break;
251                 default:
252                     $icon = '';
253                     break;
254             }
255             $label = $settingui->get_label($task);
256             $labelicon = $settingui->get_icon();
257             if (!empty($labelicon)) {
258                 $label .= '&nbsp;'.$OUTPUT->render($labelicon);
259             }
260             $this->_form->addElement('static', 'static_'.$settingui->get_name(), $label, $settingui->get_static_value().$icon);
261             $this->_form->addElement('html', html_writer::end_tag('div'));
262         }
263         $this->_form->addElement('hidden', $settingui->get_name(), $settingui->get_value());
264     }
265     /**
266      * Adds dependencies to the form recursively
267      *
268      * @param backup_setting $setting
269      */
270     function add_dependencies(backup_setting $setting) {
271         $mform = $this->_form;
272         // Apply all dependencies for backup
273         foreach ($setting->get_my_dependency_properties() as $key=>$dependency) {
274             call_user_func_array(array($this->_form, 'disabledIf'), $dependency);
275         }
276     }
277     /**
278      * Returns true if the form was cancelled, false otherwise
279      * @return bool
280      */
281     public function is_cancelled() {
282         return (optional_param('cancel', false, PARAM_BOOL) || parent::is_cancelled());
283     }
285     /**
286      * Removes an element from the form if it exists
287      * @param string $elementname
288      * @return bool
289      */
290     public function remove_element($elementname) {
291         if ($this->_form->elementExists($elementname)) {
292             return $this->_form->removeElement($elementname);
293         } else {
294             return false;
295         }
296     }
298     /**
299      * Gets an element from the form if it exists
300      *
301      * @param string $elementname
302      * @return HTML_QuickForm_input|MoodleQuickForm_group
303      */
304     public function get_element($elementname) {
305         if ($this->_form->elementExists($elementname)) {
306             return $this->_form->getElement($elementname);
307         } else {
308             return false;
309         }
310     }
312     /**
313      * Displays the form
314      */
315     public function display() {
316         global $PAGE;
318         $this->require_definition_after_data();
320         $config = new stdClass;
321         $config->title = get_string('confirmcancel', 'backup');
322         $config->question = get_string('confirmcancelquestion', 'backup');
323         $config->yesLabel = get_string('confirmcancelyes', 'backup');
324         $config->noLabel = get_string('confirmcancelno', 'backup');
325         $PAGE->requires->yui_module('moodle-backup-confirmcancel', 'M.core_backup.watch_cancel_buttons', array($config));
327         $PAGE->requires->yui_module('moodle-backup-backupselectall', 'M.core_backup.select_all_init',
328                 array(array('select' => get_string('select'), 'all' => get_string('all'), 'none' => get_string('none'))));
330         parent::display();
331     }
333     /**
334      * Ensures the the definition after data is loaded
335      */
336     public function require_definition_after_data() {
337         if (!$this->_definition_finalized) {
338             $this->definition_after_data();
339         }
340     }