Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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.

Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 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   * Page for editing random questions.
  19   *
  20   * @package    mod_quiz
  21   * @copyright  2018 Shamim Rezaie <shamim@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  require_once(__DIR__ . '/../../config.php');
  26  require_once($CFG->dirroot . '/mod/quiz/locallib.php');
  27  
  28  $slotid = required_param('slotid', PARAM_INT);
  29  $returnurl = optional_param('returnurl', '', PARAM_LOCALURL);
  30  
  31  // Get the quiz slot.
  32  $slot = $DB->get_record('quiz_slots', array('id' => $slotid));
  33  if (!$slot || empty($slot->questioncategoryid)) {
  34      print_error('invalidrandomslot', 'mod_quiz');
  35  }
  36  
  37  if (!$quiz = $DB->get_record('quiz', array('id' => $slot->quizid))) {
  38      print_error('invalidquizid', 'quiz');
  39  }
  40  
  41  $cm = get_coursemodule_from_instance('quiz', $slot->quizid, $quiz->course);
  42  
  43  require_login($cm->course, false, $cm);
  44  
  45  if ($returnurl) {
  46      $returnurl = new moodle_url($returnurl);
  47  } else {
  48      $returnurl = new moodle_url('/mod/quiz/edit.php', array('cmid' => $cm->id));
  49  }
  50  
  51  $url = new moodle_url('/mod/quiz/editrandom.php', array('slotid' => $slotid));
  52  $PAGE->set_url($url);
  53  $PAGE->set_pagelayout('admin');
  54  
  55  if (!$question = $DB->get_record('question', array('id' => $slot->questionid))) {
  56      print_error('questiondoesnotexist', 'question', $returnurl);
  57  }
  58  
  59  $qtypeobj = question_bank::get_qtype('random');
  60  
  61  // Validate the question category.
  62  if (!$category = $DB->get_record('question_categories', array('id' => $question->category))) {
  63      print_error('categorydoesnotexist', 'question', $returnurl);
  64  }
  65  
  66  // Check permissions.
  67  question_require_capability_on($question, 'edit');
  68  
  69  $thiscontext = context_module::instance($cm->id);
  70  $contexts = new question_edit_contexts($thiscontext);
  71  
  72  // Create the question editing form.
  73  $mform = new mod_quiz\form\randomquestion_form(new moodle_url('/mod/quiz/editrandom.php'),
  74          array('contexts' => $contexts));
  75  
  76  // Send the question object and a few more parameters to the form.
  77  $toform = fullclone($question);
  78  $toform->category = "{$category->id},{$category->contextid}";
  79  $toform->includesubcategories = $slot->includingsubcategories;
  80  $toform->fromtags = array();
  81  $currentslottags = quiz_retrieve_slot_tags($slot->id);
  82  foreach ($currentslottags as $slottag) {
  83      $toform->fromtags[] = "{$slottag->tagid},{$slottag->tagname}";
  84  }
  85  $toform->returnurl = $returnurl;
  86  
  87  if ($cm !== null) {
  88      $toform->cmid = $cm->id;
  89      $toform->courseid = $cm->course;
  90  } else {
  91      $toform->courseid = $COURSE->id;
  92  }
  93  
  94  $toform->slotid = $slotid;
  95  
  96  $mform->set_data($toform);
  97  
  98  if ($mform->is_cancelled()) {
  99      redirect($returnurl);
 100  } else if ($fromform = $mform->get_data()) {
 101  
 102      // If we are moving a question, check we have permission to move it from
 103      // whence it came. Where we are moving to is validated by the form.
 104      list($newcatid, $newcontextid) = explode(',', $fromform->category);
 105      if (!empty($question->id) && $newcatid != $question->category) {
 106          $contextid = $newcontextid;
 107          question_require_capability_on($question, 'move');
 108      } else {
 109          $contextid = $category->contextid;
 110      }
 111  
 112      $question = $qtypeobj->save_question($question, $fromform);
 113  
 114      // We need to save some data into the quiz_slots table.
 115      $slot->questioncategoryid = $fromform->category;
 116      $slot->includingsubcategories = $fromform->includesubcategories;
 117  
 118      $DB->update_record('quiz_slots', $slot);
 119  
 120      $tags = [];
 121      foreach ($fromform->fromtags as $tagstring) {
 122          list($tagid, $tagname) = explode(',', $tagstring);
 123          $tags[] = (object) [
 124              'id' => $tagid,
 125              'name' => $tagname
 126          ];
 127      }
 128  
 129      $recordstokeep = [];
 130      $recordstoinsert = [];
 131      $searchableslottags = array_map(function($slottag) {
 132          return ['tagid' => $slottag->tagid, 'tagname' => $slottag->tagname];
 133      }, $currentslottags);
 134  
 135      foreach ($tags as $tag) {
 136          if ($key = array_search(['tagid' => $tag->id, 'tagname' => $tag->name], $searchableslottags)) {
 137              // If found, $key would be the id field in the quiz_slot_tags table.
 138              // Therefore, there was no need to check !== false here.
 139              $recordstokeep[] = $key;
 140          } else {
 141              $recordstoinsert[] = (object)[
 142                  'slotid' => $slot->id,
 143                  'tagid' => $tag->id,
 144                  'tagname' => $tag->name
 145              ];
 146          }
 147      }
 148  
 149      // Now, delete the remaining records.
 150      if (!empty($recordstokeep)) {
 151          list($select, $params) = $DB->get_in_or_equal($recordstokeep, SQL_PARAMS_QM, 'param', false);
 152          array_unshift($params, $slot->id);
 153          $DB->delete_records_select('quiz_slot_tags', "slotid = ? AND id $select", $params);
 154      } else {
 155          $DB->delete_records('quiz_slot_tags', array('slotid' => $slot->id));
 156      }
 157  
 158      // And now, insert the extra records if there is any.
 159      if (!empty($recordstoinsert)) {
 160          $DB->insert_records('quiz_slot_tags', $recordstoinsert);
 161      }
 162  
 163      // Purge this question from the cache.
 164      question_bank::notify_question_edited($question->id);
 165  
 166      $returnurl->param('lastchanged', $question->id);
 167      redirect($returnurl);
 168  }
 169  
 170  $streditingquestion = $qtypeobj->get_heading();
 171  $PAGE->set_title($streditingquestion);
 172  $PAGE->set_heading($COURSE->fullname);
 173  $PAGE->navbar->add($streditingquestion);
 174  
 175  // Display a heading, question editing form and possibly some extra content needed for
 176  // for this question type.
 177  echo $OUTPUT->header();
 178  $heading = get_string('randomediting', 'mod_quiz');
 179  echo $OUTPUT->heading_with_help($heading, 'randomquestion', 'mod_quiz');
 180  
 181  $mform->display();
 182  
 183  echo $OUTPUT->footer();