From: bobopinna Date: Tue, 16 Jan 2007 14:03:15 +0000 (+0000) Subject: new sequencing engine X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=10fd330f3818da380ad4c131c55ce22fba706f94;p=moodle.git new sequencing engine --- diff --git a/mod/scorm/datamodels/scorm_13lib.php b/mod/scorm/datamodels/scorm_13lib.php index 852e37c5f1..3a77170beb 100644 --- a/mod/scorm/datamodels/scorm_13lib.php +++ b/mod/scorm/datamodels/scorm_13lib.php @@ -1,318 +1,4 @@ elements[$manifest][$parent->organization][$parent->identifier]->choice = 0; - } - if ($sequencing['attrs']['CHOICEEXIT'] == 'false') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->choiceexit = 0; - } - if ($sequencing['attrs']['FLOW'] == 'true') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->flow = 1; - } - if ($sequencing['attrs']['FORWARDONLY'] == 'true') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->forwardonly = 1; - } - if ($sequencing['attrs']['USECURRENTATTEMPTOBJECTINFO'] == 'true') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptobjectinfo = 1; - } - if ($sequencing['attrs']['USECURRENTATTEMPTPROGRESSINFO'] == 'true') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->usecurrentattemptprogressinfo = 1; - } - } - if ($sequencing['name']=='ADLSEQ:CONSTRAINEDCHOICECONSIDERATIONS') { - if ($sequencing['attrs']['CONSTRAINCHOICE'] == 'true') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->constrainChoice = 1; - } - if ($sequencing['attrs']['PREVENTACTIVATION'] == 'true') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->preventactivation = 1; - } - - } - if ($sequencing['name']=='IMSSS:OBJECTIVES') { - foreach ($sequencing['children'] as $objective) { - if ($objective['name']=='IMSSS:PRIMARYOBJECTIVE') { - foreach ($objective['children'] as $primaryobjective) { - if ($primaryobjective['name']=='IMSSS:MINNORMALIZEDMEASURE') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->minnormalizedmeasure = $primaryobjective['tagData']; - } - } - } - } - } - if ($sequencing['name']=='IMSSS:LIMITCONDITIONS') { - if (!empty($sequencing['attrs']['ATTEMPTLIMIT'])) { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptLimit = $sequencing['attrs']['ATTEMPTLIMIT']; - } - if (!empty($sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT'])) { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->attemptAbsoluteDurationLimit = $sequencing['attrs']['ATTEMPTABSOLUTEDURATIONLIMIT']; - } - } - if ($sequencing['name']=='IMSSS:ROLLUPRULES') { - $rolluprules = array(); - if (!empty($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED'])) { - if ($sequencing['attrs']['ROLLUPOBJECTIVESATISFIED']== 'false') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupobjectivesatisfied = 0; - } - } - if (!empty($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION'])) { - if ($sequencing['attrs']['ROLLUPPROGRESSCOMPLETION']== 'false') { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rollupprogresscompletion = 0; - } - } - if (!empty($sequencing['attrs']['OBJECTIVEMEASUREWEIGHT'])) { - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->objectivemeasureweight = $sequencing['attrs']['OBJECTIVEMEASUREWEIGHT']; - } - - if (!empty($sequencing['children'])){ - foreach ($sequencing['children'] as $sequencingrolluprule) { - if ($sequencingrolluprule['name']=='IMSSS:ROLLUPRULE' ) { - $rolluprule = new stdClass(); - if ($sequencingrolluprule['attrs']['CHILDACTIVITYSET'] !=' ') { - $rolluprule->childactivityset = $sequencingrolluprule['attrs']['CHILDACTIVITYSET']; - if (!empty($sequencingrolluprule['children'])) { - foreach ($sequencingrolluprule['children'] as $rolluproleconditions) { - if ($rolluproleconditions['name']=='IMSSS:ROLLUPCONDITIONS') { - $conditions = array(); - if (!empty($rolluproleconditions['attrs']['conditionCombination'])) { - $rolluprule->conditionCombination = $rolluproleconditions['attrs']['conditionCombination']; - } - foreach ($rolluproleconditions['children'] as $rolluprulecondition) { - if ($rolluprulecondition['name']=='IMSSS:ROLLUPCONDITION') { - $condition = new stdClass(); - if (!empty($rolluprulecondition['attrs']['OPERATOR'])) { - $condition->operator = $rolluprulecondition['attrs']['OPERATOR']; - } - if (!empty($rolluprulecondition['attrs']['CONDITION'])) { - $condition->condition = $rolluprulecondition['attrs']['CONDITION']; - } - array_push($conditions,$condition); - } - } - $rolluprule->conditions = $conditions; - } - if ($rolluproleconditions['name']=='IMSSS:ROLLUPACTION') { - $rolluprule->rollupruleaction = $rolluproleconditions['attrs']['ACTION']; - } - } - } - } - array_push($rolluprules, $rolluprule); - } - } - } - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->rolluprules = $rolluprules; - } - - if ($sequencing['name']=='IMSSS:SEQUENCINGRULES') { - $sequencingrules = array(); - foreach ($sequencing['children'] as $conditionrules) { - if ($conditionrules['name']=='IMSSS:EXITCONDITIONRULE') { - $sequencingrule = new stdClass(); - if (!empty($conditionrules['children'])) { - foreach ($conditionrules['children'] as $conditionrule) { - if ($conditionrule['name']=='IMSSS:RULECONDITIONS') { - $ruleconditions = array(); - if (!empty($conditionrule['attrs']['conditionCombination'])) { - $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination']; - } - foreach ($conditionrule['children'] as $rulecondition) { - if ($rulecondition['name']=='IMSSS:RULECONDITION') { - $condition = new stdClass(); - if (!empty($rulecondition['attrs']['OPERATOR'])) { - $condition->operator = $rulecondition['attrs']['OPERATOR']; - } - if (!empty($rulecondition['attrs']['CONDITION'])) { - $condition->condition = $rulecondition['attrs']['CONDITION']; - } - if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])) { - $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD']; - } - if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])) { - $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE']; - } - array_push($ruleconditions,$condition); - } - } - $sequencingrule->ruleconditions = $ruleconditions; - } - if ($conditionrule['name']=='IMSSS:RULEACTION') { - $sequencingrule->exitconditionruleaction = $conditionrule['attrs']['ACTION']; - } - } - } - array_push($sequencingrules,$sequencingrule); - } - if ($conditionrules['name']=='IMSSS:PRECONDITIONRULE') { - $sequencingrule = new stdClass(); - if (!empty($conditionrules['children'])) { - foreach ($conditionrules['children'] as $conditionrule) { - if ($conditionrule['name']=='IMSSS:RULECONDITIONS') { - $ruleconditions = array(); - if (!empty($conditionrule['attrs']['conditionCombination'])) { - $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination']; - } - foreach ($conditionrule['children'] as $rulecondition) { - if ($rulecondition['name']=='IMSSS:RULECONDITION') { - $condition = new stdClass(); - if (!empty($rulecondition['attrs']['OPERATOR'])) { - $condition->operator = $rulecondition['attrs']['OPERATOR']; - } - if (!empty($rulecondition['attrs']['CONDITION'])) { - $condition->condition = $rulecondition['attrs']['CONDITION']; - } - if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])) { - $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD']; - } - if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])) { - $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE']; - } - array_push($ruleconditions,$condition); - } - } - $sequencingrule->ruleconditions = $ruleconditions; - } - if ($conditionrule['name']=='IMSSS:RULEACTION') { - $sequencingrule->preconditionruleaction = $conditionrule['attrs']['ACTION']; - } - } - } - array_push($sequencingrules,$sequencingrule); - } - if ($conditionrules['name']=='IMSSS:POSTCONDITIONRULE') { - $sequencingrule = new stdClass(); - if (!empty($conditionrules['children'])) { - foreach ($conditionrules['children'] as $conditionrule) { - if ($conditionrule['name']=='IMSSS:RULECONDITIONS'){ - $ruleconditions = array(); - if (!empty($conditionrule['attrs']['conditionCombination'])){ - $sequencingrule->conditionCombination = $conditionrule['attrs']['conditionCombination']; - } - foreach ($conditionrule['children'] as $rulecondition){ - if ($rulecondition['name']=='IMSSS:RULECONDITION'){ - $condition = new stdClass(); - if (!empty($rulecondition['attrs']['OPERATOR'])){ - $condition->operator = $rulecondition['attrs']['OPERATOR']; - } - if (!empty($rulecondition['attrs']['CONDITION'])){ - $condition->condition = $rulecondition['attrs']['CONDITION']; - } - if (!empty($rulecondition['attrs']['MEASURETHRESHOLD'])){ - $condition->measurethreshold = $rulecondition['attrs']['MEASURETHRESHOLD']; - } - if (!empty($rulecondition['attrs']['REFERENCEDOBJECTIVE'])){ - $condition->referencedobjective = $rulecondition['attrs']['REFERENCEDOBJECTIVE']; - } - array_push($ruleconditions,$condition); - } - } - $sequencingrule->ruleconditions = $ruleconditions; - } - if ($conditionrule['name']=='IMSSS:RULEACTION'){ - $sequencingrule->postconditionruleaction = $conditionrule['attrs']['ACTION']; - } - } - } - array_push($sequencingrules,$sequencingrule); - } - $scoes->elements[$manifest][$parent->organization][$parent->identifier]->sequencingrules = $sequencingrules; - } - } - } - break; -*/ - -function scorm_parse_scorm($pkgdir,$scormid) { - global $CFG; - - $launch = 0; - $manifestfile = $pkgdir.'/imsmanifest.xml'; - - if (is_file($manifestfile)) { - - $xmlstring = file_get_contents($manifestfile); - $objXML = new xml2Array(); - $manifests = $objXML->parse($xmlstring); - // print_r($manifests); - $scoes = new stdClass(); - $scoes->version = ''; - $scoes = scorm_get_manifest($manifests,$scoes); - - if (count($scoes->elements) > 0) { - $olditems = get_records('scorm_scoes','scorm',$scormid); - foreach ($scoes->elements as $manifest => $organizations) { - foreach ($organizations as $organization => $items) { - foreach ($items as $identifier => $item) { - $item->scorm = $scormid; - $item->manifest = $manifest; - $item->organization = $organization; - if ($olditemid = scorm_array_search('identifier',$item->identifier,$olditems)) { - $item->id = $olditemid; - $id = update_record('scorm_scoes',$item); - unset($olditems[$olditemid]); - } else { - $id = insert_record('scorm_scoes',$item); - } - // Added by Pham Minh Duc - $item->scormid = $scormid; - $item->scoid = $id; - $idControlMode = insert_record('scorm_sequencing_controlmode',$item); - - if (!empty($item->sequencingrules)) { - foreach($item->sequencingrules as $sequencingrule) { - $sequencingrule->scormid = $scormid; - $sequencingrule->scoid = $item->scoid; - $idruleconditions = insert_record('scorm_sequencing_ruleconditions',$sequencingrule); - foreach($sequencingrule->ruleconditions as $rulecondition) { - $rulecondition->scormid = $sequencingrule->scormid; - $rulecondition->scoid = $sequencingrule->scoid; - $rulecondition->ruleconditionsid = $idruleconditions; - $idrulecondition = insert_record('scorm_sequencing_rulecondition',$rulecondition); - } - } - } - - if (!empty($item->rolluprules)) { - $idControlMode = insert_record('scorm_sequencing_rolluprules',$item); - foreach($item->rolluprules as $rollup) { - $rollup->rolluprulesid =$idControlMode; - $rollup->scormid = $scormid; - $rollup->scoid = $item->scoid; - - $idRollupRule = insert_record('scorm_sequencing_rolluprule',$rollup); - $rollup->rollupruleid = $idRollupRule; - $idconditions = insert_record('scorm_sequencing_rollupruleconditions',$rollup); - foreach($rollup->conditions as $condition){ - $condition->ruleconditionsid = $idconditions; - $condition->scormid = $rollup->scormid; - $condition->scoid = $rollup->scoid; - $idcondition = insert_record('scorm_sequencing_rolluprulecondition',$condition); - } - } - } - // End Add - if (($launch == 0) && ((empty($scoes->defaultorg)) || ($scoes->defaultorg == $identifier))) { - $launch = $id; - } - } - } - } - if (!empty($olditems)) { - foreach($olditems as $olditem) { - delete_records('scorm_scoes','id',$olditem->id); - delete_records('scorm_scoes_track','scoid',$olditem->id); - } - } - set_field('scorm','version',$scoes->version,'id',$scormid); - } - } - - return $launch; -} function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='normal',$attempt='',$play=false) { global $CFG; @@ -353,11 +39,8 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n // Retrieve user tracking data for each learning object // - // Added by Pham Minh Duc - // $suspendedscoid = scorm_get_suspendedscoid($scorm->id,$user->id,$attempt); - // End add - $usertracks = array(); + $optionaldatas = array(); foreach ($scoes as $sco) { if (!empty($sco->launch)) { if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) { @@ -366,6 +49,9 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n } $usertracks[$sco->identifier] = $usertrack; } + if ($optionaldata = scorm_get_sco($sco->id, SCO_DATA)) { + $optionaldatas[$sco->identifier] = $optionaldata; + } } } @@ -377,8 +63,9 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n $parents[$level]='/'; foreach ($scoes as $sco) { $isvisible = false; - if ($optionaldatas = scorm_get_sco($sco->id, SCO_DATA)) { - if (!isset($optionaldatas->isvisible) || (isset($optionaldatas->isvisible) && ($optionaldatas->isvisible == 'true'))) { + if (isset($optionaldatas[$sco->identifier])) { + if (!isset($optionaldatas[$sco->identifier]->isvisible) || + (isset($optionaldatas[$sco->identifier]->isvisible) && ($optionaldatas[$sco->identifier]->isvisible == 'true'))) { $isvisible = true; } } @@ -414,18 +101,21 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n } $nextsco = next($scoes); $nextisvisible = false; - if (($nextsco !== false) && ($optionaldatas = scorm_get_sco($nextsco->id, SCO_DATA))) { - if (!isset($optionaldatas->isvisible) || (isset($optionaldatas->isvisible) && ($optionaldatas->isvisible == 'true'))) { + if (($nextsco !== false) && (isset($optionaldatas[$nextsco->identifier]))) { + if (!isset($optionaldatas[$nextsco->identifier]->isvisible) || + (isset($optionaldatas[$nextsco->identifier]->isvisible) && ($optionaldatas[$nextsco->identifier]->isvisible == 'true'))) { $nextisvisible = true; } } - if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) { + if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && + (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) { $sublist++; $icon = 'minus'; if (isset($_COOKIE['hide:SCORMitem'.$nextsco->id])) { $icon = 'plus'; } - $result->toc .= ''.$strexpand.''; + $result->toc .= ''. + ''.$strexpand.''; } else if ($isvisible) { $result->toc .= ''; } @@ -478,8 +168,8 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n $startbold = ''; $endbold = ''; $findnext = true; - $shownext = $sco->next; - $showprev = $sco->previous; + $shownext = isset($optionaldatas[$sco->identifier]->next) ? $optionaldatas[$sco->identifier]->next : 0; + $showprev = isset($optionaldatas[$sco->identifier]->prev) ? $optionaldatas[$sco->identifier]->prev : 0; } if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) { @@ -487,20 +177,14 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n $previd = $sco->id; } } - if (empty($sco->prerequisites) || scorm_eval_prerequisites($sco->prerequisites,$usertracks)) { + require_once('sequencinglib.php'); + if (scorm_seq_evaluate($sco->id,$usertracks)) { if ($sco->id == $scoid) { $result->prerequisites = true; } - // Modified by Pham Minh Duc - // if (scorm_isChoice($scorm->id,$sco->id) == 1) { $url = $CFG->wwwroot.'/mod/scorm/player.php?a='.$scorm->id.'&currentorg='.$currentorg.$modestr.'&scoid='.$sco->id; $result->toc .= $statusicon.' '.$startbold.''.format_string($sco->title).''.$score.$endbold."\n"; $tocmenus[$sco->id] = scorm_repeater('−',$level) . '>' . format_string($sco->title); - // } else { - // $result->toc .= ' '.$startbold.format_string($sco->title).$score.$endbold."\n"; - // $tocmenus[$sco->id] = scorm_repeater('−',$level) . '>' . format_string($sco->title); - // } - // End modify } else { if ($sco->id == $scoid) { $result->prerequisites = false; @@ -562,168 +246,4 @@ function scorm_get_toc($user,$scorm,$liststyle,$currentorg='',$scoid='',$mode='n return $result; } -// -// Functions added by Pham Minh Duc -// -function scorm_get_score_from_parent($sco,$userid,$grademethod=VALUESCOES) { - $scores = NULL; - $scores->scoes = 0; - $scores->values = 0; - $scores->scaled = 0; - $scores->max = 0; - $scores->sum = 0; - - $scoes_total = 0; - $scoes_count = 0; - $attempt = scorm_get_last_attempt($sco->scorm, $userid); - $scoes = get_records('scorm_scoes', 'parent', $sco->identifier); - foreach ($scoes as $sco) - { - $scoes_total++; - if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) { - if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) { - $scoes_count++; - } - - $scoreraw = $userdata->score_raw; - if (!empty($userdata->score_raw)) { - $scores->values++; - $scores->sum += $userdata->score_raw; - $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max; - } - if (!empty($userdata->score_scaled)) { - $scores->scaled = $scores->scaled + $userdata->score_scaled; - } - } - } - if ($scoes_count > 0) { - $scores->scaled = ($scores->scaled)/($scoes_count); - } - switch ($grademethod) { - case VALUEHIGHEST: - return $scores->max; - break; - case VALUEAVERAGE: - if ($scores->values > 0) { - return $scores->sum/$scores->values; - } else { - return 0; - } - break; - case VALUESUM: - return $scores->sum; - break; - case VALUESCOES: - return $scores->scaled; - break; - } -} - -function scorm_get_user_sco_count($scormid, $userid) { - $scoes_count = 0; - $attempt = scorm_get_last_attempt($current->scorm, $userid); - $scoes = get_records('scorm_scoes', 'scorm', $scormid); - - foreach ($scoes as $sco) { - if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) { - if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) { - $scoes_count++; - } - } - } - return $scoes_count; -} - -function scorm_grade_user_new($scoes, $userid, $grademethod=VALUESCOES) { - $scores = NULL; - $scores->scoes = 0; - $scores->values = 0; - $scores->scaled = 0; - $scores->max = 0; - $scores->sum = 0; - - if (!$scoes) { - return ''; - } - $current = current($scoes); - $attempt = scorm_get_last_attempt($current->scorm, $userid); - foreach ($scoes as $sco) { - if ($userdata=scorm_get_tracks($sco->id, $userid,$attempt)) { - if (($userdata->status == 'completed') || ($userdata->success_status == 'passed')) { - $scores->scoes++; - } - $scaled = $userdata->score_scaled; - $scoreraw = $userdata->score_raw; - if ($scaled ==0){ - $scores->scaled = $scores->scaled / $scores->scoes; - } - if (!empty($userdata->score_raw)) { - $scores->values++; - $scores->sum += $userdata->score_raw; - $scores->max = ($userdata->score_raw > $scores->max)?$userdata->score_raw:$scores->max; - } - if (!empty($scaled)) { - $scores->scaled = (($scores->scaled) * ($scores->scoes-1) + $scaled)/($scores->scoes); - } - } - } - switch ($grademethod) { - case VALUEHIGHEST: - return $scores->max; - break; - case VALUEAVERAGE: - if ($scores->values > 0) { - return $scores->sum/$scores->values; - } else { - return 0; - } - break; - case VALUESUM: - return $scores->sum; - break; - case VALUESCOES: - return $scores->scaled; - break; - } -} - -function scorm_get_suspendedscoid($scormid,$userid,$attempt) { - if ($sco = get_record_select("scorm_scoes_track","scormid=$scormid AND userid=$userid AND attempt=$attempt AND (element='cmi.exit' OR element='cmi.core.exit') AND value='suspend'")) { - return $sco->scoid; - } else { - return 0; - } -} - -function scorm_set_attempt($scoid,$userid) { - if ($scormid = get_field('scorm_scoes','scorm','id',$scoid)) { - $attempt = scorm_get_last_attempt($scormid,$userid); - } else { - $attempt = 1; - } - $scormtype = get_field('scorm_scoes','scormtype','id',$scoid) ; - if ($scormtype == 'sco'){ - $element = 'cmi.attempt_status'; - $value = 'attempted'; - scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value); - } -} - -function scorm_isChoice($scormid,$scoid) -{ - $sco = get_record("scorm_scoes","id",$scoid); - $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent); - - return $scoparent->choice; -} - -function scorm_isChoiceexit($scormid,$scoid) -{ - $sco = get_record("scorm_scoes","id",$scoid); - $scoparent = get_record("scorm_sequencing_controlmode","scormid",$scormid,"identifier",$sco->parent); - - return $scoparent->choiceexit; -} -// End add - ?> diff --git a/mod/scorm/datamodels/scormlib.php b/mod/scorm/datamodels/scormlib.php index 955ed611ab..13adc61242 100644 --- a/mod/scorm/datamodels/scormlib.php +++ b/mod/scorm/datamodels/scormlib.php @@ -621,6 +621,57 @@ function scorm_optionals_data($item, $standarddata) { return $result; } +function scorm_is_leaf($sco) { + if (get_record('scorm_scoes','scorm',$sco->scorm,'parent',$sco->identifier)) { + return false; + } + return true; +} + +function scorm_get_parent($sco) { + if ($sco->parent != '/') { + if ($parent = get_record('scorm_scoes','scorm',$sco->scorm,'identifier',$sco->parent)) { + return scorm_get_sco($parent->id); + } + } + return null; +} + +function scorm_get_children($sco) { + if ($parent = get_records('scorm_scoes','scorm',$sco->scorm,'parent',$sco->identifier)) { + return $children; + } + return null; +} + +function scorm_get_sibling($sco) { + if ($siblings = get_records('scorm_scoes','scorm',$sco->scorm,'parent',$sco->parent)) { + unset($siblings[$sco->id]); + if (!empty($siblings)) { + return $siblings; + } + } + return null; +} + +function scorm_get_ancestors($sco) { + if ($sco->parent != '/') { + return array_push(scorm_get_ancestors(scorm_get_parent($sco))); + } else { + return $sco; + } +} + +function scorm_find_common_ancestor($ancestors, $sco) { + $pos = scorm_array_search('identifier',$sco->parent,$ancestors); + if ($sco->parent != '/') { + if ($pos === false) { + return scorm_find_common_ancestor($ancestors,scorm_get_parent($sco)); + } + } + return $pos; +} + /* Usage Grab some XML data, either from a file, URL, etc. however you want. Assume storage in $strYourXML; diff --git a/mod/scorm/datamodels/sequencinglib.php b/mod/scorm/datamodels/sequencinglib.php index b9547025ab..96ac3cb983 100755 --- a/mod/scorm/datamodels/sequencinglib.php +++ b/mod/scorm/datamodels/sequencinglib.php @@ -1,513 +1,386 @@ ->>>> SCO goi Rollup la ".$scoidchild); - $scochild = get_record("scorm_scoes","id",$scoidchild); - $scoparent = get_record("scorm_scoes","scorm",$scormid,"identifier",$scochild->parent); - //Danh sach cac con cua cha - $scochildren = get_records_select("scorm_scoes","scorm =".$scormid." and parent ='".$scoparent->identifier."'"); - //Lay gia tri last attempt - //fwrite($ft,"\n >>>>> Bat dau xu ly Rollup SCO cha ".$scoparent->id); - $attempt = scorm_get_last_attempt($scormid,$userid); - - if(!empty($scoparent)){ - $scoid = $scoparent->id; - $rolluprules = get_record("scorm_sequencing_rolluprules","scormid",$scormid,"scoid",$scoid); - if (!empty($rolluprules)){ - $idrolluprules = $rolluprules->id; - $rules = get_records_select('scorm_sequencing_rolluprule','scoid ='.$scoid.' and rolluprulesid ='. $idrolluprules); - - foreach ($rules as $rule){ - $ruleid = $rule->id; - $ruleConditions = get_record("scorm_sequencing_rollupruleconditions","scoid",$scoid,"rollupruleid",$ruleid); - $idruleConditions = $ruleConditions->id; - $conditions = get_records_select('scorm_sequencing_rolluprulecondition','scoid ='.$scoid.' and ruleconditionsid ='.$idruleConditions); - - //Truong hop 1: childactivitySet = all - // conditioncombination = any - if (($rule->childactivityset == 'all') && ($ruleConditions->conditioncombination=='any')){ - foreach($conditions as $condition){ - $conditionOK = false; - //Condition 1: condition = attempted operator = 'noOp' - // Thuc hien rollupaction - if (($condition->condition == 'attempted') && ($condition->operator=='noOp')){ - $conditionOK = true; - foreach ($scochildren as $sco){ - //fwrite($ft,"\n >>>>> Xu ly Rollup voi dieu kien attempt \n"); - $usertrack = scorm_get_tracks($sco->id,$userid); - if ($usertrack->attempt_status != 'attempted'){ - //fwrite($ft,"\n >>>>> Co SCO con chua attempted \n"); - $conditionOK = false; - } - } - } - //Condition 2: condition = attempted operator = 'not' - // Thuc hien rollupaction - if (($condition->condition == 'attempted') && ($condition->operator=='not')){ - $conditionOK = true; - foreach ($scochildren as $sco){ - //fwrite($ft,"\n >>>>> Xu ly Rollup voi dieu kien not attempt \n"); - $usertrack = scorm_get_tracks($sco->id,$userid); - if ($usertrack->attempt_status != 'notattempted'){ - $conditionOK = false; - } - } - } - //Condition 3: condition = satisfied operator = 'noOp' - // Thuc hien rollupaction - if (($condition->condition == 'satisfied') && ($condition->operator=='noOp')){ - $conditionOK = true; - foreach ($scochildren as $sco){ - $usertrack = scorm_get_tracks($sco->id,$userid); - if ($usertrack->satisfied_status != 'satisfied'){ - $conditionOK = false; - } - } - } - //Condition 4: condition = satisfied operator = 'not' - // Thuc hien rollupaction - if (($condition->condition == 'satisfied') && ($condition->operator=='not')){ - $conditionOK = true; - foreach ($scochildren as $sco){ - $usertrack = scorm_get_tracks($sco->id,$userid); - if ($usertrack->satisfied_status != 'notSatisfied'){ - $conditionOK = false; - } - } - } - //Condition 5: condition = completed operator = 'noOp' - // Thuc hien rollupaction - if (($condition->condition == 'completed') && ($condition->operator=='noOp')){ - $conditionOK = true; - foreach ($scochildren as $sco){ - $usertrack = scorm_get_tracks($sco->id,$userid); - if ($usertrack->attempt_status != 'completed'){ - $conditionOK = false; - } - } - } - //Condition 6: condition = completed operator = 'not' - // Thuc hien rollupaction - if (($condition->condition == 'completed') && ($condition->operator=='not')){ - $conditionOK = true; - foreach ($scochildren as $sco){ - $usertrack = scorm_get_tracks($sco->id,$userid); - if ($usertrack->attempt_status != 'notcompleted'){ - $conditionOK = false; - } - } - } - //Neu dieu kien van dung sau khi xem xet thi thuc hien action - if ($conditionOK == true){ - if ($ruleConditions->rollupruleaction == 'completed') - { - scorm_insert_track($userid,$scormid,$scoid,$attempt,'cmi.completion_status','completed'); - //fwrite($ft,"\n >>>>> Xu ly Rollup thanh cong voi completed cho SCO ".$scoid); - } - if ($ruleConditions->rollupruleaction == 'satisfied') - { - scorm_insert_track($userid,$scormid,$scoid,$attempt,'cmi.success_status','passed'); - //fwrite($ft,"\n >>>>> Xu ly Rollup thanh cong voi satisfied\n"); - } - if ($ruleConditions->rollupruleaction == 'notSatisfied') - { - scorm_insert_track($userid,$scormid,$scoid,$attempt,'cmi.success_status','failed'); - //fwrite($ft,"\n >>>>> Xu ly Rollup thanh cong voi notSatisfied\n"); - } - //echo ""; - $sequencingResult->rule = 'exit'; - $sequencingResult->action = 'exit'; - } - if ($sequencingrule->preconditionruleaction=='disabled') - { - //fwrite($ft,"\n >>>>> Xu ly Sequencing thanh cong -- Thuc hien su kien disable \n"); - echo ""; - $sequencingResult->rule = 'pre'; - $sequencingResult->action = 'disable'; - - } - - } - } - } - } - return $sequencingResult; -} -function get_sco_after_exit($scoid,$scormid){ - $scochild = get_record("scorm_scoes","id",$scoid); - $scoparent = get_record("scorm_scoes","scorm",$scormid,"identifier",$scochild->parent); - $exitscoid = $scoid++; - $exitscochild = get_record("scorm_scoes","id",$exitscoid,"scorm",$scormid); - if (empty($exitscochild)){ - //Da ra ngoai vung scoid. Hay day chinh la sco cuoi cung - return 0; - } - else{ - $exitscoparent = get_record("scorm_scoes","scorm",$scormid,"identifier",$exitscochild->parent); - //Neu chua ra khoi activity do thi tiep tuc - while ($exitscoparent->id == $scoparent->id){ - $exitscoid++; - $exitscochild = get_record("scorm_scoes","id",$exitscoid); - if (empty($exitscochild)){ - //Da ra ngoai vung scoid. Hay day chinh la sco cuoi cung - return 0; - } - else{ - $exitscoparent = get_record("scorm_scoes","scorm",$scormid,"identifier",$exitscochild->parent); - } - } - } - return $exitscoid; -} - -?> +navigation) { + if ($seq->termination != null) { + $seq = scorm_seq_termination($scoid,$userid,$seq); + } + if ($seq->sequencing != null) { + // scorm_sequencing_sequencing($scoid,$userid,$seq); + } + if ($seq->target != null) { + // scorm_sequencing_delivery($scoid,$userid,$seq); + } + } + if ($seq->exception != null) { + // scorm_sequencing_exception($seq); + } + return 'true'; +} + +function scorm_seq_navigation ($scoid,$userid,$request) { + /// Sequencing structure + $seq = new stdClass(); + $seq->currentactivity = scorm_get_sco($scoid); + $seq->active = scorm_seq_is('active',$scoid,$userid); + $seq->suspended = scorm_seq_is('suspended',$scoid,$userid); + $seq->navigation = null; + $seq->termination = null; + $seq->sequencing = null; + $seq->target = null; + $seq->exception = null; + + switch ($request) { + case 'start_': + if (empty($seq->currentactivity)) { + $seq->navigation = true; + $seq->sequencing = 'start'; + } else { + $seq->exception = 'NB.2.1-1'; /// Sequencing session already begun + } + break; + case 'resumeall_': + if (empty($seq->currentactivity)) { + if ($track = get_record('scorm_scoes_track','scoid',$scoid,'userid',$userid,'name','suspendedactivity')) { + $seq->navigation = true; + $seq->sequencing = 'resumeall'; + } else { + $seq->exception = 'NB.2.1-3'; /// No suspended activity found + } + } else { + $seq->exception = 'NB.2.1-1'; /// Sequencing session already begun + } + break; + case 'continue_': + case 'previous_': + if (!empty($seq->currentactivity)) { + $sco = $seq->currentactivity; + if ($sco->parent != '/') { + if ($parentsco = scorm_get_parent($sco)) { + if (isset($parentsco->flow) && ($parent->flow == true)) { + // Current activity is active ! + if ($request == 'continue_') { + $seq->navigation = true; + $seq->termination = 'exit'; + $seq->sequencing = 'continue'; + } else { + if (isset($parentsco->forwardonly) && ($parent->forwardolny == false)) { + $seq->navigation = true; + $seq->termination = 'exit'; + $seq->sequencing = 'previous'; + } else { + $seq->exception = 'NB.2.1-5'; /// Violates control mode + } + } + } + } + } + } else { + $seq->exception = 'NB.2.1-2'; /// Current activity not defined + } + break; + case 'forward_': + case 'backward_': + $seq->exception = 'NB.2.1-7' ; /// None to be done, behavior not defined + break; + case 'exit_': + case 'abandon_': + if (!empty($seq->currentactivity)) { + // Current activity is active ! + $seq->navigation = true; + $seq->termination = substr($request,0,-1); + $seq->sequencing = 'exit'; + } else { + $seq->exception = 'NB.2.1-2'; /// Current activity not defined + } + case 'exitall_': + case 'abandonall_': + case 'suspendall_': + if (!empty($seq->currentactivity)) { + $seq->navigation = true; + $seq->termination = substr($request,0,-1); + $seq->sequencing = 'exit'; + } else { + $seq->exception = 'NB.2.1-2'; /// Current activity not defined + } + break; + default: /// {target=}choice + if ($targetsco = get_record('scorm_scoes','scorm',$sco->scorm,'identifier',$request)) { + if ($targetsco->parent != '/') { + $seq->target = $request; + } else { + if ($parentsco = scorm_get_parent($targetsco)) { + if (isset($parentsco->choice) && ($parent->choice == true)) { + $seq->target = $request; + } + } + } + if ($seq->target != null) { + if (empty($seq->currentactivity)) { + $seq->navigation = true; + $seq->sequencing = 'choice'; + } else { + if (!$sco = scorm_get_sco($scoid)) { + return $seq; + } + if ($sco->parent != $target->parent) { + $ancestors = scorm_get_ancestors($sco); + $commonpos = scorm_find_common_ancestor($ancestors,$targetsco); + if ($commonpos !== false) { + if ($activitypath = array_slice($ancestors,0,$commonpos)) { + foreach ($activitypath as $activity) { + if (scorm_seq_is('active',$activity->id,$userid) && (isset($activity->choiceexit) && ($activity->choiceexit == false))) { + $seq->navigation = false; + $seq->termination = null; + $seq->sequencing = null; + $seq->target = null; + $seq->exception = 'NB.2.1-8'; /// Violates control mode + return $seq; + } + } + } else { + $seq->navigation = false; + $seq->termination = null; + $seq->sequencing = null; + $seq->target = null; + $seq->exception = 'NB.2.1-9'; + } + } + } + // Current activity is active ! + $seq->navigation = true; + $seq->sequencing = 'choice'; + } + } else { + $seq->exception = 'NB.2.1-10'; /// Violates control mode + } + } else { + $seq->exception = 'NB.2.1-11'; /// Target activity does not exists + } + break; + } + return $seq; +} + +function scorm_seq_temination ($seq,$userid) { + if (empty($seq->currentactivity)) { + $seq->termination = false; + $seq->exception = 'TB.2.3-1'; + return $seq; + } + + $sco = $seq->currentactivity; + + if ((($seq->termination == 'exit') || ($seq->termination == 'abandon')) && !$seq->active) { + $seq->termination = false; + $seq->exception = 'TB.2.3-2'; + return $seq; + } + switch ($seq->termination) { + case 'exit': + scorm_seq_end_attempt($sco,$userid); + $seq = scorm_seq_exit_action_rules($seq,$userid); + do { + $exit = true; + $seq = scorm_seq_post_cond_rules($seq,$userid); + if ($seq->termination == 'exitparent') { + if ($sco->parent != '/') { + $sco = scorm_get_parent($sco); + $seq->currentactivity = $sco; + $seq->active = scorm_seq_is('active',$sco->id,$userid); + scorm_seq_end_attempt($sco,$userid); + $exit = false; + } else { + $seq->termination = false; + $seq->exception = 'TB.2.3-4'; + return $seq; + } + } + } while (($exit == false) && ($seq->termination == 'exit')); + if ($seq->termination == 'exit') { + $seq->termination = true; + return $seq; + } + case 'exitall': + if ($seq->active) { + scorm_seq_end_attempt($sco,$userid); + } + /// Terminate Descendent Attempts Process + if ($ancestors = scorm_get_ancestors($sco)) { + foreach ($ancestors as $ancestor) { + scorm_seq_end_attempt($ancestor,$userid); + $seq->currentactivity = $ancestor; + } + } + $seq->active = scorm_seq_is('active',$seq->currentactivity->id,$userid); + $seq->termination = true; + break; + case 'suspendall': + if (($seq->active) || ($seq->suspended)) { + scorm_seq_set('suspended',$sco->id,$userid); + } else { + if ($sco->parent != '/') { + $parentsco = scorm_get_parent($sco); + scorm_seq_set('suspended',$parentsco->id,$userid); + } else { + $seq->termination = false; + $seq->exception = 'TB.2.3-3'; + // return $seq; + } + } + if ($ancestors = scorm_get_ancestors($sco)) { + foreach ($ancestors as $ancestor) { + scorm_seq_set('active',$ancestor->id,$userid,0,false); + scorm_seq_set('suspended',$ancestor->id,$userid); + $seq->currentactivity = $ancestor; + } + $seq->termination = true; + $seq->sequencing = 'exit'; + } else { + $seq->termination = false; + $seq->exception = 'TB.2.3-5'; + } + break; + case 'abandon': + scorm_seq_set('active',$sco->id,$userid,0,false); + $seq->active = null; + $seq->termination = true; + break; + case 'abandonall': + if ($ancestors = scorm_get_ancestors($sco)) { + foreach ($ancestors as $ancestor) { + scorm_seq_set('active',$ancestor->id,$userid,0,false); + $seq->currentactivity = $ancestor; + } + $seq->termination = true; + $seq->sequencing = 'exit'; + } else { + $seq->termination = false; + $seq->exception = 'TB.2.3-6'; + } + break; + default: + $seq->termination = false; + $seq->exception = 'TB.2.3-7'; + break; + } + return $seq; +} + +function scorm_seq_end_attempt($sco,$userid) { + if (scorm_is_leaf($sco)) { + if (!isset($sco->tracked) || ($sco->tracked == 1)) { + if (!scorm_seq_is('suspended',$sco->id,$userid)) { + if (!isset($sco->completionsetbycontent) || ($sco->completionsetbycontent == 0)) { + if (!scorm_seq_is('attemptprogressstatus',$sco->id,$userid,$attempt)) { + scorm_seq_set('attemptprogressstatus',$sco->id,$userid,$attempt); + scorm_seq_set('attemptcompletionstatus',$sco->id,$userid,$attempt); + } + } + if (!isset($sco->objectivesetbycontent) || ($sco->objectivesetbycontent == 0)) { + if ($sco->objectives) { + foreach ($objectives as $objective) { + if ($objective->primary) { + if (!scorm_seq_objective_progress_status($sco,$userid,$objective)) { + scorm_seq_set('objectiveprogressstatus',$sco->id,$userid,$attempt); + scorm_seq_set('objectivesatisfiedstatus',$sco->id,$userid,$attempt); + } + } + } + } + } + } + } + } else { + if ($children = scorm_get_children($sco)) { + $suspended = false; + foreach ($children as $child) { + if (scorm_seq_is('suspended',$child,$userid)) { + $suspended = true; + break; + } + } + if ($suspended) { + scorm_seq_set('suspended',$sco,$userid); + } else { + scorm_seq_set('suspended',$sco,$userid,0,false); + } + } + } + scorm_seq_set('active',$sco,$userid,0,false); + scorm_seq_overall_rollup($sco,$userid); +} + +function scorm_seq_is($what, $scoid, $userid, $attempt=0) { + /// Check if passed activity $what is active + $active = false; + if ($track = get_record('scorm_scoes_track','scoid',$scoid,'userid',$userid,'element',$what)) { + $active = true; + } + return $active; +} + +function scorm_seq_set($what, $scoid, $userid, $attempt=0, $value='true') { + /// set passed activity to active or not + if ($value == false) { + delete_record('scorm_scoes_track','scoid',$scoid,'userid',$userid,'element',$what); + } else { + $sco = scorm_get_sco($scoid); + scorm_insert_track($userid, $sco->scorm, $sco->id, 0, $what, $value); + } +} + +function scorm_seq_exit_action_rules($seq,$userid) { + $sco = $seq->currentactivity; + $ancestors = scorm_get_ancestors($sco); + $exittarget = null; + foreach (array_reverse($ancestors) as $ancestor) { + if (scorm_seq_rules_check($ancestor,'exit') != null) { + $exittarget = $ancestor; + break; + } + } + if ($exittarget != null) { + $commons = array_slice($ancestors,0,scorm_find_common_ancestor($ancestors,$exittarget)); + + /// Terminate Descendent Attempts Process + if ($commons) { + foreach ($commons as $ancestor) { + scorm_seq_end_attempt($ancestor,$userid); + $seq->currentactivity = $ancestor; + } + } + } + return $seq; +} + +function scorm_seq_post_cond_rules($seq,$userid) { + $sco = $seq->currentactivity; + if (!$seq->suspended) { + if ($action = scorm_seq_rules_check($sco,'post') != null) { + switch($action) { + case 'retry': + case 'continue': + case 'previous': + $seq->sequencing = $action; + break; + case 'exitparent': + case 'exitall': + $seq->termination = $action; + break; + case 'retryall': + $seq->termination = 'exitall'; + $seq->sequencing = 'retry'; + break; + } + } + } + return $seq; +} + +?>