PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

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

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