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
 * SCORM module external API
19
 *
20
 * @package    mod_scorm
21
 * @category   external
22
 * @copyright  2015 Juan Leyva <juan@moodle.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
 
38
require_once($CFG->dirroot . '/mod/scorm/lib.php');
39
require_once($CFG->dirroot . '/mod/scorm/locallib.php');
40
 
41
/**
42
 * SCORM module external functions
43
 *
44
 * @package    mod_scorm
45
 * @category   external
46
 * @copyright  2015 Juan Leyva <juan@moodle.com>
47
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
48
 * @since      Moodle 3.0
49
 */
50
class mod_scorm_external extends external_api {
51
 
52
    /**
53
     * Returns description of method parameters
54
     *
55
     * @return external_function_parameters
56
     * @since Moodle 3.0
57
     */
58
    public static function view_scorm_parameters() {
59
        return new external_function_parameters(
60
            array(
61
                'scormid' => new external_value(PARAM_INT, 'scorm instance id')
62
            )
63
        );
64
    }
65
 
66
    /**
67
     * Trigger the course module viewed event.
68
     *
69
     * @param int $scormid the scorm instance id
70
     * @return array of warnings and status result
71
     * @since Moodle 3.0
72
     * @throws moodle_exception
73
     */
74
    public static function view_scorm($scormid) {
75
        global $DB, $CFG;
76
        require_once($CFG->dirroot . '/mod/scorm/lib.php');
77
 
78
        $params = self::validate_parameters(self::view_scorm_parameters(),
79
                                            array(
80
                                                'scormid' => $scormid
81
                                            ));
82
        $warnings = array();
83
 
84
        // Request and permission validation.
85
        $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
86
        list($course, $cm) = get_course_and_cm_from_instance($scorm, 'scorm');
87
 
88
        $context = context_module::instance($cm->id);
89
        self::validate_context($context);
90
 
91
        // Call the scorm/lib API.
92
        scorm_view($scorm, $course, $cm, $context);
93
 
94
        $result = array();
95
        $result['status'] = true;
96
        $result['warnings'] = $warnings;
97
        return $result;
98
    }
99
 
100
    /**
101
     * Returns description of method result value
102
     *
103
     * @return \core_external\external_description
104
     * @since Moodle 3.0
105
     */
106
    public static function view_scorm_returns() {
107
        return new external_single_structure(
108
            array(
109
                'status' => new external_value(PARAM_BOOL, 'status: true if success'),
110
                'warnings' => new external_warnings()
111
            )
112
        );
113
    }
114
 
115
    /**
116
     * Describes the parameters for get_scorm_attempt_count.
117
     *
118
     * @return external_function_parameters
119
     * @since Moodle 3.0
120
     */
121
    public static function get_scorm_attempt_count_parameters() {
122
        return new external_function_parameters(
123
            array(
124
                'scormid' => new external_value(PARAM_INT, 'SCORM instance id'),
125
                'userid' => new external_value(PARAM_INT, 'User id'),
126
                'ignoremissingcompletion' => new external_value(PARAM_BOOL,
127
                                                'Ignores attempts that haven\'t reported a grade/completion',
128
                                                VALUE_DEFAULT, false),
129
            )
130
        );
131
    }
132
 
133
    /**
134
     * Return the number of attempts done by a user in the given SCORM.
135
     *
136
     * @param int $scormid the scorm id
137
     * @param int $userid the user id
138
     * @param bool $ignoremissingcompletion ignores attempts that haven't reported a grade/completion
139
     * @return array of warnings and the attempts count
140
     * @since Moodle 3.0
141
     */
142
    public static function get_scorm_attempt_count($scormid, $userid, $ignoremissingcompletion = false) {
143
        global $USER, $DB;
144
 
145
        $params = self::validate_parameters(self::get_scorm_attempt_count_parameters(),
146
                                            array('scormid' => $scormid, 'userid' => $userid,
147
                                                'ignoremissingcompletion' => $ignoremissingcompletion));
148
 
149
        $attempts = array();
150
        $warnings = array();
151
 
152
        $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
153
        $cm = get_coursemodule_from_instance('scorm', $scorm->id);
154
 
155
        $context = context_module::instance($cm->id);
156
        self::validate_context($context);
157
 
158
        $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
159
        core_user::require_active_user($user);
160
 
161
        // Extra checks so only users with permissions can view other users attempts.
162
        if ($USER->id != $user->id) {
163
            require_capability('mod/scorm:viewreport', $context);
164
        }
165
 
166
        // If the SCORM is not open this function will throw exceptions.
167
        scorm_require_available($scorm);
168
 
169
        $attemptscount = scorm_get_attempt_count($user->id, $scorm, false, $params['ignoremissingcompletion']);
170
 
171
        $result = array();
172
        $result['attemptscount'] = $attemptscount;
173
        $result['warnings'] = $warnings;
174
        return $result;
175
    }
176
 
177
    /**
178
     * Describes the get_scorm_attempt_count return value.
179
     *
180
     * @return external_single_structure
181
     * @since Moodle 3.0
182
     */
183
    public static function get_scorm_attempt_count_returns() {
184
 
185
        return new external_single_structure(
186
            array(
187
                'attemptscount' => new external_value(PARAM_INT, 'Attempts count'),
188
                'warnings' => new external_warnings(),
189
            )
190
        );
191
    }
192
 
193
    /**
194
     * Describes the parameters for get_scorm_scoes.
195
     *
196
     * @return external_function_parameters
197
     * @since Moodle 3.0
198
     */
199
    public static function get_scorm_scoes_parameters() {
200
        return new external_function_parameters(
201
            array(
202
                'scormid' => new external_value(PARAM_INT, 'scorm instance id'),
203
                'organization' => new external_value(PARAM_RAW, 'organization id', VALUE_DEFAULT, '')
204
            )
205
        );
206
    }
207
 
208
    /**
209
     * Returns a list containing all the scoes data related to the given scorm id
210
     *
211
     * @param int $scormid the scorm id
212
     * @param string $organization the organization id
213
     * @return array warnings and the scoes data
214
     * @since Moodle 3.0
215
     */
216
    public static function get_scorm_scoes($scormid, $organization = '') {
217
        global $DB;
218
 
219
        $params = self::validate_parameters(self::get_scorm_scoes_parameters(),
220
                                            array('scormid' => $scormid, 'organization' => $organization));
221
 
222
        $scoes = array();
223
        $warnings = array();
224
 
225
        $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
226
        $cm = get_coursemodule_from_instance('scorm', $scorm->id);
227
 
228
        $context = context_module::instance($cm->id);
229
        self::validate_context($context);
230
 
231
        // Check settings / permissions to view the SCORM.
232
        scorm_require_available($scorm, true, $context);
233
 
234
        if (!$scoes = scorm_get_scoes($scorm->id, $params['organization'])) {
235
            // Function scorm_get_scoes return false, not an empty array.
236
            $scoes = array();
237
        } else {
238
            $scoreturnstructure = self::get_scorm_scoes_returns();
239
            foreach ($scoes as $sco) {
240
                $extradata = array();
241
                foreach ($sco as $element => $value) {
242
                    // Check if the element is extra data (not a basic SCO element).
243
                    if (!isset($scoreturnstructure->keys['scoes']->content->keys[$element])) {
244
                        $extradata[] = array(
245
                            'element' => $element,
246
                            'value' => $value
247
                        );
248
                    }
249
                }
250
                $sco->extradata = $extradata;
251
            }
252
        }
253
 
254
        $result = array();
255
        $result['scoes'] = $scoes;
256
        $result['warnings'] = $warnings;
257
        return $result;
258
    }
259
 
260
    /**
261
     * Describes the get_scorm_scoes return value.
262
     *
263
     * @return external_single_structure
264
     * @since Moodle 3.0
265
     */
266
    public static function get_scorm_scoes_returns() {
267
 
268
        return new external_single_structure(
269
            array(
270
                'scoes' => new external_multiple_structure(
271
                    new external_single_structure(
272
                        array(
273
                            'id' => new external_value(PARAM_INT, 'sco id'),
274
                            'scorm' => new external_value(PARAM_INT, 'scorm id'),
275
                            'manifest' => new external_value(PARAM_NOTAGS, 'manifest id'),
276
                            'organization' => new external_value(PARAM_NOTAGS, 'organization id'),
277
                            'parent' => new external_value(PARAM_NOTAGS, 'parent'),
278
                            'identifier' => new external_value(PARAM_NOTAGS, 'identifier'),
279
                            'launch' => new external_value(PARAM_NOTAGS, 'launch file'),
280
                            'scormtype' => new external_value(PARAM_ALPHA, 'scorm type (asset, sco)'),
281
                            'title' => new external_value(PARAM_NOTAGS, 'sco title'),
282
                            'sortorder' => new external_value(PARAM_INT, 'sort order'),
283
                            'extradata' => new external_multiple_structure(
284
                                new external_single_structure(
285
                                    array(
286
                                        'element' => new external_value(PARAM_RAW, 'element name'),
287
                                        'value' => new external_value(PARAM_RAW, 'element value')
288
                                    )
289
                                ), 'Additional SCO data', VALUE_OPTIONAL
290
                            )
291
                        ), 'SCORM SCO data'
292
                    )
293
                ),
294
                'warnings' => new external_warnings(),
295
            )
296
        );
297
    }
298
 
299
    /**
300
     * Describes the parameters for get_scorm_user_data.
301
     *
302
     * @return external_function_parameters
303
     * @since Moodle 3.0
304
     */
305
    public static function get_scorm_user_data_parameters() {
306
        return new external_function_parameters(
307
            array(
308
                'scormid' => new external_value(PARAM_INT, 'scorm instance id'),
309
                'attempt' => new external_value(PARAM_INT, 'attempt number')
310
            )
311
        );
312
    }
313
 
314
    /**
315
     * Retrieves user tracking and SCO data and default SCORM values
316
     *
317
     * @param int $scormid the scorm id
318
     * @param int $attempt the attempt number
319
     * @return array warnings and the scoes data
320
     * @throws  moodle_exception
321
     * @since Moodle 3.0
322
     */
323
    public static function get_scorm_user_data($scormid, $attempt) {
324
        global $CFG, $DB;
325
 
326
        $params = self::validate_parameters(self::get_scorm_user_data_parameters(),
327
                                            array('scormid' => $scormid, 'attempt' => $attempt));
328
 
329
        $data = array();
330
        $warnings = array();
331
 
332
        $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
333
        $cm = get_coursemodule_from_instance('scorm', $scorm->id);
334
 
335
        $context = context_module::instance($cm->id);
336
        self::validate_context($context);
337
 
338
        scorm_require_available($scorm, true, $context);
339
 
340
        $scorm->version = strtolower(clean_param($scorm->version, PARAM_SAFEDIR));
341
        if (!file_exists($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'lib.php')) {
342
            $scorm->version = 'scorm_12';
343
        }
344
        require_once($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'lib.php');
345
 
346
        if ($scoes = scorm_get_scoes($scorm->id)) {
347
            $def = new stdClass();
348
            $user = new stdClass();
349
 
350
            foreach ($scoes as $sco) {
351
                $def->{$sco->id} = new stdClass();
352
                $user->{$sco->id} = new stdClass();
353
                // We force mode normal, this can be override by the client at any time.
354
                $def->{$sco->id} = get_scorm_default($user->{$sco->id}, $scorm, $sco->id, $params['attempt'], 'normal');
355
 
356
                $userdata = array();
357
                $defaultdata = array();
358
 
359
                foreach ((array) $user->{$sco->id} as $key => $val) {
360
                    $userdata[] = array(
361
                        'element' => $key,
362
                        'value' => $val
363
                    );
364
                }
365
                foreach ($def->{$sco->id} as $key => $val) {
366
                    $defaultdata[] = array(
367
                        'element' => $key,
368
                        'value' => $val
369
                    );
370
                }
371
 
372
                $data[] = array(
373
                    'scoid' => $sco->id,
374
                    'userdata' => $userdata,
375
                    'defaultdata' => $defaultdata,
376
                );
377
            }
378
        }
379
 
380
        $result = array();
381
        $result['data'] = $data;
382
        $result['warnings'] = $warnings;
383
        return $result;
384
    }
385
 
386
    /**
387
     * Describes the get_scorm_user_data return value.
388
     *
389
     * @return external_single_structure
390
     * @since Moodle 3.0
391
     */
392
    public static function get_scorm_user_data_returns() {
393
 
394
        return new external_single_structure(
395
            array(
396
                'data' => new external_multiple_structure(
397
                    new external_single_structure(
398
                        array(
399
                            'scoid' => new external_value(PARAM_INT, 'sco id'),
400
                            'userdata' => new external_multiple_structure(
401
                                            new external_single_structure(
402
                                                array(
403
                                                    'element' => new external_value(PARAM_RAW, 'element name'),
404
                                                    'value' => new external_value(PARAM_RAW, 'element value')
405
                                                )
406
                                            )
407
                                          ),
408
                            'defaultdata' => new external_multiple_structure(
409
                                                new external_single_structure(
410
                                                    array(
411
                                                        'element' => new external_value(PARAM_RAW, 'element name'),
412
                                                        'value' => new external_value(PARAM_RAW, 'element value')
413
                                                    )
414
                                                )
415
                                             ),
416
                        ), 'SCO data'
417
                    )
418
                ),
419
                'warnings' => new external_warnings(),
420
            )
421
        );
422
    }
423
 
424
    /**
425
     * Describes the parameters for insert_scorm_tracks.
426
     *
427
     * @return external_function_parameters
428
     * @since Moodle 3.0
429
     */
430
    public static function insert_scorm_tracks_parameters() {
431
        return new external_function_parameters(
432
            array(
433
                'scoid' => new external_value(PARAM_INT, 'SCO id'),
434
                'attempt' => new external_value(PARAM_INT, 'attempt number'),
435
                'tracks' => new external_multiple_structure(
436
                    new external_single_structure(
437
                        array(
438
                            'element' => new external_value(PARAM_RAW, 'element name'),
439
                            'value' => new external_value(PARAM_RAW, 'element value')
440
                        )
441
                    )
442
                ),
443
            )
444
        );
445
    }
446
 
447
    /**
448
     * Saves a SCORM tracking record.
449
     * It will overwrite any existing tracking data for this attempt.
450
     * Validation should be performed before running the function to ensure the user will not lose any existing attempt data.
451
     *
452
     * @param int $scoid the SCO id
453
     * @param string $attempt the attempt number
454
     * @param array $tracks the track records to be stored
455
     * @return array warnings and the scoes data
456
     * @throws moodle_exception
457
     * @since Moodle 3.0
458
     */
459
    public static function insert_scorm_tracks($scoid, $attempt, $tracks) {
460
        global $USER, $DB;
461
 
462
        $params = self::validate_parameters(self::insert_scorm_tracks_parameters(),
463
                                            array('scoid' => $scoid, 'attempt' => $attempt, 'tracks' => $tracks));
464
 
465
        $trackids = array();
466
        $warnings = array();
467
 
468
        $sco = scorm_get_sco($params['scoid'], SCO_ONLY);
469
        if (!$sco) {
470
            throw new moodle_exception('cannotfindsco', 'scorm');
471
        }
472
 
473
        $scorm = $DB->get_record('scorm', array('id' => $sco->scorm), '*', MUST_EXIST);
474
        $cm = get_coursemodule_from_instance('scorm', $scorm->id);
475
 
476
        $context = context_module::instance($cm->id);
477
        self::validate_context($context);
478
 
479
        // Check settings / permissions to view the SCORM.
480
        require_capability('mod/scorm:savetrack', $context);
481
 
482
        // Check settings / permissions to view the SCORM.
483
        scorm_require_available($scorm);
484
        $attemptobject = scorm_get_attempt($USER->id, $scorm->id, $params['attempt']);
485
 
486
        foreach ($params['tracks'] as $track) {
487
            $element = $track['element'];
488
            $value = $track['value'];
489
            $trackid = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attemptobject, $element, $value,
490
                                            $scorm->forcecompleted);
491
 
492
            if ($trackid) {
493
                $trackids[] = $trackid;
494
            } else {
495
                $warnings[] = array(
496
                    'item' => 'scorm',
497
                    'itemid' => $scorm->id,
498
                    'warningcode' => 1,
499
                    'message' => 'Element: ' . $element . ' was not saved'
500
                );
501
            }
502
        }
503
 
504
        $result = array();
505
        $result['trackids'] = $trackids;
506
        $result['warnings'] = $warnings;
507
        return $result;
508
    }
