Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 401 and 402] [Versions 401 and 403]

   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;
  18  
  19  use context;
  20  use moodle_url;
  21  
  22  defined('MOODLE_INTERNAL') || die();
  23  
  24  global $CFG;
  25  require_once($CFG->libdir . '/formslib.php');
  26  
  27  /**
  28   * Class modal
  29   *
  30   * Extend this class to create a form that can be used in a modal dialogue.
  31   *
  32   * @package     core_form
  33   * @copyright   2020 Marina Glancy
  34   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  abstract class dynamic_form extends \moodleform {
  37  
  38      /**
  39       * Constructor for modal forms can not be overridden, however the same form can be used both in AJAX and normally
  40       *
  41       * @param string $action
  42       * @param array $customdata
  43       * @param string $method
  44       * @param string $target
  45       * @param array $attributes
  46       * @param bool $editable
  47       * @param array $ajaxformdata Forms submitted via ajax, must pass their data here, instead of relying on _GET and _POST.
  48       * @param bool $isajaxsubmission whether the form is called from WS and it needs to validate user access and set up context
  49       */
  50      final public function __construct(
  51          ?string $action = null,
  52          ?array $customdata = null,
  53          string $method = 'post',
  54          string $target = '',
  55          ?array $attributes = [],
  56          bool $editable = true,
  57          ?array $ajaxformdata = null,
  58          bool $isajaxsubmission = false
  59      ) {
  60          global $PAGE, $CFG;
  61  
  62          $this->_ajaxformdata = $ajaxformdata;
  63          if ($isajaxsubmission) {
  64              require_once($CFG->libdir . '/externallib.php');
  65              // This form was created from the WS that needs to validate user access to it and set page context.
  66              // It has to be done before calling parent constructor because elements definitions may need to use
  67              // format_string functions and other methods that expect the page to be set up.
  68              \external_api::validate_context($this->get_context_for_dynamic_submission());
  69              $PAGE->set_url($this->get_page_url_for_dynamic_submission());
  70              $this->check_access_for_dynamic_submission();
  71          }
  72          $attributes = ['data-random-ids' => 1] + ($attributes ?: []);
  73          parent::__construct($action, $customdata, $method, $target, $attributes, $editable, $ajaxformdata);
  74      }
  75  
  76      /**
  77       * Returns context where this form is used
  78       *
  79       * This context is validated in {@see \external_api::validate_context()}
  80       *
  81       * If context depends on the form data, it is available in $this->_ajaxformdata or
  82       * by calling $this->optional_param()
  83       *
  84       * Example:
  85       *     $cmid = $this->optional_param('cmid', 0, PARAM_INT);
  86       *     return context_module::instance($cmid);
  87       *
  88       * @return context
  89       */
  90      abstract protected function get_context_for_dynamic_submission(): context;
  91  
  92      /**
  93       * Checks if current user has access to this form, otherwise throws exception
  94       *
  95       * Sometimes permission check may depend on the action and/or id of the entity.
  96       * If necessary, form data is available in $this->_ajaxformdata or
  97       * by calling $this->optional_param()
  98       *
  99       * Example:
 100       *     require_capability('dosomething', $this->get_context_for_dynamic_submission());
 101       */
 102      abstract protected function check_access_for_dynamic_submission(): void;
 103  
 104      /**
 105       * Process the form submission, used if form was submitted via AJAX
 106       *
 107       * This method can return scalar values or arrays that can be json-encoded, they will be passed to the caller JS.
 108       *
 109       * Submission data can be accessed as: $this->get_data()
 110       *
 111       * Example:
 112       *     $data = $this->get_data();
 113       *     file_postupdate_standard_filemanager($data, ....);
 114       *     api::save_entity($data); // Save into the DB, trigger event, etc.
 115       *
 116       * @return mixed
 117       */
 118      abstract public function process_dynamic_submission();
 119  
 120      /**
 121       * Load in existing data as form defaults
 122       *
 123       * Can be overridden to retrieve existing values from db by entity id and also
 124       * to preprocess editor and filemanager elements
 125       *
 126       * Example:
 127       *     $id = $this->optional_param('id', 0, PARAM_INT);
 128       *     $data = api::get_entity($id); // For example, retrieve a row from the DB.
 129       *     file_prepare_standard_filemanager($data, ...);
 130       *     $this->set_data($data);
 131       */
 132      abstract public function set_data_for_dynamic_submission(): void;
 133  
 134      /**
 135       * Returns url to set in $PAGE->set_url() when form is being rendered or submitted via AJAX
 136       *
 137       * This is used in the form elements sensitive to the page url, such as Atto autosave in 'editor'
 138       *
 139       * If the form has arguments (such as 'id' of the element being edited), the URL should
 140       * also have respective argument.
 141       *
 142       * Example:
 143       *     $id = $this->optional_param('id', 0, PARAM_INT);
 144       *     return new moodle_url('/my/page/where/form/is/used.php', ['id' => $id]);
 145       *
 146       * @return moodle_url
 147       */
 148      abstract protected function get_page_url_for_dynamic_submission(): moodle_url;
 149  }