Proyectos de Subversion Moodle

Rev

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