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