MDL-74610 quiz: web service to update grade item for a slot
[moodle.git] / mod / quiz / classes / external / update_slots.php
blob0798119480182b8888e77c5042b1d4aa6b1dd35b
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.
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/>.
17 namespace mod_quiz\external;
19 use core_external\external_api;
20 use core_external\external_description;
21 use core_external\external_function_parameters;
22 use core_external\external_multiple_structure;
23 use core_external\external_single_structure;
24 use core_external\external_value;
25 use mod_quiz\quiz_attempt;
26 use mod_quiz\quiz_settings;
27 use moodle_exception;
29 /**
30 * Web service method to update the properties of one or more slots in a quiz.
32 * The user must have the 'mod/quiz:manage' capability for the quiz.
34 * All the properties that can be set are optional. Only the ones passed are changed.
35 * The full properties of the updated slot are returned.
37 * @package mod_quiz
38 * @copyright 2023 The Open University
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 class update_slots extends external_api {
43 /**
44 * Declare the method parameters.
46 * @return external_function_parameters
48 public static function execute_parameters(): external_function_parameters {
49 return new external_function_parameters([
50 'quizid' => new external_value(PARAM_INT, 'The quiz to update slots for.'),
51 'slots' => new external_multiple_structure(
52 new external_single_structure([
53 'id' => new external_value(PARAM_INT, 'id of the slot'),
54 'displaynumber' => new external_value(
55 PARAM_TEXT,
56 'If passed, new customised question number. Empty string to clear customisation. ' .
57 'Null, or not specified, to leave unchanged.',
58 VALUE_OPTIONAL
60 'requireprevious' => new external_value(
61 PARAM_BOOL,
62 'Whether to make this slot dependent on the previous one. Null, or not specified, to leave unchanged.',
63 VALUE_OPTIONAL
65 'maxmark' => new external_value(
66 PARAM_FLOAT,
67 'Mark that this questions is out of. Null, or not specified, to leave unchanged.',
68 VALUE_OPTIONAL
70 'quizgradeitemid' => new external_value(
71 PARAM_INT,
72 'For quizzes with multiple grades, which grade this slot contributes to (quiz_grade_id). ' .
73 '0 to set to nothing. Null, or not specified, to leave unchanged.',
74 VALUE_OPTIONAL
78 ]);
81 /**
82 * Update the properties of one or more slots in a quiz.
84 * @param int $quizid the id of the quiz to update slots in.
85 * @param array $slotsdata list of slots update. Must have properties id, any any other properties to change.
87 public static function execute(int $quizid, array $slotsdata): void {
88 global $DB;
91 'quizid' => $quizid,
92 'slots' => $slotsdata,
93 ] = self::validate_parameters(self::execute_parameters(), [
94 'quizid' => $quizid,
95 'slots' => $slotsdata,
96 ]);
98 // Check the request is valid.
99 $quizobj = quiz_settings::create($quizid);
100 require_capability('mod/quiz:manage', $quizobj->get_context());
101 self::validate_context($quizobj->get_context());
103 $transaction = $DB->start_delegated_transaction();
105 $structure = $quizobj->get_structure();
106 $gradingsetupchanged = false;
107 foreach ($slotsdata as $slotdata) {
108 // Check this slot exists in this quiz.
109 $slot = $structure->get_slot_by_id($slotdata['id']);
111 if (isset($slotdata['displaynumber'])) {
112 $structure->update_slot_display_number($slot->id, $slotdata['displaynumber']);
114 if (isset($slotdata['requireprevious'])) {
115 $structure->update_question_dependency($slot->id, $slotdata['requireprevious']);
117 if (isset($slotdata['maxmark'])) {
118 $gradingsetupchanged = $structure->update_slot_maxmark($slot, $slotdata['maxmark'])
119 || $gradingsetupchanged;
121 if (array_key_exists('quizgradeitemid', $slotdata)) {
122 $gradingsetupchanged = $structure->update_slot_grade_item($slot, $slotdata['quizgradeitemid'])
123 || $gradingsetupchanged;
127 // If the grade setup has canged, recompute things.
128 if ($gradingsetupchanged) {
129 $gradecalculator = $quizobj->get_grade_calculator();
130 quiz_delete_previews($quizobj->get_quiz());
131 $gradecalculator->recompute_quiz_sumgrades();
132 $gradecalculator->recompute_all_attempt_sumgrades();
133 $gradecalculator->recompute_all_final_grades();
134 quiz_update_grades($quizobj->get_quiz(), 0, true);
137 $transaction->allow_commit();
141 * Define the webservice response.
143 * @return external_description|null always null.
145 public static function execute_returns(): ?external_description {
146 return null;