ILIAS  Release_4_2_x_branch Revision 61807
 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" => "write", "cmd" => "showPage", "lang_var" => "tst_edit_questions"),
278  array("permission" => "write", "cmd" => "properties", "lang_var" => "settings"),
279  array("permission" => "read", "cmd" => "infoScreen", "lang_var" => "tst_run",
280  "default" => true),
281  //array("permission" => "write", "cmd" => "", "lang_var" => "edit"),
282  array("permission" => "tst_statistics", "cmd" => "outEvaluation", "lang_var" => "tst_statistical_evaluation"),
283  );
284 
285  return $commands;
286  }
287 
288  //
289  // object specific access related methods
290  //
291 
295  function _lookupCreationComplete($a_obj_id)
296  {
297  global $ilDB;
298 
299  $result = $ilDB->queryF("SELECT complete FROM tst_tests WHERE obj_fi=%s",
300  array('integer'),
301  array($a_obj_id)
302  );
303  if ($result->numRows() == 1)
304  {
305  $row = $ilDB->fetchAssoc($result);
306  }
307 
308  return ($row['complete']) ? true : false;
309  }
310 
320  function _hasFinished($a_user_id,$a_obj_id)
321  {
322  global $ilDB;
323 
324  $res = $ilDB->queryF("SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s AND tries > '0'",
325  array('integer','integer'),
326  array($a_user_id, ilObjTestAccess::_getTestIDFromObjectID($a_obj_id))
327  );
328  return $res->numRows() ? true : false;
329  }
330 
338  function _getTestIDFromObjectID($object_id)
339  {
340  global $ilDB;
341  $test_id = FALSE;
342  $result = $ilDB->queryF("SELECT test_id FROM tst_tests WHERE obj_fi = %s",
343  array('integer'),
344  array($object_id)
345  );
346  if ($result->numRows())
347  {
348  $row = $ilDB->fetchAssoc($result);
349  $test_id = $row["test_id"];
350  }
351  return $test_id;
352  }
353 
354  function &_getTestQuestions($active_id, $pass = NULL)
355  {
356  if (is_null($pass))
357  {
358  $pass = 0;
359  }
360  $questions = array();
361 
362  global $ilDB;
363  $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
364  array('integer'),
365  array($active_id)
366  );
367  $test_id = "";
368  if ($result->numRows())
369  {
370  $row = $ilDB->fetchAssoc($result);
371  $test_id = $row["test_fi"];
372  }
373  else
374  {
375  return $questions;
376  }
377  $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",
378  array('integer'),
379  array($test_id)
380  );
381  if ($result->numRows())
382  {
383  // standard test
384  while ($row = $ilDB->fetchAssoc($result))
385  {
386  array_push($questions, $row);
387  }
388  }
389  else
390  {
391  // random test
392  $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",
393  array('integer','integer'),
394  array($active_id, $pass)
395  );
396  if ($result->numRows())
397  {
398  while ($row = $ilDB->fetchAssoc($result))
399  {
400  array_push($questions, $row);
401  }
402  }
403  }
404  return $questions;
405  }
406 
413  function _isComplete($a_obj_id)
414  {
415  global $ilDB;
416 
417  $test_id = ilObjTestAccess::_getTestIDFromObjectID($a_obj_id);
418  $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",
419  array('integer'),
420  array($test_id)
421  );
422  $found = $result->numRows();
423  if ($found)
424  {
425  $row = $ilDB->fetchAssoc($result);
426  // check for at least: title, author and minimum of 1 mark step
427  if ((strlen($row["title"])) &&
428  (strlen($row["author"])) &&
429  ($found))
430  {
431  // check also for minmum of 1 question
432  if (ilObjTestAccess::_getQuestionCount($test_id) > 0)
433  {
434  return true;
435  }
436  else
437  {
438  return false;
439  }
440  }
441  else
442  {
443  return false;
444  }
445  }
446  else
447  {
448  return false;
449  }
450  $test = new ilObjTest($obj_id, false);
451  $test->loadFromDb();
452  if (($test->getTitle()) and ($test->author) and (count($test->mark_schema->mark_steps)) and (count($test->questions)))
453  {
454  return true;
455  }
456  else
457  {
458  return false;
459  }
460  }
461 
469  function &_getTestData($test_id)
470  {
471  global $ilDB;
472  $result = $ilDB->queryF("SELECT * FROM tst_tests WHERE test_id = %s",
473  array('integer'),
474  array($test_id)
475  );
476  if (!$result->numRows())
477  {
478  return 0;
479  }
480  return $ilDB->fetchAssoc($result);
481  }
482 
489  function _lookupObjIdForTestId($a_test_id)
490  {
491  global $ilDB;
492 
493  $result = $ilDB->queryF("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
494  array('integer'),
495  array($a_test_id)
496  );
497 
498  $row = $ilDB->fetchAssoc($result);
499  return $row["obj_fi"];
500  }
501 
508 function _getQuestionCount($test_id)
509 {
510  global $ilDB;
511 
512  $num = 0;
513 
515 
516  if ($test["random_test"] == 1)
517  {
518  if ($test["random_question_count"] > 0)
519  {
520  $num = $test["random_question_count"];
521  }
522  else
523  {
524  $result = $ilDB->queryF("SELECT SUM(num_of_q) questioncount FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
525  array('integer'),
526  array($test_id)
527  );
528  if ($result->numRows())
529  {
530  $row = $ilDB->fetchAssoc($result);
531  $num = $row["questioncount"];
532  }
533  }
534  }
535  else
536  {
537  $result = $ilDB->queryF("SELECT test_question_id FROM tst_test_question WHERE test_fi = %s",
538  array('integer'),
539  array($test_id)
540  );
541  $num = $result->numRows();
542  }
543  return $num;
544 }
545 
554  {
555  global $ilDB;
556 
557  $query = 'SELECT DISTINCT t.obj_fi '
558  .'FROM tst_tests t '
559  .'INNER JOIN tst_test_random r '
560  .'ON t.test_id = r.test_fi '
561  .'WHERE r.questionpool_fi = '
562  . $ilDB->quote($qpl_id, 'integer');
563 
564  $result = $ilDB->query($query);
565 
566  $tests = array();
567  while ($row = $ilDB->fetchAssoc($result))
568  {
569  $tests[] = $row['obj_fi'];
570  }
571 
572  return $tests;
573  }
574  // fim.
575 
582  function _lookupOnlineTestAccess($a_test_id, $a_user_id)
583  {
584  global $ilDB, $lng;
585 
586  $result = $ilDB->queryF("SELECT tst_tests.* FROM tst_tests WHERE tst_tests.obj_fi = %s",
587  array('integer'),
588  array($a_test_id)
589  );
590  if ($result->numRows())
591  {
592  $row = $ilDB->fetchAssoc($result);
593  if ($row["fixed_participants"])
594  {
595  $result = $ilDB->queryF("SELECT * FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
596  array('integer','integer'),
597  array($row["test_id"], $a_user_id)
598  );
599  if ($result->numRows())
600  {
601  $row = $ilDB->fetchAssoc($result);
602  if (trim($row['clientip']) != "")
603  {
604  $row['clientip'] = preg_replace("/[^0-9.?*,:]+/","",$row['clientip']);
605  $row['clientip'] = str_replace(".","\\.",$row['clientip']);
606  $row['clientip'] = str_replace(Array("?","*",","), Array("[0-9]","[0-9]*","|"), $row['clientip']);
607  if (!preg_match("/^".$row['clientip']."$/", $_SERVER["REMOTE_ADDR"]))
608  {
609  return $lng->txt("tst_user_wrong_clientip");
610  }
611  else
612  {
613  return true;
614  }
615  }
616  else
617  {
618  return true;
619  }
620  }
621  else
622  {
623  return $lng->txt("tst_user_not_invited");
624  }
625  }
626  else
627  {
628  return true;
629  }
630  }
631  else
632  {
633  return true;
634  }
635  }
636 
644  function _getParticipantData($active_id)
645  {
646  global $lng, $ilDB;
647 
648  $result = $ilDB->queryF("SELECT * FROM tst_active WHERE active_id = %s",
649  array("integer"),
650  array($active_id)
651  );
652  $row = $ilDB->fetchAssoc($result);
653  $user_id = $row["user_fi"];
654  $test_id = $row["test_fi"];
655  $importname = $row['importname'];
656 
657  $result = $ilDB->queryF("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
658  array("integer"),
659  array($test_id)
660  );
661  $row = $ilDB->fetchAssoc($result);
662  $obj_id = $row["obj_fi"];
663 
664  include_once "./Modules/Test/classes/class.ilObjTest.php";
665  $is_anonymous = ilObjTest::_lookupAnonymity($obj_id);
666 
667  include_once './Services/User/classes/class.ilObjUser.php';
668  $uname = ilObjUser::_lookupName($user_id);
669 
670  $name = "";
671  if (strlen($importname))
672  {
673  $name = $importname . ' (' . $lng->txt('imported') . ')';
674  }
675  else if (strlen($uname["firstname"].$uname["lastname"]) == 0)
676  {
677  $name = $lng->txt("deleted_user");
678  }
679  else
680  {
681  if ($user_id == ANONYMOUS_USER_ID)
682  {
683  $name = $lastname;
684  }
685  else
686  {
687  $name = trim($uname["lastname"] . ", " . $uname["firstname"] . " " . $uname["title"]);
688  }
689  if ($is_anonymous)
690  {
691  $name = $lng->txt("anonymous");
692  }
693  }
694  return $name;
695  }
696 
703  function _getParticipantId($active_id)
704  {
705  global $lng, $ilDB;
706 
707  $result = $ilDB->queryF("SELECT user_fi FROM tst_active WHERE active_id = %s",
708  array("integer"),
709  array($active_id)
710  );
711  $row = $ilDB->fetchAssoc($result);
712  return $row["user_fi"];
713  }
714 
715 
730  function &_getPassedUsers($a_obj_id)
731  {
732  global $ilDB;
733 
734  $passed_users = array();
735  // Maybe SELECT DISTINCT(tst_active.user_fi)... ?
736  $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",
737  array('integer'),
738  array($a_obj_id)
739  );
740  $all_participants = array();
741  while ($row = $ilDB->fetchAssoc($userresult))
742  {
743  array_push($all_participants, $row['active_id']);
744  }
745 
746  $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'));
747  $found_all = ($result->numRows() == count($all_participants)) ? true : false;
748  if (!$found_all)
749  {
750  // if the result cache entries do not exist, create them
751  $found_participants = array();
752  while ($data = $ilDB->fetchAssoc($result))
753  {
754  array_push($found_participants, $data['active_fi']);
755  }
756  foreach ($all_participants as $active_id)
757  {
758  if (!in_array($active_id, $found_participants))
759  {
760  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
762  }
763  }
764  $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'));
765  }
766  while ($data = $ilDB->fetchAssoc($result))
767  {
768  $data['user_id'] = $data['user_fi'];
769  array_push($passed_users, $data);
770  }
771  return $passed_users;
772  }
773 
777  function _checkGoto($a_target)
778  {
779  global $ilAccess;
780 
781  $t_arr = explode("_", $a_target);
782 
783  if ($t_arr[0] != "tst" || ((int) $t_arr[1]) <= 0)
784  {
785  return false;
786  }
787 
788  if ($ilAccess->checkAccess("visible", "", $t_arr[1]))
789  {
790  return true;
791  }
792  return false;
793  }
794 
803  static function _isOffline($a_obj_id)
804  {
805 // global $ilUser;
806 // return (self::_lookupOnlineTestAccess($a_obj_id, $ilUser->getId()) !== true) ||
807 // (!ilObjTestAccess::_lookupCreationComplete($a_obj_id));
808  return !self::_isOnline($a_obj_id);
809  }
810 
817  public static function _isOnline($a_obj_id)
818  {
819  global $ilDB;
820 
821  $query = "
822  SELECT test_id
823  FROM tst_tests
824  WHERE obj_fi = %s
825  AND online_status = 1
826  ";
827 
828  $result = $ilDB->queryF( $query, array('integer'), array($a_obj_id) );
829 
830  return $result->numRows() == 1;
831  }
832 }
833 
834 ?>