ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilTestSession.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
14{
15 const ACCESS_CODE_SESSION_INDEX = "tst_access_code";
16
17 const ACCESS_CODE_CHAR_DOMAIN = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
18
20
26 public $active_id;
27
33 public $user_id;
34
41
47 public $test_id;
48
55
60
66 public $submitted;
67
73 public $tstamp;
74
81
83
85
87
96 public function __construct()
97 {
98 $this->active_id = 0;
99 $this->user_id = 0;
100 $this->anonymous_id = 0;
101 $this->test_id = 0;
102 $this->lastsequence = 0;
103 $this->lastPresentationMode = null;
104 $this->submitted = false;
105 $this->submittedTimestamp = "";
106 $this->pass = 0;
107 $this->ref_id = 0;
108 $this->tstamp = 0;
109
110 $this->lastStartedPass = null;
111 $this->lastFinishedPass = null;
112 $this->objectiveOrientedContainerId = 0;
113 }
114
120 public function setRefId($a_val)
121 {
122 $this->ref_id = $a_val;
123 }
124
130 public function getRefId()
131 {
132 return $this->ref_id;
133 }
134
135 protected function activeIDExists($user_id, $test_id)
136 {
137 global $DIC;
138 $ilDB = $DIC['ilDB'];
139
140 if ($GLOBALS['DIC']['ilUser']->getId() != ANONYMOUS_USER_ID) {
141 $result = $ilDB->queryF(
142 "SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
143 array('integer','integer'),
144 array($user_id, $test_id)
145 );
146 if ($result->numRows()) {
147 $row = $ilDB->fetchAssoc($result);
148 $this->active_id = $row["active_id"];
149 $this->user_id = $row["user_fi"];
150 $this->anonymous_id = $row["anonymous_id"];
151 $this->test_id = $row["test_fi"];
152 $this->lastsequence = $row["lastindex"];
153 $this->pass = $row["tries"];
154 $this->submitted = ($row["submitted"]) ? true : false;
155 $this->submittedTimestamp = $row["submittimestamp"];
156 $this->tstamp = $row["tstamp"];
157
158 $this->setLastStartedPass($row['last_started_pass']);
159 $this->setLastFinishedPass($row['last_finished_pass']);
160 $this->setObjectiveOrientedContainerId((int) $row['objective_container']);
161
162 return true;
163 }
164 }
165 return false;
166 }
167
168 public function increaseTestPass()
169 {
170 global $DIC;
171 $ilDB = $DIC['ilDB'];
172 $ilLog = $DIC['ilLog'];
173
174 if (!$this->active_id) {
175 require_once 'Modules/Test/exceptions/class.ilTestException.php';
176 throw new ilTestException('missing active id on test pass increase!');
177 }
178
179 $this->increasePass();
180 $this->setLastSequence(0);
181 $submitted = ($this->isSubmitted()) ? 1 : 0;
182
183 if (!isset($_SESSION[$this->active_id]['tst_last_increase_pass'])) {
184 $_SESSION[$this->active_id]['tst_last_increase_pass'] = 0;
185 }
186
187 // there has to be at least 10 seconds between new test passes (to ensure that noone double clicks the finish button and increases the test pass by more than 1)
188 if (time() - $_SESSION[$this->active_id]['tst_last_increase_pass'] > 10) {
189 $_SESSION[$this->active_id]['tst_last_increase_pass'] = time();
190 $this->tstamp = time();
191 $ilDB->update(
192 'tst_active',
193 array(
194 'lastindex' => array('integer', $this->getLastSequence()),
195 'tries' => array('integer', $this->getPass()),
196 'submitted' => array('integer', $submitted),
197 'submittimestamp' => array('timestamp', strlen($this->getSubmittedTimestamp()) ? $this->getSubmittedTimestamp() : null),
198 'tstamp' => array('integer', time()),
199 'last_finished_pass' => array('integer', $this->getLastFinishedPass()),
200 'last_started_pass' => array('integer', $this->getLastStartedPass()),
201 'objective_container' => array('integer', (int) $this->getObjectiveOrientedContainerId())
202 ),
203 array(
204 'active_id' => array('integer', $this->getActiveId())
205 )
206 );
207 }
208 }
209
210 public function saveToDb()
211 {
212 global $DIC;
213 $ilDB = $DIC['ilDB'];
214 $ilLog = $DIC['ilLog'];
215
216 $submitted = ($this->isSubmitted()) ? 1 : 0;
217 if ($this->active_id > 0) {
218 $ilDB->update(
219 'tst_active',
220 array(
221 'lastindex' => array('integer', $this->getLastSequence()),
222 'tries' => array('integer', $this->getPass()),
223 'submitted' => array('integer', $submitted),
224 'submittimestamp' => array('timestamp', (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : null),
225 'tstamp' => array('integer', time() - 10),
226 'last_finished_pass' => array('integer', $this->getLastFinishedPass()),
227 'last_started_pass' => array('integer', $this->getPass()),
228 'objective_container' => array('integer', (int) $this->getObjectiveOrientedContainerId())
229 ),
230 array(
231 'active_id' => array('integer', $this->getActiveId())
232 )
233 );
234 } else {
235 if (!$this->activeIDExists($this->getUserId(), $this->getTestId())) {
236 $anonymous_id = ($this->getAnonymousId()) ? $this->getAnonymousId() : null;
237
238 $next_id = $ilDB->nextId('tst_active');
239 $ilDB->insert(
240 'tst_active',
241 array(
242 'active_id' => array('integer', $next_id),
243 'user_fi' => array('integer', $this->getUserId()),
244 'anonymous_id' => array('text', $anonymous_id),
245 'test_fi' => array('integer', $this->getTestId()),
246 'lastindex' => array('integer', $this->getLastSequence()),
247 'tries' => array('integer', $this->getPass()),
248 'submitted' => array('integer', $submitted),
249 'submittimestamp' => array('timestamp', (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : null),
250 'tstamp' => array('integer', time() - 10),
251 'last_finished_pass' => array('integer', $this->getLastFinishedPass()),
252 'last_started_pass' => array('integer', $this->getPass()),
253 'objective_container' => array('integer', (int) $this->getObjectiveOrientedContainerId())
254 )
255 );
256 $this->active_id = $next_id;
257 }
258 }
259 }
260
261 public function loadTestSession($test_id, $user_id = "", $anonymous_id = "")
262 {
263 global $DIC;
264 $ilDB = $DIC['ilDB'];
265 $ilUser = $DIC['ilUser'];
266
267 if (!$user_id) {
268 $user_id = $ilUser->getId();
269 }
270 if (($GLOBALS['DIC']['ilUser']->getId() == ANONYMOUS_USER_ID) && $this->doesAccessCodeInSessionExists()) {
271 $result = $ilDB->queryF(
272 "SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
273 array('integer','integer','text'),
275 );
276 } elseif (strlen($anonymous_id)) {
277 $result = $ilDB->queryF(
278 "SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
279 array('integer','integer','text'),
281 );
282 } else {
283 if ($GLOBALS['DIC']['ilUser']->getId() == ANONYMOUS_USER_ID) {
284 return null;
285 }
286 $result = $ilDB->queryF(
287 "SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
288 array('integer','integer'),
289 array($user_id, $test_id)
290 );
291 }
292
293 // TODO bheyser: Refactor
294 $this->user_id = $user_id;
295
296 if ($result->numRows()) {
297 $row = $ilDB->fetchAssoc($result);
298 $this->active_id = $row["active_id"];
299 $this->user_id = $row["user_fi"];
300 $this->anonymous_id = $row["anonymous_id"];
301 $this->test_id = $row["test_fi"];
302 $this->lastsequence = $row["lastindex"];
303 $this->pass = $row["tries"];
304 $this->submitted = ($row["submitted"]) ? true : false;
305 $this->submittedTimestamp = $row["submittimestamp"];
306 $this->tstamp = $row["tstamp"];
307
308 $this->setLastStartedPass($row['last_started_pass']);
309 $this->setLastFinishedPass($row['last_finished_pass']);
310 $this->setObjectiveOrientedContainerId((int) $row['objective_container']);
311 } elseif ($this->doesAccessCodeInSessionExists()) {
313 }
314 }
315
321 public function loadFromDb($active_id)
322 {
323 global $DIC;
324 $ilDB = $DIC['ilDB'];
325 $result = $ilDB->queryF(
326 "SELECT * FROM tst_active WHERE active_id = %s",
327 array('integer'),
328 array($active_id)
329 );
330 if ($result->numRows()) {
331 $row = $ilDB->fetchAssoc($result);
332 $this->active_id = $row["active_id"];
333 $this->user_id = $row["user_fi"];
334 $this->anonymous_id = $row["anonymous_id"];
335 $this->test_id = $row["test_fi"];
336 $this->lastsequence = $row["lastindex"];
337 $this->pass = $row["tries"];
338 $this->submitted = ($row["submitted"]) ? true : false;
339 $this->submittedTimestamp = $row["submittimestamp"];
340 $this->tstamp = $row["tstamp"];
341
342 $this->setLastStartedPass($row['last_started_pass']);
343 $this->setLastFinishedPass($row['last_finished_pass']);
344 $this->setObjectiveOrientedContainerId((int) $row['objective_container']);
345 }
346 }
347
348 public function getActiveId()
349 {
350 return $this->active_id;
351 }
352
353 public function setUserId($user_id)
354 {
355 $this->user_id = $user_id;
356 }
357
358 public function getUserId()
359 {
360 return $this->user_id;
361 }
362
363 public function setTestId($test_id)
364 {
365 $this->test_id = $test_id;
366 }
367
368 public function getTestId()
369 {
370 return $this->test_id;
371 }
372
374 {
375 $this->anonymous_id = $anonymous_id;
376 }
377
378 public function getAnonymousId()
379 {
380 return $this->anonymous_id;
381 }
382
384 {
385 $this->lastsequence = $lastsequence;
386 }
387
388 public function getLastSequence()
389 {
390 return $this->lastsequence;
391 }
392
393 public function setPass($pass)
394 {
395 $this->pass = $pass;
396 }
397
398 public function getPass()
399 {
400 return $this->pass;
401 }
402
403 public function increasePass()
404 {
405 $this->pass += 1;
406 }
407
408 public function isSubmitted()
409 {
410 return $this->submitted;
411 }
412
413 public function setSubmitted()
414 {
415 $this->submitted = true;
416 }
417
418 public function getSubmittedTimestamp()
419 {
421 }
422
423 public function setSubmittedTimestamp()
424 {
425 $this->submittedTimestamp = strftime("%Y-%m-%d %H:%M:%S");
426 }
427
429 {
430 $this->lastFinishedPass = $lastFinishedPass;
431 }
432
433 public function getLastFinishedPass()
434 {
436 }
437
438 public function setObjectiveOrientedContainerId($objectiveOriented)
439 {
440 $this->objectiveOrientedContainerId = $objectiveOriented;
441 }
442
444 {
446 }
447
451 public function getLastStartedPass()
452 {
454 }
455
460 {
461 $this->lastStartedPass = $lastStartedPass;
462 }
463
464 public function isObjectiveOriented()
465 {
466 return (bool) $this->getObjectiveOrientedContainerId();
467 }
468
469 public function persistTestStartLock($testStartLock)
470 {
471 global $DIC;
472 $ilDB = $DIC['ilDB'];
473
474 $ilDB->update(
475 'tst_active',
476 array('start_lock' => array('text', $testStartLock)),
477 array('active_id' => array('integer', $this->getActiveId()))
478 );
479 }
480
481 public function lookupTestStartLock()
482 {
483 global $DIC;
484 $ilDB = $DIC['ilDB'];
485
486 $res = $ilDB->queryF(
487 "SELECT start_lock FROM tst_active WHERE active_id = %s",
488 array('integer'),
489 array($this->getActiveId())
490 );
491
492 while ($row = $ilDB->fetchAssoc($res)) {
493 return $row['start_lock'];
494 }
495
496 return null;
497 }
498
499 public function setAccessCodeToSession($access_code)
500 {
501 if (!is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX])) {
503 }
504
505 $_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()] = $access_code;
506 }
507
508 public function unsetAccessCodeInSession()
509 {
510 unset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]);
511 }
512
513 public function getAccessCodeFromSession()
514 {
515 if (!is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX])) {
516 return null;
517 }
518
519 if (!isset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()])) {
520 return null;
521 }
522
524 }
525
527 {
528 if (!is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX])) {
529 return false;
530 }
531
532 return isset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]);
533 }
534
535 public function createNewAccessCode()
536 {
537 do {
538 $code = $this->buildAccessCode();
539 } while ($this->isAccessCodeUsed($code));
540
541 return $code;
542 }
543
544 public function isAccessCodeUsed($code)
545 {
546 global $DIC;
547 $ilDB = $DIC['ilDB'];
548
549 $query = "SELECT anonymous_id FROM tst_active WHERE test_fi = %s AND anonymous_id = %s";
550
551 $result = $ilDB->queryF(
552 $query,
553 array('integer', 'text'),
554 array($this->getTestId(), $code)
555 );
556
557 return ($result->numRows() > 0);
558 }
559
560 private function buildAccessCode()
561 {
562 // create a 5 character code
563 $codestring = self::ACCESS_CODE_CHAR_DOMAIN;
564
565 mt_srand();
566
567 $code = "";
568
569 for ($i = 1; $i <= self::ACCESS_CODE_LENGTH; $i++) {
570 $index = mt_rand(0, strlen($codestring) - 1);
571 $code .= substr($codestring, $index, 1);
572 }
573
574 return $code;
575 }
576
577 public function isAnonymousUser()
578 {
579 return $this->getUserId() == ANONYMOUS_USER_ID;
580 }
581
586
591 public function reportableResultsAvailable(ilObjTest $testOBJ)
592 {
593 if ($this->reportableResultsAvailable === null) {
594 $this->reportableResultsAvailable = true;
595
596 if (!$this->getActiveId()) {
597 $this->reportableResultsAvailable = false;
598 }
599
600 if (!$testOBJ->canShowTestResults($this)) {
601 $this->reportableResultsAvailable = false;
602 }
603 }
604
606 }
607
611 public function hasSinglePassReportable(ilObjTest $testObj)
612 {
613 global $DIC; /* @var ILIAS\DI\Container $DIC */
614
615 require_once 'Modules/Test/classes/class.ilTestPassesSelector.php';
616 $testPassesSelector = new ilTestPassesSelector($DIC->database(), $testObj);
617 $testPassesSelector->setActiveId($this->getActiveId());
618 $testPassesSelector->setLastFinishedPass($this->getLastFinishedPass());
619
620 if (count($testPassesSelector->getReportablePasses()) == 1) {
621 return true;
622 }
623
624 return false;
625 }
626}
$result
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
canShowTestResults(ilTestSession $testSession)
Base Exception for all Exceptions relating to Modules/Test.
Test session handler.
activeIDExists($user_id, $test_id)
setAccessCodeToSession($access_code)
persistTestStartLock($testStartLock)
__construct()
ilTestSession constructor
setAnonymousId($anonymous_id)
setRefId($a_val)
Set Ref id.
setObjectiveOrientedContainerId($objectiveOriented)
loadTestSession($test_id, $user_id="", $anonymous_id="")
loadFromDb($active_id)
Loads the session data for a given active id.
getRefId()
Get Ref id.
setLastSequence($lastsequence)
setLastFinishedPass($lastFinishedPass)
reportableResultsAvailable(ilObjTest $testOBJ)
setLastStartedPass($lastStartedPass)
hasSinglePassReportable(ilObjTest $testObj)
$index
Definition: metadata.php:128
$i
Definition: metadata.php:24
$query
foreach($_POST as $key=> $value) $res
global $ilDB
$ilUser
Definition: imgupload.php:18
$DIC
Definition: xapitoken.php:46