509
 
510
    /**
511
     * Describes the insert_scorm_tracks return value.
512
     *
513
     * @return external_single_structure
514
     * @since Moodle 3.0
515
     */
516
    public static function insert_scorm_tracks_returns() {
517
 
518
        return new external_single_structure(
519
            array(
520
                'trackids' => new external_multiple_structure(new external_value(PARAM_INT, 'track id')),
521
                'warnings' => new external_warnings(),
522
            )
523
        );
524
    }
525
 
526
    /**
527
     * Describes the parameters for get_scorm_sco_tracks.
528
     *
529
     * @return external_function_parameters
530
     * @since Moodle 3.0
531
     */
532
    public static function get_scorm_sco_tracks_parameters() {
533
        return new external_function_parameters(
534
            array(
535
                'scoid' => new external_value(PARAM_INT, 'sco id'),
536
                'userid' => new external_value(PARAM_INT, 'user id'),
537
                'attempt' => new external_value(PARAM_INT, 'attempt number (0 for last attempt)', VALUE_DEFAULT, 0)
538
            )
539
        );
540
    }
541
 
542
    /**
543
     * Retrieves SCO tracking data for the given user id and attempt number
544
     *
545
     * @param int $scoid the sco id
546
     * @param int $userid the user id
547
     * @param int $attempt the attempt number
548
     * @return array warnings and the scoes data
549
     * @since Moodle 3.0
550
     */
