ILIAS  Release_3_10_x_branch Revision 61812
 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 
102  function _getMaxPointsForTestPass($random, $user_id, $test_id, $pass)
103  {
104  global $ilDB;
105  $max = 0;
106  if ($random)
107  {
108  $query = sprintf("SELECT SUM(qpl_questions.points) AS maxpoints FROM tst_test_random_question, qpl_questions, tst_active WHERE tst_active.active_id = tst_test_random_question.active_fi AND tst_test_random_question.question_fi = qpl_questions.question_id AND tst_active.test_fi = %s AND tst_test_random_question.pass = %s AND tst_active.user_fi = %s",
109  $ilDB->quote($test_id . ""),
110  $ilDB->quote($pass . ""),
111  $ilDB->quote($user_id . "")
112  );
113  $result = $ilDB->query($query);
114  if ($result->numRows())
115  {
116  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
117  $max = $row["maxpoints"];
118  }
119  }
120  else
121  {
122  $query = sprintf("SELECT SUM(qpl_questions.points) AS maxpoints FROM tst_test_question, qpl_questions WHERE tst_test_question.question_fi = qpl_questions.question_id AND tst_test_question.test_fi = %s",
123  $ilDB->quote($test_id . "")
124  );
125  $result = $ilDB->query($query);
126  if ($result->numRows())
127  {
128  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
129  $max = $row["maxpoints"];
130  }
131  }
132  return $max;
133  }
134 
144  function _isPassed($user_id, $a_obj_id)
145  {
146  global $ilDB;
147  $query = sprintf("SELECT tst_test_pass_result.*, tst_tests.pass_scoring, tst_tests.random_test, tst_tests.test_id FROM tst_test_pass_result, tst_active, tst_tests, object_data WHERE object_data.obj_id = tst_tests.obj_fi AND tst_active.test_fi = tst_tests.test_id AND tst_active.user_fi = %s AND object_data.obj_id = %s AND tst_test_pass_result.active_fi = tst_active.active_id ORDER BY tst_test_pass_result.pass",
148  $ilDB->quote($user_id . ""),
149  $ilDB->quote($a_obj_id . "")
150  );
151  $result = $ilDB->query($query);
152  $points = array();
153  while ($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))
154  {
155  array_push($points, $row);
156  }
157  $reached = 0;
158  $max = 0;
159  if ($points[0]["pass_scoring"] == 0)
160  {
161  $reached = $points[count($points)-1]["points"];
162  $max = ilObjTestAccess::_getMaxPointsForTestPass($points[count($points)-1]["random_test"], $user_id, $points[count($points)-1]["test_id"], $points[count($points)-1]["pass"]);
163  if (!strlen($max))
164  {
165  include_once "./Modules/Test/classes/class.ilTestEvaluationData.php";
166  include_once "./Modules/Test/classes/class.ilObjTest.php";
167  $test = new ilObjTest($a_obj_id, false);
168  $test->loadFromDb();
170  $p = $data->getParticipants();
171  if (!is_null($p))
172  {
173  $user = $p[$points[count($points)-1]["active_fi"]];
174  if (!is_null($user))
175  {
176  $max = $user->getMaxpoints();
177  }
178  }
179  }
180  }
181  else
182  {
183  foreach ($points as $row)
184  {
185  if ($row["points"] > $reached)
186  {
187  $max = ilObjTestAccess::_getMaxPointsForTestPass($row["random_test"], $user_id, $row["test_id"], $row["pass"]);
188  if (!strlen($max))
189  {
190  include_once "./Modules/Test/classes/class.ilTestEvaluationData.php";
191  include_once "./Modules/Test/classes/class.ilObjTest.php";
192  $test = new ilObjTest($a_obj_id, false);
193  $test->loadFromDb();
195  $p = $data->getParticipants();
196  if (!is_null($p))
197  {
198  $user = $p[$points[count($points)-1]["active_fi"]];
199  if (!is_null($user))
200  {
201  $max = $user->getMaxpoints();
202  }
203  }
204  }
205  $reached = $row["points"];
206  }
207  }
208  }
209  include_once "./Modules/Test/classes/class.assMarkSchema.php";
210  $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
211  $mark = ASS_MarkSchema::_getMatchingMarkFromObjId($a_obj_id, $percentage);
212  return ($mark["passed"]) ? TRUE : FALSE;
213  }
214 
220  function _checkCondition($a_obj_id, $a_operator, $a_value, $a_usr_id = 0)
221  {
222  global $ilUser;
223 
224  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
225 
226  switch($a_operator)
227  {
228  case 'passed':
229  return ilObjTestAccess::_isPassed($a_usr_id, $a_obj_id);
230  break;
231 
232  case 'finished':
233  return ilObjTestAccess::_hasFinished($a_usr_id,$a_obj_id);
234 
235  case 'not_finished':
236  return !ilObjTestAccess::_hasFinished($a_usr_id,$a_obj_id);
237 
238  default:
239  return true;
240  }
241  return true;
242  }
243 
256  function _getCommands()
257  {
258  $commands = array
259  (
260  array("permission" => "read", "cmd" => "infoScreen", "lang_var" => "tst_run",
261  "default" => true),
262  array("permission" => "write", "cmd" => "", "lang_var" => "edit"),
263  array("permission" => "tst_statistics", "cmd" => "outEvaluation", "lang_var" => "tst_statistical_evaluation")
264  );
265 
266  return $commands;
267  }
268 
269  //
270  // object specific access related methods
271  //
272 
276  function _lookupCreationComplete($a_obj_id)
277  {
278  global $ilDB;
279 
280  $q = sprintf("SELECT * FROM tst_tests WHERE obj_fi=%s",
281  $ilDB->quote($a_obj_id)
282  );
283  $result = $ilDB->query($q);
284  if ($result->numRows() == 1)
285  {
286  $row = $result->fetchRow(MDB2_FETCHMODE_OBJECT);
287  }
288 
289  if (!$row->complete)
290  {
291  return false;
292  }
293 
294  return true;
295  }
296 
306  function _hasFinished($a_user_id,$a_obj_id)
307  {
308  global $ilDB;
309 
310  $query = sprintf("SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s AND tries > '0'",
311  $ilDB->quote($a_user_id . ""),
312  $ilDB->quote(ilObjTestAccess::_getTestIDFromObjectID($a_obj_id) . "")
313  );
314  $res = $ilDB->query($query);
315 
316  return $res->numRows() ? true : false;
317  }
318 
328  function _getTestIDFromObjectID($object_id)
329  {
330  global $ilDB;
331  $test_id = FALSE;
332  $query = sprintf("SELECT test_id FROM tst_tests WHERE obj_fi = %s",
333  $ilDB->quote($object_id . "")
334  );
335  $result = $ilDB->query($query);
336  if ($result->numRows())
337  {
338  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
339  $test_id = $row["test_id"];
340  }
341  return $test_id;
342  }
343 
344  function &_getTestQuestions($active_id, $pass = NULL)
345  {
346  if (is_null($pass))
347  {
348  $pass = 0;
349  }
350  $questions = array();
351 
352  global $ilDB;
353  $query = sprintf("SELECT test_fi FROM tst_active WHERE active_id = %s",
354  $ilDB->quote($active_id . "")
355  );
356  $result = $ilDB->query($query);
357  $test_id = "";
358  if ($result->numRows())
359  {
360  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
361  $test_id = $row["test_fi"];
362  }
363  else
364  {
365  return $questions;
366  }
367  $query = sprintf("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",
368  $ilDB->quote($test_id . "")
369  );
370  $result = $ilDB->query($query);
371  if ($result->numRows())
372  {
373  // standard test
374  while ($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))
375  {
376  array_push($questions, $row);
377  }
378  }
379  else
380  {
381  // random test
382  $query = sprintf("SELECT qpl_questions.question_id, qpl_questions.points FROM qpl_questions, tst_test_random_question WHERE tst_test_random_question.question_fi = qpl_questions.question_id AND tst_test_random_question.active_fi = %s AND tst_test_random_question.pass = %s ORDER BY tst_test_random_question.sequence",
383  $ilDB->quote($active_id . ""),
384  $ilDB->quote($pass . "")
385  );
386  $result = $ilDB->query($query);
387  if ($result->numRows())
388  {
389  while ($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))
390  {
391  array_push($questions, $row);
392  }
393  }
394  }
395  return $questions;
396  }
397 
406  function _isComplete($a_obj_id)
407  {
408  global $ilDB;
409 
410  $test_id = ilObjTestAccess::_getTestIDFromObjectID($a_obj_id);
411  $query = sprintf("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",
412  $ilDB->quote($test_id . "")
413  );
414  $result = $ilDB->query($query);
415  $found = $result->numRows();
416  if ($found)
417  {
418  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
419  // check for at least: title, author and minimum of 1 mark step
420  if ((strlen($row["title"])) &&
421  (strlen($row["author"])) &&
422  ($found))
423  {
424  // check also for minmum of 1 question
425  if (ilObjTestAccess::_getQuestionCount($test_id) > 0)
426  {
427  return true;
428  }
429  else
430  {
431  return false;
432  }
433  }
434  else
435  {
436  return false;
437  }
438  }
439  else
440  {
441  return false;
442  }
443  $test = new ilObjTest($obj_id, false);
444  $test->loadFromDb();
445  if (($test->getTitle()) and ($test->author) and (count($test->mark_schema->mark_steps)) and (count($test->questions)))
446  {
447  return true;
448  }
449  else
450  {
451  return false;
452  }
453  }
454 
464  function &_getTestData($test_id)
465  {
466  global $ilDB;
467  $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
468  $ilDB->quote($test_id . "")
469  );
470  $result = $ilDB->query($query);
471  if (!$result->numRows())
472  {
473  return 0;
474  }
475  $test = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
476  return $test;
477  }
478 
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  $query = sprintf("SELECT SUM(num_of_q) AS questioncount FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
504  $ilDB->quote($test_id . "")
505  );
506  $result = $ilDB->query($query);
507  if ($result->numRows())
508  {
509  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
510  $num = $row["questioncount"];
511  }
512  }
513  }
514  else
515  {
516  $query = sprintf("SELECT test_question_id FROM tst_test_question WHERE test_fi = %s",
517  $ilDB->quote($test_id . "")
518  );
519  $result = $ilDB->query($query);
520  $num = $result->numRows();
521  }
522  return $num;
523 }
524 
533  function _lookupOnlineTestAccess($a_test_id, $a_user_id)
534  {
535  global $ilDB, $lng;
536 
537  $query = sprintf("SELECT tst_tests.* FROM tst_tests WHERE tst_tests.obj_fi = %s",
538  $ilDB->quote($a_test_id . "")
539  );
540  $result = $ilDB->query($query);
541  if ($result->numRows())
542  {
543  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
544  if ($row["fixed_participants"])
545  {
546  $query = sprintf("SELECT * FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
547  $ilDB->quote($row["test_id"] . ""),
548  $ilDB->quote($a_user_id . "")
549  );
550  $result = $ilDB->query($query);
551  if ($result->numRows())
552  {
553  $row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
554  if (trim($row['clientip']) != "")
555  {
556  $row['clientip'] = preg_replace("/[^0-9.?*,:]+/","",$row['clientip']);
557  $row['clientip'] = str_replace(".","\\.",$row['clientip']);
558  $row['clientip'] = str_replace(Array("?","*",","), Array("[0-9]","[0-9]*","|"), $row['clientip']);
559  if (!preg_match("/^".$row['clientip']."$/", $_SERVER["REMOTE_ADDR"]))
560  {
561  return $lng->txt("tst_user_wrong_clientip");
562  }
563  else
564  {
565  return true;
566  }
567  }
568  else
569  {
570  return true;
571  }
572  }
573  else
574  {
575  return $lng->txt("tst_user_not_invited");
576  }
577  }
578  else
579  {
580  return true;
581  }
582  }
583  else
584  {
585  return true;
586  }
587  }
588 
596  function _getParticipantData($active_id)
597  {
598  global $lng, $ilDB;
599 
600  $statement = $ilDB->prepare("SELECT user_fi, test_fi FROM tst_active WHERE active_id = ?",
601  array(
602  "integer"
603  )
604  );
605  $result = $ilDB->execute($statement,
606  array(
607  $active_id
608  )
609  );
610  $row = $ilDB->fetchAssoc($result);
611  $user_id = $row["user_fi"];
612  $test_id = $row["test_fi"];
613 
614  $statement = $ilDB->prepare("SELECT obj_fi FROM tst_tests WHERE test_id = ?",
615  array(
616  "integer"
617  )
618  );
619  $result = $ilDB->execute($statement,
620  array(
621  $test_id
622  )
623  );
624  $row = $ilDB->fetchAssoc($result);
625  $obj_id = $row["obj_fi"];
626 
627  include_once "./Modules/Test/classes/class.ilObjTest.php";
628  $is_anonymous = ilObjTest::_lookupAnonymity($obj_id);
629 
630  include_once './Services/User/classes/class.ilObjUser.php';
631  $uname = ilObjUser::_lookupName($user_id);
632 
633  $name = "";
634  if (strlen($uname["firstname"].$uname["lastname"]) == 0)
635  {
636  $name = $lng->txt("deleted_user");
637  }
638  else
639  {
640  if ($user_id == ANONYMOUS_USER_ID)
641  {
642  $name = $lastname;
643  }
644  else
645  {
646  $name = trim($uname["lastname"] . ", " . $uname["firstname"] . " " . $uname["title"]);
647  }
648  if ($is_anonymous)
649  {
650  $name = $lng->txt("anonymous");
651  }
652  }
653  return $name;
654  }
655 
672  function &_getPassedUsers($a_obj_id)
673  {
674  global $ilDB;
675 
676  $passed_users = array();
677  $query = sprintf("SELECT tst_active.user_fi FROM tst_active, tst_tests WHERE tst_tests.test_id = tst_active.test_fi AND tst_tests.obj_fi = %s",
678  $ilDB->quote($a_obj_id . "")
679  );
680  $userresult = $ilDB->query($query);
681  if ($userresult->numRows())
682  {
683  while ($userrow = $userresult->fetchRow(MDB2_FETCHMODE_ASSOC))
684  {
685  $user_id = $userrow["user_fi"];
686  $query = sprintf("SELECT tst_test_pass_result.*, tst_tests.pass_scoring, tst_tests.random_test, tst_tests.test_id FROM tst_test_pass_result, tst_active, tst_tests, object_data WHERE object_data.obj_id = tst_tests.obj_fi AND tst_active.test_fi = tst_tests.test_id AND tst_active.user_fi = %s AND object_data.obj_id = %s AND tst_test_pass_result.active_fi = tst_active.active_id ORDER BY tst_test_pass_result.pass",
687  $ilDB->quote($user_id . ""),
688  $ilDB->quote($a_obj_id . "")
689  );
690  $result = $ilDB->query($query);
691  $points = array();
692  while ($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))
693  {
694  array_push($points, $row);
695  }
696  $reached = 0;
697  $max = 0;
698  if ($points[0]["pass_scoring"] == 0)
699  {
700  $reached = $points[count($points)-1]["points"];
701  $max = ilObjTestAccess::_getMaxPointsForTestPass($points[count($points)-1]["random_test"], $user_id, $points[count($points)-1]["test_id"], $points[count($points)-1]["pass"]);
702  if (!strlen($max))
703  {
704  include_once "./Modules/Test/classes/class.ilTestEvaluationData.php";
705  include_once "./Modules/Test/classes/class.ilObjTest.php";
706  $test = new ilObjTest($a_obj_id, false);
707  $test->loadFromDb();
709  $p = $data->getParticipants();
710  if (!is_null($p))
711  {
712  $user = $p[$points[count($points)-1]["active_fi"]];
713  if (!is_null($user))
714  {
715  $max = $user->getMaxpoints();
716  }
717  }
718  }
719  }
720  else
721  {
722  foreach ($points as $row)
723  {
724  if ($row["points"] > $reached)
725  {
726  $max = ilObjTestAccess::_getMaxPointsForTestPass($row["random_test"], $user_id, $row["test_id"], $row["pass"]);
727  if (!strlen($max))
728  {
729  include_once "./Modules/Test/classes/class.ilTestEvaluationData.php";
730  include_once "./Modules/Test/classes/class.ilObjTest.php";
731  $test = new ilObjTest($a_obj_id, false);
732  $test->loadFromDb();
734  $p = $data->getParticipants();
735  if (!is_null($p))
736  {
737  $user = $p[$points[count($points)-1]["active_fi"]];
738  if (!is_null($user))
739  {
740  $max = $user->getMaxpoints();
741  }
742  }
743  }
744  $reached = $row["points"];
745  }
746  }
747  }
748  include_once "./Modules/Test/classes/class.assMarkSchema.php";
749  $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
750  $mark = ASS_MarkSchema::_getMatchingMarkFromObjId($a_obj_id, $percentage);
751  array_push($passed_users,
752  array(
753  "user_id" => $user_id,
754  "max_points" => $max,
755  "reached_points" => $reached,
756  "mark_short" => $mark["short_name"],
757  "mark_official" => $mark["official_name"],
758  "passed" => ($mark["passed"]) ? TRUE : FALSE,
759  "failed" => (!$mark["passed"]) ? TRUE : FALSE
760  )
761  );
762  }
763  }
764  return $passed_users;
765  }
766 
770  function _checkGoto($a_target)
771  {
772  global $ilAccess;
773 
774  $t_arr = explode("_", $a_target);
775 
776  if ($t_arr[0] != "tst" || ((int) $t_arr[1]) <= 0)
777  {
778  return false;
779  }
780 
781  if ($ilAccess->checkAccess("visible", "", $t_arr[1]))
782  {
783  return true;
784  }
785  return false;
786  }
787 }
788 
789 ?>