Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
   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   * Base class for editing form for the drag-and-drop images onto images question type.
  19   *
  20   * @package   qtype_ddimageortext
  21   * @copyright 2011 The Open University
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  /**
  28   * Base class for drag-and-drop onto images editing form definition.
  29   *
  30   * @copyright  2011 The Open University
  31   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32   */
  33  abstract class qtype_ddtoimage_edit_form_base extends question_edit_form {
  34      /**
  35       * Maximum number of different groups of drag items there can be in a question.
  36       */
  37      const MAX_GROUPS = 8;
  38  
  39      /**
  40       * The default starting number of drop zones.
  41       */
  42      const START_NUM_ITEMS = 6;
  43  
  44      /**
  45       * The number of drop zones that get added at a time.
  46       */
  47      const ADD_NUM_ITEMS = 3;
  48  
  49      /**
  50       * Options shared by all file pickers in the form.
  51       *
  52       * @return array Array of filepicker options.
  53       */
  54      public static function file_picker_options() {
  55          $filepickeroptions = array();
  56          $filepickeroptions['accepted_types'] = array('web_image');
  57          $filepickeroptions['maxbytes'] = 0;
  58          $filepickeroptions['maxfiles'] = 1;
  59          $filepickeroptions['subdirs'] = 0;
  60          return $filepickeroptions;
  61      }
  62  
  63      /**
  64       * definition_inner adds all specific fields to the form.
  65       *
  66       * @param MoodleQuickForm $mform (the form being built).
  67       */
  68      protected function definition_inner($mform) {
  69  
  70          $mform->addElement('header', 'previewareaheader',
  71                              get_string('previewareaheader', 'qtype_'.$this->qtype()));
  72          $mform->setExpanded('previewareaheader');
  73          $mform->addElement('static', 'previewarea', '',
  74                              get_string('previewareamessage', 'qtype_'.$this->qtype()));
  75  
  76          $mform->registerNoSubmitButton('refresh');
  77          $mform->addElement('submit', 'refresh', get_string('refresh', 'qtype_'.$this->qtype()));
  78          $mform->addElement('filepicker', 'bgimage', get_string('bgimage', 'qtype_'.$this->qtype()),
  79                                                                 null, self::file_picker_options());
  80          $mform->closeHeaderBefore('dropzoneheader');
  81  
  82          // Add the draggable image fields & drop zones to the form.
  83          list($itemrepeatsatstart, $imagerepeats) = $this->get_drag_item_repeats();
  84          $this->definition_draggable_items($mform, $itemrepeatsatstart);
  85          $this->definition_drop_zones($mform, $imagerepeats);
  86  
  87          $this->add_combined_feedback_fields(true);
  88          $this->add_interactive_settings(true, true);
  89      }
  90  
  91      /**
  92       * Make and add drop zones to the form.
  93       *
  94       * @param object $mform The Moodle form object.
  95       * @param int $imagerepeats The initial number of repeat elements.
  96       */
  97      protected function definition_drop_zones($mform, $imagerepeats) {
  98          $mform->addElement('header', 'dropzoneheader', get_string('dropzoneheader', 'qtype_'.$this->qtype()));
  99  
 100          $countdropzones = 0;
 101          if (isset($this->question->id)) {
 102              foreach ($this->question->options->drops as $drop) {
 103                  $countdropzones = max($countdropzones, $drop->no);
 104              }
 105          }
 106  
 107          if (!$countdropzones) {
 108              $countdropzones = self::START_NUM_ITEMS;
 109          }
 110          $dropzonerepeatsatstart = $countdropzones;
 111  
 112          $this->repeat_elements($this->drop_zone($mform, $imagerepeats), $dropzonerepeatsatstart,
 113                  $this->drop_zones_repeated_options(),
 114                  'nodropzone', 'adddropzone', self::ADD_NUM_ITEMS,
 115                  get_string('addmoredropzones', 'qtype_ddimageortext'), true);
 116      }
 117  
 118      /**
 119       * Returns an array with a drop zone form element.
 120       *
 121       * @param object $mform The Moodle form object.
 122       * @param int $imagerepeats The number of repeat images.
 123       * @return array Array with the dropzone element.
 124       */
 125      abstract protected function drop_zone($mform, $imagerepeats);
 126  
 127      /**
 128       * Returns an array of default drop zone repeat options.
 129       *
 130       * @return array
 131       */
 132      abstract protected function drop_zones_repeated_options();
 133  
 134      /**
 135       * Builds and adds the needed form items for draggable items.
 136       *
 137       * @param object $mform The Moodle form object.
 138       * @param int $itemrepeatsatstart The initial number of repeat elements.
 139       */
 140      abstract protected function definition_draggable_items($mform, $itemrepeatsatstart);
 141  
 142      /**
 143       * Creates and returns a set of form elements to make a draggable item.
 144       *
 145       * @param object $mform The Moodle form object.
 146       * @return array An array of form elements.
 147       */
 148      abstract protected function draggable_item($mform);
 149  
 150      /**
 151       * Returns an array of default repeat options.
 152       *
 153       * @return array
 154       */
 155      abstract protected function draggable_items_repeated_options();
 156  
 157      /**
 158       * Returns an array of starting number of repeats, and the total number of repeats.
 159       *
 160       * @return array
 161       */
 162      protected function get_drag_item_repeats() {
 163          $countimages = 0;
 164          if (isset($this->question->id)) {
 165              foreach ($this->question->options->drags as $drag) {
 166                  $countimages = max($countimages, $drag->no);
 167              }
 168          }
 169  
 170          if (!$countimages) {
 171              $countimages = self::START_NUM_ITEMS;
 172          }
 173          $itemrepeatsatstart = $countimages;
 174  
 175          $imagerepeats = optional_param('noitems', $itemrepeatsatstart, PARAM_INT);
 176          $addfields = optional_param('additems', false, PARAM_BOOL);
 177          if ($addfields) {
 178              $imagerepeats += self::ADD_NUM_ITEMS;
 179          }
 180          return array($itemrepeatsatstart, $imagerepeats);
 181      }
 182  
 183      /**
 184       * Performce the needed JS setup for this question type.
 185       */
 186      abstract public function js_call();
 187  
 188      /**
 189       * Checks to see if a file has been uploaded.
 190       *
 191       * @param string $draftitemid The draft id
 192       * @return bool True if files exist, false if not.
 193       */
 194      public static function file_uploaded($draftitemid) {
 195          $draftareafiles = file_get_drafarea_files($draftitemid);
 196          do {
 197              $draftareafile = array_shift($draftareafiles->list);
 198          } while ($draftareafile !== null && $draftareafile->filename == '.');
 199          if ($draftareafile === null) {
 200              return false;
 201          }
 202          return true;
 203      }
 204  
 205  }