551
    public static function get_scorm_sco_tracks($scoid, $userid, $attempt = 0) {
552
        global $USER, $DB;
553
 
554
        $params = self::validate_parameters(self::get_scorm_sco_tracks_parameters(),
555
                                            array('scoid' => $scoid, 'userid' => $userid, 'attempt' => $attempt));
556
 
557
        $tracks = array();
558
        $warnings = array();
559
 
560
        $sco = scorm_get_sco($params['scoid'], SCO_ONLY);
561
        if (!$sco) {
562
            throw new moodle_exception('cannotfindsco', 'scorm');
563
        }
564
 
565
        $scorm = $DB->get_record('scorm', array('id' => $sco->scorm), '*', MUST_EXIST);
566
        $cm = get_coursemodule_from_instance('scorm', $scorm->id);
567
 
568
        $context = context_module::instance($cm->id);
569
        self::validate_context($context);
570
 
571
        $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
572
        core_user::require_active_user($user);
573
 
574
        // Extra checks so only users with permissions can view other users attempts.
575
        if ($USER->id != $user->id) {
576
            require_capability('mod/scorm:viewreport', $context);
577
        }
578
 
579
        scorm_require_available($scorm, true, $context);
580
 
581
        if (empty($params['attempt'])) {
582
            $params['attempt'] = scorm_get_last_attempt($scorm->id, $user->id);
583
        }
584
 
585
        $attempted = false;
586
        if ($scormtracks = scorm_get_tracks($sco->id, $params['userid'], $params['attempt'])) {
587
            // Check if attempted.
588
            if ($scormtracks->status != '') {
589
                $attempted = true;
590
                foreach ($scormtracks as $element => $value) {
591
                    $tracks[] = array(
592
                        'element' => $element,
593
                        'value' => $value,
594
                    );
595
                }
596
            }
597
        }
598
 
599
        if (!$attempted) {
600
            $warnings[] = array(
601
                'item' => 'attempt',
602
                'itemid' => $params['attempt'],
603
                'warningcode' => 'notattempted',
604
                'message' => get_string('notattempted', 'scorm')
605
            );
606
        }
607
 
608
        $result = array();
609
        $result['data']['attempt'] = $params['attempt'];
610
        $result['data']['tracks'] = $tracks;
611
        $result['warnings'] = $warnings;
612
        return $result;
613
    }
