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