Merge branch 'm20_MDL-26176_cleanup' of github.com:danmarsden/moodle
[moodle.git] / mod / scorm / loadSCO.php
1 <?php
2     require_once('../../config.php');
3     require_once($CFG->dirroot.'/mod/scorm/locallib.php');
5     $id    = optional_param('id', '', PARAM_INT);    // Course Module ID, or
6     $a     = optional_param('a', '', PARAM_INT);     // scorm ID
7     $scoid = required_param('scoid', PARAM_INT);     // sco ID
9     $delayseconds = 2;  // Delay time before sco launch, used to give time to browser to define API
11     if (!empty($id)) {
12         if (! $cm = get_coursemodule_from_id('scorm', $id)) {
13             print_error('invalidcoursemodule');
14         }
15         if (! $course = $DB->get_record('course', array('id'=>$cm->course))) {
16             print_error('coursemisconf');
17         }
18         if (! $scorm = $DB->get_record('scorm', array('id'=>$cm->instance))) {
19             print_error('invalidcoursemodule');
20         }
21     } else if (!empty($a)) {
22         if (! $scorm = $DB->get_record('scorm', array('id'=>$a))) {
23             print_error('coursemisconf');
24         }
25         if (! $course = $DB->get_record('course', array('id'=>$scorm->course))) {
26             print_error('coursemisconf');
27         }
28         if (! $cm = get_coursemodule_from_instance('scorm', $scorm->id, $course->id)) {
29             print_error('invalidcoursemodule');
30         }
31     } else {
32         print_error('missingparameter');
33     }
35     $PAGE->set_url('/mod/scorm/loadSCO.php', array('scoid'=>$scoid, 'id'=>$cm->id));
37     require_login($course->id, false, $cm);
39     //check if scorm closed
40     $timenow = time();
41     if ($scorm->timeclose !=0) {
42         if ($scorm->timeopen > $timenow) {
43             print_error('notopenyet', 'scorm', null, userdate($scorm->timeopen));
44         } else if ($timenow > $scorm->timeclose) {
45             print_error('expired', 'scorm', null, userdate($scorm->timeclose));
46         }
47     }
49     $context = get_context_instance(CONTEXT_MODULE, $cm->id);
51     if (!empty($scoid)) {
52     //
53     // Direct SCO request
54     //
55         if ($sco = scorm_get_sco($scoid)) {
56             if ($sco->launch == '') {
57                 // Search for the next launchable sco
58                 if ($scoes = $DB->get_records_select('scorm_scoes',"scorm = ? AND '.$DB->sql_isnotempty('scorm_scoes', 'launch', false, true).' AND id > ?",array($scorm->id,$sco->id), 'id ASC')) {
59                     $sco = current($scoes);
60                 }
61             }
62         }
63     }
64     //
65     // If no sco was found get the first of SCORM package
66     //
67     if (!isset($sco)) {
68         $scoes = $DB->get_records_select('scorm_scoes',"scorm = ? AND ".$DB->sql_isnotempty('scorm_scoes', 'launch', false, true), array($scorm->id),'id ASC');
69         $sco = current($scoes);
70     }
72     if ($sco->scormtype == 'asset') {
73        $attempt = scorm_get_last_attempt($scorm->id,$USER->id);
74        $element = ($scorm->version == 'scorm_13' || $scorm->version == 'SCORM_1.3') ? 'cmi.completion_status':'cmi.core.lesson_status';
75        $value = 'completed';
76        $result = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attempt, $element, $value);
77     }
79     //
80     // Forge SCO URL
81     //
82     $connector = '';
83     $version = substr($scorm->version,0,4);
84     if ((isset($sco->parameters) && (!empty($sco->parameters))) || ($version == 'AICC')) {
85         if (stripos($sco->launch,'?') !== false) {
86             $connector = '&';
87         } else {
88             $connector = '?';
89         }
90         if ((isset($sco->parameters) && (!empty($sco->parameters))) && ($sco->parameters[0] == '?')) {
91             $sco->parameters = substr($sco->parameters,1);
92         }
93     }
95     if ($version == 'AICC') {
96         $sco_params = '';
97         if (isset($sco->parameters) && (!empty($sco->parameters))) {
98             $sco_params = '&'. $sco->parameters;
99         }
100         $launcher = $sco->launch.$connector.'aicc_sid='.sesskey().'&aicc_url='.$CFG->wwwroot.'/mod/scorm/aicc.php'.$sco_params;
101     } else {
102         if (isset($sco->parameters) && (!empty($sco->parameters))) {
103             $launcher = $sco->launch.$connector.$sco->parameters;
104         } else {
105             $launcher = $sco->launch;
106         }
107     }
109     if (scorm_external_link($sco->launch)) {
110         //TODO: does this happen?
111         $result = $launcher;
113     } else if ($scorm->scormtype === SCORM_TYPE_EXTERNAL) {
114         // Remote learning activity
115         $result = dirname($scorm->reference).'/'.$launcher;
117     } else if ($scorm->scormtype === SCORM_TYPE_IMSREPOSITORY) {
118         // Repository
119         $result = $CFG->repositorywebroot.substr($scorm->reference, 1).'/'.$sco->launch;
121     } else if ($scorm->scormtype === SCORM_TYPE_LOCAL or $scorm->scormtype === SCORM_TYPE_LOCALSYNC) {
122         //note: do not convert this to use get_file_url() or moodle_url()
123         //SCORM does not work without slasharguments and moodle_url() encodes querystring vars
124         $result = "$CFG->wwwroot/pluginfile.php/$context->id/mod_scorm/content/$scorm->revision/$launcher";
125     }
127     // which API are we looking for
128     $LMS_api = ($scorm->version == 'scorm_12' || $scorm->version == 'SCORM_1.2' || empty($scorm->version)) ? 'API' : 'API_1484_11';
129 ?>
130 <html>
131     <head>
132         <title>LoadSCO</title>
133         <script type="text/javascript">
134         //<![CDATA[
135         var myApiHandle = null;
136         var myFindAPITries = 0;
138         function myGetAPIHandle() {
139            myFindAPITries = 0;
140            if (myApiHandle == null) {
141               myApiHandle = myGetAPI();
142            }
143            return myApiHandle;
144         }
146         function myFindAPI(win) {
147            while ((win.<?php echo $LMS_api; ?> == null) && (win.parent != null) && (win.parent != win)) {
148               myFindAPITries++;
149               // Note: 7 is an arbitrary number, but should be more than sufficient
150               if (myFindAPITries > 7) {
151                  return null;
152               }
153               win = win.parent;
154            }
155            return win.<?php echo $LMS_api; ?>;
156         }
158         // hun for the API - needs to be loaded before we can launch the package
159         function myGetAPI() {
160            var theAPI = myFindAPI(window);
161            if ((theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined")) {
162               theAPI = myFindAPI(window.opener);
163            }
164            if (theAPI == null) {
165               return null;
166            }
167            return theAPI;
168         }
170        function doredirect() {
171             if (myGetAPIHandle() != null) {
172                 location = "<?php echo $result ?>";
173             }
174             else {
175                 document.body.innerHTML = "<p><?php echo get_string('activityloading', 'scorm');?> <span id='countdown'><?php echo $delayseconds ?></span> <?php echo get_string('numseconds', 'moodle', '');?>. &nbsp; <img src='<?php echo $OUTPUT->pix_url('wait', 'scorm') ?>'><p>";
176                 var e = document.getElementById("countdown");
177                 var cSeconds = parseInt(e.innerHTML);
178                 var timer = setInterval(function() {
179                                                 if( cSeconds && myGetAPIHandle() == null ) {
180                                                     e.innerHTML = --cSeconds;
181                                                 } else {
182                                                     clearInterval(timer);
183                                                     document.body.innerHTML = "<p><?php echo get_string('activitypleasewait', 'scorm');?></p>";
184                                                     location = "<?php echo $result ?>";
185                                                 }
186                                             }, 1000);
187             }
188         }
189         //]]>
190         </script>
191         <noscript>
192             <meta http-equiv="refresh" content="0;url=<?php echo $result ?>" />
193         </noscript>
194     </head>
195     <body onload="doredirect();">
196         <p><?php echo get_string('activitypleasewait', 'scorm');?></p>
197         <?php if (debugging('',DEBUG_DEVELOPER)) {
198                   add_to_log($course->id, 'scorm', 'launch', 'view.php?id='.$cm->id, $result, $cm->id);
199               }
200         ?>
201     </body>
202 </html>