614
 
615
    /**
616
     * Describes the get_scorm_sco_tracks return value.
617
     *
618
     * @return external_single_structure
619
     * @since Moodle 3.0
620
     */
621
    public static function get_scorm_sco_tracks_returns() {
622
 
623
        return new external_single_structure(
624
            array(
625
                'data' => new external_single_structure(
626
                    array(
627
                        'attempt' => new external_value(PARAM_INT, 'Attempt number'),
628
                        'tracks' => new external_multiple_structure(
629
                            new external_single_structure(
630
                                array(
631
                                    'element' => new external_value(PARAM_RAW, 'Element name'),
632
                                    'value' => new external_value(PARAM_RAW, 'Element value')
633
                                ), 'Tracks data'
634
                            )
635
                        ),
636
                    ), 'SCO data'
637
                ),
638
                'warnings' => new external_warnings(),
639
            )
640
        );
641
    }
642
 
643
    /**
644
     * Describes the parameters for get_scorms_by_courses.
645
     *
646
     * @return external_function_parameters
647
     * @since Moodle 3.0
648
     */
649
    public static function get_scorms_by_courses_parameters() {
650
        return new external_function_parameters (
651
            array(
652
                'courseids' => new external_multiple_structure(
653
                    new external_value(PARAM_INT, 'course id'), 'Array of course ids', VALUE_DEFAULT, array()
654
                ),
655
            )
656
        );
657
    }
