MDL-66809 core_grades: Implement scale-based marking
[moodle.git] / grade / classes / grades / grader / gradingpanel / scale / external / store.php
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/>.
17 /**
18  * Web service functions relating to scale grades and grading.
19  *
20  * @package    core_grades
21  * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 declare(strict_types = 1);
27 namespace core_grades\grades\grader\gradingpanel\scale\external;
29 use coding_exception;
30 use context;
31 use core_user;
32 use core_grades\component_gradeitem as gradeitem;
33 use core_grades\component_gradeitems;
34 use external_api;
35 use external_function_parameters;
36 use external_multiple_structure;
37 use external_single_structure;
38 use external_value;
39 use external_warnings;
40 use moodle_exception;
41 use required_capability_exception;
43 /**
44  * External grading panel scale API
45  *
46  * @package    core_grades
47  * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
48  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
49  */
50 class store extends external_api {
52     /**
53      * Describes the parameters for fetching the grading panel for a simple grade.
54      *
55      * @return external_function_parameters
56      * @since Moodle 3.8
57      */
58     public static function execute_parameters(): external_function_parameters {
59         return new external_function_parameters ([
60             'component' => new external_value(
61                 PARAM_ALPHANUMEXT,
62                 'The name of the component',
63                 VALUE_REQUIRED
64             ),
65             'contextid' => new external_value(
66                 PARAM_INT,
67                 'The ID of the context being graded',
68                 VALUE_REQUIRED
69             ),
70             'itemname' => new external_value(
71                 PARAM_ALPHANUM,
72                 'The grade item itemname being graded',
73                 VALUE_REQUIRED
74             ),
75             'gradeduserid' => new external_value(
76                 PARAM_INT,
77                 'The ID of the user show',
78                 VALUE_REQUIRED
79             ),
80             'formdata' => new external_value(
81                 PARAM_RAW,
82                 'The serialised form data representing the grade',
83                 VALUE_REQUIRED
84             ),
85         ]);
86     }
88     /**
89      * Fetch the data required to build a grading panel for a simple grade.
90      *
91      * @param string $component
92      * @param int $contextid
93      * @param string $itemname
94      * @param int $gradeduserid
95      * @return array
96      * @since Moodle 3.8
97      */
98     public static function execute(string $component, int $contextid, string $itemname, int $gradeduserid, string $formdata): array {
99         global $USER;
101         [
102             'component' => $component,
103             'contextid' => $contextid,
104             'itemname' => $itemname,
105             'gradeduserid' => $gradeduserid,
106             'formdata' => $formdata,
107         ] = self::validate_parameters(self::execute_parameters(), [
108             'component' => $component,
109             'contextid' => $contextid,
110             'itemname' => $itemname,
111             'gradeduserid' => $gradeduserid,
112             'formdata' => $formdata,
113         ]);
115         // Validate the context.
116         $context = context::instance_by_id($contextid);
117         self::validate_context($context);
119         // Validate that the supplied itemname is a gradable item.
120         if (!component_gradeitems::is_valid_itemname($component, $itemname)) {
121             throw new coding_exception("The '{$itemname}' item is not valid for the '{$component}' component");
122         }
124         // Fetch the gradeitem instance.
125         $gradeitem = gradeitem::instance($component, $context, $itemname);
127         // Validate that this gradeitem is actually enabled.
128         if (!$gradeitem->is_grading_enabled()) {
129             throw new moodle_exception("Grading is not enabled for {$itemname} in this context");
130         }
132         // Fetch the record for the graded user.
133         $gradeduser = \core_user::get_user($gradeduserid);
135         // Require that this user can save grades.
136         $gradeitem->require_user_can_grade($gradeduser, $USER);
138         if (!$gradeitem->is_using_scale()) {
139             throw new moodle_exception("The {$itemname} item in {$component}/{$contextid} is not configured for grading with scales");
140         }
142         // Parse the serialised string into an object.
143         $data = [];
144         parse_str($formdata, $data);
146         // Grade.
147         $gradeitem->store_grade_from_formdata($gradeduser, $USER, (object) $data);
149         return fetch::get_fetch_data($gradeitem, $gradeduser);
150     }
152     /**
153      * Describes the data returned from the external function.
154      *
155      * @return external_single_structure
156      * @since Moodle 3.8
157      */
158     public static function execute_returns(): external_single_structure {
159         return fetch::execute_returns();
160     }