ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 
19  const ACCESS_CODE_LENGTH = 5;
20 
27 
33  var $user_id;
34 
41 
47  var $test_id;
48 
55 
60 
67 
73  var $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  function setRefId($a_val)
121  {
122  $this->ref_id = $a_val;
123  }
124 
130  function getRefId()
131  {
132  return $this->ref_id;
133  }
134 
135  protected function activeIDExists($user_id, $test_id)
136  {
137  global $ilDB;
138 
139  if ($GLOBALS['DIC']['ilUser']->getId() != ANONYMOUS_USER_ID)
140  {
141  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
142  array('integer','integer'),
143  array($user_id, $test_id)
144  );
145  if ($result->numRows())
146  {
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  function increaseTestPass()
169  {
170  global $ilDB, $ilLog;
171 
172  if( !$this->active_id )
173  {
174  require_once 'Modules/Test/exceptions/class.ilTestException.php';
175  throw new ilTestException('missing active id on test pass increase!');
176  }
177 
178  $this->increasePass();
179  $this->setLastSequence(0);
180  $submitted = ($this->isSubmitted()) ? 1 : 0;
181 
182  if( !isset($_SESSION[$this->active_id]['tst_last_increase_pass']) )
183  {
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  {
190  $_SESSION[$this->active_id]['tst_last_increase_pass'] = time();
191  $this->tstamp = time();
192  $ilDB->update('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  function saveToDb()
211  {
212  global $ilDB, $ilLog;
213 
214  $submitted = ($this->isSubmitted()) ? 1 : 0;
215  if ($this->active_id > 0)
216  {
217  $ilDB->update('tst_active',
218  array(
219  'lastindex' => array('integer', $this->getLastSequence()),
220  'tries' => array('integer', $this->getPass()),
221  'submitted' => array('integer', $submitted),
222  'submittimestamp' => array('timestamp', (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : NULL),
223  'tstamp' => array('integer', time()-10),
224  'last_finished_pass' => array('integer', $this->getLastFinishedPass()),
225  'last_started_pass' => array('integer', $this->getPass()),
226  'objective_container' => array('integer', (int)$this->getObjectiveOrientedContainerId())
227  ),
228  array(
229  'active_id' => array('integer', $this->getActiveId())
230  )
231  );
232  }
233  else
234  {
235  if (!$this->activeIDExists($this->getUserId(), $this->getTestId()))
236  {
237  $anonymous_id = ($this->getAnonymousId()) ? $this->getAnonymousId() : NULL;
238 
239  $next_id = $ilDB->nextId('tst_active');
240  $ilDB->insert('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 
262  function loadTestSession($test_id, $user_id = "", $anonymous_id = "")
263  {
264  global $ilDB;
265  global $ilUser;
266 
267  if (!$user_id)
268  {
269  $user_id = $ilUser->getId();
270  }
271  if (($GLOBALS['DIC']['ilUser']->getId() == ANONYMOUS_USER_ID) && $this->doesAccessCodeInSessionExists())
272  {
273  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
274  array('integer','integer','text'),
275  array($user_id, $test_id, $this->getAccessCodeFromSession())
276  );
277  }
278  else if (strlen($anonymous_id))
279  {
280  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
281  array('integer','integer','text'),
282  array($user_id, $test_id, $anonymous_id)
283  );
284  }
285  else
286  {
287  if ($GLOBALS['DIC']['ilUser']->getId() == ANONYMOUS_USER_ID)
288  {
289  return NULL;
290  }
291  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
292  array('integer','integer'),
293  array($user_id, $test_id)
294  );
295  }
296 
297  // TODO bheyser: Refactor
298  $this->user_id = $user_id;
299 
300  if ($result->numRows())
301  {
302  $row = $ilDB->fetchAssoc($result);
303  $this->active_id = $row["active_id"];
304  $this->user_id = $row["user_fi"];
305  $this->anonymous_id = $row["anonymous_id"];
306  $this->test_id = $row["test_fi"];
307  $this->lastsequence = $row["lastindex"];
308  $this->pass = $row["tries"];
309  $this->submitted = ($row["submitted"]) ? TRUE : FALSE;
310  $this->submittedTimestamp = $row["submittimestamp"];
311  $this->tstamp = $row["tstamp"];
312 
313  $this->setLastStartedPass($row['last_started_pass']);
314  $this->setLastFinishedPass($row['last_finished_pass']);
315  $this->setObjectiveOrientedContainerId((int)$row['objective_container']);
316  }
317  elseif( $this->doesAccessCodeInSessionExists() )
318  {
319  $this->unsetAccessCodeInSession();
320  }
321  }
322 
328  public function loadFromDb($active_id)
329  {
330  global $ilDB;
331  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE active_id = %s",
332  array('integer'),
333  array($active_id)
334  );
335  if ($result->numRows())
336  {
337  $row = $ilDB->fetchAssoc($result);
338  $this->active_id = $row["active_id"];
339  $this->user_id = $row["user_fi"];
340  $this->anonymous_id = $row["anonymous_id"];
341  $this->test_id = $row["test_fi"];
342  $this->lastsequence = $row["lastindex"];
343  $this->pass = $row["tries"];
344  $this->submitted = ($row["submitted"]) ? TRUE : FALSE;
345  $this->submittedTimestamp = $row["submittimestamp"];
346  $this->tstamp = $row["tstamp"];
347 
348  $this->setLastStartedPass($row['last_started_pass']);
349  $this->setLastFinishedPass($row['last_finished_pass']);
350  $this->setObjectiveOrientedContainerId((int)$row['objective_container']);
351  }
352  }
353 
354  function getActiveId()
355  {
356  return $this->active_id;
357  }
358 
359  function setUserId($user_id)
360  {
361  $this->user_id = $user_id;
362  }
363 
364  function getUserId()
365  {
366  return $this->user_id;
367  }
368 
369  function setTestId($test_id)
370  {
371  $this->test_id = $test_id;
372  }
373 
374  function getTestId()
375  {
376  return $this->test_id;
377  }
378 
379  function setAnonymousId($anonymous_id)
380  {
381  $this->anonymous_id = $anonymous_id;
382  }
383 
384  function getAnonymousId()
385  {
386  return $this->anonymous_id;
387  }
388 
389  public function setLastSequence($lastsequence)
390  {
391  $this->lastsequence = $lastsequence;
392  }
393 
394  public function getLastSequence()
395  {
396  return $this->lastsequence;
397  }
398 
399  function setPass($pass)
400  {
401  $this->pass = $pass;
402  }
403 
404  function getPass()
405  {
406  return $this->pass;
407  }
408 
409  function increasePass()
410  {
411  $this->pass += 1;
412  }
413 
414  function isSubmitted()
415  {
416  return $this->submitted;
417  }
418 
419  function setSubmitted()
420  {
421  $this->submitted = TRUE;
422  }
423 
425  {
427  }
428 
430  {
431  $this->submittedTimestamp = strftime("%Y-%m-%d %H:%M:%S");
432  }
433 
435  {
436  $this->lastFinishedPass = $lastFinishedPass;
437  }
438 
439  public function getLastFinishedPass()
440  {
442  }
443 
444  public function setObjectiveOrientedContainerId($objectiveOriented)
445  {
446  $this->objectiveOrientedContainerId = $objectiveOriented;
447  }
448 
450  {
452  }
453 
457  public function getLastStartedPass()
458  {
459  return $this->lastStartedPass;
460  }
461 
466  {
467  $this->lastStartedPass = $lastStartedPass;
468  }
469 
470  public function isObjectiveOriented()
471  {
472  return (bool)$this->getObjectiveOrientedContainerId();
473  }
474 
475  public function persistTestStartLock($testStartLock)
476  {
477  global $ilDB;
478 
479  $ilDB->update(
480  'tst_active',
481  array('start_lock' => array('text', $testStartLock)),
482  array('active_id' => array('integer', $this->getActiveId()))
483  );
484  }
485 
486  public function lookupTestStartLock()
487  {
488  global $ilDB;
489 
490  $res = $ilDB->queryF(
491  "SELECT start_lock FROM tst_active WHERE active_id = %s",
492  array('integer'), array($this->getActiveId())
493  );
494 
495  while($row = $ilDB->fetchAssoc($res))
496  {
497  return $row['start_lock'];
498  }
499 
500  return null;
501  }
502 
503  public function setAccessCodeToSession($access_code)
504  {
505  if (!is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX]))
506  {
507  $_SESSION[self::ACCESS_CODE_SESSION_INDEX] = array();
508  }
509 
510  $_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()] = $access_code;
511  }
512 
513  public function unsetAccessCodeInSession()
514  {
515  unset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]);
516  }
517 
518  public function getAccessCodeFromSession()
519  {
520  if( !is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX]) )
521  {
522  return null;
523  }
524 
525  if( !isset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]) )
526  {
527  return null;
528  }
529 
530  return $_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()];
531  }
532 
534  {
535  if( !is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX]) )
536  {
537  return false;
538  }
539 
540  return isset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]);
541  }
542 
543  public function createNewAccessCode()
544  {
545  do
546  {
547  $code = $this->buildAccessCode();
548  }
549  while( $this->isAccessCodeUsed($code) );
550 
551  return $code;
552  }
553 
554  public function isAccessCodeUsed($code)
555  {
556  global $ilDB;
557 
558  $query = "SELECT anonymous_id FROM tst_active WHERE test_fi = %s AND anonymous_id = %s";
559 
560  $result = $ilDB->queryF(
561  $query, array('integer', 'text'), array($this->getTestId(), $code)
562  );
563 
564  return ($result->numRows() > 0);
565  }
566 
567  private function buildAccessCode()
568  {
569  // create a 5 character code
570  $codestring = self::ACCESS_CODE_CHAR_DOMAIN;
571 
572  mt_srand();
573 
574  $code = "";
575 
576  for($i = 1; $i <= self::ACCESS_CODE_LENGTH; $i++)
577  {
578  $index = mt_rand(0, strlen($codestring)-1);
579  $code .= substr($codestring, $index, 1);
580  }
581 
582  return $code;
583  }
584 
585  public function isAnonymousUser()
586  {
587  return $this->getUserId() == ANONYMOUS_USER_ID;
588  }
589 }
$_SESSION["AccountId"]
$result
$code
Definition: example_050.php:99
setObjectiveOrientedContainerId($objectiveOriented)
setRefId($a_val)
Set Ref id.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
__construct()
ilTestSession constructor
setAnonymousId($anonymous_id)
Base Exception for all Exceptions relating to Modules/Test.
setAccessCodeToSession($access_code)
loadFromDb($active_id)
Loads the session data for a given active id.
setLastFinishedPass($lastFinishedPass)
setLastStartedPass($lastStartedPass)
getRefId()
Get Ref id.
$ilUser
Definition: imgupload.php:18
Test session handler.
Create styles array
The data for the language used.
persistTestStartLock($testStartLock)
$ref_id
Definition: sahs_server.php:39
global $ilDB
setLastSequence($lastsequence)
activeIDExists($user_id, $test_id)
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
loadTestSession($test_id, $user_id="", $anonymous_id="")