Search moodle.org's
Developer Documentation

See Release Notes

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

Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 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  /**
  18   * Form for editing steps.
  19   *
  20   * @package    tool_usertours
  21   * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  namespace tool_usertours\local\forms;
  26  
  27  use stdClass;
  28  use tool_usertours\helper;
  29  use tool_usertours\step;
  30  
  31  defined('MOODLE_INTERNAL') || die('Direct access to this script is forbidden.');
  32  
  33  require_once($CFG->libdir . '/formslib.php');
  34  
  35  /**
  36   * Form for editing steps.
  37   *
  38   * @copyright  2016 Andrew Nicols <andrew@nicols.co.uk>
  39   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  40   */
  41  class editstep extends \moodleform {
  42      /**
  43       * @var tool_usertours\step $step
  44       */
  45      protected $step;
  46  
  47      /**
  48       * @var int Display the step's content by using Moodle language string.
  49       */
  50      private const CONTENTTYPE_LANGSTRING = 0;
  51  
  52      /**
  53       * @var int Display the step's content by entering it manually.
  54       */
  55      private const CONTENTTYPE_MANUAL = 1;
  56  
  57      /**
  58       * Create the edit step form.
  59       *
  60       * @param   string      $target     The target of the form.
  61       * @param   step        $step       The step being editted.
  62       */
  63      public function __construct($target, \tool_usertours\step $step) {
  64          $this->step = $step;
  65  
  66          parent::__construct($target);
  67      }
  68  
  69      /**
  70       * Form definition.
  71       */
  72      public function definition() {
  73          global $CFG;
  74  
  75          $mform = $this->_form;
  76  
  77          $mform->addElement('header', 'heading_target', get_string('target_heading', 'tool_usertours'));
  78          $types = [];
  79          foreach (\tool_usertours\target::get_target_types() as $value => $type) {
  80              $types[$value] = get_string('target_' . $type, 'tool_usertours');
  81          }
  82          $mform->addElement('select', 'targettype', get_string('targettype', 'tool_usertours'), $types);
  83          $mform->addHelpButton('targettype', 'targettype', 'tool_usertours');
  84  
  85          // The target configuration.
  86          foreach (\tool_usertours\target::get_target_types() as $value => $type) {
  87              $targetclass = \tool_usertours\target::get_classname($type);
  88              $targetclass::add_config_to_form($mform);
  89          }
  90  
  91          // Content of the step.
  92          $mform->addElement('header', 'heading_content', get_string('content_heading', 'tool_usertours'));
  93          $mform->addElement('textarea', 'title', get_string('title', 'tool_usertours'));
  94          $mform->addRule('title', get_string('required'), 'required', null, 'client');
  95          $mform->setType('title', PARAM_TEXT);
  96          $mform->addHelpButton('title', 'title', 'tool_usertours');
  97  
  98          // Content type.
  99          $typeoptions = [
 100              static::CONTENTTYPE_LANGSTRING => get_string('content_type_langstring', 'tool_usertours'),
 101              static::CONTENTTYPE_MANUAL => get_string('content_type_manual', 'tool_usertours')
 102          ];
 103          $mform->addElement('select', 'contenttype', get_string('content_type', 'tool_usertours'), $typeoptions);
 104          $mform->addHelpButton('contenttype', 'content_type', 'tool_usertours');
 105          $mform->setDefault('contenttype', static::CONTENTTYPE_MANUAL);
 106  
 107          // Language identifier.
 108          $mform->addElement('textarea', 'contentlangstring', get_string('moodle_language_identifier', 'tool_usertours'));
 109          $mform->setType('contentlangstring', PARAM_TEXT);
 110          $mform->hideIf('contentlangstring', 'contenttype', 'eq', static::CONTENTTYPE_MANUAL);
 111  
 112          $editoroptions = [
 113              'subdirs' => 1,
 114              'maxbytes' => $CFG->maxbytes,
 115              'maxfiles' => EDITOR_UNLIMITED_FILES,
 116              'changeformat' => 1,
 117              'trusttext' => true
 118          ];
 119          $objs = $mform->createElement('editor', 'content', get_string('content', 'tool_usertours'), null, $editoroptions);
 120          // TODO: MDL-68540 We need to add the editor to a group element because editor element will not work with hideIf.
 121          $mform->addElement('group', 'contenthtmlgrp', get_string('content', 'tool_usertours'), [$objs], ' ', false);
 122          $mform->addHelpButton('contenthtmlgrp', 'content', 'tool_usertours');
 123          $mform->hideIf('contenthtmlgrp', 'contenttype', 'eq', static::CONTENTTYPE_LANGSTRING);
 124  
 125          // Add the step configuration.
 126          $mform->addElement('header', 'heading_options', get_string('options_heading', 'tool_usertours'));
 127          // All step configuration is defined in the step.
 128          $this->step->add_config_to_form($mform);
 129  
 130          // And apply any form constraints.
 131          foreach (\tool_usertours\target::get_target_types() as $value => $type) {
 132              $targetclass = \tool_usertours\target::get_classname($type);
 133              $targetclass::add_disabled_constraints_to_form($mform);
 134          }
 135  
 136          $this->add_action_buttons();
 137      }
 138  
 139      /**
 140       * Validate the database on the submitted content type.
 141       *
 142       * @param array $data array of ("fieldname"=>value) of submitted data
 143       * @param array $files array of uploaded files "element_name"=>tmp_file_path
 144       * @return array of "element_name"=>"error_description" if there are errors,
 145       *         or an empty array if everything is OK (true allowed for backwards compatibility too).
 146       */
 147      public function validation($data, $files): array {
 148          $errors = parent::validation($data, $files);
 149  
 150          if ($data['contenttype'] == static::CONTENTTYPE_LANGSTRING) {
 151              if (!isset($data['contentlangstring']) || trim($data['contentlangstring']) == '') {
 152                  $errors['contentlangstring'] = get_string('required');
 153              } else {
 154                  $splitted = explode(',', trim($data['contentlangstring']), 2);
 155                  $langid = $splitted[0];
 156                  $langcomponent = $splitted[1];
 157                  if (!get_string_manager()->string_exists($langid, $langcomponent)) {
 158                      $errors['contentlangstring'] = get_string('invalid_lang_id', 'tool_usertours');
 159                  }
 160              }
 161          }
 162  
 163          // Validate manually entered text content. Validation logic derived from \MoodleQuickForm_Rule_Required::validate()
 164          // without the checking of the "strictformsrequired" admin setting.
 165          if ($data['contenttype'] == static::CONTENTTYPE_MANUAL) {
 166              $value = $data['content']['text'] ?? '';
 167  
 168              // All tags except img, canvas and hr, plus all forms of whitespaces.
 169              $stripvalues = [
 170                  '#</?(?!img|canvas|hr).*?>#im',
 171                  '#(\xc2\xa0|\s|&nbsp;)#',
 172              ];
 173              $value = preg_replace($stripvalues, '', (string)$value);
 174              if (empty($value)) {
 175                  $errors['contenthtmlgrp'] = get_string('required');
 176              }
 177          }
 178  
 179          return $errors;
 180      }
 181  
 182      /**
 183       * Load in existing data as form defaults. Usually new entry defaults are stored directly in
 184       * form definition (new entry form); this function is used to load in data where values
 185       * already exist and data is being edited (edit entry form).
 186       *
 187       * @param stdClass|array $data object or array of default values
 188       */
 189      public function set_data($data): void {
 190          $data = (object) $data;
 191          if (!isset($data->contenttype)) {
 192              if (!empty($data->content['text']) && helper::is_language_string_from_input($data->content['text'])) {
 193                  $data->contenttype = static::CONTENTTYPE_LANGSTRING;
 194                  $data->contentlangstring = $data->content['text'];
 195  
 196                  // Empty the editor content.
 197                  $data->content = ['text' => ''];
 198              } else {
 199                  $data->contenttype = static::CONTENTTYPE_MANUAL;
 200              }
 201          }
 202          parent::set_data($data);
 203      }
 204  
 205      /**
 206       * Return submitted data if properly submitted or returns NULL if validation fails or
 207       * if there is no submitted data.
 208       *
 209       * @return object|null submitted data; NULL if not valid or not submitted or cancelled
 210       */
 211      public function get_data(): ?object {
 212          $data = parent::get_data();
 213          if ($data) {
 214              if ($data->contenttype == static::CONTENTTYPE_LANGSTRING) {
 215                  $data->content = [
 216                      'text' => $data->contentlangstring,
 217                      'format' => FORMAT_MOODLE,
 218                  ];
 219              }
 220          }
 221          return $data;
 222      }
 223  }