Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
/**
19
 * External question API
20
 *
21
 * @package    core_question
22
 * @category   external
23
 * @copyright  2016 Pau Ferrer <pau@moodle.com>
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
 
1441 ariadna 27
use core\context;
28
use core\notification;
1 efrain 29
use core_external\external_api;
30
use core_external\external_description;
31
use core_external\external_value;
32
use core_external\external_single_structure;
33
use core_external\external_multiple_structure;
34
use core_external\external_function_parameters;
35
use core_external\external_warnings;
1441 ariadna 36
use core_question\local\bank\filter_condition_manager;
1 efrain 37
 
38
defined('MOODLE_INTERNAL') || die();
39
 
40
require_once($CFG->dirroot . '/question/engine/lib.php');
41
require_once($CFG->dirroot . '/question/engine/datalib.php');
42
require_once($CFG->libdir . '/questionlib.php');
43
 
44
/**
45
 * Question external functions
46
 *
47
 * @package    core_question
48
 * @category   external
49
 * @copyright  2016 Pau Ferrer <pau@moodle.com>
50
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
51
 * @since Moodle 3.1
52
 */
53
class core_question_external extends external_api {
54
 
55
    /**
56
     * Returns description of method parameters
57
     *
58
     * @return external_function_parameters
59
     * @since Moodle 3.1
60
     */
61
    public static function update_flag_parameters() {
62
        return new external_function_parameters(
63
            array(
64
                'qubaid' => new external_value(PARAM_INT, 'the question usage id.'),
65
                'questionid' => new external_value(PARAM_INT, 'the question id'),
66
                'qaid' => new external_value(PARAM_INT, 'the question_attempt id'),
67
                'slot' => new external_value(PARAM_INT, 'the slot number within the usage'),
68
                'checksum' => new external_value(PARAM_ALPHANUM, 'computed checksum with the last three arguments and
69
                             the users username'),
70
                'newstate' => new external_value(PARAM_BOOL, 'the new state of the flag. true = flagged')
71
            )
72
        );
73
    }
74
 
75
    /**
76
     * Update the flag state of a question attempt.
77
     *
78
     * @param int $qubaid the question usage id.
79
     * @param int $questionid the question id.
80
     * @param int $qaid the question_attempt id.
81
     * @param int $slot the slot number within the usage.
82
     * @param string $checksum checksum, as computed by {@link get_toggle_checksum()}
83
     *      corresponding to the last three arguments and the users username.
84
     * @param bool $newstate the new state of the flag. true = flagged.
85
     * @return array (success infos and fail infos)
86
     * @since Moodle 3.1
87
     */
88
    public static function update_flag($qubaid, $questionid, $qaid, $slot, $checksum, $newstate) {
89
        global $CFG, $DB;
90
 
91
        $params = self::validate_parameters(self::update_flag_parameters(),
92
            array(
93
                'qubaid' => $qubaid,
94
                'questionid' => $questionid,
95
                'qaid' => $qaid,
96
                'slot' => $slot,
97
                'checksum' => $checksum,
98
                'newstate' => $newstate
99
            )
100
        );
101
 
102
        $warnings = array();
103
        self::validate_context(context_system::instance());
104
 
105
        // The checksum will be checked to provide security flagging other users questions.
106
        question_flags::update_flag($params['qubaid'], $params['questionid'], $params['qaid'], $params['slot'], $params['checksum'],
107
                                    $params['newstate']);
108
 
109
        $result = array();
110
        $result['status'] = true;
111
        $result['warnings'] = $warnings;
112
        return $result;
113
    }
114
 
115
    /**
116
     * Returns description of method result value
117
     *
118
     * @return external_description
119
     * @since Moodle 3.1
120
     */
121
    public static function update_flag_returns() {
122
        return new external_single_structure(
123
            array(
124
                'status' => new external_value(PARAM_BOOL, 'status: true if success'),
125
                'warnings' => new external_warnings()
126
            )
127
        );
128
    }
129
 
130
    /**
131
     * Returns description of method parameters.
132
     *
133
     * @return external_function_parameters.
134
     */
135
    public static function get_random_question_summaries_parameters() {
136
        return new external_function_parameters([
137
                'categoryid' => new external_value(PARAM_INT, 'Category id to find random questions'),
138
                'includesubcategories' => new external_value(PARAM_BOOL, 'Include the subcategories in the search'),
139
                'tagids' => new external_multiple_structure(
140
                    new external_value(PARAM_INT, 'Tag id')
141
                ),
142
                'contextid' => new external_value(PARAM_INT,
143
                    'Context id that the questions will be rendered in (used for exporting)'),
144
                'limit' => new external_value(PARAM_INT, 'Maximum number of results to return',
145
                    VALUE_DEFAULT, 0),
146
                'offset' => new external_value(PARAM_INT, 'Number of items to skip from the begging of the result set',
147
                    VALUE_DEFAULT, 0)
148
        ]);
149
    }
150
 
151
    /**
152
     * Gets the list of random questions for the given criteria. The questions
153
     * will be exported in a summaries format and won't include all of the
154
     * question data.
155
     *
156
     * @param int $categoryid Category id to find random questions
157
     * @param bool $includesubcategories Include the subcategories in the search
158
     * @param int[] $tagids Only include questions with these tags
159
     * @param int $contextid The context id where the questions will be rendered
160
     * @param int $limit Maximum number of results to return
161
     * @param int $offset Number of items to skip from the beginning of the result set.
162
     * @return array The list of questions and total question count.
163
     */
164
    public static function get_random_question_summaries(
165
        $categoryid,
166
        $includesubcategories,
167
        $tagids,
168
        $contextid,
169
        $limit = 0,
170
        $offset = 0
171
    ) {
172
        global $DB, $PAGE;
173
 
174
        // Parameter validation.
175
        $params = self::validate_parameters(
176
            self::get_random_question_summaries_parameters(),
177
            [
178
                'categoryid' => $categoryid,
179
                'includesubcategories' => $includesubcategories,
180
                'tagids' => $tagids,
181
                'contextid' => $contextid,
182
                'limit' => $limit,
183
                'offset' => $offset
184
            ]
185
        );
186
        $categoryid = $params['categoryid'];
187
        $includesubcategories = $params['includesubcategories'];
188
        $tagids = $params['tagids'];
189
        $contextid = $params['contextid'];
190
        $limit = $params['limit'];
191
        $offset = $params['offset'];
192
 
193
        $context = \context::instance_by_id($contextid);
194
        self::validate_context($context);
195
 
196
        $categorycontextid = $DB->get_field('question_categories', 'contextid', ['id' => $categoryid], MUST_EXIST);
197
        $categorycontext = \context::instance_by_id($categorycontextid);
198
        $editcontexts = new \core_question\local\bank\question_edit_contexts($categorycontext);
199
        // The user must be able to view all questions in the category that they are requesting.
200
        $editcontexts->require_cap('moodle/question:viewall');
201
 
202
        $loader = new \core_question\local\bank\random_question_loader(new qubaid_list([]));
203
        // Only load the properties we require from the DB.
204
        $properties = \core_question\external\question_summary_exporter::get_mandatory_properties();
205
 
206
        // Transform to filters.
207
        $filters = [
208
            'category' => [
209
                'jointype' => \qbank_managecategories\category_condition::JOINTYPE_DEFAULT,
210
                'values' => [$categoryid],
211
                'filteroptions' => ['includesubcategories' => $includesubcategories],
212
            ],
213
            'qtagids' => [
214
                'jointype' => \qbank_tagquestion\tag_condition::JOINTYPE_DEFAULT,
215
                'values' => $tagids,
216
            ],
217
        ];
218
 
219
        $questions = $loader->get_filtered_questions($filters, $limit, $offset, $properties);
220
        $totalcount = $loader->count_filtered_questions($filters);
221
        $renderer = $PAGE->get_renderer('core');
222
 
223
        $formattedquestions = array_map(function($question) use ($context, $renderer) {
224
            $exporter = new \core_question\external\question_summary_exporter($question, ['context' => $context]);
225
            return $exporter->export($renderer);
226
        }, $questions);
227
 
228
        return [
229
            'totalcount' => $totalcount,
230
            'questions' => $formattedquestions
231
        ];
232
    }
233
 
234
    /**
235
     * Returns description of method result value.
236
     */
237
    public static function get_random_question_summaries_returns() {
238
        return new external_single_structure([
239
            'totalcount' => new external_value(PARAM_INT, 'total number of questions in result set'),
240
            'questions' => new external_multiple_structure(
241
                \core_question\external\question_summary_exporter::get_read_structure()
242
            )
243
        ]);
244
    }
245
}