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 * Rest endpoint for ajax editing of quiz structure. 19 * 20 * @package mod_quiz 21 * @copyright 1999 Martin Dougiamas http://dougiamas.com 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25if (!defined('AJAX_SCRIPT')) { 26 define('AJAX_SCRIPT', true); 27} 28 29require_once(__DIR__ . '/../../config.php'); 30require_once($CFG->dirroot . '/mod/quiz/locallib.php'); 31 32// Initialise ALL the incoming parameters here, up front. 33$quizid = required_param('quizid', PARAM_INT); 34$class = required_param('class', PARAM_ALPHA); 35$field = optional_param('field', '', PARAM_ALPHA); 36$instanceid = optional_param('instanceId', 0, PARAM_INT); 37$sectionid = optional_param('sectionId', 0, PARAM_INT); 38$previousid = optional_param('previousid', 0, PARAM_INT); 39$value = optional_param('value', 0, PARAM_INT); 40$column = optional_param('column', 0, PARAM_ALPHA); 41$id = optional_param('id', 0, PARAM_INT); 42$summary = optional_param('summary', '', PARAM_RAW); 43$sequence = optional_param('sequence', '', PARAM_SEQUENCE); 44$visible = optional_param('visible', 0, PARAM_INT); 45$pageaction = optional_param('action', '', PARAM_ALPHA); // Used to simulate a DELETE command. 46$maxmark = optional_param('maxmark', '', PARAM_FLOAT); 47$newheading = optional_param('newheading', '', PARAM_TEXT); 48$shuffle = optional_param('newshuffle', 0, PARAM_INT); 49$page = optional_param('page', '', PARAM_INT); 50$ids = optional_param('ids', '', PARAM_SEQUENCE); 51$PAGE->set_url('/mod/quiz/edit-rest.php', 52 array('quizid' => $quizid, 'class' => $class)); 53 54require_sesskey(); 55$quiz = $DB->get_record('quiz', array('id' => $quizid), '*', MUST_EXIST); 56$cm = get_coursemodule_from_instance('quiz', $quiz->id, $quiz->course); 57$course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); 58require_login($course, false, $cm); 59 60$quizobj = new quiz($quiz, $cm, $course); 61$structure = $quizobj->get_structure(); 62$modcontext = context_module::instance($cm->id); 63 64echo $OUTPUT->header(); // Send headers. 65 66// All these AJAX actions should be logically atomic. 67$transaction = $DB->start_delegated_transaction(); 68 69// OK, now let's process the parameters and do stuff 70// MDL-10221 the DELETE method is not allowed on some web servers, 71// so we simulate it with the action URL param. 72$requestmethod = $_SERVER['REQUEST_METHOD']; 73if ($pageaction == 'DELETE') { 74 $requestmethod = 'DELETE'; 75} 76 77$result = null; 78 79switch($requestmethod) { 80 case 'POST': 81 case 'GET': // For debugging. 82 switch ($class) { 83 case 'section': 84 $table = 'quiz_sections'; 85 $section = $structure->get_section_by_id($id); 86 switch ($field) { 87 case 'getsectiontitle': 88 require_capability('mod/quiz:manage', $modcontext); 89 $result = array('instancesection' => $section->heading); 90 break; 91 case 'updatesectiontitle': 92 require_capability('mod/quiz:manage', $modcontext); 93 $structure->set_section_heading($id, $newheading); 94 $result = array('instancesection' => format_string($newheading)); 95 break; 96 case 'updateshufflequestions': 97 require_capability('mod/quiz:manage', $modcontext); 98 $structure->set_section_shuffle($id, $shuffle); 99 $result = array('instanceshuffle' => $section->shufflequestions); 100 break; 101 } 102 break; 103 104 case 'resource': 105 switch ($field) { 106 case 'move': 107 require_capability('mod/quiz:manage', $modcontext); 108 if (!$previousid) { 109 $section = $structure->get_section_by_id($sectionid); 110 if ($section->firstslot > 1) { 111 $previousid = $structure->get_slot_id_for_slot($section->firstslot - 1); 112 $page = $structure->get_page_number_for_slot($section->firstslot); 113 } 114 } 115 $structure->move_slot($id, $previousid, $page); 116 quiz_delete_previews($quiz); 117 $result = array('visible' => true); 118 break; 119 120 case 'getmaxmark': 121 require_capability('mod/quiz:manage', $modcontext); 122 $slot = $DB->get_record('quiz_slots', array('id' => $id), '*', MUST_EXIST); 123 $result = array('instancemaxmark' => quiz_format_question_grade($quiz, $slot->maxmark)); 124 break; 125 126 case 'updatemaxmark': 127 require_capability('mod/quiz:manage', $modcontext); 128 $slot = $structure->get_slot_by_id($id); 129 if ($structure->update_slot_maxmark($slot, $maxmark)) { 130 // Grade has really changed. 131 quiz_delete_previews($quiz); 132 quiz_update_sumgrades($quiz); 133 quiz_update_all_attempt_sumgrades($quiz); 134 quiz_update_all_final_grades($quiz); 135 quiz_update_grades($quiz, 0, true); 136 } 137 $result = array('instancemaxmark' => quiz_format_question_grade($quiz, $maxmark), 138 'newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades)); 139 break; 140 141 case 'updatepagebreak': 142 require_capability('mod/quiz:manage', $modcontext); 143 $slots = $structure->update_page_break($id, $value); 144 $json = array(); 145 foreach ($slots as $slot) { 146 $json[$slot->slot] = array('id' => $slot->id, 'slot' => $slot->slot, 147 'page' => $slot->page); 148 } 149 $result = array('slots' => $json); 150 break; 151 152 case 'deletemultiple': 153 require_capability('mod/quiz:manage', $modcontext); 154 155 $ids = explode(',', $ids); 156 foreach ($ids as $id) { 157 $slot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'id' => $id), 158 '*', MUST_EXIST); 159 if (quiz_has_question_use($quiz, $slot->slot)) { 160 $structure->remove_slot($slot->slot); 161 } 162 } 163 quiz_delete_previews($quiz); 164 quiz_update_sumgrades($quiz); 165 166 $result = array('newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades), 167 'deleted' => true, 'newnumquestions' => $structure->get_question_count()); 168 break; 169 170 case 'updatedependency': 171 require_capability('mod/quiz:manage', $modcontext); 172 $slot = $structure->get_slot_by_id($id); 173 $value = (bool) $value; 174 $structure->update_question_dependency($slot->id, $value); 175 $result = array('requireprevious' => $value); 176 break; 177 } 178 break; 179 } 180 break; 181 182 case 'DELETE': 183 switch ($class) { 184 case 'section': 185 require_capability('mod/quiz:manage', $modcontext); 186 $structure->remove_section_heading($id); 187 $result = array('deleted' => true); 188 break; 189 190 case 'resource': 191 require_capability('mod/quiz:manage', $modcontext); 192 if (!$slot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'id' => $id))) { 193 throw new moodle_exception('AJAX commands.php: Bad slot ID '.$id); 194 } 195 $structure->remove_slot($slot->slot); 196 quiz_delete_previews($quiz); 197 quiz_update_sumgrades($quiz); 198 $result = array('newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades), 199 'deleted' => true, 'newnumquestions' => $structure->get_question_count()); 200 break; 201 } 202 break; 203} 204 205$transaction->allow_commit(); 206echo json_encode($result); 207