658
 
659
    /**
660
     * Returns a list of scorms in a provided list of courses,
661
     * if no list is provided all scorms that the user can view will be returned.
662
     *
663
     * @param array $courseids the course ids
664
     * @return array the scorm details
665
     * @since Moodle 3.0
666
     */
667
    public static function get_scorms_by_courses($courseids = array()) {
668
        global $CFG;
669
 
670
        $returnedscorms = array();
671
        $warnings = array();
672
 
673
        $params = self::validate_parameters(self::get_scorms_by_courses_parameters(), array('courseids' => $courseids));
674
 
675
        $courses = array();
676
        if (empty($params['courseids'])) {
677
            $courses = enrol_get_my_courses();
678
            $params['courseids'] = array_keys($courses);
679
        }
680
 
681
        // Ensure there are courseids to loop through.
682
        if (!empty($params['courseids'])) {
683
 
684
            list($courses, $warnings) = util::validate_courses($params['courseids'], $courses);
685
 
686
            // Get the scorms in this course, this function checks users visibility permissions.
687
            // We can avoid then additional validate_context calls.
688
            $scorms = get_all_instances_in_courses("scorm", $courses);
689
 
690
            $fs = get_file_storage();
691
            foreach ($scorms as $scorm) {
692
 
693
                $context = context_module::instance($scorm->coursemodule);
694
 
695
                // Entry to return.
696
                $module = helper_for_get_mods_by_courses::standard_coursemodule_element_values($scorm, 'mod_scorm');
697
 
698
                // Check if the SCORM open and return warnings if so.
699
                list($open, $openwarnings) = scorm_get_availability_status($scorm, true, $context);
700
 
701
                if (!$open) {
702
                    foreach ($openwarnings as $warningkey => $warningdata) {
703
                        $warnings[] = array(
704
                            'item' => 'scorm',
705
                            'itemid' => $scorm->id,
706
                            'warningcode' => $warningkey,
707
                            'message' => get_string($warningkey, 'scorm', $warningdata)
708
                        );
709
                    }
710
                } else {
711
                    $module['packagesize'] = 0;
712
                    // SCORM size.
713
                    if ($scorm->scormtype === SCORM_TYPE_LOCAL or $scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
714
                        if ($packagefile = $fs->get_file($context->id, 'mod_scorm', 'package', 0, '/', $scorm->reference)) {
715
                            $module['packagesize'] = $packagefile->get_filesize();
716
                            // Download URL.
717
                            $module['packageurl'] = moodle_url::make_webservice_pluginfile_url(
718
                                                    $context->id, 'mod_scorm', 'package', 0, '/', $scorm->reference)->out(false);
719
                        }
720
                    }
721
 
722
                    $module['protectpackagedownloads'] = get_config('scorm', 'protectpackagedownloads');
723
 
724
                    $viewablefields = array('version', 'maxgrade', 'grademethod', 'whatgrade', 'maxattempt', 'forcecompleted',
725
                                            'forcenewattempt', 'lastattemptlock', 'displayattemptstatus', 'displaycoursestructure',
726
                                            'sha1hash', 'md5hash', 'revision', 'launch', 'skipview', 'hidebrowse', 'hidetoc', 'nav',
727
                                            'navpositionleft', 'navpositiontop', 'auto', 'popup', 'width', 'height', 'timeopen',
728
                                            'timeclose', 'scormtype', 'reference');
729
 
730
                    // Check additional permissions for returning optional private settings.
731
                    if (has_capability('moodle/course:manageactivities', $context)) {
732
                        $additionalfields = array('updatefreq', 'options', 'completionstatusrequired', 'completionscorerequired',
733
                                                  'completionstatusallscos', 'autocommit', 'timemodified');
734
                        $viewablefields = array_merge($viewablefields, $additionalfields);
735
                    }
736
 
737
                    foreach ($viewablefields as $field) {
738
                        $module[$field] = $scorm->{$field};
739
                    }
740
                }
741
 
742
                $returnedscorms[] = $module;
743
            }
744
        }
745
 
746
        $settings = [
747
            [
748
                'name' => 'scormstandard',
749
                'value' => get_config('scorm', 'scormstandard'),
750
            ]
751
        ];
752
        $result = [
753
            'scorms'   => $returnedscorms,
754
            'options'  => $settings,
755
            'warnings' => $warnings
756
        ];
757
        return $result;
758
    }
