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
 * Choice module external API
19
 *
20
 * @package    mod_choice
21
 * @category   external
22
 * @copyright  2015 Costantino Cito <ccito@cvaconsulting.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 * @since      Moodle 3.0
25
 */
26
 
27
use core_course\external\helper_for_get_mods_by_courses;
28
use core_external\external_api;
29
use core_external\external_function_parameters;
30
use core_external\external_multiple_structure;
31
use core_external\external_single_structure;
32
use core_external\external_value;
33
use core_external\external_warnings;
34
use core_external\util;
35
 
36
defined('MOODLE_INTERNAL') || die;
37
require_once($CFG->dirroot . '/mod/choice/lib.php');
38
 
39
/**
40
 * Choice module external functions
41
 *
42
 * @package    mod_choice
43
 * @category   external
44
 * @copyright  2015 Costantino Cito <ccito@cvaconsulting.com>
45
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46
 * @since      Moodle 3.0
47
 */
48
class mod_choice_external extends external_api {
49
 
50
    /**
51
     * Describes the parameters for get_choices_by_courses.
52
     *
53
     * @return external_function_parameters
54
     * @since Moodle 3.0
55
     */
56
    public static function get_choice_results_parameters() {
57
        return new external_function_parameters (array('choiceid' => new external_value(PARAM_INT, 'choice instance id')));
58
    }
59
    /**
60
     * Returns user's results for a specific choice
61
     * and a list of those users that did not answered yet.
62
     *
63
     * @param int $choiceid the choice instance id
64
     * @return array of responses details
65
     * @since Moodle 3.0
66
     */
67
    public static function get_choice_results($choiceid) {
68
        global $USER, $PAGE;
69
 
70
        $params = self::validate_parameters(self::get_choice_results_parameters(), array('choiceid' => $choiceid));
71
 
72
        if (!$choice = choice_get_choice($params['choiceid'])) {
73
            throw new moodle_exception("invalidcoursemodule", "error");
74
        }
75
        list($course, $cm) = get_course_and_cm_from_instance($choice, 'choice');
76
 
77
        $context = context_module::instance($cm->id);
78
        self::validate_context($context);
79
 
80
        $groupmode = groups_get_activity_groupmode($cm);
81
        // Check if we have to include responses from inactive users.
82
        $onlyactive = $choice->includeinactive ? false : true;
83
        $users = choice_get_response_data($choice, $cm, $groupmode, $onlyactive);
84
        // Show those who haven't answered the question.
85
        if (!empty($choice->showunanswered)) {
86
            $choice->option[0] = get_string('notanswered', 'choice');
87
            $choice->maxanswers[0] = 0;
88
        }
89
        $results = prepare_choice_show_results($choice, $course, $cm, $users);
90
 
91
        $options = array();
92
        $fullnamecap = has_capability('moodle/site:viewfullnames', $context);
93
        foreach ($results->options as $optionid => $option) {
94
 
95
            $userresponses = array();
96
            $numberofuser = 0;
97
            $percentageamount = 0;
98
            if (property_exists($option, 'user') and
99
                (has_capability('mod/choice:readresponses', $context) or choice_can_view_results($choice))) {
100
                $numberofuser = count($option->user);
101
                $percentageamount = ((float)$numberofuser / (float)$results->numberofuser) * 100.0;
102
                if ($choice->publish) {
103
                    foreach ($option->user as $userresponse) {
104
                        $response = array();
105
                        $response['userid'] = $userresponse->id;
106
                        $response['fullname'] = fullname($userresponse, $fullnamecap);
107
 
108
                        $userpicture = new user_picture($userresponse);
109
                        $userpicture->size = 1; // Size f1.
110
                        $response['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
111
 
112
                        // Add optional properties.
113
                        foreach (array('answerid', 'timemodified') as $field) {
114
                            if (property_exists($userresponse, 'answerid')) {
115
                                $response[$field] = $userresponse->$field;
116
                            }
117
                        }
118
                        $userresponses[] = $response;
119
                    }
120
                }
121
            }
122
 
123
            $options[] = array('id'               => $optionid,
124
                               'text'             => \core_external\util::format_string($option->text, $context->id),
125
                               'maxanswer'        => $option->maxanswer,
126
                               'userresponses'    => $userresponses,
127
                               'numberofuser'     => $numberofuser,
128
                               'percentageamount' => $percentageamount
129
                              );
130
        }
131
 
132
        $warnings = array();
133
        return array(
134
            'options' => $options,
135
            'warnings' => $warnings
136
        );
137
    }
138
 
139
    /**
140
     * Describes the get_choice_results return value.
141
     *
142
     * @return external_single_structure
143
     * @since Moodle 3.0
144
     */
145
    public static function get_choice_results_returns() {
146
        return new external_single_structure(
147
            array(
148
                'options' => new external_multiple_structure(
149
                    new external_single_structure(
150
                        array(
151
                            'id' => new external_value(PARAM_INT, 'choice instance id'),
152
                            'text' => new external_value(PARAM_RAW, 'text of the choice'),
153
                            'maxanswer' => new external_value(PARAM_INT, 'maximum number of answers'),
154
                            'userresponses' => new external_multiple_structure(
155
                                 new external_single_structure(
156
                                     array(
157
                                        'userid' => new external_value(PARAM_INT, 'user id'),
158
                                        'fullname' => new external_value(PARAM_NOTAGS, 'user full name'),
159
                                        'profileimageurl' => new external_value(PARAM_URL, 'profile user image url'),
160
                                        'answerid' => new external_value(PARAM_INT, 'answer id', VALUE_OPTIONAL),
161
                                        'timemodified' => new external_value(PARAM_INT, 'time of modification', VALUE_OPTIONAL),
162
                                     ), 'User responses'
163
                                 )
164
                            ),
165
                            'numberofuser' => new external_value(PARAM_INT, 'number of users answers'),
166
                            'percentageamount' => new external_value(PARAM_FLOAT, 'percentage of users answers')
167
                        ), 'Options'
168
                    )
169
                ),
170
                'warnings' => new external_warnings(),
171
            )
172
        );
173
    }
174
 
175
    /**
176
     * Describes the parameters for mod_choice_get_choice_options.
177
     *
178
     * @return external_function_parameters
179
     * @since Moodle 3.0
180
     */
181
    public static function get_choice_options_parameters() {
182
        return new external_function_parameters (array('choiceid' => new external_value(PARAM_INT, 'choice instance id')));
183
    }
184
 
185
    /**
186
     * Returns options for a specific choice
187
     *
188
     * @param int $choiceid the choice instance id
189
     * @return array of options details
190
     * @since Moodle 3.0
191
     */
192
    public static function get_choice_options($choiceid) {
193
        global $USER;
194
        $warnings = array();
195
        $params = self::validate_parameters(self::get_choice_options_parameters(), array('choiceid' => $choiceid));
196
 
197
        if (!$choice = choice_get_choice($params['choiceid'])) {
198
            throw new moodle_exception("invalidcoursemodule", "error");
199
        }
200
        list($course, $cm) = get_course_and_cm_from_instance($choice, 'choice');
201
 
202
        $context = context_module::instance($cm->id);
203
        self::validate_context($context);
204
 
205
        require_capability('mod/choice:choose', $context);
206
 
207
        $groupmode = groups_get_activity_groupmode($cm);
208
        $onlyactive = $choice->includeinactive ? false : true;
209
        $allresponses = choice_get_response_data($choice, $cm, $groupmode, $onlyactive);
210
 
211
        $timenow = time();
212
        $choiceopen = true;
213
        $showpreview = false;
214
 
215
        if (!empty($choice->timeopen) && ($choice->timeopen > $timenow)) {
216
            $choiceopen = false;
217
            $warnings[1] = get_string("notopenyet", "choice", userdate($choice->timeopen));
218
            if ($choice->showpreview) {
219
                $warnings[2] = get_string('previewonly', 'choice', userdate($choice->timeopen));
220
                $showpreview = true;
221
            }
222
        }
223
        if (!empty($choice->timeclose) && ($timenow > $choice->timeclose)) {
224
            $choiceopen = false;
225
            $warnings[3] = get_string("expired", "choice", userdate($choice->timeclose));
226
        }
227
 
228
        $optionsarray = array();
229
 
230
        if ($choiceopen or $showpreview) {
231
 
232
            $options = choice_prepare_options($choice, $USER, $cm, $allresponses);
233
 
234
            foreach ($options['options'] as $option) {
235
                $optionarr = array();
236
                $optionarr['id']            = $option->attributes->value;
237
                $optionarr['text']          = \core_external\util::format_string($option->text, $context->id);
238
                $optionarr['maxanswers']    = $option->maxanswers;
239
                $optionarr['displaylayout'] = $option->displaylayout;
240
                $optionarr['countanswers']  = $option->countanswers;
241
                foreach (array('checked', 'disabled') as $field) {
242
                    if (property_exists($option->attributes, $field) and $option->attributes->$field == 1) {
243
                        $optionarr[$field] = 1;
244
                    } else {
245
                        $optionarr[$field] = 0;
246
                    }
247
                }
248
                // When showpreview is active, we show options as disabled.
249
                if ($showpreview or ($optionarr['checked'] == 1 and !$choice->allowupdate)) {
250
                    $optionarr['disabled'] = 1;
251
                }
252
                $optionsarray[] = $optionarr;
253
            }
254
        }
255
        foreach ($warnings as $key => $message) {
256
            $warnings[$key] = array(
257
                'item' => 'choice',
258
                'itemid' => $cm->id,
259
                'warningcode' => $key,
260
                'message' => $message
261
            );
262
        }
263
        return array(
264
            'options' => $optionsarray,
265
            'warnings' => $warnings
266
        );
267
    }
268
 
269
    /**
270
     * Describes the get_choice_results return value.
271
     *
272
     * @return external_multiple_structure
273
     * @since Moodle 3.0
274
     */
275
    public static function get_choice_options_returns() {
276
        return new external_single_structure(
277
            array(
278
                'options' => new external_multiple_structure(
279
                    new external_single_structure(
280
                        array(
281
                            'id' => new external_value(PARAM_INT, 'option id'),
282
                            'text' => new external_value(PARAM_RAW, 'text of the choice'),
283
                            'maxanswers' => new external_value(PARAM_INT, 'maximum number of answers'),
284
                            'displaylayout' => new external_value(PARAM_BOOL, 'true for orizontal, otherwise vertical'),
285
                            'countanswers' => new external_value(PARAM_INT, 'number of answers'),
286
                            'checked' => new external_value(PARAM_BOOL, 'we already answered'),
287
                            'disabled' => new external_value(PARAM_BOOL, 'option disabled'),
288
                            )
289
                    ), 'Options'
290
                ),
291
                'warnings' => new external_warnings(),
292
            )
293
        );
294
    }
295
 
296
    /**
297
     * Describes the parameters for submit_choice_response.
298
     *
299
     * @return external_function_parameters
300
     * @since Moodle 3.0
301
     */
302
    public static function submit_choice_response_parameters() {
303
        return new external_function_parameters (
304
            array(
305
                'choiceid' => new external_value(PARAM_INT, 'choice instance id'),
306
                'responses' => new external_multiple_structure(
307
                    new external_value(PARAM_INT, 'answer id'),
308
                    'Array of response ids'
309
                ),
310
            )
311
        );
312
    }
313
 
314
    /**
315
     * Submit choice responses
316
     *
317
     * @param int $choiceid the choice instance id
318
     * @param array $responses the response ids
319
     * @return array answers information and warnings
320
     * @since Moodle 3.0
321
     */
322
    public static function submit_choice_response($choiceid, $responses) {
323
        global $USER;
324
 
325
        $warnings = array();
326
        $params = self::validate_parameters(self::submit_choice_response_parameters(),
327
                                            array(
328
                                                'choiceid' => $choiceid,
329
                                                'responses' => $responses
330
                                            ));
331
 
332
        if (!$choice = choice_get_choice($params['choiceid'])) {
333
            throw new moodle_exception("invalidcoursemodule", "error");
334
        }
335
        list($course, $cm) = get_course_and_cm_from_instance($choice, 'choice');
336
 
337
        $context = context_module::instance($cm->id);
338
        self::validate_context($context);
339
 
340
        require_capability('mod/choice:choose', $context);
341
 
342
        $timenow = time();
343
        if (!empty($choice->timeopen) && ($choice->timeopen > $timenow)) {
344
            throw new moodle_exception("notopenyet", "choice", '', userdate($choice->timeopen));
345
        } else if (!empty($choice->timeclose) && ($timenow > $choice->timeclose)) {
346
            throw new moodle_exception("expired", "choice", '', userdate($choice->timeclose));
347
        }
348
 
349
        if (!choice_get_my_response($choice) or $choice->allowupdate) {
350
            // When a single response is given, we convert the array to a simple variable
351
            // in order to avoid choice_user_submit_response to check with allowmultiple even
352
            // for a single response.
353
            if (count($params['responses']) == 1) {
354
                $params['responses'] = reset($params['responses']);
355
            }
356
            choice_user_submit_response($params['responses'], $choice, $USER->id, $course, $cm);
357
        } else {
358
            throw new moodle_exception('missingrequiredcapability', 'webservice', '', 'allowupdate');
359
        }
360
        $answers = choice_get_my_response($choice);
361
 
362
        return array(
363
            'answers' => $answers,
364
            'warnings' => $warnings
365
        );
366
    }
367
 
368
    /**
369
     * Describes the submit_choice_response return value.
370
     *
371
     * @return external_multiple_structure
372
     * @since Moodle 3.0
373
     */
374
    public static function submit_choice_response_returns() {
375
        return new external_single_structure(
376
            array(
377
                'answers' => new external_multiple_structure(
378
                     new external_single_structure(
379
                         array(
380
                             'id'           => new external_value(PARAM_INT, 'answer id'),
381
                             'choiceid'     => new external_value(PARAM_INT, 'choiceid'),
382
                             'userid'       => new external_value(PARAM_INT, 'user id'),
383
                             'optionid'     => new external_value(PARAM_INT, 'optionid'),
384
                             'timemodified' => new external_value(PARAM_INT, 'time of last modification')
385
                         ), 'Answers'
386
                     )
387
                ),
388
                'warnings' => new external_warnings(),
389
            )
390
        );
391
    }
392
 
393
    /**
394
     * Returns description of method parameters
395
     *
396
     * @return external_function_parameters
397
     * @since Moodle 3.0
398
     */
399
    public static function view_choice_parameters() {
400
        return new external_function_parameters(
401
            array(
402
                'choiceid' => new external_value(PARAM_INT, 'choice instance id')
403
            )
404
        );
405
    }
406
 
407
    /**
408
     * Trigger the course module viewed event and update the module completion status.
409
     *
410
     * @param int $choiceid the choice instance id
411
     * @return array of warnings and status result
412
     * @since Moodle 3.0
413
     * @throws moodle_exception
414
     */
415
    public static function view_choice($choiceid) {
416
        global $CFG;
417
 
418
        $params = self::validate_parameters(self::view_choice_parameters(),
419
                                            array(
420
                                                'choiceid' => $choiceid
421
                                            ));
422
        $warnings = array();
423
 
424
        // Request and permission validation.
425
        if (!$choice = choice_get_choice($params['choiceid'])) {
426
            throw new moodle_exception("invalidcoursemodule", "error");
427
        }
428
        list($course, $cm) = get_course_and_cm_from_instance($choice, 'choice');
429
 
430
        $context = context_module::instance($cm->id);
431
        self::validate_context($context);
432
 
433
        // Trigger course_module_viewed event and completion.
434
        choice_view($choice, $course, $cm, $context);
435
 
436
        $result = array();
437
        $result['status'] = true;
438
        $result['warnings'] = $warnings;
439
        return $result;
440
    }
441
 
442
    /**
443
     * Returns description of method result value
444
     *
445
     * @return \core_external\external_description
446
     * @since Moodle 3.0
447
     */
448
    public static function view_choice_returns() {
449
        return new external_single_structure(
450
            array(
451
                'status' => new external_value(PARAM_BOOL, 'status: true if success'),
452
                'warnings' => new external_warnings()
453
            )
454
        );
455
    }
456
 
457
    /**
458
     * Describes the parameters for get_choices_by_courses.
459
     *
460
     * @return external_function_parameters
461
     * @since Moodle 3.0
462
     */
463
    public static function get_choices_by_courses_parameters() {
464
        return new external_function_parameters (
465
            array(
466
                'courseids' => new external_multiple_structure(
467
                    new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array()
468
                ),
469
            )
470
        );
471
    }
472
 
473
    /**
474
     * Returns a list of choices in a provided list of courses,
475
     * if no list is provided all choices that the user can view will be returned.
476
     *
477
     * @param array $courseids the course ids
478
     * @return array of choices details
479
     * @since Moodle 3.0
480
     */
481
    public static function get_choices_by_courses($courseids = array()) {
482
        $returnedchoices = array();
483
        $warnings = array();
484
 
485
        $params = self::validate_parameters(self::get_choices_by_courses_parameters(), array('courseids' => $courseids));
486
 
487
        $courses = array();
488
        if (empty($params['courseids'])) {
489
            $courses = enrol_get_my_courses();
490
            $params['courseids'] = array_keys($courses);
491
        }
492
 
493
        // Ensure there are courseids to loop through.
494
        if (!empty($params['courseids'])) {
495
 
496
            list($courses, $warnings) = util::validate_courses($params['courseids'], $courses);
497
 
498
            // Get the choices in this course, this function checks users visibility permissions.
499
            // We can avoid then additional validate_context calls.
500
            $choices = get_all_instances_in_courses("choice", $courses);
501
            foreach ($choices as $choice) {
502
                $context = context_module::instance($choice->coursemodule);
503
 
504
                $choicedetails = helper_for_get_mods_by_courses::standard_coursemodule_element_values($choice, 'mod_choice');
505
 
506
                if (has_capability('mod/choice:choose', $context)) {
507
                    $choicedetails['publish']  = $choice->publish;
508
                    $choicedetails['showresults']  = $choice->showresults;
509
                    $choicedetails['showpreview']  = $choice->showpreview;
510
                    $choicedetails['timeopen']  = $choice->timeopen;
511
                    $choicedetails['timeclose']  = $choice->timeclose;
512
                    $choicedetails['display']  = $choice->display;
513
                    $choicedetails['allowupdate']  = $choice->allowupdate;
514
                    $choicedetails['allowmultiple']  = $choice->allowmultiple;
515
                    $choicedetails['limitanswers']  = $choice->limitanswers;
516
                    $choicedetails['showunanswered']  = $choice->showunanswered;
517
                    $choicedetails['includeinactive']  = $choice->includeinactive;
518
                    $choicedetails['showavailable']  = $choice->showavailable;
519
                }
520
 
521
                if (has_capability('moodle/course:manageactivities', $context)) {
522
                    $choicedetails['timemodified']  = $choice->timemodified;
523
                    $choicedetails['completionsubmit']  = $choice->completionsubmit;
524
                }
525
                $returnedchoices[] = $choicedetails;
526
            }
527
        }
528
        $result = array();
529
        $result['choices'] = $returnedchoices;
530
        $result['warnings'] = $warnings;
531
        return $result;
532
    }
533
 
534
    /**
535
     * Describes the mod_choice_get_choices_by_courses return value.
536
     *
537
     * @return external_single_structure
538
     * @since Moodle 3.0
539
     */
540
    public static function get_choices_by_courses_returns() {
541
        return new external_single_structure(
542
            array(
543
                'choices' => new external_multiple_structure(
544
                    new external_single_structure(array_merge(
545
                        helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(),
546
                        [
547
                            'publish' => new external_value(PARAM_BOOL, 'If choice is published', VALUE_OPTIONAL),
548
                            'showresults' => new external_value(PARAM_INT, '0 never, 1 after answer, 2 after close, 3 always',
549
                                                                VALUE_OPTIONAL),
550
                            'display' => new external_value(PARAM_INT, 'Display mode (vertical, horizontal)', VALUE_OPTIONAL),
551
                            'allowupdate' => new external_value(PARAM_BOOL, 'Allow update', VALUE_OPTIONAL),
552
                            'allowmultiple' => new external_value(PARAM_BOOL, 'Allow multiple choices', VALUE_OPTIONAL),
553
                            'showunanswered' => new external_value(PARAM_BOOL, 'Show users who not answered yet', VALUE_OPTIONAL),
554
                            'includeinactive' => new external_value(PARAM_BOOL, 'Include inactive users', VALUE_OPTIONAL),
555
                            'limitanswers' => new external_value(PARAM_BOOL, 'Limit unswers', VALUE_OPTIONAL),
556
                            'timeopen' => new external_value(PARAM_INT, 'Date of opening validity', VALUE_OPTIONAL),
557
                            'timeclose' => new external_value(PARAM_INT, 'Date of closing validity', VALUE_OPTIONAL),
558
                            'showpreview' => new external_value(PARAM_BOOL, 'Show preview before timeopen', VALUE_OPTIONAL),
559
                            'timemodified' => new external_value(PARAM_INT, 'Time of last modification', VALUE_OPTIONAL),
560
                            'completionsubmit' => new external_value(PARAM_BOOL, 'Completion on user submission', VALUE_OPTIONAL),
561
                            'showavailable' => new external_value(PARAM_BOOL, 'Show available spaces', VALUE_OPTIONAL),
562
                        ]
563
                    ), 'Choices')
564
                ),
565
                'warnings' => new external_warnings(),
566
            )
567
        );
568
    }
569
 
570
    /**
571
     * Describes the parameters for delete_choice_responses.
572
     *
573
     * @return external_function_parameters
574
     * @since Moodle 3.0
575
     */
576
    public static function delete_choice_responses_parameters() {
577
        return new external_function_parameters (
578
            array(
579
                'choiceid' => new external_value(PARAM_INT, 'choice instance id'),
580
                'responses' => new external_multiple_structure(
581
                    new external_value(PARAM_INT, 'response id'),
582
                    'Array of response ids, empty for deleting all the current user responses.',
583
                    VALUE_DEFAULT,
584
                    array()
585
                ),
586
            )
587
        );
588
    }
589
 
590
    /**
591
     * Delete the given submitted responses in a choice
592
     *
593
     * @param int $choiceid the choice instance id
594
     * @param array $responses the response ids,  empty for deleting all the current user responses
595
     * @return array status information and warnings
596
     * @throws moodle_exception
597
     * @since Moodle 3.0
598
     */
599
    public static function delete_choice_responses($choiceid, $responses = array()) {
600
 
601
        $status = false;
602
        $warnings = array();
603
        $params = self::validate_parameters(self::delete_choice_responses_parameters(),
604
                                            array(
605
                                                'choiceid' => $choiceid,
606
                                                'responses' => $responses
607
                                            ));
608
 
609
        if (!$choice = choice_get_choice($params['choiceid'])) {
610
            throw new moodle_exception("invalidcoursemodule", "error");
611
        }
612
        list($course, $cm) = get_course_and_cm_from_instance($choice, 'choice');
613
 
614
        $context = context_module::instance($cm->id);
615
        self::validate_context($context);
616
 
617
        require_capability('mod/choice:choose', $context);
618
 
619
        $candeleteall = has_capability('mod/choice:deleteresponses', $context);
620
        if ($candeleteall || $choice->allowupdate) {
621
 
622
            // Check if we can delete our own responses.
623
            if (!$candeleteall) {
624
                $timenow = time();
625
                if (!empty($choice->timeclose) && ($timenow > $choice->timeclose)) {
626
                    throw new moodle_exception("expired", "choice", '', userdate($choice->timeclose));
627
                }
628
            }
629
 
630
            if (empty($params['responses'])) {
631
                // No responses indicated so delete only my responses.
632
                $todelete = array_keys(choice_get_my_response($choice));
633
            } else {
634
                // Fill an array with the responses that can be deleted for this choice.
635
                if ($candeleteall) {
636
                    // Teacher/managers can delete any.
637
                    $allowedresponses = array_keys(choice_get_all_responses($choice));
638
                } else {
639
                    // Students can delete only their own responses.
640
                    $allowedresponses = array_keys(choice_get_my_response($choice));
641
                }
642
 
643
                $todelete = array();
644
                foreach ($params['responses'] as $response) {
645
                    if (!in_array($response, $allowedresponses)) {
646
                        $warnings[] = array(
647
                            'item' => 'response',
648
                            'itemid' => $response,
649
                            'warningcode' => 'nopermissions',
650
                            'message' => 'Invalid response id, the response does not exist or you are not allowed to delete it.'
651
                        );
652
                    } else {
653
                        $todelete[] = $response;
654
                    }
655
                }
656
            }
657
 
658
            $status = choice_delete_responses($todelete, $choice, $cm, $course);
659
        } else {
660
            // The user requires the capability to delete responses.
661
            throw new required_capability_exception($context, 'mod/choice:deleteresponses', 'nopermissions', '');
662
        }
663
 
664
        return array(
665
            'status' => $status,
666
            'warnings' => $warnings
667
        );
668
    }
669
 
670
    /**
671
     * Describes the delete_choice_responses return value.
672
     *
673
     * @return external_multiple_structure
674
     * @since Moodle 3.0
675
     */
676
    public static function delete_choice_responses_returns() {
677
        return new external_single_structure(
678
            array(
679
                'status' => new external_value(PARAM_BOOL, 'status, true if everything went right'),
680
                'warnings' => new external_warnings(),
681
            )
682
        );
683
    }
684
 
685
}