Пример #1
0
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;
                }
            }
        }
    }
}
Пример #2
0
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;
    }
}