759
 
760
    /**
761
     * Describes the get_scorms_by_courses return value.
762
     *
763
     * @return external_single_structure
764
     * @since Moodle 3.0
765
     */
766
    public static function get_scorms_by_courses_returns() {
767
 
768
        return new external_single_structure(
769
            array(
770
                'scorms' => new external_multiple_structure(
771
                    new external_single_structure(array_merge(
772
                        helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(),
773
                        [
774
                            'packagesize' => new external_value(PARAM_INT, 'SCORM zip package size', VALUE_OPTIONAL),
775
                            'packageurl' => new external_value(PARAM_URL, 'SCORM zip package URL', VALUE_OPTIONAL),
776
                            'version' => new external_value(PARAM_NOTAGS, 'SCORM version (SCORM_12, SCORM_13, SCORM_AICC)',
777
                                                            VALUE_OPTIONAL),
778
                            'maxgrade' => new external_value(PARAM_INT, 'Max grade', VALUE_OPTIONAL),
779
                            'grademethod' => new external_value(PARAM_INT, 'Grade method', VALUE_OPTIONAL),
780
                            'whatgrade' => new external_value(PARAM_INT, 'What grade', VALUE_OPTIONAL),
781
                            'maxattempt' => new external_value(PARAM_INT, 'Maximum number of attemtps', VALUE_OPTIONAL),
782
                            'forcecompleted' => new external_value(PARAM_BOOL, 'Status current attempt is forced to "completed"',
783
                                                                    VALUE_OPTIONAL),
784
                            'forcenewattempt' => new external_value(PARAM_INT, 'Controls re-entry behaviour',
785
                                                                    VALUE_OPTIONAL),
786
                            'lastattemptlock' => new external_value(PARAM_BOOL, 'Prevents to launch new attempts once finished',
787
                                                                    VALUE_OPTIONAL),
788
                            'displayattemptstatus' => new external_value(PARAM_INT, 'How to display attempt status',
789
                                                                            VALUE_OPTIONAL),
790
                            'displaycoursestructure' => new external_value(PARAM_BOOL, 'Display contents structure',
791
                                                                            VALUE_OPTIONAL),
792
                            'sha1hash' => new external_value(PARAM_NOTAGS, 'Package content or ext path hash', VALUE_OPTIONAL),
793
                            'md5hash' => new external_value(PARAM_NOTAGS, 'MD5 Hash of package file', VALUE_OPTIONAL),
794
                            'revision' => new external_value(PARAM_INT, 'Revison number', VALUE_OPTIONAL),
795
                            'launch' => new external_value(PARAM_INT, 'First content to launch', VALUE_OPTIONAL),
796
                            'skipview' => new external_value(PARAM_INT, 'How to skip the content structure page', VALUE_OPTIONAL),
797
                            'hidebrowse' => new external_value(PARAM_BOOL, 'Disable preview mode?', VALUE_OPTIONAL),
798
                            'hidetoc' => new external_value(PARAM_INT, 'How to display the SCORM structure in player',
799
                                                            VALUE_OPTIONAL),
800
                            'nav' => new external_value(PARAM_INT, 'Show navigation buttons', VALUE_OPTIONAL),
801
                            'navpositionleft' => new external_value(PARAM_INT, 'Navigation position left', VALUE_OPTIONAL),
802
                            'navpositiontop' => new external_value(PARAM_INT, 'Navigation position top', VALUE_OPTIONAL),
803
                            'auto' => new external_value(PARAM_BOOL, 'Auto continue?', VALUE_OPTIONAL),
804
                            'popup' => new external_value(PARAM_INT, 'Display in current or new window', VALUE_OPTIONAL),
805
                            'width' => new external_value(PARAM_INT, 'Frame width', VALUE_OPTIONAL),
806
                            'height' => new external_value(PARAM_INT, 'Frame height', VALUE_OPTIONAL),
807
                            'timeopen' => new external_value(PARAM_INT, 'Available from', VALUE_OPTIONAL),
808
                            'timeclose' => new external_value(PARAM_INT, 'Available to', VALUE_OPTIONAL),
809
                            'scormtype' => new external_value(PARAM_ALPHA, 'SCORM type', VALUE_OPTIONAL),
810
                            'reference' => new external_value(PARAM_NOTAGS, 'Reference to the package', VALUE_OPTIONAL),
811
                            'protectpackagedownloads' => new external_value(PARAM_BOOL, 'Protect package downloads?',
812
                                                                            VALUE_OPTIONAL),
813
                            'updatefreq' => new external_value(PARAM_INT, 'Auto-update frequency for remote packages',
814
                                                                VALUE_OPTIONAL),
815
                            'options' => new external_value(PARAM_RAW, 'Additional options', VALUE_OPTIONAL),
816
                            'completionstatusrequired' => new external_value(PARAM_INT, 'Status passed/completed required?',
817
                                                                                VALUE_OPTIONAL),
818
                            'completionscorerequired' => new external_value(PARAM_INT, 'Minimum score required', VALUE_OPTIONAL),
819
                            'completionstatusallscos' => new external_value(PARAM_INT, 'Require all scos to return completion status', VALUE_OPTIONAL),
820
                            'autocommit' => new external_value(PARAM_BOOL, 'Save track data automatically?', VALUE_OPTIONAL),
821
                            'timemodified' => new external_value(PARAM_INT, 'Time of last modification', VALUE_OPTIONAL),
822
                        ]
823
                    ), 'SCORM')
824
                ),
825
                'options' => new external_multiple_structure(
826
                    new external_single_structure(
827
                        [
828
                            'name' => new external_value(PARAM_RAW, 'Options name'),
829
                            'value' => new external_value(PARAM_RAW, 'Option value')
830
                        ]
831
                    ), 'Global SCORM options', VALUE_OPTIONAL
832
                ),
833
                'warnings' => new external_warnings(),
834
            )
835
        );
836
    }
