1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/Test/interfaces/interface.ilTestQuestionSequence.php';
5
6/**
7 * @author		Björn Heyser <bheyser@databay.de>
8 * @version		$Id$
9 *
10 * @package     Modules/Test
11 */
12class ilTestVirtualSequence implements ilTestQuestionSequence
13{
14    /**
15     * @var ilDBInterface
16     */
17    protected $db;
18
19    /**
20     * @var ilObjTest
21     */
22    protected $testOBJ;
23
24    /**
25     * @var ilTestSequenceFactory
26     */
27    protected $testSequenceFactory;
28
29    /**
30     * @var integer
31     */
32    protected $activeId;
33
34    /**
35     * @var array
36     */
37    protected $questionsPassMap;
38
39    public function __construct(ilDBInterface $db, ilObjTest $testOBJ, ilTestSequenceFactory $testSequenceFactory)
40    {
41        $this->db = $db;
42        $this->testOBJ = $testOBJ;
43        $this->testSequenceFactory = $testSequenceFactory;
44
45        $this->activeId = null;
46
47        $this->questionsPassMap = array();
48    }
49
50    public function getActiveId()
51    {
52        return $this->activeId;
53    }
54
55    public function setActiveId($activeId)
56    {
57        $this->activeId = $activeId;
58    }
59
60    public function getQuestionIds()
61    {
62        return array_keys($this->questionsPassMap);
63    }
64
65    public function getQuestionsPassMap()
66    {
67        return $this->questionsPassMap;
68    }
69
70    public function getUniquePasses()
71    {
72        return array_unique(array_values($this->questionsPassMap));
73    }
74
75    public function init()
76    {
77        $passes = $this->getExistingPassesDescendent($this->getActiveId());
78        $this->fetchQuestionsFromPasses($this->getActiveId(), $passes);
79    }
80
81    private function getExistingPassesDescendent($activeId)
82    {
83        require_once 'Modules/Test/classes/class.ilTestPassesSelector.php';
84        $passesSelector = new ilTestPassesSelector($this->db, $this->testOBJ);
85        $passesSelector->setActiveId($activeId);
86
87        $passes = $passesSelector->getExistingPasses();
88
89        rsort($passes, SORT_NUMERIC);
90
91        return $passes;
92    }
93
94    protected function getTestSequence($activeId, $pass)
95    {
96        $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($activeId, $pass);
97
98        $testSequence->loadFromDb();
99        $testSequence->loadQuestions();
100
101        $testSequence->setConsiderHiddenQuestionsEnabled(true);
102        $testSequence->setConsiderOptionalQuestionsEnabled(true);
103        return $testSequence;
104    }
105
106    protected function wasAnsweredInThisPass(ilTestSequence $testSequence, $questionId)
107    {
108        if ($testSequence->isHiddenQuestion($questionId)) {
109            return false;
110        }
111
112        if (!$testSequence->isQuestionOptional($questionId)) {
113            return true;
114        }
115
116        if ($testSequence->isAnsweringOptionalQuestionsConfirmed()) {
117            return true;
118        }
119
120        return false;
121    }
122
123    protected function fetchQuestionsFromPasses($activeId, $passes)
124    {
125        $this->questionsPassMap = array();
126
127        foreach ($passes as $pass) {
128            $testSequence = $this->getTestSequence($activeId, $pass);
129
130            foreach ($testSequence->getOrderedSequenceQuestions() as $questionId) {
131                if (isset($this->questionsPassMap[$questionId])) {
132                    continue;
133                }
134
135                if ($this->wasAnsweredInThisPass($testSequence, $questionId)) {
136                    $this->questionsPassMap[$questionId] = $pass;
137                }
138            }
139        }
140    }
141}
142