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