Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

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;
  18  
  19  use context;
  20  use core_external\external_api;
  21  use moodle_url;
  22  
  23  defined('MOODLE_INTERNAL') || die();
  24  
  25  global $CFG;
  26  require_once($CFG->libdir . '/formslib.php');
  27  
  28  /**
  29   * Class modal
  30   *
  31   * Extend this class to create a form that can be used in a modal dialogue.
  32   *
  33   * @package     core_form
  34   * @copyright   2020 Marina Glancy
  35   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  abstract class dynamic_form extends \moodleform {
  38  
  39      /**
  40       * Constructor for modal forms can not be overridden, however the same form can be used both in AJAX and normally
  41       *
  42       * @param string $action
  43       * @param array $customdata
  44       * @param string $method
  45       * @param string $target
  46       * @param array $attributes
  47       * @param bool $editable
  48       * @param array $ajaxformdata Forms submitted via ajax, must pass their data here, instead of relying on _GET and _POST.
  49       * @param bool $isajaxsubmission whether the form is called from WS and it needs to validate user access and set up context
  50       */
  51      final public function __construct(
  52          ?string $action = null,
  53          ?array $customdata = null,
  54          string $method = 'post',
  55          string $target = '',
  56          ?array $attributes = [],
  57          bool $editable = true,
  58          ?array $ajaxformdata = null,
  59          bool $isajaxsubmission = false
  60      ) {
  61          global $PAGE, $CFG;
  62  
  63          $this->_ajaxformdata = $ajaxformdata;
  64          if ($isajaxsubmission) {
  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  }