ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObjTestAccess.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2006 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 include_once "./classes/class.ilObjectAccess.php";
25 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
26 
40 {
56  function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "")
57  {
58  global $ilUser, $lng, $rbacsystem, $ilAccess;
59  if ($a_user_id == "")
60  {
61  $a_user_id = $ilUser->getId();
62  }
63 
64  switch ($a_permission)
65  {
66  case "read":
67  case "visible":
69  (!$rbacsystem->checkAccess('write', $a_ref_id)))
70  {
71  $ilAccess->addInfoItem(IL_NO_OBJECT_ACCESS, $lng->txt("tst_warning_test_not_complete"));
72  return false;
73  }
74  break;
75  }
76  switch ($a_cmd)
77  {
78  case "eval_a":
79  case "eval_stat":
81  {
82  $ilAccess->addInfoItem(IL_NO_OBJECT_ACCESS, $lng->txt("tst_warning_test_not_complete"));
83  return false;
84  }
85  break;
86 
87  }
88 
89  return true;
90  }
91 
100  function _getMaxPointsForTestPass($random, $user_id, $test_id, $pass)
101  {
102  global $ilDB;
103  $max = 0;
104  if ($random)
105  {
106  $result = $ilDB->queryF("SELECT SUM(qpl_questions.points) maxpoints FROM tst_test_rnd_qst, qpl_questions, tst_active WHERE tst_active.active_id = tst_test_rnd_qst.active_fi AND tst_test_rnd_qst.question_fi = qpl_questions.question_id AND tst_active.test_fi = %s AND tst_test_rnd_qst.pass = %s AND tst_active.user_fi = %s",
107  array('integer','integer','integer'),
108  array($test_id, $pass, $user_id)
109  );
110  if ($result->numRows())
111  {
112  $row = $ilDB->fetchAssoc($result);
113  $max = $row["maxpoints"];
114  }
115  }
116  else
117  {
118  $result = $ilDB->queryF("SELECT SUM(qpl_questions.points) maxpoints FROM tst_test_question, qpl_questions WHERE tst_test_question.question_fi = qpl_questions.question_id AND tst_test_question.test_fi = %s",
119  array('integer'),
120  array($test_id)
121  );
122  if ($result->numRows())
123  {
124  $row = $ilDB->fetchAssoc($result);
125  $max = $row["maxpoints"];
126  }
127  }
128  return $max;
129  }
130 
138  public static function _isPassed($user_id, $a_obj_id)
139  {
140  global $ilDB;
141 
142  $result = $ilDB->queryF("SELECT tst_result_cache.* FROM tst_result_cache, tst_active, tst_tests WHERE tst_active.test_fi = tst_tests.test_id AND tst_active.user_fi = %s AND tst_tests.obj_fi = %s AND tst_result_cache.active_fi = tst_active.active_id",
143  array('integer','integer'),
144  array($user_id, $a_obj_id)
145  );
146  if (!$result->numRows())
147  {
148  $result = $ilDB->queryF("SELECT tst_active.active_id FROM tst_active, tst_tests WHERE tst_active.test_fi = tst_tests.test_id AND tst_active.user_fi = %s AND tst_tests.obj_fi = %s",
149  array('integer','integer'),
150  array($user_id, $a_obj_id)
151  );
152  $row = $ilDB->fetchAssoc($result);
153  if ($row['active_id'] > 0)
154  {
155  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
157  }
158  else
159  {
160  return false;
161  }
162  }
163  $result = $ilDB->queryF("SELECT tst_result_cache.* FROM tst_result_cache, tst_active, tst_tests WHERE tst_active.test_fi = tst_tests.test_id AND tst_active.user_fi = %s AND tst_tests.obj_fi = %s AND tst_result_cache.active_fi = tst_active.active_id",
164  array('integer','integer'),
165  array($user_id, $a_obj_id)
166  );
167  if (!$result->numRows())
168  {
169  $result = $ilDB->queryF("SELECT tst_pass_result.*, tst_tests.pass_scoring, tst_tests.random_test, tst_tests.test_id FROM tst_pass_result, tst_active, tst_tests WHERE tst_active.test_fi = tst_tests.test_id AND tst_active.user_fi = %s AND tst_tests.obj_fi = %s AND tst_pass_result.active_fi = tst_active.active_id ORDER BY tst_pass_result.pass",
170  array('integer','integer'),
171  array($user_id, $a_obj_id)
172  );
173  $points = array();
174  while ($row = $ilDB->fetchAssoc($result))
175  {
176  array_push($points, $row);
177  }
178  $reached = 0;
179  $max = 0;
180  if ($points[0]["pass_scoring"] == 0)
181  {
182  $reached = $points[count($points)-1]["points"];
183  $max = $points[count($points)-1]["maxpoints"];
184  if (!$max)
185  {
186  $active_id = $points[count($points)-1]["active_fi"];
187  $pass = $points[count($points)-1]["pass"];
188  if (strlen($active_id) && strlen($pass))
189  {
190  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
192  $max = $res['maxpoints'];
193  $reached = $res['points'];
194  }
195  }
196  }
197  else
198  {
199  foreach ($points as $row)
200  {
201  if ($row["points"] > $reached)
202  {
203  $reached = $row["points"];
204  $max = $row["maxpoints"];
205  if (!$max)
206  {
207  $active_id = $row["active_fi"];
208  $pass = $row["pass"];
209  if (strlen($active_id) && strlen($pass))
210  {
211  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
213  $max = $res['maxpoints'];
214  $reached = $res['points'];
215  }
216  }
217  }
218  }
219  }
220  include_once "./Modules/Test/classes/class.assMarkSchema.php";
221  $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
222  $mark = ASS_MarkSchema::_getMatchingMarkFromObjId($a_obj_id, $percentage);
223  return ($mark["passed"]) ? TRUE : FALSE;
224  }
225  else
226  {
227  $row = $ilDB->fetchAssoc($result);
228  return ($row['passed']) ? true : false;
229  }
230  }
231 
237  function _checkCondition($a_obj_id, $a_operator, $a_value, $a_usr_id = 0)
238  {
239  global $ilUser;
240 
241  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
242 
243  switch($a_operator)
244  {
245  case 'passed':
246  return ilObjTestAccess::_isPassed($a_usr_id, $a_obj_id);
247  break;
248 
249  case 'finished':
250  return ilObjTestAccess::_hasFinished($a_usr_id,$a_obj_id);
251 
252  case 'not_finished':
253  return !ilObjTestAccess::_hasFinished($a_usr_id,$a_obj_id);
254 
255  default:
256  return true;
257  }
258  return true;
259  }
260 
273  function _getCommands()
274  {
275  $commands = array
276  (
277  array("permission" => "read", "cmd" => "infoScreen", "lang_var" => "tst_run",
278  "default" => true),
279  array("permission" => "write", "cmd" => "", "lang_var" => "edit"),
280  array("permission" => "tst_statistics", "cmd" => "outEvaluation", "lang_var" => "tst_statistical_evaluation")
281  );
282 
283  return $commands;
284  }
285 
286  //
287  // object specific access related methods
288  //
289 
293  function _lookupCreationComplete($a_obj_id)
294  {
295  global $ilDB;
296 
297  $result = $ilDB->queryF("SELECT complete FROM tst_tests WHERE obj_fi=%s",
298  array('integer'),
299  array($a_obj_id)
300  );
301  if ($result->numRows() == 1)
302  {
303  $row = $ilDB->fetchAssoc($result);
304  }
305 
306  return ($row['complete']) ? true : false;
307  }
308 
318  function _hasFinished($a_user_id,$a_obj_id)
319  {
320  global $ilDB;
321 
322  $res = $ilDB->queryF("SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s AND tries > '0'",
323  array('integer','integer'),
324  array($a_user_id, ilObjTestAccess::_getTestIDFromObjectID($a_obj_id))
325  );
326  return $res->numRows() ? true : false;
327  }
328 
336  function _getTestIDFromObjectID($object_id)
337  {
338  global $ilDB;
339  $test_id = FALSE;
340  $result = $ilDB->queryF("SELECT test_id FROM tst_tests WHERE obj_fi = %s",
341  array('integer'),
342  array($object_id)
343  );
344  if ($result->numRows())
345  {
346  $row = $ilDB->fetchAssoc($result);
347  $test_id = $row["test_id"];
348  }
349  return $test_id;
350  }
351 
352  function &_getTestQuestions($active_id, $pass = NULL)
353  {
354  if (is_null($pass))
355  {
356  $pass = 0;
357  }
358  $questions = array();
359 
360  global $ilDB;
361  $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
362  array('integer'),
363  array($active_id)
364  );
365  $test_id = "";
366  if ($result->numRows())
367  {
368  $row = $ilDB->fetchAssoc($result);
369  $test_id = $row["test_fi"];
370  }
371  else
372  {
373  return $questions;
374  }
375  $result = $ilDB->queryF("SELECT qpl_questions.question_id, qpl_questions.points FROM qpl_questions, tst_test_question WHERE tst_test_question.question_fi = qpl_questions.question_id AND tst_test_question.test_fi = %s ORDER BY tst_test_question.sequence",
376  array('integer'),
377  array($test_id)
378  );
379  if ($result->numRows())
380  {
381  // standard test
382  while ($row = $ilDB->fetchAssoc($result))
383  {
384  array_push($questions, $row);
385  }
386  }
387  else
388  {
389  // random test
390  $result = $ilDB->queryF("SELECT qpl_questions.question_id, qpl_questions.points FROM qpl_questions, tst_test_rnd_qst WHERE tst_test_rnd_qst.question_fi = qpl_questions.question_id AND tst_test_rnd_qst.active_fi = %s AND tst_test_rnd_qst.pass = %s ORDER BY tst_test_rnd_qst.sequence",
391  array('integer','integer'),
392  array($active_id, $pass)
393  );
394  if ($result->numRows())
395  {
396  while ($row = $ilDB->fetchAssoc($result))
397  {
398  array_push($questions, $row);
399  }
400  }
401  }
402  return $questions;
403  }
404 
411  function _isComplete($a_obj_id)
412  {
413  global $ilDB;
414 
415  $test_id = ilObjTestAccess::_getTestIDFromObjectID($a_obj_id);
416  $result = $ilDB->queryF("SELECT tst_mark.*, tst_tests.* FROM tst_tests, tst_mark WHERE tst_mark.test_fi = tst_tests.test_id AND tst_tests.test_id = %s",
417  array('integer'),
418  array($test_id)
419  );
420  $found = $result->numRows();
421  if ($found)
422  {
423  $row = $ilDB->fetchAssoc($result);
424  // check for at least: title, author and minimum of 1 mark step
425  if ((strlen($row["title"])) &&
426  (strlen($row["author"])) &&
427  ($found))
428  {
429  // check also for minmum of 1 question
430  if (ilObjTestAccess::_getQuestionCount($test_id) > 0)
431  {
432  return true;
433  }
434  else
435  {
436  return false;
437  }
438  }
439  else
440  {
441  return false;
442  }
443  }
444  else
445  {
446  return false;
447  }
448  $test = new ilObjTest($obj_id, false);
449  $test->loadFromDb();
450  if (($test->getTitle()) and ($test->author) and (count($test->mark_schema->mark_steps)) and (count($test->questions)))
451  {
452  return true;
453  }
454  else
455  {
456  return false;
457  }
458  }
459 
467  function &_getTestData($test_id)
468  {
469  global $ilDB;
470  $result = $ilDB->queryF("SELECT * FROM tst_tests WHERE test_id = %s",
471  array('integer'),
472  array($test_id)
473  );
474  if (!$result->numRows())
475  {
476  return 0;
477  }
478  return $ilDB->fetchAssoc($result);
479  }
480 
487  function _lookupObjIdForTestId($a_test_id)
488  {
489  global $ilDB;
490 
491  $result = $ilDB->queryF("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
492  array('integer'),
493  array($a_test_id)
494  );
495 
496  $row = $ilDB->fetchAssoc($result);
497  return $row["obj_fi"];
498  }
499 
506 function _getQuestionCount($test_id)
507 {
508  global $ilDB;
509 
510  $num = 0;
511 
513 
514  if ($test["random_test"] == 1)
515  {
516  if ($test["random_question_count"] > 0)
517  {
518  $num = $test["random_question_count"];
519  }
520  else
521  {
522  $result = $ilDB->queryF("SELECT SUM(num_of_q) questioncount FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
523  array('integer'),
524  array($test_id)
525  );
526  if ($result->numRows())
527  {
528  $row = $ilDB->fetchAssoc($result);
529  $num = $row["questioncount"];
530  }
531  }
532  }
533  else
534  {
535  $result = $ilDB->queryF("SELECT test_question_id FROM tst_test_question WHERE test_fi = %s",
536  array('integer'),
537  array($test_id)
538  );
539  $num = $result->numRows();
540  }
541  return $num;
542 }
543 
552  {
553  global $ilDB;
554 
555  $query = 'SELECT DISTINCT t.obj_fi '
556  .'FROM tst_tests t '
557  .'INNER JOIN tst_test_random r '
558  .'ON t.test_id = r.test_fi '
559  .'WHERE r.questionpool_fi = '
560  . $ilDB->quote($qpl_id, 'integer');
561 
562  $result = $ilDB->query($query);
563 
564  $tests = array();
565  while ($row = $ilDB->fetchAssoc($result))
566  {
567  $tests[] = $row['obj_fi'];
568  }
569 
570  return $tests;
571  }
572  // fim.
573 
580  function _lookupOnlineTestAccess($a_test_id, $a_user_id)
581  {
582  global $ilDB, $lng;
583 
584  $result = $ilDB->queryF("SELECT tst_tests.* FROM tst_tests WHERE tst_tests.obj_fi = %s",
585  array('integer'),
586  array($a_test_id)
587  );
588  if ($result->numRows())
589  {
590  $row = $ilDB->fetchAssoc($result);
591  if ($row["fixed_participants"])
592  {
593  $result = $ilDB->queryF("SELECT * FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
594  array('integer','integer'),
595  array($row["test_id"], $a_user_id)
596  );
597  if ($result->numRows())
598  {
599  $row = $ilDB->fetchAssoc($result);
600  if (trim($row['clientip']) != "")
601  {
602  $row['clientip'] = preg_replace("/[^0-9.?*,:]+/","",$row['clientip']);
603  $row['clientip'] = str_replace(".","\\.",$row['clientip']);
604  $row['clientip'] = str_replace(Array("?","*",","), Array("[0-9]","[0-9]*","|"), $row['clientip']);
605  if (!preg_match("/^".$row['clientip']."$/", $_SERVER["REMOTE_ADDR"]))
606  {
607  return $lng->txt("tst_user_wrong_clientip");
608  }
609  else
610  {
611  return true;
612  }
613  }
614  else
615  {
616  return true;
617  }
618  }
619  else
620  {
621  return $lng->txt("tst_user_not_invited");
622  }
623  }
624  else
625  {
626  return true;
627  }
628  }
629  else
630  {
631  return true;
632  }
633  }
634 
642  function _getParticipantData($active_id)
643  {
644  global $lng, $ilDB;
645 
646  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE active_id = %s",
647  array("integer"),
648  array($active_id)
649  );
650  $row = $ilDB->fetchAssoc($result);
651  $user_id = $row["user_fi"];
652  $test_id = $row["test_fi"];
653  $importname = $row['importname'];
654 
655  $result = $ilDB->queryF("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
656  array("integer"),
657  array($test_id)
658  );
659  $row = $ilDB->fetchAssoc($result);
660  $obj_id = $row["obj_fi"];
661 
662  include_once "./Modules/Test/classes/class.ilObjTest.php";
663  $is_anonymous = ilObjTest::_lookupAnonymity($obj_id);
664 
665  include_once './Services/User/classes/class.ilObjUser.php';
666  $uname = ilObjUser::_lookupName($user_id);
667 
668  $name = "";
669  if (strlen($importname))
670  {
671  $name = $importname . ' (' . $lng->txt('imported') . ')';
672  }
673  else if (strlen($uname["firstname"].$uname["lastname"]) == 0)
674  {
675  $name = $lng->txt("deleted_user");
676  }
677  else
678  {
679  if ($user_id == ANONYMOUS_USER_ID)
680  {
681  $name = $lastname;
682  }
683  else
684  {
685  $name = trim($uname["lastname"] . ", " . $uname["firstname"] . " " . $uname["title"]);
686  }
687  if ($is_anonymous)
688  {
689  $name = $lng->txt("anonymous");
690  }
691  }
692  return $name;
693  }
694 
701  function _getParticipantId($active_id)
702  {
703  global $lng, $ilDB;
704 
705  $result = $ilDB->queryF("SELECT user_fi FROM tst_active WHERE active_id = %s",
706  array("integer"),
707  array($active_id)
708  );
709  $row = $ilDB->fetchAssoc($result);
710  return $row["user_fi"];
711  }
712 
713 
728  function &_getPassedUsers($a_obj_id)
729  {
730  global $ilDB;
731 
732  $passed_users = array();
733  // Maybe SELECT DISTINCT(tst_active.user_fi)... ?
734  $userresult = $ilDB->queryF("SELECT DISTINCT(tst_active.active_id) FROM tst_active, tst_tests WHERE tst_tests.test_id = tst_active.test_fi AND tst_tests.obj_fi = %s",
735  array('integer'),
736  array($a_obj_id)
737  );
738  $all_participants = array();
739  while ($row = $ilDB->fetchAssoc($userresult))
740  {
741  array_push($all_participants, $row['active_id']);
742  }
743 
744  $result = $ilDB->query("SELECT tst_result_cache.*, tst_active.user_fi FROM tst_result_cache, tst_active WHERE tst_active.active_id = tst_result_cache.active_fi AND " . $ilDB->in('active_fi', $all_participants, false, 'integer'));
745  $found_all = ($result->numRows() == count($all_participants)) ? true : false;
746  if (!$found_all)
747  {
748  // if the result cache entries do not exist, create them
749  $found_participants = array();
750  while ($data = $ilDB->fetchAssoc($result))
751  {
752  array_push($found_participants, $data['active_fi']);
753  }
754  foreach ($all_participants as $active_id)
755  {
756  if (!in_array($active_id, $found_participants))
757  {
758  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
760  }
761  }
762  $result = $ilDB->query("SELECT tst_result_cache.*, tst_active.user_fi FROM tst_result_cache, tst_active WHERE tst_active.active_id = tst_result_cache.active_fi AND " . $ilDB->in('active_fi', $all_participants, false, 'integer'));
763  }
764  while ($data = $ilDB->fetchAssoc($result))
765  {
766  $data['user_id'] = $data['user_fi'];
767  array_push($passed_users, $data);
768  }
769  return $passed_users;
770  }
771 
775  function _checkGoto($a_target)
776  {
777  global $ilAccess;
778 
779  $t_arr = explode("_", $a_target);
780 
781  if ($t_arr[0] != "tst" || ((int) $t_arr[1]) <= 0)
782  {
783  return false;
784  }
785 
786  if ($ilAccess->checkAccess("visible", "", $t_arr[1]))
787  {
788  return true;
789  }
790  return false;
791  }
792 }
793 
794 ?>