ILIAS  Release_4_0_x_branch Revision 61816
 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 _getQuestionCount($test_id)
488 {
489  global $ilDB;
490 
491  $num = 0;
492 
494 
495  if ($test["random_test"] == 1)
496  {
497  if ($test["random_question_count"] > 0)
498  {
499  $num = $test["random_question_count"];
500  }
501  else
502  {
503  $result = $ilDB->queryF("SELECT SUM(num_of_q) questioncount FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
504  array('integer'),
505  array($test_id)
506  );
507  if ($result->numRows())
508  {
509  $row = $ilDB->fetchAssoc($result);
510  $num = $row["questioncount"];
511  }
512  }
513  }
514  else
515  {
516  $result = $ilDB->queryF("SELECT test_question_id FROM tst_test_question WHERE test_fi = %s",
517  array('integer'),
518  array($test_id)
519  );
520  $num = $result->numRows();
521  }
522  return $num;
523 }
524 
531  function _lookupOnlineTestAccess($a_test_id, $a_user_id)
532  {
533  global $ilDB, $lng;
534 
535  $result = $ilDB->queryF("SELECT tst_tests.* FROM tst_tests WHERE tst_tests.obj_fi = %s",
536  array('integer'),
537  array($a_test_id)
538  );
539  if ($result->numRows())
540  {
541  $row = $ilDB->fetchAssoc($result);
542  if ($row["fixed_participants"])
543  {
544  $result = $ilDB->queryF("SELECT * FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
545  array('integer','integer'),
546  array($row["test_id"], $a_user_id)
547  );
548  if ($result->numRows())
549  {
550  $row = $ilDB->fetchAssoc($result);
551  if (trim($row['clientip']) != "")
552  {
553  $row['clientip'] = preg_replace("/[^0-9.?*,:]+/","",$row['clientip']);
554  $row['clientip'] = str_replace(".","\\.",$row['clientip']);
555  $row['clientip'] = str_replace(Array("?","*",","), Array("[0-9]","[0-9]*","|"), $row['clientip']);
556  if (!preg_match("/^".$row['clientip']."$/", $_SERVER["REMOTE_ADDR"]))
557  {
558  return $lng->txt("tst_user_wrong_clientip");
559  }
560  else
561  {
562  return true;
563  }
564  }
565  else
566  {
567  return true;
568  }
569  }
570  else
571  {
572  return $lng->txt("tst_user_not_invited");
573  }
574  }
575  else
576  {
577  return true;
578  }
579  }
580  else
581  {
582  return true;
583  }
584  }
585 
593  function _getParticipantData($active_id)
594  {
595  global $lng, $ilDB;
596 
597  $result = $ilDB->queryF("SELECT user_fi, test_fi FROM tst_active WHERE active_id = %s",
598  array("integer"),
599  array($active_id)
600  );
601  $row = $ilDB->fetchAssoc($result);
602  $user_id = $row["user_fi"];
603  $test_id = $row["test_fi"];
604 
605  $result = $ilDB->queryF("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
606  array("integer"),
607  array($test_id)
608  );
609  $row = $ilDB->fetchAssoc($result);
610  $obj_id = $row["obj_fi"];
611 
612  include_once "./Modules/Test/classes/class.ilObjTest.php";
613  $is_anonymous = ilObjTest::_lookupAnonymity($obj_id);
614 
615  include_once './Services/User/classes/class.ilObjUser.php';
616  $uname = ilObjUser::_lookupName($user_id);
617 
618  $name = "";
619  if (strlen($uname["firstname"].$uname["lastname"]) == 0)
620  {
621  $name = $lng->txt("deleted_user");
622  }
623  else
624  {
625  if ($user_id == ANONYMOUS_USER_ID)
626  {
627  $name = $lastname;
628  }
629  else
630  {
631  $name = trim($uname["lastname"] . ", " . $uname["firstname"] . " " . $uname["title"]);
632  }
633  if ($is_anonymous)
634  {
635  $name = $lng->txt("anonymous");
636  }
637  }
638  return $name;
639  }
640 
655  function &_getPassedUsers($a_obj_id)
656  {
657  global $ilDB;
658 
659  $passed_users = array();
660  // Maybe SELECT DISTINCT(tst_active.user_fi)... ?
661  $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",
662  array('integer'),
663  array($a_obj_id)
664  );
665  $all_participants = array();
666  while ($row = $ilDB->fetchAssoc($userresult))
667  {
668  array_push($all_participants, $row['active_id']);
669  }
670 
671  $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'));
672  $found_all = ($result->numRows() == count($all_participants)) ? true : false;
673  if (!$found_all)
674  {
675  // if the result cache entries do not exist, create them
676  $found_participants = array();
677  while ($data = $ilDB->fetchAssoc($result))
678  {
679  array_push($found_participants, $data['active_fi']);
680  }
681  foreach ($all_participants as $active_id)
682  {
683  if (!in_array($active_id, $found_participants))
684  {
685  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
687  }
688  }
689  $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'));
690  }
691  while ($data = $ilDB->fetchAssoc($result))
692  {
693  $data['user_id'] = $data['user_fi'];
694  array_push($passed_users, $data);
695  }
696  return $passed_users;
697  }
698 
702  function _checkGoto($a_target)
703  {
704  global $ilAccess;
705 
706  $t_arr = explode("_", $a_target);
707 
708  if ($t_arr[0] != "tst" || ((int) $t_arr[1]) <= 0)
709  {
710  return false;
711  }
712 
713  if ($ilAccess->checkAccess("visible", "", $t_arr[1]))
714  {
715  return true;
716  }
717  return false;
718  }
719 }
720 
721 ?>