From 4ecf8438197061585641260bdce0d6cc4acb1193 Mon Sep 17 00:00:00 2001 From: piers Date: Mon, 21 Jul 2008 01:31:55 +0000 Subject: [PATCH] MDL-14455 also affects, MDL-11892, MDL-14485, and MDL-14486 - patches supplied by Martin Holden described in MDL-14455 (thank you!) applied to HEAD. --- mod/scorm/aicc.php | 134 ++++++++++++++++--------------- mod/scorm/datamodels/aicc.js.php | 40 +++++---- 2 files changed, 94 insertions(+), 80 deletions(-) diff --git a/mod/scorm/aicc.php b/mod/scorm/aicc.php index b1f6368cab..b5fedc234a 100755 --- a/mod/scorm/aicc.php +++ b/mod/scorm/aicc.php @@ -1,20 +1,29 @@ scorm_scoid)) { $scoid = $SESSION->scorm_scoid; } else { - print_error('cannotcallscript'); + error('Invalid script call'); } $mode = 'normal'; if (isset($SESSION->scorm_mode)) { @@ -31,14 +40,14 @@ } if ($sco = scorm_get_sco($scoid, SCO_ONLY)) { - if (!$scorm = $DB->get_record('scorm', array('id'=>$sco->scorm))) { - print_error('cannotcallscript'); + if (!$scorm = get_record('scorm','id',$sco->scorm)) { + error('Invalid script call'); } } else { - print_error('cannotcallscript'); + error('Invalid script call'); } - if ($scorm = $DB->get_record('scorm', array('id'=>$sco->scorm))) { + if ($scorm = get_record('scorm','id',$sco->scorm)) { switch ($command) { case 'getparam': if ($status == 'Not Initialized') { @@ -46,7 +55,7 @@ $status = 'Running'; } if ($status != 'Running') { - echo "error = 101\nerror_text = Terminated\n"; + echo "error=101\nerror_text=Terminated\n"; } else { if ($usertrack=scorm_get_tracks($scoid,$USER->id,$attempt)) { $userdata = $usertrack; @@ -61,16 +70,16 @@ $userdata->credit = 'credit'; } else { $userdata->credit = 'no-credit'; - } - + } + if ($sco = scorm_get_sco($scoid)) { $userdata->course_id = $sco->identifier; $userdata->datafromlms = isset($sco->datafromlms)?$sco->datafromlms:''; - $userdata->masteryscore = isset($sco->masteryscore)?$sco->masteryscore:''; - $userdata->maxtimeallowed = isset($sco->maxtimeallowed)?$sco->maxtimeallowed:''; - $userdata->timelimitaction = isset($sco->timelimitaction)?$sco->timelimitaction:''; - - echo "error = 0\nerror_text = Successful\naicc_data=\n"; + $userdata->mastery_score = isset($sco->mastery_score)?$sco->mastery_score:''; + $userdata->max_time_allowed = isset($sco->max_time_allowed)?$sco->max_time_allowed:''; + $userdata->time_limit_action = isset($sco->time_limit_action)?$sco->time_limit_action:''; + + echo "error=0\nerror_text=Successful\naicc_data="; echo "[Core]\n"; echo 'Student_ID = '.$userdata->student_id."\n"; echo 'Student_Name = '.$userdata->student_name."\n"; @@ -118,25 +127,25 @@ } echo 'Lesson_Mode = '.$userdata->mode."\n"; if (isset($userdata->{'cmi.suspend_data'})) { - echo "[Core_Lesson]\n".$userdata->{'cmi.suspend_data'}."\n"; + echo "[Core_Lesson]\n".rawurldecode($userdata->{'cmi.suspend_data'})."\n"; } else { echo "[Core_Lesson]\n"."\n"; } echo "[Core_Vendor]\n".$userdata->datafromlms."\n"; echo "[Evaluation]\nCourse_ID = {".$userdata->course_id."}\n"; echo "[Student_Data]\n"; - echo 'Mastery_Score = '.$userdata->masteryscore."\n"; - echo 'Max_Time_Allowed = '.$userdata->maxtimeallowed."\n"; - echo 'Time_Limit_Action = '.$userdata->timelimitaction."\n"; + echo 'Mastery_Score = '.$userdata->mastery_score."\n"; + echo 'Max_Time_Allowed = '.$userdata->max_time_allowed."\n"; + echo 'Time_Limit_Action = '.$userdata->time_limit_action."\n"; } else { - print_error('cannotfindsco', 'scorm'); + error('Sco not found'); } } break; case 'putparam': if ($status == 'Running') { if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $scorm->course)) { - echo "error = 1\nerror_text = Unknown\n"; // No one must see this error message if not hacked + echo "error=1\nerror_text=Unknown\n"; // No one must see this error message if not hacked } if (!empty($aiccdata) && has_capability('mod/scorm:savetrack', get_context_instance(CONTEXT_MODULE, $cm->id))) { $initlessonstatus = 'not attempted'; @@ -217,7 +226,7 @@ $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attempt, $subelement, $value); } } - + $value = ''; if (is_numeric($values[0])) { $value = trim($values[0]); @@ -238,9 +247,10 @@ $value .= $datarow; next($datarows); } + $value = rawurlencode(stripslashes($value)); $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attempt, $element, $value); } - } + } } if (($mode == 'browse') && ($initlessonstatus == 'not attempted')){ $lessonstatus = 'browsed'; @@ -248,109 +258,107 @@ } if ($mode == 'normal') { if ($lessonstatus == 'completed') { - if (!empty($sco->masteryscore) && !empty($score) && ($score >= $sco->masteryscore)) { - $lessonstatus = 'passed'; - } else { - $lessonstatus = 'failed'; + if ($sco = scorm_get_sco($scoid)) { + if (!empty($sco->mastery_score) && !empty($score) && ($score >= $sco->mastery_score)) { + $lessonstatus = 'passed'; + } else { + $lessonstatus = 'failed'; + } + $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attempt, 'cmi.core.lesson_status', $lessonstatus); } - $id = scorm_insert_track($USER->id, $scorm->id, $sco->id, $attempt, 'cmi.core.lesson_status', $lessonstatus); } - } + } } - echo "error = 0\nerror_text = Successful\n"; + echo "error=0\nerror_text=Successful\n"; } else if ($status == 'Terminated') { - echo "error = 1\nerror_text = Terminated\n"; + echo "error=1\nerror_text=Terminated\n"; } else { - echo "error = 1\nerror_text = Not Initialized\n"; + echo "error=1\nerror_text=Not Initialized\n"; } break; case 'putcomments': if ($status == 'Running') { - echo "error = 0\nerror_text = Successful\n"; + echo "error=0\nerror_text=Successful\n"; } else if ($status == 'Terminated') { - echo "error = 1\nerror_text = Terminated\n"; + echo "error=1\nerror_text=Terminated\n"; } else { - echo "error = 1\nerror_text = Not Initialized\n"; + echo "error=1\nerror_text=Not Initialized\n"; } break; case 'putinteractions': if ($status == 'Running') { - echo "error = 0\nerror_text = Successful\n"; + echo "error=0\nerror_text=Successful\n"; } else if ($status == 'Terminated') { - echo "error = 1\nerror_text = Terminated\n"; + echo "error=1\nerror_text=Terminated\n"; } else { - echo "error = 1\nerror_text = Not Initialized\n"; + echo "error=1\nerror_text=Not Initialized\n"; } break; case 'putobjectives': if ($status == 'Running') { - echo "error = 0\nerror_text = Successful\n"; + echo "error=0\nerror_text=Successful\n"; } else if ($status == 'Terminated') { - echo "error = 1\nerror_text = Terminated\n"; + echo "error=1\nerror_text=Terminated\n"; } else { - echo "error = 1\nerror_text = Not Initialized\n"; + echo "error=1\nerror_text=Not Initialized\n"; } break; case 'putpath': if ($status == 'Running') { - echo "error = 0\nerror_text = Successful\n"; + echo "error=0\nerror_text=Successful\n"; } else if ($status == 'Terminated') { - echo "error = 1\nerror_text = Terminated\n"; + echo "error=1\nerror_text=Terminated\n"; } else { - echo "error = 1\nerror_text = Not Initialized\n"; + echo "error=1\nerror_text=Not Initialized\n"; } break; case 'putperformance': if ($status == 'Running') { - echo "error = 0\nerror_text = Successful\n"; + echo "error=0\nerror_text=Successful\n"; } else if ($status == 'Terminated') { - echo "error = 1\nerror_text = Terminated\n"; + echo "error=1\nerror_text=Terminated\n"; } else { - echo "error = 1\nerror_text = Not Initialized\n"; + echo "error=1\nerror_text=Not Initialized\n"; } break; case 'exitau': if ($status == 'Running') { if (isset($SESSION->scorm_session_time) && ($SESSION->scorm_session_time != '')) { - if ($track = $DB->get_record('scorm_scoes_track', array('userid'=>$USER->id,'scormid'=>$scorm->id, 'scoid'=>$sco->id, 'element'=>'cmi.core.total_time'))) { - // Add session_time to total_time + if ($track = get_record_select('scorm_scoes_track',"userid='$USER->id' AND scormid='$scorm->id' AND scoid='$sco->id' AND element='cmi.core.total_time'")) { + // Add session_time to total_time $value = scorm_add_time($track->value, $SESSION->scorm_session_time); $track->value = $value; $track->timemodified = time(); - $DB->update_record('scorm_scoes_track',$track); - $id = $track->id; + $id = update_record('scorm_scoes_track',$track); } else { - $track = new object(); $track->userid = $USER->id; $track->scormid = $scorm->id; $track->scoid = $sco->id; $track->element = 'cmi.core.total_time'; $track->value = $SESSION->scorm_session_time; $track->timemodified = time(); - $id = $DB->insert_record('scorm_scoes_track',$track); + $id = insert_record('scorm_scoes_track',$track); } - scorm_update_grades($scorm, $USER->id); } - $SESSION->scorm_status = 'Terminated'; $SESSION->scorm_session_time = ''; - echo "error = 0\nerror_text = Successful\n"; + echo "error=0\nerror_text=Successful\n"; } else if ($status == 'Terminated') { - echo "error = 1\nerror_text = Terminated\n"; + echo "error=1\nerror_text=Terminated\n"; } else { - echo "error = 1\nerror_text = Not Initialized\n"; + echo "error=1\nerror_text=Not Initialized\n"; } break; default: - echo "error = 1\nerror_text = Invalid Command\n"; + echo "error=1\nerror_text=Invalid Command\n"; break; } } } else { if (empty($command)) { - echo "error = 1\nerror_text = Invalid Command\n"; + echo "error=1\nerror_text=Invalid Command\n"; } else { - echo "error = 3\nerror_text = Invalid Session ID\n"; + echo "error=3\nerror_text=Invalid Session ID\n"; } } -?> +?> \ No newline at end of file diff --git a/mod/scorm/datamodels/aicc.js.php b/mod/scorm/datamodels/aicc.js.php index dadb18626a..bc78c1801b 100644 --- a/mod/scorm/datamodels/aicc.js.php +++ b/mod/scorm/datamodels/aicc.js.php @@ -17,7 +17,6 @@ function AICCapi() { // Standard Data Type Definition CMIString256 = '^.{0,255}$'; - //CMIString4096 = '^[.|\\n|\\r]{0,4095}$'; CMIString4096 = '^.{0,4096}$'; CMITime = '^([0-2]{1}[0-9]{1}):([0-5]{1}[0-9]{1}):([0-5]{1}[0-9]{1})(\.[0-9]{1,2})?$'; CMITimespan = '^([0-9]{2,4}):([0-9]{2}):([0-9]{2})(\.[0-9]{1,2})?$'; @@ -27,6 +26,7 @@ function AICCapi() { CMIIdentifier = '^\\w{1,255}$'; CMIFeedback = CMIString256; // This must be redefined CMIIndex = '[._](\\d+).'; + // Vocabulary Data Type Definition CMIStatus = '^passed$|^completed$|^failed$|^incomplete$|^browsed$'; CMIStatus2 = '^passed$|^completed$|^failed$|^incomplete$|^browsed$|^not attempted$'; @@ -34,6 +34,7 @@ function AICCapi() { CMIType = '^true-false$|^choice$|^fill-in$|^matching$|^performance$|^sequencing$|^likert$|^numeric$'; CMIResult = '^correct$|^wrong$|^unanticipated$|^neutral$|^([0-9]{0,3})?(\.[0-9]{1,2})?$'; NAVEvent = '^previous$|^continue$'; + // Children lists cmi_children = 'core, suspend_data, launch_data, comments, objectives, student_data, student_preference, interactions'; core_children = 'student_id, student_name, lesson_location, credit, lesson_status, entry, score, total_time, lesson_mode, exit, session_time'; @@ -43,12 +44,14 @@ function AICCapi() { student_data_children = 'attempt_number, tries, mastery_score, max_time_allowed, time_limit_action'; student_preference_children = 'audio, language, speed, text'; interactions_children = 'id, objectives, time, type, correct_responses, weighting, student_response, result, latency'; + // Data ranges score_range = '0#100'; audio_range = '-1#100'; speed_range = '-100#100'; weighting_range = '-100#100'; text_range = '-1#1'; + // The AICC data model var datamodel = { 'cmi._children':{'defaultvalue':cmi_children, 'mod':'r', 'writeerror':'402'}, @@ -57,7 +60,7 @@ function AICCapi() { 'cmi.core.student_id':{'defaultvalue':'student_id ?>', 'mod':'r', 'writeerror':'403'}, 'cmi.core.student_name':{'defaultvalue':'student_name ?>', 'mod':'r', 'writeerror':'403'}, 'cmi.core.lesson_location':{'defaultvalue':'{'cmi.core.lesson_location'})?$userdata->{'cmi.core.lesson_location'}:'' ?>', 'format':CMIString256, 'mod':'rw', 'writeerror':'405'}, - 'cmi.core.credit':{'defaultvalue':'credit ?>', 'mod':'r', 'writeerror':'403'}, + 'cmi.core.credit':{'defaultvalue':'credit ?>', 'mod':'r', 'writeerror':'403'}, 'cmi.core.lesson_status':{'defaultvalue':'{'cmi.core.lesson_status'})?$userdata->{'cmi.core.lesson_status'}:'' ?>', 'format':CMIStatus, 'mod':'rw', 'writeerror':'405'}, 'cmi.core.exit':{'defaultvalue':'{'cmi.core.exit'})?$userdata->{'cmi.core.exit'}:'' ?>', 'format':CMIExit, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'cmi.core.entry':{'defaultvalue':'entry ?>', 'mod':'r', 'writeerror':'403'}, @@ -92,9 +95,9 @@ function AICCapi() { 'cmi.student_data.tries.n.score.max':{'defaultvalue':'', 'pattern':CMIIndex, 'format':CMIDecimal, 'range':score_range, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.tries.n.status':{'pattern':CMIIndex, 'format':CMIStatus2, 'mod':'rw', 'writeerror':'405'}, 'cmi.student_data.tries.n.time':{'pattern':CMIIndex, 'format':CMITime, 'mod':'rw', 'writeerror':'405'}, - 'cmi.student_data.mastery_score':{'defaultvalue':'masteryscore)?$userdata->masteryscore:'' ?>', 'mod':'r', 'writeerror':'403'}, - 'cmi.student_data.max_time_allowed':{'defaultvalue':'maxtimeallowed)?$userdata->maxtimeallowed:'' ?>', 'mod':'r', 'writeerror':'403'}, - 'cmi.student_data.time_limit_action':{'defaultvalue':'timelimitaction)?$userdata->timelimitaction:'' ?>', 'mod':'r', 'writeerror':'403'}, + 'cmi.student_data.mastery_score':{'defaultvalue':'mastery_score)?$userdata->mastery_score:'' ?>', 'mod':'r', 'writeerror':'403'}, + 'cmi.student_data.max_time_allowed':{'defaultvalue':'max_time_allowed)?$userdata->max_time_allowed:'' ?>', 'mod':'r', 'writeerror':'403'}, + 'cmi.student_data.time_limit_action':{'defaultvalue':'time_limit_action)?$userdata->time_limit_action:'' ?>', 'mod':'r', 'writeerror':'403'}, 'cmi.student_data.tries_during_lesson':{'defaultvalue':'{'cmi.student_data.tries_during_lesson'})?$userdata->{'cmi.student_data.tries_during_lesson'}:'' ?>', 'mod':'r', 'writeerror':'402'}, 'cmi.student_preference._children':{'defaultvalue':student_preference_children, 'mod':'r', 'writeerror':'402'}, 'cmi.student_preference.audio':{'defaultvalue':'0', 'format':CMISInteger, 'range':audio_range, 'mod':'rw', 'writeerror':'405'}, @@ -116,6 +119,7 @@ function AICCapi() { 'cmi.interactions.n.latency':{'pattern':CMIIndex, 'format':CMITimespan, 'mod':'w', 'readerror':'404', 'writeerror':'405'}, 'nav.event':{'defaultvalue':'', 'format':NAVEvent, 'mod':'w', 'readerror':'404', 'writeerror':'405'} }; + // // Datamodel inizialization // @@ -126,6 +130,8 @@ function AICCapi() { cmi.student_data = new Object(); cmi.student_preference = new Object(); cmi.interactions = new Object(); + cmi.evaluation = new Object(); + cmi.evaluation.comments = new Object(); // Navigation Object var nav = new Object(); @@ -168,8 +174,8 @@ function AICCapi() { if (cmi.core.lesson_status == '') { cmi.core.lesson_status = 'not attempted'; - } - + } + // // API Methods definition // @@ -190,7 +196,7 @@ function AICCapi() { } return "false"; } - + function LMSFinish (param) { errorCode = "0"; if (param == "") { @@ -207,7 +213,7 @@ function AICCapi() { if (auto ?> == 1) { setTimeout('top.nextSCO();',500); } - } + } return "true"; } else { errorCode = "301"; @@ -217,7 +223,7 @@ function AICCapi() { } return "false"; } - + function LMSGetValue (element) { errorCode = "0"; if (Initialized) { @@ -233,7 +239,7 @@ function AICCapi() { while ((i < elementIndexes.length) && (typeof eval(subelement) != "undefined")) { subelement += '.'+elementIndexes[i++]; } - if (subelement == element) { + if (subelement == element) { errorCode = "0"; return eval(element); } else { @@ -271,7 +277,7 @@ function AICCapi() { } return ""; } - + function LMSSetValue (element,value) { errorCode = "0"; if (Initialized) { @@ -297,7 +303,7 @@ function AICCapi() { } if (elementIndexes[i+1] == eval(subelement+'.'+elementIndex+'._count')) { eval(subelement+'.'+elementIndex+'._count++;'); - } + } if (elementIndexes[i+1] > eval(subelement+'.'+elementIndex+'._count')) { errorCode = "201"; } @@ -365,7 +371,7 @@ function AICCapi() { } return "false"; } - + function LMSCommit (param) { errorCode = "0"; if (param == "") { @@ -380,11 +386,11 @@ function AICCapi() { } return "false"; } - + function LMSGetLastError () { return errorCode; } - + function LMSGetErrorString (param) { if (param != "") { var errorString = new Array(); @@ -404,7 +410,7 @@ function AICCapi() { return ""; } } - + function LMSGetDiagnostic (param) { if (param == "") { param = errorCode; -- 2.39.5