|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00017 //Prevent Caching Headers 00018 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 00019 header("Cache-Control: no-cache"); 00020 header("Pragma: no-cache"); 00021 00022 require_once('../../config.php'); 00023 require_once($CFG->dirroot.'/mod/scorm/lib.php'); 00024 require_once($CFG->dirroot.'/mod/scorm/locallib.php'); 00025 require_once($CFG->dirroot.'/mod/scorm/datamodels/aicclib.php'); 00026 00027 foreach ($_POST as $key => $value) { 00028 $tempkey = strtolower($key); 00029 $_POST[$tempkey] = $value; 00030 } 00031 00032 $command = required_param('command', PARAM_ALPHA); 00033 $sessionid = required_param('session_id', PARAM_ALPHANUM); 00034 $aiccdata = optional_param('aicc_data', '', PARAM_RAW); 00035 00036 $cfg_scorm = get_config('scorm'); 00037 00038 $url = new moodle_url('/mod/scorm/aicc.php', array('command'=>$command, 'session_id'=>$sessionid)); 00039 if ($aiccdata !== 0) { 00040 $url->param('aicc_data', $aiccdata); 00041 } 00042 $PAGE->set_url($url); 00043 00044 if (empty($cfg_scorm->allowaicchacp)) { 00045 require_login(); 00046 if (!confirm_sesskey($sessionid)) { 00047 print_error('invalidsesskey'); 00048 } 00049 $aiccuser = $USER; 00050 $scormsession = $SESSION->scorm; 00051 } else { 00052 $scormsession = scorm_aicc_confirm_hacp_session($sessionid); 00053 if (empty($scormsession)) { 00054 print_error('invalidhacpsession', 'scorm'); 00055 } 00056 $aiccuser = $DB->get_record('user', array('id'=>$scormsession->userid), 'id,username,lastname,firstname', MUST_EXIST); 00057 } 00058 00059 if (!empty($command)) { 00060 $command = strtolower($command); 00061 00062 if (isset($scormsession->scoid)) { 00063 $scoid = $scormsession->scoid; 00064 } else { 00065 print_error('cannotcallscript'); 00066 } 00067 $mode = 'normal'; 00068 if (isset($scormsession->scormmode)) { 00069 $mode = $scormsession->scormmode; 00070 } 00071 $status = 'Not Initialized'; 00072 if (isset($scormsession->scormstatus)) { 00073 $status = $scormsession->scormstatus; 00074 } 00075 if (isset($scormsession->attempt)) { 00076 $attempt = $scormsession->attempt; 00077 } else { 00078 $attempt = 1; 00079 } 00080 00081 if ($sco = scorm_get_sco($scoid, SCO_ONLY)) { 00082 if (!$scorm = $DB->get_record('scorm', array('id'=>$sco->scorm))) { 00083 print_error('cannotcallscript'); 00084 } 00085 } else { 00086 print_error('cannotcallscript'); 00087 } 00088 $aiccrequest = "MOODLE scoid: $scoid" 00089 . "\r\nMOODLE mode: $mode" 00090 . "\r\nMOODLE status: $status" 00091 . "\r\nMOODLE attempt: $attempt" 00092 . "\r\nAICC sessionid: $sessionid" 00093 . "\r\nAICC command: $command" 00094 . "\r\nAICC aiccdata:\r\n$aiccdata"; 00095 scorm_debug_log_write("aicc", "HACP Request:\r\n$aiccrequest", $scoid); 00096 ob_start(); 00097 00098 if ($scorm = $DB->get_record('scorm', array('id'=>$sco->scorm))) { 00099 switch ($command) { 00100 case 'getparam': 00101 if ($status == 'Not Initialized') { 00102 $scormsession->scormstatus = 'Running'; 00103 $status = 'Running'; 00104 } 00105 if ($status != 'Running') { 00106 echo "error=101\r\nerror_text=Terminated\r\n"; 00107 } else { 00108 if ($usertrack=scorm_get_tracks($scoid, $aiccuser->id, $attempt)) { 00109 $userdata = $usertrack; 00110 } else { 00111 $userdata->status = ''; 00112 $userdata->score_raw = ''; 00113 } 00114 $userdata->student_id = $aiccuser->username; 00115 $userdata->student_name = $aiccuser->lastname .', '. $aiccuser->firstname; 00116 $userdata->mode = $mode; 00117 if ($userdata->mode == 'normal') { 00118 $userdata->credit = 'credit'; 00119 } else { 00120 $userdata->credit = 'no-credit'; 00121 } 00122 00123 if ($sco = scorm_get_sco($scoid)) { 00124 $userdata->course_id = $sco->identifier; 00125 $userdata->datafromlms = isset($sco->datafromlms)?$sco->datafromlms:''; 00126 $userdata->mastery_score = isset($sco->mastery_score) && is_numeric($sco->mastery_score)?trim($sco->mastery_score):''; 00127 $userdata->max_time_allowed = isset($sco->max_time_allowed)?$sco->max_time_allowed:''; 00128 $userdata->time_limit_action = isset($sco->time_limit_action)?$sco->time_limit_action:''; 00129 00130 echo "error=0\r\nerror_text=Successful\r\naicc_data="; 00131 echo "[Core]\r\n"; 00132 echo 'Student_ID='.$userdata->student_id."\r\n"; 00133 echo 'Student_Name='.$userdata->student_name."\r\n"; 00134 if (isset($userdata->{'cmi.core.lesson_location'})) { 00135 echo 'Lesson_Location='.$userdata->{'cmi.core.lesson_location'}."\r\n"; 00136 } else { 00137 echo 'Lesson_Location='."\r\n"; 00138 } 00139 echo 'Credit='.$userdata->credit."\r\n"; 00140 if (isset($userdata->status)) { 00141 if ($userdata->status == '') { 00142 $userdata->entry = ', ab-initio'; 00143 } else { 00144 if (isset($userdata->{'cmi.core.exit'}) && ($userdata->{'cmi.core.exit'} == 'suspend')) { 00145 $userdata->entry = ', resume'; 00146 } else { 00147 $userdata->entry = ''; 00148 } 00149 } 00150 } 00151 if (isset($userdata->{'cmi.core.lesson_status'})) { 00152 echo 'Lesson_Status='.$userdata->{'cmi.core.lesson_status'}.$userdata->entry."\r\n"; 00153 $scormsession->scorm_lessonstatus = $userdata->{'cmi.core.lesson_status'}; 00154 } else { 00155 echo 'Lesson_Status=not attempted'.$userdata->entry."\r\n"; 00156 $scormsession->scorm_lessonstatus = 'not attempted'; 00157 } 00158 if (isset($userdata->{'cmi.core.score.raw'})) { 00159 $max = ''; 00160 $min = ''; 00161 if (isset($userdata->{'cmi.core.score.max'}) && !empty($userdata->{'cmi.core.score.max'})) { 00162 $max = ', '.$userdata->{'cmi.core.score.max'}; 00163 if (isset($userdata->{'cmi.core.score.min'}) && !empty($userdata->{'cmi.core.score.min'})) { 00164 $min = ', '.$userdata->{'cmi.core.score.min'}; 00165 } 00166 } 00167 echo 'Score='.$userdata->{'cmi.core.score.raw'}.$max.$min."\r\n"; 00168 } else { 00169 echo 'Score='."\r\n"; 00170 } 00171 if (isset($userdata->{'cmi.core.total_time'})) { 00172 echo 'Time='.$userdata->{'cmi.core.total_time'}."\r\n"; 00173 } else { 00174 echo 'Time='.'00:00:00'."\r\n"; 00175 } 00176 echo 'Lesson_Mode='.$userdata->mode."\r\n"; 00177 if (isset($userdata->{'cmi.suspend_data'})) { 00178 echo "[Core_Lesson]\r\n".rawurldecode($userdata->{'cmi.suspend_data'})."\r\n"; 00179 } else { 00180 echo "[Core_Lesson]\r\n"; 00181 } 00182 echo "[Core_Vendor]\r\n".$userdata->datafromlms."\r\n"; 00183 echo "[Evaluation]\r\nCourse_ID = {".$userdata->course_id."}\r\n"; 00184 echo "[Student_Data]\r\n"; 00185 echo 'Mastery_Score='.$userdata->mastery_score."\r\n"; 00186 echo 'Max_Time_Allowed='.$userdata->max_time_allowed."\r\n"; 00187 echo 'Time_Limit_Action='.$userdata->time_limit_action."\r\n"; 00188 } else { 00189 print_error('cannotfindsco', 'scorm'); 00190 } 00191 } 00192 break; 00193 case 'putparam': 00194 if ($status == 'Running') { 00195 if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $scorm->course)) { 00196 echo "error=1\r\nerror_text=Unknown\r\n"; // No one must see this error message if not hacked 00197 } 00198 if (!empty($aiccdata) && has_capability('mod/scorm:savetrack', get_context_instance(CONTEXT_MODULE, $cm->id), $aiccuser->id)) { 00199 $initlessonstatus = 'not attempted'; 00200 $lessonstatus = 'not attempted'; 00201 if (isset($scormsession->scorm_lessonstatus)) { 00202 $initlessonstatus = $scormsession->scorm_lessonstatus; 00203 } 00204 $score = ''; 00205 $datamodel['lesson_location'] = 'cmi.core.lesson_location'; 00206 $datamodel['lesson_status'] = 'cmi.core.lesson_status'; 00207 $datamodel['score'] = 'cmi.core.score.raw'; 00208 $datamodel['time'] = 'cmi.core.session_time'; 00209 $datamodel['[core_lesson]'] = 'cmi.suspend_data'; 00210 $datamodel['[comments]'] = 'cmi.comments'; 00211 $datarows = explode("\r\n", $aiccdata); 00212 reset($datarows); 00213 while ((list(, $datarow) = each($datarows)) !== false) { 00214 if (($equal = strpos($datarow, '=')) !== false) { 00215 $element = strtolower(trim(substr($datarow, 0, $equal))); 00216 $value = trim(substr($datarow, $equal+1)); 00217 if (isset($datamodel[$element])) { 00218 $element = $datamodel[$element]; 00219 switch ($element) { 00220 case 'cmi.core.lesson_location': 00221 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, $element, $value); 00222 break; 00223 case 'cmi.core.lesson_status': 00224 $statuses = array( 00225 'passed' => 'passed', 00226 'completed' => 'completed', 00227 'failed' => 'failed', 00228 'incomplete' => 'incomplete', 00229 'browsed' => 'browsed', 00230 'not attempted' => 'not attempted', 00231 'p' => 'passed', 00232 'c' => 'completed', 00233 'f' => 'failed', 00234 'i' => 'incomplete', 00235 'b' => 'browsed', 00236 'n' => 'not attempted' 00237 ); 00238 $exites = array( 00239 'logout' => 'logout', 00240 'time-out' => 'time-out', 00241 'suspend' => 'suspend', 00242 'l' => 'logout', 00243 't' => 'time-out', 00244 's' => 'suspend', 00245 ); 00246 $values = explode(',', $value); 00247 $value = ''; 00248 if (count($values) > 1) { 00249 $value = trim(strtolower($values[1])); 00250 $value = $value[0]; 00251 if (isset($exites[$value])) { 00252 $value = $exites[$value]; 00253 } 00254 } 00255 if (empty($value) || isset($exites[$value])) { 00256 $subelement = 'cmi.core.exit'; 00257 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, $subelement, $value); 00258 } 00259 $value = trim(strtolower($values[0])); 00260 $value = $value[0]; 00261 if (isset($statuses[$value]) && ($mode == 'normal')) { 00262 $value = $statuses[$value]; 00263 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, $element, $value); 00264 } 00265 $lessonstatus = $value; 00266 break; 00267 case 'cmi.core.score.raw': 00268 $values = explode(',', $value); 00269 if ((count($values) > 1) && ($values[1] >= $values[0]) && is_numeric($values[1])) { 00270 $subelement = 'cmi.core.score.max'; 00271 $value = trim($values[1]); 00272 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, $subelement, $value); 00273 if ((count($values) == 3) && ($values[2] <= $values[0]) && is_numeric($values[2])) { 00274 $subelement = 'cmi.core.score.min'; 00275 $value = trim($values[2]); 00276 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, $subelement, $value); 00277 } 00278 } 00279 00280 $value = ''; 00281 if (is_numeric($values[0])) { 00282 $value = trim($values[0]); 00283 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, $element, $value); 00284 } 00285 $score = $value; 00286 break; 00287 case 'cmi.core.session_time': 00288 $scormsession->sessiontime = $value; 00289 break; 00290 } 00291 } 00292 } else { 00293 if (isset($datamodel[strtolower(trim($datarow))])) { 00294 $element = $datamodel[strtolower(trim($datarow))]; 00295 $value = ''; 00296 while ((($datarow = current($datarows)) !== false) && (substr($datarow, 0, 1) != '[')) { 00297 $value .= $datarow."\r\n"; 00298 next($datarows); 00299 } 00300 $value = rawurlencode($value); 00301 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, $element, $value); 00302 } 00303 } 00304 } 00305 if (($mode == 'browse') && ($initlessonstatus == 'not attempted')) { 00306 $lessonstatus = 'browsed'; 00307 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, 'cmi.core.lesson_status', 'browsed'); 00308 } 00309 if ($mode == 'normal') { 00310 if ($sco = scorm_get_sco($scoid)) { 00311 if (isset($sco->mastery_score) && is_numeric($sco->mastery_score)) { 00312 if ($score != '') { // $score is correctly initialized w/ an empty string, see above 00313 if ($score >= trim($sco->mastery_score)) { 00314 $lessonstatus = 'passed'; 00315 } else { 00316 $lessonstatus = 'failed'; 00317 } 00318 } 00319 } 00320 $id = scorm_insert_track($aiccuser->id, $scorm->id, $sco->id, $attempt, 'cmi.core.lesson_status', $lessonstatus); 00321 } 00322 } 00323 } 00324 echo "error=0\r\nerror_text=Successful\r\n"; 00325 } else if ($status == 'Terminated') { 00326 echo "error=1\r\nerror_text=Terminated\r\n"; 00327 } else { 00328 echo "error=1\r\nerror_text=Not Initialized\r\n"; 00329 } 00330 break; 00331 case 'putcomments': 00332 if ($status == 'Running') { 00333 echo "error=0\r\nerror_text=Successful\r\n"; 00334 } else if ($status == 'Terminated') { 00335 echo "error=1\r\nerror_text=Terminated\r\n"; 00336 } else { 00337 echo "error=1\r\nerror_text=Not Initialized\r\n"; 00338 } 00339 break; 00340 case 'putinteractions': 00341 if ($status == 'Running') { 00342 echo "error=0\r\nerror_text=Successful\r\n"; 00343 } else if ($status == 'Terminated') { 00344 echo "error=1\r\nerror_text=Terminated\r\n"; 00345 } else { 00346 echo "error=1\r\nerror_text=Not Initialized\r\n"; 00347 } 00348 break; 00349 case 'putobjectives': 00350 if ($status == 'Running') { 00351 echo "error=0\r\nerror_text=Successful\r\n"; 00352 } else if ($status == 'Terminated') { 00353 echo "error=1\r\nerror_text=Terminated\r\n"; 00354 } else { 00355 echo "error=1\r\nerror_text=Not Initialized\r\n"; 00356 } 00357 break; 00358 case 'putpath': 00359 if ($status == 'Running') { 00360 echo "error=0\r\nerror_text=Successful\r\n"; 00361 } else if ($status == 'Terminated') { 00362 echo "error=1\r\nerror_text=Terminated\r\n"; 00363 } else { 00364 echo "error=1\r\nerror_text=Not Initialized\r\n"; 00365 } 00366 break; 00367 case 'putperformance': 00368 if ($status == 'Running') { 00369 echo "error=0\r\nerror_text=Successful\r\n"; 00370 } else if ($status == 'Terminated') { 00371 echo "error=1\r\nerror_text=Terminated\r\n"; 00372 } else { 00373 echo "error=1\r\nerror_text=Not Initialized\r\n"; 00374 } 00375 break; 00376 case 'exitau': 00377 if ($status == 'Running') { 00378 if (isset($scormsession->sessiontime) && ($scormsession->sessiontime != '')) { 00379 if ($track = $DB->get_record('scorm_scoes_track', array("userid"=>$aiccuser->id, 00380 "scormid"=>$scorm->id, 00381 "scoid"=>$sco->id, 00382 "attempt"=>$attempt, 00383 "element"=>'cmi.core.total_time'))) { 00384 // Add session_time to total_time 00385 $value = scorm_add_time($track->value, $scormsession->sessiontime); 00386 $track->value = $value; 00387 $track->timemodified = time(); 00388 $DB->update_record('scorm_scoes_track', $track); 00389 } else { 00390 $track = new stdClass(); 00391 $track->userid = $aiccuser->id; 00392 $track->scormid = $scorm->id; 00393 $track->scoid = $sco->id; 00394 $track->element = 'cmi.core.total_time'; 00395 $track->value = $scormsession->sessiontime; 00396 $track->attempt = $attempt; 00397 $track->timemodified = time(); 00398 $id = $DB->insert_record('scorm_scoes_track', $track); 00399 } 00400 scorm_update_grades($scorm, $aiccuser->id); 00401 } 00402 $scormsession->scormstatus = 'Terminated'; 00403 $scormsession->session_time = ''; 00404 echo "error=0\r\nerror_text=Successful\r\n"; 00405 } else if ($status == 'Terminated') { 00406 echo "error=1\r\nerror_text=Terminated\r\n"; 00407 } else { 00408 echo "error=1\r\nerror_text=Not Initialized\r\n"; 00409 } 00410 break; 00411 default: 00412 echo "error=1\r\nerror_text=Invalid Command\r\n"; 00413 break; 00414 } 00415 } 00416 } else { 00417 if (empty($command)) { 00418 echo "error=1\r\nerror_text=Invalid Command\r\n"; 00419 } else { 00420 echo "error=3\r\nerror_text=Invalid Session ID\r\n"; 00421 } 00422 } 00423 if (empty($cfg_scorm->allowaicchacp)) { 00424 $SESSION->scorm = $scormsession; 00425 } else { 00426 $scormsession->timemodified = time(); 00427 $DB->update_record('scorm_aicc_session', $scormsession); 00428 } 00429 00430 $aiccresponse = ob_get_contents(); 00431 scorm_debug_log_write("aicc", "HACP Response:\r\n$aiccresponse", $scoid); 00432 ob_end_flush();