ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
62 
68  var $tstamp;
69 
76 
78 
80 
89  public function __construct()
90  {
91  $this->active_id = 0;
92  $this->user_id = 0;
93  $this->anonymous_id = 0;
94  $this->test_id = 0;
95  $this->lastsequence = 0;
96  $this->submitted = FALSE;
97  $this->submittedTimestamp = "";
98  $this->pass = 0;
99  $this->ref_id = 0;
100  $this->tstamp = 0;
101 
102  $this->lastFinishedPass = null;
103  $this->objectiveOrientedContainerId = 0;
104  }
105 
111  function setRefId($a_val)
112  {
113  $this->ref_id = $a_val;
114  }
115 
121  function getRefId()
122  {
123  return $this->ref_id;
124  }
125 
126  protected function activeIDExists($user_id, $test_id)
127  {
128  global $ilDB;
129 
130  if ($_SESSION["AccountId"] != ANONYMOUS_USER_ID)
131  {
132  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
133  array('integer','integer'),
134  array($user_id, $test_id)
135  );
136  if ($result->numRows())
137  {
138  $row = $ilDB->fetchAssoc($result);
139  $this->active_id = $row["active_id"];
140  $this->user_id = $row["user_fi"];
141  $this->anonymous_id = $row["anonymous_id"];
142  $this->test_id = $row["test_fi"];
143  $this->lastsequence = $row["lastindex"];
144  $this->pass = $row["tries"];
145  $this->submitted = ($row["submitted"]) ? TRUE : FALSE;
146  $this->submittedTimestamp = $row["submittimestamp"];
147  $this->tstamp = $row["tstamp"];
148 
149  $this->setLastFinishedPass($row['last_finished_pass']);
150  $this->setObjectiveOrientedContainerId((int)$row['objective_container']);
151 
152  return true;
153  }
154  }
155  return false;
156  }
157 
158  function increaseTestPass()
159  {
160  global $ilDB, $ilLog;
161 
162  $this->increasePass();
163  $this->setLastSequence(0);
164  $submitted = ($this->isSubmitted()) ? 1 : 0;
165  // 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)
166  if (time() - $_SESSION['tst_last_increase_pass'] > 10)
167  {
168  $_SESSION['tst_last_increase_pass'] = time();
169  $this->tstamp = time();
170  if ($this->active_id > 0)
171  {
172  $ilDB->update('tst_active',
173  array(
174  'lastindex' => array('integer', $this->getLastSequence()),
175  'tries' => array('integer', $this->getPass()),
176  'submitted' => array('integer', $submitted),
177  'submittimestamp' => array('timestamp', strlen($this->getSubmittedTimestamp()) ? $this->getSubmittedTimestamp() : NULL),
178  'tstamp' => array('integer', time()),
179  'last_finished_pass' => array('integer', $this->getLastFinishedPass()),
180  'objective_container' => array('integer', (int)$this->getObjectiveOrientedContainerId())
181  ),
182  array(
183  'active_id' => array('integer', $this->getActiveId())
184  )
185  );
186 
187  // update learning progress
188  include_once("./Modules/Test/classes/class.ilObjTestAccess.php");
189  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
191  ilObjTestAccess::_getParticipantId($this->active_id));
192  }
193  else
194  {
195  if (!$this->activeIDExists($this->getUserId(), $this->getTestId()))
196  {
197  $anonymous_id = ($this->getAnonymousId()) ? $this->getAnonymousId() : NULL;
198  $next_id = $ilDB->nextId('tst_active');
199  $affectedRows = $ilDB->manipulateF("INSERT INTO tst_active (active_id, user_fi, anonymous_id, test_fi, lastindex, tries, submitted, submittimestamp, tstamp, objective_container) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
200  array('integer', 'integer', 'text', 'integer', 'integer', 'integer', 'integer', 'timestamp', 'integer', 'integer'),
201  array(
202  $next_id,
203  $this->getUserId(),
205  $this->getTestId(),
206  $this->getLastSequence(),
207  $this->getPass(),
208  $submitted,
209  (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : NULL,
210  time(),
211  (int)$this->getObjectiveOrientedContainerId()
212  )
213  );
214  $this->active_id = $next_id;
215 
216  // update learning progress
217  include_once("./Modules/Test/classes/class.ilObjTestAccess.php");
218  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
220  $this->getUserId());
221  }
222  }
223  }
224  }
225 
226  function saveToDb()
227  {
228  global $ilDB, $ilLog;
229 
230  $submitted = ($this->isSubmitted()) ? 1 : 0;
231  if ($this->active_id > 0)
232  {
233  $ilDB->update('tst_active',
234  array(
235  'lastindex' => array('integer', $this->getLastSequence()),
236  'tries' => array('integer', $this->getPass()),
237  'submitted' => array('integer', $submitted),
238  'submittimestamp' => array('timestamp', (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : NULL),
239  'tstamp' => array('integer', time()-10),
240  'last_finished_pass' => array('integer', $this->getLastFinishedPass()),
241  'objective_container' => array('integer', (int)$this->getObjectiveOrientedContainerId())
242  ),
243  array(
244  'active_id' => array('integer', $this->getActiveId())
245  )
246  );
247 
248  // update learning progress
249  include_once("./Modules/Test/classes/class.ilObjTestAccess.php");
250  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
253  }
254  else
255  {
256  if (!$this->activeIDExists($this->getUserId(), $this->getTestId()))
257  {
258  $anonymous_id = ($this->getAnonymousId()) ? $this->getAnonymousId() : NULL;
259 
260  $next_id = $ilDB->nextId('tst_active');
261  $ilDB->insert('tst_active',
262  array(
263  'active_id' => array('integer', $next_id),
264  'user_fi' => array('integer', $this->getUserId()),
265  'anonymous_id' => array('text', $anonymous_id),
266  'test_fi' => array('integer', $this->getTestId()),
267  'lastindex' => array('integer', $this->getLastSequence()),
268  'tries' => array('integer', $this->getPass()),
269  'submitted' => array('integer', $submitted),
270  'submittimestamp' => array('timestamp', (strlen($this->getSubmittedTimestamp())) ? $this->getSubmittedTimestamp() : NULL),
271  'tstamp' => array('integer', time()-10),
272  'last_finished_pass' => array('integer', $this->getLastFinishedPass()),
273  'objective_container' => array('integer', (int)$this->getObjectiveOrientedContainerId())
274  )
275  );
276  $this->active_id = $next_id;
277 
278  // update learning progress
279  include_once("./Modules/Test/classes/class.ilObjTestAccess.php");
280  include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
282  $this->getUserId());
283  }
284  }
285  include_once './Modules/Test/classes/class.ilObjTestAccess.php';
286  include_once("./Services/Tracking/classes/class.ilLearningProgress.php");
289  $this->getRefId(),
290  'tst');
291  }
292 
294  {
295  global $ilDB;
296  global $ilUser;
297 
298  if (!$user_id)
299  {
300  $user_id = $ilUser->getId();
301  }
302  if (($_SESSION["AccountId"] == ANONYMOUS_USER_ID) && $this->doesAccessCodeInSessionExists())
303  {
304  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
305  array('integer','integer','text'),
306  array($user_id, $test_id, $this->getAccessCodeFromSession())
307  );
308  }
309  else if (strlen($anonymous_id))
310  {
311  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s AND anonymous_id = %s",
312  array('integer','integer','text'),
314  );
315  }
316  else
317  {
318  if ($_SESSION["AccountId"] == ANONYMOUS_USER_ID)
319  {
320  return NULL;
321  }
322  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
323  array('integer','integer'),
324  array($user_id, $test_id)
325  );
326  }
327  if ($result->numRows())
328  {
329  $row = $ilDB->fetchAssoc($result);
330  $this->active_id = $row["active_id"];
331  $this->user_id = $row["user_fi"];
332  $this->anonymous_id = $row["anonymous_id"];
333  $this->test_id = $row["test_fi"];
334  $this->lastsequence = $row["lastindex"];
335  $this->pass = $row["tries"];
336  $this->submitted = ($row["submitted"]) ? TRUE : FALSE;
337  $this->submittedTimestamp = $row["submittimestamp"];
338  $this->tstamp = $row["tstamp"];
339 
340  $this->setLastFinishedPass($row['last_finished_pass']);
341  $this->setObjectiveOrientedContainerId((int)$row['objective_container']);
342  }
343  elseif( $this->doesAccessCodeInSessionExists() )
344  {
345  $this->unsetAccessCodeInSession();
346  }
347  }
348 
354  public function loadFromDb($active_id)
355  {
356  global $ilDB;
357  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE active_id = %s",
358  array('integer'),
359  array($active_id)
360  );
361  if ($result->numRows())
362  {
363  $row = $ilDB->fetchAssoc($result);
364  $this->active_id = $row["active_id"];
365  $this->user_id = $row["user_fi"];
366  $this->anonymous_id = $row["anonymous_id"];
367  $this->test_id = $row["test_fi"];
368  $this->lastsequence = $row["lastindex"];
369  $this->pass = $row["tries"];
370  $this->submitted = ($row["submitted"]) ? TRUE : FALSE;
371  $this->submittedTimestamp = $row["submittimestamp"];
372  $this->tstamp = $row["tstamp"];
373 
374  $this->setLastFinishedPass($row['last_finished_pass']);
375  $this->setObjectiveOrientedContainerId((int)$row['objective_container']);
376  }
377  }
378 
379  function getActiveId()
380  {
381  return $this->active_id;
382  }
383 
384  function setUserId($user_id)
385  {
386  $this->user_id = $user_id;
387  }
388 
389  function getUserId()
390  {
391  return $this->user_id;
392  }
393 
394  function setTestId($test_id)
395  {
396  $this->test_id = $test_id;
397  }
398 
399  function getTestId()
400  {
401  return $this->test_id;
402  }
403 
405  {
406  $this->anonymous_id = $anonymous_id;
407  }
408 
409  function getAnonymousId()
410  {
411  return $this->anonymous_id;
412  }
413 
415  {
416  $this->lastsequence = $lastsequence;
417  }
418 
419  function getLastSequence()
420  {
421  return $this->lastsequence;
422  }
423 
424  function setPass($pass)
425  {
426  $this->pass = $pass;
427  }
428 
429  function getPass()
430  {
431  return $this->pass;
432  }
433 
434  function increasePass()
435  {
436  $this->pass += 1;
437  }
438 
439  function isSubmitted()
440  {
441  return $this->submitted;
442  }
443 
444  function setSubmitted()
445  {
446  $this->submitted = TRUE;
447  }
448 
450  {
452  }
453 
455  {
456  $this->submittedTimestamp = strftime("%Y-%m-%d %H:%M:%S");
457  }
458 
460  {
461  $this->lastFinishedPass = $lastFinishedPass;
462  }
463 
464  public function getLastFinishedPass()
465  {
467  }
468 
469  public function setObjectiveOrientedContainerId($objectiveOriented)
470  {
471  $this->objectiveOrientedContainerId = $objectiveOriented;
472  }
473 
475  {
477  }
478 
479  public function isObjectiveOriented()
480  {
481  return (bool)$this->getObjectiveOrientedContainerId();
482  }
483 
484  public function persistTestStartLock($testStartLock)
485  {
486  global $ilDB;
487 
488  $ilDB->update(
489  'tst_active',
490  array('start_lock' => array('text', $testStartLock)),
491  array('active_id' => array('integer', $this->getActiveId()))
492  );
493  }
494 
495  public function lookupTestStartLock()
496  {
497  global $ilDB;
498 
499  $res = $ilDB->queryF(
500  "SELECT start_lock FROM tst_active WHERE active_id = %s",
501  array('integer'), array($this->getActiveId())
502  );
503 
504  while($row = $ilDB->fetchAssoc($res))
505  {
506  return $row['start_lock'];
507  }
508 
509  return null;
510  }
511 
512  public function setAccessCodeToSession($access_code)
513  {
514  if (!is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX]))
515  {
517  }
518 
519  $_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()] = $access_code;
520  }
521 
522  public function unsetAccessCodeInSession()
523  {
524  unset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]);
525  }
526 
527  public function getAccessCodeFromSession()
528  {
529  if( !is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX]) )
530  {
531  return null;
532  }
533 
534  if( !isset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]) )
535  {
536  return null;
537  }
538 
540  }
541 
543  {
544  if( !is_array($_SESSION[self::ACCESS_CODE_SESSION_INDEX]) )
545  {
546  return false;
547  }
548 
549  return isset($_SESSION[self::ACCESS_CODE_SESSION_INDEX][$this->getTestId()]);
550  }
551 
552  public function createNewAccessCode()
553  {
554  do
555  {
556  $code = $this->buildAccessCode();
557  }
558  while( $this->isAccessCodeUsed($code) );
559 
560  return $code;
561  }
562 
563  public function isAccessCodeUsed($code)
564  {
565  global $ilDB;
566 
567  $query = "SELECT anonymous_id FROM tst_active WHERE test_fi = %s AND anonymous_id = %s";
568 
569  $result = $ilDB->queryF(
570  $query, array('integer', 'text'), array($this->getTestId(), $code)
571  );
572 
573  return ($result->numRows() > 0);
574  }
575 
576  private function buildAccessCode()
577  {
578  // create a 5 character code
579  $codestring = self::ACCESS_CODE_CHAR_DOMAIN;
580 
581  mt_srand();
582 
583  $code = "";
584 
585  for($i = 1; $i <= self::ACCESS_CODE_LENGTH; $i++)
586  {
587  $index = mt_rand(0, strlen($codestring)-1);
588  $code .= substr($codestring, $index, 1);
589  }
590 
591  return $code;
592  }
593 
594  public function isAnonymousUser()
595  {
596  return $this->getUserId() == ANONYMOUS_USER_ID;
597  }
598 }