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; }
function scorm_terminate_descendent_attempts($activity, $userid, $seq) { $ancestors = scorm_get_ancestors($seq->currentactivity); $commonpos = scorm_find_common_ancestor($ancestors, $activity); if ($commonpos !== false) { if ($activitypath = array_slice($ancestors, 1, $commonpos - 2)) { if (!empty($activitypath)) { foreach ($activitypath as $sco) { scorm_seq_end_attempt($sco, $userid, $seq->attempt); } } } } }
function scorm_seq_navigation($scoid, $userid, $request, $attempt = 0) { global $DB; // Sequencing structure. $seq = new stdClass(); $seq->currentactivity = scorm_get_sco($scoid); $seq->traversaldir = null; $seq->nextactivity = null; $seq->deliveryvalid = null; $seq->attempt = $attempt; $seq->identifiedactivity = null; $seq->delivery = null; $seq->deliverable = false; $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->endsession = null; $seq->exception = null; $seq->reachable = true; $seq->prevact = true; $sco = scorm_get_sco($scoid); 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)) { // TODO: I think it's suspend instead of suspendedactivity. if ($track = $DB->get_record('scorm_scoes_track', array('scoid' => $scoid, 'userid' => $userid, 'element' => '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) && $parentsco->flow == true) { // I think it's parentsco. // Current activity is active! if (scorm_seq_is('active', $sco->id, $userid)) { if ($request == 'continue_') { $seq->navigation = true; $seq->termination = 'exit'; $seq->sequencing = 'continue'; } else { if (!isset($parentsco->forwardonly) || $parentsco->forwardonly == 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: // Example {target=<STRING>}choice. if ($targetsco = $DB->get_record('scorm_scoes', array('scorm' => $sco->scorm, 'identifier' => $request))) { if ($targetsco->parent != '/') { $seq->target = $request; } else { if ($parentsco = scorm_get_parent($targetsco)) { if (!isset($parentsco->choice) || $parentsco->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 != $targetsco->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_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; }