PageRenderTime 78ms CodeModel.GetById 53ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/backup/util/ui/base_moodleform.class.php

https://bitbucket.org/moodle/moodle
PHP | 422 lines | 253 code | 31 blank | 138 comment | 45 complexity | 795070d32a34650b2dcc755188b54bb9 MD5 | raw file
  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/>.
 16
 17/**
 18 * This file contains the generic moodleform bridge for the backup user interface
 19 * as well as the individual forms that relate to the different stages the user
 20 * interface can exist within.
 21 *
 22 * @package   core_backup
 23 * @copyright 2010 Sam Hemelryk
 24 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 25 */
 26
 27defined('MOODLE_INTERNAL') || die();
 28
 29require_once($CFG->libdir . '/formslib.php');
 30
 31/**
 32 * Base moodleform bridge
 33 *
 34 * Ahhh the mighty moodleform bridge! Strong enough to take the weight of 682 full
 35 * grown african swallows all of whom have been carring coconuts for several days.
 36 * EWWWWW!!!!!!!!!!!!!!!!!!!!!!!!
 37 *
 38 * @package   core_backup
 39 * @copyright 2010 Sam Hemelryk
 40 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 41 */
 42abstract class base_moodleform extends moodleform {
 43
 44    /**
 45     * The stage this form belongs to
 46     * @var base_ui_stage
 47     */
 48    protected $uistage = null;
 49
 50    /**
 51     * True if we have a course div open, false otherwise
 52     * @var bool
 53     */
 54    protected $coursediv = false;
 55
 56    /**
 57     * True if we have a section div open, false otherwise
 58     * @var bool
 59     */
 60    protected $sectiondiv = false;
 61
 62    /**
 63     * True if we have an activity div open, false otherwise
 64     * @var bool
 65     */
 66    protected $activitydiv = false;
 67
 68    /**
 69     * Creates the form
 70     *
 71     * @param base_ui_stage $uistage
 72     * @param moodle_url|string $action
 73     * @param mixed $customdata
 74     * @param string $method get|post
 75     * @param string $target
 76     * @param array $attributes
 77     * @param bool $editable
 78     */
 79    public function __construct(base_ui_stage $uistage, $action = null, $customdata = null, $method = 'post',
 80                                $target = '', $attributes = null, $editable = true) {
 81        $this->uistage = $uistage;
 82        // Add a class to the attributes to prevent the default collapsible behaviour.
 83        if (!$attributes) {
 84            $attributes = array();
 85        }
 86        $attributes['class'] = 'unresponsive';
 87        if (!isset($attributes['enctype'])) {
 88            $attributes['enctype'] = 'application/x-www-form-urlencoded'; // Enforce compatibility with our max_input_vars hack.
 89        }
 90        parent::__construct($action, $customdata, $method, $target, $attributes, $editable);
 91    }
 92
 93    /**
 94     * The standard form definition... obviously not much here
 95     */
 96    public function definition() {
 97        $ui = $this->uistage->get_ui();
 98        $mform = $this->_form;
 99        $mform->setDisableShortforms();
100        $stage = $mform->addElement('hidden', 'stage', $this->uistage->get_stage());
101        $mform->setType('stage', PARAM_INT);
102        $stage = $mform->addElement('hidden', $ui->get_name(), $ui->get_uniqueid());
103        $mform->setType($ui->get_name(), PARAM_ALPHANUM);
104        $params = $this->uistage->get_params();
105        if (is_array($params) && count($params) > 0) {
106            foreach ($params as $name => $value) {
107                // TODO: Horrible hack, but current backup ui structure does not allow
108                // to make this easy (only changing params to objects that would be
109                // possible. MDL-38735.
110                $intparams = array(
111                        'contextid', 'importid', 'target');
112                $stage = $mform->addElement('hidden', $name, $value);
113                if (in_array($name, $intparams)) {
114                    $mform->setType($name, PARAM_INT);
115                } else {
116                    // Adding setType() to avoid missing setType() warnings.
117                    // MDL-39126: support $mform->setType() for additional backup parameters.
118                    $mform->setType($name, PARAM_RAW);
119                }
120            }
121        }
122    }
123    /**
124     * Definition applied after the data is organised.. why's it here? because I want
125     * to add elements on the fly.
126     * @global moodle_page $PAGE
127     */
128    public function definition_after_data() {
129        $buttonarray = array();
130        if (!$this->uistage->is_first_stage()) {
131            $buttonarray[] = $this->_form->createElement('submit', 'previous', get_string('previousstage', 'backup'));
132        } else if ($this->uistage instanceof backup_ui_stage) {
133            // Only display the button on the first stage of backup, they only place where it has an effect.
134            $buttonarray[] = $this->_form->createElement('submit', 'oneclickbackup', get_string('jumptofinalstep', 'backup'),
135                array('class' => 'oneclickbackup'));
136        }
137        $buttonarray[] = $this->_form->createElement('cancel', 'cancel', get_string('cancel'), array('class' => 'confirmcancel'));
138        $buttonarray[] = $this->_form->createElement(
139            'submit',
140            'submitbutton',
141            get_string($this->uistage->get_ui()->get_name().'stage'.$this->uistage->get_stage().'action', 'backup'),
142            array('class' => 'proceedbutton')
143        );
144        $this->_form->addGroup($buttonarray, 'buttonar', '', array(' '), false);
145        $this->_form->closeHeaderBefore('buttonar');
146
147        $this->_definition_finalized = true;
148    }
149
150    /**
151     * Closes any open divs
152     */
153    public function close_task_divs() {
154        if ($this->activitydiv) {
155            $this->_form->addElement('html', html_writer::end_tag('div'));
156            $this->activitydiv = false;
157        }
158        if ($this->sectiondiv) {
159            $this->_form->addElement('html', html_writer::end_tag('div'));
160            $this->sectiondiv = false;
161        }
162        if ($this->coursediv) {
163            $this->_form->addElement('html', html_writer::end_tag('div'));
164            $this->coursediv = false;
165        }
166    }
167
168    /**
169     * Adds the backup_setting as a element to the form
170     * @param backup_setting $setting
171     * @param base_task $task
172     * @return bool
173     */
174    public function add_setting(backup_setting $setting, base_task $task = null) {
175        return $this->add_settings(array(array($setting, $task)));
176    }
177
178    /**
179     * Adds multiple backup_settings as elements to the form
180     * @param array $settingstasks Consists of array($setting, $task) elements
181     * @return bool
182     */
183    public function add_settings(array $settingstasks) {
184        global $OUTPUT;
185
186        // Determine highest setting level, which is displayed in this stage. This is relevant for considering only
187        // locks of dependency settings for parent settings, which are not displayed in this stage.
188        $highestlevel = backup_setting::ACTIVITY_LEVEL;
189        foreach ($settingstasks as $st) {
190            list($setting, $task) = $st;
191            if ($setting->get_level() < $highestlevel) {
192                $highestlevel = $setting->get_level();
193            }
194        }
195
196        $defaults = array();
197        foreach ($settingstasks as $st) {
198            list($setting, $task) = $st;
199            // If the setting cant be changed or isn't visible then add it as a fixed setting.
200            if (!$setting->get_ui()->is_changeable($highestlevel) ||
201                $setting->get_visibility() != backup_setting::VISIBLE) {
202                $this->add_fixed_setting($setting, $task);
203                continue;
204            }
205
206            // First add the formatting for this setting.
207            $this->add_html_formatting($setting);
208
209            // Then call the add method with the get_element_properties array.
210            call_user_func_array(array($this->_form, 'addElement'), $setting->get_ui()->get_element_properties($task, $OUTPUT));
211            $this->_form->setType($setting->get_ui_name(), $setting->get_param_validation());
212            $defaults[$setting->get_ui_name()] = $setting->get_value();
213            if ($setting->has_help()) {
214                list($identifier, $component) = $setting->get_help();
215                $this->_form->addHelpButton($setting->get_ui_name(), $identifier, $component);
216            }
217            $this->_form->addElement('html', html_writer::end_tag('div'));
218        }
219        $this->_form->setDefaults($defaults);
220        return true;
221    }
222
223    /**
224     * Adds a heading to the form
225     * @param string $name
226     * @param string $text
227     */
228    public function add_heading($name , $text) {
229        $this->_form->addElement('header', $name, $text);
230    }
231
232    /**
233     * Adds HTML formatting for the given backup setting, needed to group/segment
234     * correctly.
235     * @param backup_setting $setting
236     */
237    protected function add_html_formatting(backup_setting $setting) {
238        $mform = $this->_form;
239        $isincludesetting = (strpos($setting->get_name(), '_include') !== false);
240        if ($isincludesetting && $setting->get_level() != backup_setting::ROOT_LEVEL) {
241            switch ($setting->get_level()) {
242                case backup_setting::COURSE_LEVEL:
243                    if ($this->activitydiv) {
244                        $this->_form->addElement('html', html_writer::end_tag('div'));
245                        $this->activitydiv = false;
246                    }
247                    if ($this->sectiondiv) {
248                        $this->_form->addElement('html', html_writer::end_tag('div'));
249                        $this->sectiondiv = false;
250                    }
251                    if ($this->coursediv) {
252                        $this->_form->addElement('html', html_writer::end_tag('div'));
253                    }
254                    $mform->addElement('html', html_writer::start_tag('div', array('class' => 'grouped_settings course_level')));
255                    $mform->addElement('html', html_writer::start_tag('div', array('class' => 'include_setting course_level')));
256                    $this->coursediv = true;
257                    break;
258                case backup_setting::SECTION_LEVEL:
259                    if ($this->activitydiv) {
260                        $this->_form->addElement('html', html_writer::end_tag('div'));
261                        $this->activitydiv = false;
262                    }
263                    if ($this->sectiondiv) {
264                        $this->_form->addElement('html', html_writer::end_tag('div'));
265                    }
266                    $mform->addElement('html', html_writer::start_tag('div', array('class' => 'grouped_settings section_level')));
267                    $mform->addElement('html', html_writer::start_tag('div', array('class' => 'include_setting section_level')));
268                    $this->sectiondiv = true;
269                    break;
270                case backup_setting::ACTIVITY_LEVEL:
271                    if ($this->activitydiv) {
272                        $this->_form->addElement('html', html_writer::end_tag('div'));
273                    }
274                    $mform->addElement('html', html_writer::start_tag('div', array('class' => 'grouped_settings activity_level')));
275                    $mform->addElement('html', html_writer::start_tag('div', array('class' => 'include_setting activity_level')));
276                    $this->activitydiv = true;
277                    break;
278                default:
279                    $mform->addElement('html', html_writer::start_tag('div', array('class' => 'normal_setting')));
280                    break;
281            }
282        } else if ($setting->get_level() == backup_setting::ROOT_LEVEL) {
283            $mform->addElement('html', html_writer::start_tag('div', array('class' => 'root_setting')));
284        } else {
285            $mform->addElement('html', html_writer::start_tag('div', array('class' => 'normal_setting')));
286        }
287    }
288
289    /**
290     * Adds a fixed or static setting to the form
291     * @param backup_setting $setting
292     * @param base_task $task
293     */
294    public function add_fixed_setting(backup_setting $setting, base_task $task) {
295        global $OUTPUT;
296        $settingui = $setting->get_ui();
297        if ($setting->get_visibility() == backup_setting::VISIBLE) {
298            $this->add_html_formatting($setting);
299            switch ($setting->get_status()) {
300                case backup_setting::LOCKED_BY_PERMISSION:
301                    $icon = ' '.$OUTPUT->pix_icon('i/permissionlock', get_string('lockedbypermission', 'backup'), 'moodle',
302                            array('class' => 'smallicon lockedicon permissionlock'));
303                    break;
304                case backup_setting::LOCKED_BY_CONFIG:
305                    $icon = ' '.$OUTPUT->pix_icon('i/configlock', get_string('lockedbyconfig', 'backup'), 'moodle',
306                            array('class' => 'smallicon lockedicon configlock'));
307                    break;
308                case backup_setting::LOCKED_BY_HIERARCHY:
309                    $icon = ' '.$OUTPUT->pix_icon('i/hierarchylock', get_string('lockedbyhierarchy', 'backup'), 'moodle',
310                            array('class' => 'smallicon lockedicon configlock'));
311                    break;
312                default:
313                    $icon = '';
314                    break;
315            }
316            $context = context_course::instance($task->get_courseid());
317            $label = format_string($settingui->get_label($task), true, array('context' => $context));
318            $labelicon = $settingui->get_icon();
319            if (!empty($labelicon)) {
320                $label .= '&nbsp;'.$OUTPUT->render($labelicon);
321            }
322            $this->_form->addElement('static', 'static_'.$settingui->get_name(), $label, $settingui->get_static_value().$icon);
323            $this->_form->addElement('html', html_writer::end_tag('div'));
324        }
325        $this->_form->addElement('hidden', $settingui->get_name(), $settingui->get_value());
326        $this->_form->setType($settingui->get_name(), $settingui->get_param_validation());
327    }
328
329    /**
330     * Adds dependencies to the form recursively
331     *
332     * @param backup_setting $setting
333     */
334    public function add_dependencies(backup_setting $setting) {
335        $mform = $this->_form;
336        // Apply all dependencies for backup.
337        foreach ($setting->get_my_dependency_properties() as $key => $dependency) {
338            call_user_func_array(array($this->_form, 'disabledIf'), $dependency);
339        }
340    }
341
342    /**
343     * Returns true if the form was cancelled, false otherwise
344     * @return bool
345     */
346    public function is_cancelled() {
347        return (optional_param('cancel', false, PARAM_BOOL) || parent::is_cancelled());
348    }
349
350    /**
351     * Removes an element from the form if it exists
352     * @param string $elementname
353     * @return bool
354     */
355    public function remove_element($elementname) {
356        if ($this->_form->elementExists($elementname)) {
357            return $this->_form->removeElement($elementname);
358        } else {
359            return false;
360        }
361    }
362
363    /**
364     * Gets an element from the form if it exists
365     *
366     * @param string $elementname
367     * @return HTML_QuickForm_input|MoodleQuickForm_group
368     */
369    public function get_element($elementname) {
370        if ($this->_form->elementExists($elementname)) {
371            return $this->_form->getElement($elementname);
372        } else {
373            return false;
374        }
375    }
376
377    /**
378     * Displays the form
379     */
380    public function display() {
381        global $PAGE, $COURSE;
382
383        $this->require_definition_after_data();
384
385        $config = new stdClass;
386        if ($this->uistage->get_ui() instanceof import_ui) {
387            $config->title = get_string('confirmcancelimport', 'backup');
388        } else if ($this->uistage->get_ui() instanceof restore_ui) {
389            $config->title = get_string('confirmcancelrestore', 'backup');
390        } else {
391            $config->title = get_string('confirmcancel', 'backup');
392        }
393        $config->question = get_string('confirmcancelquestion', 'backup');
394        $config->yesLabel = $config->title;
395        $config->noLabel = get_string('confirmcancelno', 'backup');
396        $config->closeButtonTitle = get_string('close', 'editor');
397        $PAGE->requires->yui_module(
398            'moodle-backup-confirmcancel',
399            'M.core_backup.confirmcancel.watch_cancel_buttons',
400            array($config)
401        );
402
403        // Get list of module types on course.
404        $modinfo = get_fast_modinfo($COURSE);
405        $modnames = $modinfo->get_used_module_names(true);
406        $PAGE->requires->yui_module('moodle-backup-backupselectall', 'M.core_backup.backupselectall',
407                array($modnames));
408        $PAGE->requires->strings_for_js(array('select', 'all', 'none'), 'moodle');
409        $PAGE->requires->strings_for_js(array('showtypes', 'hidetypes'), 'backup');
410
411        parent::display();
412    }
413
414    /**
415     * Ensures the the definition after data is loaded
416     */
417    public function require_definition_after_data() {
418        if (!$this->_definition_finalized) {
419            $this->definition_after_data();
420        }
421    }
422}