837
 
838
    /**
839
     * Returns description of method parameters
840
     *
841
     * @return external_function_parameters
842
     * @since Moodle 3.1
843
     */
844
    public static function launch_sco_parameters() {
845
        return new external_function_parameters(
846
            array(
847
                'scormid' => new external_value(PARAM_INT, 'SCORM instance id'),
848
                'scoid' => new external_value(PARAM_INT, 'SCO id (empty for launching the first SCO)', VALUE_DEFAULT, 0)
849
            )
850
        );
851
    }
852
 
853
    /**
854
     * Trigger the course module viewed event.
855
     *
856
     * @param int $scormid the SCORM instance id
857
     * @param int $scoid the SCO id
858
     * @return array of warnings and status result
859
     * @since Moodle 3.1
860
     * @throws moodle_exception
861
     */
862
    public static function launch_sco($scormid, $scoid = 0) {
863
        global $DB, $CFG;
864
 
865
        require_once($CFG->libdir . '/completionlib.php');
866
 
867
        $params = self::validate_parameters(self::launch_sco_parameters(),
868
                                            array(
869
                                                'scormid' => $scormid,
870
                                                'scoid' => $scoid
871
                                            ));
872
        $warnings = array();
873
 
874
        // Request and permission validation.
875
        $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
876
        list($course, $cm) = get_course_and_cm_from_instance($scorm, 'scorm');
877
 
878
        $context = context_module::instance($cm->id);
879
        self::validate_context($context);
880
 
881
        // If the SCORM is not open this function will throw exceptions.
882
        scorm_require_available($scorm);
883
 
884
        if (!empty($params['scoid']) and !($sco = scorm_get_sco($params['scoid'], SCO_ONLY))) {
885
            throw new moodle_exception('cannotfindsco', 'scorm');
886
        }
887
 
888
        // Mark module viewed.
889
        $completion = new completion_info($course);
890
        $completion->set_module_viewed($cm);
891
 
892
        list($sco, $scolaunchurl) = scorm_get_sco_and_launch_url($scorm, $params['scoid'], $context);
893
        // Trigger the SCO launched event.
894
        scorm_launch_sco($scorm, $sco, $cm, $context, $scolaunchurl);
895
 
896
        $result = array();
897
        $result['status'] = true;
898
        $result['warnings'] = $warnings;
899
        return $result;
900
    }
