Differences Between: [Versions 311 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 namespace core_form\external; 18 19 use core_external\external_api; 20 use core_external\external_function_parameters; 21 use core_external\external_single_structure; 22 use core_external\external_value; 23 24 /** 25 * Implements the external functions provided by the core_form subsystem. 26 * 27 * @copyright 2020 Marina Glancy 28 * @package core_form 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 */ 31 class dynamic_form extends external_api { 32 33 /** 34 * Parameters for modal form 35 * 36 * @return external_function_parameters 37 */ 38 public static function execute_parameters(): external_function_parameters { 39 return new external_function_parameters([ 40 'form' => new external_value(PARAM_RAW_TRIMMED, 'Form class', VALUE_REQUIRED), 41 'formdata' => new external_value(PARAM_RAW, 'url-encoded form data', VALUE_REQUIRED), 42 ]); 43 } 44 45 /** 46 * Submit a form from a modal dialogue. 47 * 48 * @param string $formclass 49 * @param string $formdatastr 50 * @return array 51 * @throws \moodle_exception 52 */ 53 public static function execute(string $formclass, string $formdatastr): array { 54 global $PAGE, $OUTPUT; 55 56 $params = self::validate_parameters(self::execute_parameters(), [ 57 'form' => $formclass, 58 'formdata' => $formdatastr, 59 ]); 60 $formclass = $params['form']; 61 parse_str($params['formdata'], $formdata); 62 63 self::autoload_block_edit_form($formclass); 64 65 if (!class_exists($formclass) || !is_subclass_of($formclass, \core_form\dynamic_form::class)) { 66 // For security reason we don't throw exception "class does not exist" but rather an access exception. 67 throw new \moodle_exception('nopermissionform', 'core_form'); 68 } 69 70 /** @var \core_form\dynamic_form $form */ 71 $form = new $formclass(null, null, 'post', '', [], true, $formdata, true); 72 $form->set_data_for_dynamic_submission(); 73 if (!$form->is_cancelled() && $form->is_submitted() && $form->is_validated()) { 74 // Form was properly submitted, process and return results of processing. No need to render it again. 75 return ['submitted' => true, 'data' => json_encode($form->process_dynamic_submission())]; 76 } 77 78 // Render actual form. 79 80 if ($form->no_submit_button_pressed()) { 81 // If form has not been submitted, we have to recreate the form for being able to properly handle non-submit action 82 // like "repeat elements" to include additional JS. 83 /** @var \core_form\dynamic_form $form */ 84 $form = new $formclass(null, null, 'post', '', [], true, $formdata, true); 85 $form->set_data_for_dynamic_submission(); 86 } 87 // Hack alert: Forcing bootstrap_renderer to initiate moodle page. 88 $OUTPUT->header(); 89 90 $PAGE->start_collecting_javascript_requirements(); 91 $data = $form->render(); 92 $jsfooter = $PAGE->requires->get_end_code(); 93 $output = ['submitted' => false, 'html' => $data, 'javascript' => $jsfooter]; 94 return $output; 95 } 96 97 /** 98 * Special autoloading for block forms. 99 * 100 * @param string $formclass 101 * @return void 102 */ 103 protected static function autoload_block_edit_form(string $formclass): void { 104 global $CFG; 105 if (preg_match('/^block_([\w_]+)_edit_form$/', $formclass, $matches)) { 106 \block_manager::get_block_edit_form_class($matches[1]); 107 } 108 if ($formclass === 'block_edit_form') { 109 require_once($CFG->dirroot . '/blocks/edit_form.php'); 110 } 111 } 112 113 /** 114 * Return for modal 115 * @return external_single_structure 116 */ 117 public static function execute_returns(): external_single_structure { 118 return new external_single_structure( 119 array( 120 'submitted' => new external_value(PARAM_BOOL, 'If form was submitted and validated'), 121 'data' => new external_value(PARAM_RAW, 'JSON-encoded return data from form processing method', VALUE_OPTIONAL), 122 'html' => new external_value(PARAM_RAW, 'HTML fragment of the form', VALUE_OPTIONAL), 123 'javascript' => new external_value(PARAM_RAW, 'JavaScript fragment of the form', VALUE_OPTIONAL) 124 ) 125 ); 126 } 127 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body