1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/Test/classes/class.ilTestSession.php';
5require_once 'Modules/Test/classes/class.ilTestDynamicQuestionSetFilterSelection.php';
6
7require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php';
8
9/**
10 * Test session handler for tests with mode dynamic question set
11 *
12 * @author		Björn Heyser <bheyser@databay.de>
13 * @version		$Id$
14 *
15 * @package		Modules/Test
16 */
17class ilTestSessionDynamicQuestionSet extends ilTestSession
18{
19    /**
20     * @var ilTestDynamicQuestionSetFilterSelection
21     */
22    private $questionSetFilterSelection = null;
23
24    public function __construct()
25    {
26        parent::__construct();
27
28        $this->questionSetFilterSelection = new ilTestDynamicQuestionSetFilterSelection();
29    }
30
31    /**
32     * @return ilTestDynamicQuestionSetFilterSelection
33     */
34    public function getQuestionSetFilterSelection()
35    {
36        return $this->questionSetFilterSelection;
37    }
38
39    public function loadFromDb($active_id)
40    {
41        global $DIC;
42        $ilDB = $DIC['ilDB'];
43        $result = $ilDB->queryF(
44            "SELECT * FROM tst_active WHERE active_id = %s",
45            array('integer'),
46            array($active_id)
47        );
48        if ($result->numRows()) {
49            $row = $ilDB->fetchAssoc($result);
50            $this->active_id = $row["active_id"];
51            $this->user_id = $row["user_fi"];
52            $this->anonymous_id = $row["anonymous_id"];
53            $this->test_id = $row["test_fi"];
54            $this->lastsequence = $row["lastindex"];
55            $this->pass = $row["tries"];
56            $this->submitted = ($row["submitted"]) ? true : false;
57            $this->submittedTimestamp = $row["submittimestamp"];
58            $this->tstamp = $row["tstamp"];
59
60            $this->questionSetFilterSelection->setTaxonomySelection(unserialize($row['taxfilter']));
61            $this->questionSetFilterSelection->setAnswerStatusSelection($row['answerstatusfilter']);
62            $this->questionSetFilterSelection->setAnswerStatusActiveId($row['active_id']);
63        }
64    }
65
66    public function loadTestSession($test_id, $user_id = "", $anonymous_id = "")
67    {
68        global $DIC;
69        $ilDB = $DIC['ilDB'];
70        $ilUser = $DIC['ilUser'];
71
72        if (!$user_id) {
73            $user_id = $ilUser->getId();
74        }
75        if (($GLOBALS['DIC']['ilUser']->getId() == ANONYMOUS_USER_ID) && $this->doesAccessCodeInSessionExists()) {
76            $result = $ilDB->queryF(
77                "SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
78                array('integer','integer','text'),
79                array($user_id, $test_id, $this->getAccessCodeFromSession())
80            );
81        } elseif (strlen($anonymous_id)) {
82            $result = $ilDB->queryF(
83                "SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
84                array('integer','integer','text'),
85                array($user_id, $test_id, $anonymous_id)
86            );
87        } else {
88            if ($GLOBALS['DIC']['ilUser']->getId() == ANONYMOUS_USER_ID) {
89                return null;
90            }
91            $result = $ilDB->queryF(
92                "SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
93                array('integer','integer'),
94                array($user_id, $test_id)
95            );
96        }
97
98        // TODO bheyser: Refactor
99        $this->user_id = $user_id;
100
101        if ($result->numRows()) {
102            $row = $ilDB->fetchAssoc($result);
103            $this->active_id = $row["active_id"];
104            $this->user_id = $row["user_fi"];
105            $this->anonymous_id = $row["anonymous_id"];
106            $this->test_id = $row["test_fi"];
107            $this->lastsequence = $row["lastindex"];
108            $this->pass = $row["tries"];
109            $this->submitted = ($row["submitted"]) ? true : false;
110            $this->submittedTimestamp = $row["submittimestamp"];
111            $this->tstamp = $row["tstamp"];
112
113            $this->questionSetFilterSelection->setTaxonomySelection(unserialize($row['taxfilter']));
114            $this->questionSetFilterSelection->setAnswerStatusSelection($row['answerstatusfilter']);
115            $this->questionSetFilterSelection->setAnswerStatusActiveId($row['active_id']);
116        } elseif ($this->doesAccessCodeInSessionExists()) {
117            $this->unsetAccessCodeInSession();
118        }
119    }
120
121    public function saveToDb()
122    {
123        global $DIC;
124        $ilDB = $DIC['ilDB'];
125        $ilLog = $DIC['ilLog'];
126
127        $submitted = ($this->isSubmitted()) ? 1 : 0;
128        if ($this->active_id > 0) {
129            $affectedRows = $ilDB->update(
130                'tst_active',
131                array(
132                    'lastindex' => array('integer', $this->getLastSequence()),
133                    'tries' => array('integer', $this->getPass()),
134                    'submitted' => array('integer', $submitted),
135                    'submittimestamp' => array('timestamp', (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : null),
136                    'tstamp' => array('integer', time() - 10),
137                    'taxfilter' => array('text', serialize($this->getQuestionSetFilterSelection()->getTaxonomySelection())),
138                    'answerstatusfilter' => array('text', $this->getQuestionSetFilterSelection()->getAnswerStatusSelection())
139                ),
140                array(
141                    'active_id' => array('integer', $this->getActiveId())
142                )
143            );
144
145            // update learning progress
146            include_once("./Modules/Test/classes/class.ilObjTestAccess.php");
147            include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
148            ilLPStatusWrapper::_updateStatus(
149                ilObjTestAccess::_lookupObjIdForTestId($this->getTestId()),
150                ilObjTestAccess::_getParticipantId($this->getActiveId())
151            );
152        } else {
153            if (!$this->activeIDExists($this->getUserId(), $this->getTestId())) {
154                $anonymous_id = ($this->getAnonymousId()) ? $this->getAnonymousId() : null;
155
156                $next_id = $ilDB->nextId('tst_active');
157                $affectedRows = $ilDB->insert(
158                    'tst_active',
159                    array(
160                        'active_id' => array('integer', $next_id),
161                        'user_fi' => array('integer', $this->getUserId()),
162                        'anonymous_id' => array('text', $anonymous_id),
163                        'test_fi' => array('integer', $this->getTestId()),
164                        'lastindex' => array('integer', $this->getLastSequence()),
165                        'tries' => array('integer', $this->getPass()),
166                        'submitted' => array('integer', $submitted),
167                        'submittimestamp' => array('timestamp', (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : null),
168                        'tstamp' => array('integer', time() - 10),
169                        'taxfilter' => array('text', serialize($this->getQuestionSetFilterSelection()->getTaxonomySelection())),
170                        'answerstatusfilter' => array('text', $this->getQuestionSetFilterSelection()->getAnswerStatusSelection())
171                    )
172                );
173                $this->active_id = $next_id;
174
175                // update learning progress
176                include_once("./Modules/Test/classes/class.ilObjTestAccess.php");
177                include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
178                ilLPStatusWrapper::_updateStatus(
179                    ilObjTestAccess::_lookupObjIdForTestId($this->getTestId()),
180                    $this->getUserId()
181                );
182            }
183        }
184
185        include_once("./Services/Tracking/classes/class.ilLearningProgress.php");
186        ilLearningProgress::_tracProgress(
187            $this->getUserId(),
188            ilObjTestAccess::_lookupObjIdForTestId($this->getTestId()),
189            $this->getRefId(),
190            'tst'
191        );
192    }
193
194    public function getCurrentQuestionId()
195    {
196        return $this->getLastSequence();
197    }
198
199    public function setCurrentQuestionId($currentQuestionId)
200    {
201        $this->setLastSequence((int) $currentQuestionId);
202    }
203}
204