901
 
902
    /**
903
     * Returns description of method result value
904
     *
905
     * @return \core_external\external_description
906
     * @since Moodle 3.1
907
     */
908
    public static function launch_sco_returns() {
909
        return new external_single_structure(
910
            array(
911
                'status' => new external_value(PARAM_BOOL, 'status: true if success'),
912
                'warnings' => new external_warnings()
913
            )
914
        );
915
    }
916
 
917
    /**
918
     * Describes the parameters for get_scorm_access_information.
919
     *
920
     * @return external_external_function_parameters
921
     * @since Moodle 3.7
922
     */
923
    public static function get_scorm_access_information_parameters() {
924
        return new external_function_parameters (
925
            array(
926
                'scormid' => new external_value(PARAM_INT, 'scorm instance id.')
927
            )
928
        );
929
    }
930
 
931
    /**
932
     * Return access information for a given scorm.
933
     *
934
     * @param int $scormid scorm instance id
935
     * @return array of warnings and the access information
936
     * @since Moodle 3.7
937
     * @throws  moodle_exception
938
     */
939
    public static function get_scorm_access_information($scormid) {
940
        global $DB;
941
 
942
        $params = self::validate_parameters(self::get_scorm_access_information_parameters(), array('scormid' => $scormid));
943
 
944
        // Request and permission validation.
945
        $scorm = $DB->get_record('scorm', array('id' => $params['scormid']), '*', MUST_EXIST);
946
        list($course, $cm) = get_course_and_cm_from_instance($scorm, 'scorm');
947
 
948
        $context = context_module::instance($cm->id);
949
        self::validate_context($context);
950
 
951
        $result = array();
952
        // Return all the available capabilities.
953
        $capabilities = load_capability_def('mod_scorm');
954
        foreach ($capabilities as $capname => $capdata) {
955
            // Get fields like cansubmit so it is consistent with the access_information function implemented in other modules.
956
            $field = 'can' . str_replace('mod/scorm:', '', $capname);
957
            $result[$field] = has_capability($capname, $context);
958
        }
959
 
960
        $result['warnings'] = array();
961
        return $result;
962
    }
963
 
964
    /**
965
     * Describes the get_scorm_access_information return value.
966
     *
967
     * @return external_single_structure
968
     * @since Moodle 3.7
969
     */
970
    public static function get_scorm_access_information_returns() {
971
 
972
        $structure = array(
973
            'warnings' => new external_warnings()
974
        );
975
 
976
        $capabilities = load_capability_def('mod_scorm');
977
        foreach ($capabilities as $capname => $capdata) {
978
            // Get fields like cansubmit so it is consistent with the access_information function implemented in other modules.
979
            $field = 'can' . str_replace('mod/scorm:', '', $capname);
980
            $structure[$field] = new external_value(PARAM_BOOL, 'Whether the user has the capability ' . $capname . ' allowed.',
981
                VALUE_OPTIONAL);
982
        }
983
 
984
        return new external_single_structure($structure);
985
    }
986
}