function scorm_seq_flow_tree_traversal($activity, $direction, $childrenflag, $prevdirection, $seq, $userid, $skip = false) { $revdirection = false; $parent = scorm_get_parent($activity); if (!empty($parent)) { $children = scorm_get_available_children($parent); } else { $children = array(); } $childrensize = count($children); if ($prevdirection != null && $prevdirection == 'backward' && $children[$childrensize - 1]->id == $activity->id) { $direction = 'backward'; $activity = $children[0]; $revdirection = true; } if ($direction == 'forward') { $ancestors = scorm_get_ancestors($activity); $ancestorsroot = array_reverse($ancestors); $preorder = array(); $preorder = scorm_get_preorder($preorder, $ancestorsroot[0]); $preordersize = count($preorder); if ($activity->id == $preorder[$preordersize - 1]->id || $activity->parent == '/' && !$childrenflag) { // scorm_seq_terminate_descent($ancestorsroot, $userid); TODO: undefined $seq->endsession = true; $seq->nextactivity = null; return $seq; } if (scorm_is_leaf($activity) || !$childrenflag) { if ($children[$childrensize - 1]->id == $activity->id) { $seq = scorm_seq_flow_tree_traversal($parent, $direction, false, null, $seq, $userid); if ($seq->nextactivity->launch == null) { $seq = scorm_seq_flow_tree_traversal($seq->nextactivity, $direction, true, null, $seq, $userid); } return $seq; } else { $position = 0; foreach ($children as $sco) { if ($sco->id == $activity->id) { break; } $position++; } if ($position != $childrensize - 1) { $seq->nextactivity = $children[$position + 1]; $seq->traversaldir = $direction; return $seq; } else { $siblings = scorm_get_siblings($activity); $children = scorm_get_children($siblings[0]); $seq->nextactivity = $children[0]; return $seq; } } } else { $children = scorm_get_available_children($activity); if (!empty($children)) { $seq->traversaldir = $direction; $seq->nextactivity = $children[0]; return $seq; } else { $seq->traversaldir = null; $seq->nextactivity = null; $seq->exception = 'SB.2.1-2'; return $seq; } } } else { if ($direction == 'backward') { if ($activity->parent == '/') { $seq->traversaldir = null; $seq->nextactivity = null; $seq->exception = 'SB.2.1-3'; return $seq; } if (scorm_is_leaf($activity) || !$childrenflag) { if (!$revdirection) { if (isset($parent->forwardonly) && ($parent->forwardonly == true && !$skip)) { $seq->traversaldir = null; $seq->nextactivity = null; $seq->exception = 'SB.2.1-4'; return $seq; } } if ($children[0]->id == $activity->id) { $seq = scorm_seq_flow_tree_traversal($parent, 'backward', false, null, $seq, $userid); return $seq; } else { $ancestors = scorm_get_ancestors($activity); $ancestorsroot = array_reverse($ancestors); $preorder = array(); $preorder = scorm_get_preorder($preorder, $ancestorsroot[0]); $position = 0; foreach ($preorder as $sco) { if ($sco->id == $activity->id) { break; } $position++; } if (isset($preorder[$position])) { $seq->nextactivity = $preorder[$position - 1]; $seq->traversaldir = $direction; } return $seq; } } else { $children = scorm_get_available_children($activity); if (!empty($children)) { if (isset($parent->flow) && $parent->flow == true) { $seq->traversaldir = 'forward'; $seq->nextactivity = $children[0]; return $seq; } else { $seq->traversaldir = 'backward'; $seq->nextactivity = $children[count($children) - 1]; return $seq; } } else { $seq->traversaldir = null; $seq->nextactivity = null; $seq->exception = 'SB.2.1-2'; return $seq; } } } } }
function scorm_seq_choice_sequencing($sco, $userid, $seq) { $avchildren = array(); $comancestor = null; $traverse = null; if ($sco == null) { $seq->delivery = null; $seq->exception = 'SB.2.9-1'; return $seq; } $ancestors = scorm_get_ancestors($sco); $arrpath = array_reverse($ancestors); array_push($arrpath, $sco); //path from the root to the target foreach ($arrpath as $activity) { if ($activity->parent != '/') { $avchildren = scorm_get_available_children(scorm_get_parent($activity)); $position = array_search($avchildren, $activity); if ($position !== false) { $seq->delivery = null; $seq->exception = 'SB.2.9-2'; return $seq; } } if (scorm_seq_rules_check($activity, 'hidefromchoice' != null)) { $seq->delivery = null; $seq->exception = 'SB.2.9-3'; return $seq; } } if ($sco->parent != '/') { $parent = scorm_sco_get_parent($sco); if (isset($parent->choice) && $parent->choice == false) { $seq->delivery = null; $seq->exception = 'SB.2.9-4'; return $seq; } } if ($seq->currentactivity != null) { $commonpos = scorm_find_common_ancestor($ancestors, $seq->currentactivity); $comancestor = $arrpath[$commonpos]; } else { $comancestor = $arrpath[0]; } if ($seq->currentactivity === $sco) { break; } $sib = scorm_get_siblings($seq->currentactivity); $pos = array_search($sib, $sco); if ($pos !== false) { $siblings = array_slice($sib, 0, $pos - 1); if (empty($siblings)) { $seq->delivery = null; $seq->exception = 'SB.2.9-5'; return $seq; } $children = scorm_get_children(scorm_get_parent($sco)); $pos1 = array_search($children, $sco); $pos2 = array_search($seq->currentactivity, $sco); if ($pos1 > $pos2) { $traverse = 'forward'; } else { $traverse = 'backward'; } foreach ($siblings as $sibling) { $seq = scorm_seq_choice_activity_traversal($sibling, $userid, $seq, $traverse); if (!$seq->reachable) { $seq->delivery = null; return $seq; } } break; } if ($seq->currentactivity == null || $seq->currentactivity == $comancestor) { $commonpos = scorm_find_common_ancestor($ancestors, $seq->currentactivity); $comtarget = array_slice($ancestors, 1, $commonpos - 1); //path from the common ancestor to the target activity $comtarget = array_reverse($comtarget); if (empty($comtarget)) { $seq->delivery = null; $seq->exception = 'SB.2.9-5'; return $seq; } foreach ($comtarget as $act) { $seq = scorm_seq_choice_activity_traversal($act, $userid, $seq, 'forward'); if (!$seq->reachable) { $seq->delivery = null; return $seq; } $act = scorm_get_sco($acti->id); if (scorm_seq_is('active', $act->id, $userid) && ($act->id != $comancestor->id && $act->preventactivation)) { //adlseq:can i write it like another property for the $seq object? $seq->delivery = null; $seq->exception = 'SB.2.9-6'; return $seq; } } break; } if ($comancestor->id == $sco->id) { $ancestorscurrent = scorm_get_ancestors($seq->currentactivity); $possco = array_search($ancestorscurrent, $sco); $curtarget = array_slice($ancestorscurrent, 0, $possco); //path from the current activity to the target if (empty($curtarget)) { $seq->delivery = null; $seq->exception = 'SB.2.9-5'; return $seq; } $i = 0; foreach ($curtarget as $activ) { $i++; if ($i != sizeof($curtarget)) { if (isset($activ->choiceexit) && $activ->choiceexit == false) { $seq->delivery = null; $seq->exception = 'SB.2.9-7'; return $seq; } } } break; } if (array_search($ancestors, $comancestor) !== false) { $ancestorscurrent = scorm_get_ancestors($seq->currentactivity); $commonpos = scorm_find_common_ancestor($ancestors, $sco); $curcommon = array_slice($ancestorscurrent, 0, $commonpos - 1); if (empty($curcommon)) { $seq->delivery = null; $seq->exception = 'SB.2.9-5'; return $seq; } $constrained = null; foreach ($curcommon as $acti) { $acti = scorm_get_sco($acti->id); if (isset($acti->choiceexit) && $acti->choiceexit == false) { $seq->delivery = null; $seq->exception = 'SB.2.9-7'; return $seq; } if ($constrained == null) { if ($acti->constrainchoice == true) { $constrained = $acti; } } } if ($constrained != null) { $fwdir = scorm_get_preorder($constrained); if (array_search($fwdir, $sco) !== false) { $traverse = 'forward'; } else { $traverse = 'backward'; } $seq = scorm_seq_choice_flow($constrained, $traverse, $seq); $actconsider = $seq->identifiedactivity; $avdescendents = array(); $avdescendents = scorm_get_available_descendents($actconsider); if (array_search($avdescendents, $sco) !== false && $sco->id != $actconsider->id && $constrained->id != $sco->id) { $seq->delivery = null; $seq->exception = 'SB.2.9-8'; return $seq; } //CONTINUE 11.5.5 } $commonpos = scorm_find_common_ancestor($ancestors, $seq->currentactivity); $comtarget = array_slice($ancestors, 1, $commonpos - 1); //path from the common ancestor to the target activity $comtarget = array_reverse($comtarget); if (empty($comtarget)) { $seq->delivery = null; $seq->exception = 'SB.2.9-5'; return $seq; } $fwdir = scorm_get_preorder($seq->currentactivity); if (array_search($fwdir, $sco) !== false) { foreach ($comtarget as $act) { $seq = scorm_seq_choice_activity_traversal($act, $userid, $seq, 'forward'); if (!$seq->reachable) { $seq->delivery = null; return $seq; } $act = scorm_get_sco($act->id); if (scorm_seq_is('active', $act->id, $userid) && ($act->id != $comancestor->id && $act->preventactivation == true)) { $seq->delivery = null; $seq->exception = 'SB.2.9-6'; return $seq; } } } else { foreach ($comtarget as $act) { $act = scorm_get_sco($act->id); if (scorm_seq_is('active', $act->id, $userid) && ($act->id != $comancestor->id && $act->preventactivation == true)) { $seq->delivery = null; $seq->exception = 'SB.2.9-6'; return $seq; } } } break; } if (scorm_is_leaf($sco)) { $seq->delivery = $sco; $seq->exception = 'SB.2.9-6'; return $seq; } $seq = scorm_seq_flow($sco, 'forward', $seq, true, $userid); if ($seq->deliverable == false) { scorm_terminate_descendent_attempts($comancestor, $userid, $seq); scorm_seq_end_attempt($comancestor, $userid, $seq->attempt); $seq->currentactivity = $sco; $seq->delivery = null; $seq->exception = 'SB.2.9-9'; return $seq; } else { return $seq; } }