00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 include_once "./classes/class.ilObjectAccess.php";
00025 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
00026
00039 class ilObjTestAccess extends ilObjectAccess
00040 {
00056 function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_user_id = "")
00057 {
00058 global $ilUser, $lng, $rbacsystem, $ilAccess;
00059 if ($a_user_id == "")
00060 {
00061 $a_user_id = $ilUser->getId();
00062 }
00063
00064 switch ($a_permission)
00065 {
00066 case "read":
00067 case "visible":
00068 if (!ilObjTestAccess::_lookupCreationComplete($a_obj_id) &&
00069 (!$rbacsystem->checkAccess('write', $a_ref_id)))
00070 {
00071 $ilAccess->addInfoItem(IL_NO_OBJECT_ACCESS, $lng->txt("tst_warning_test_not_complete"));
00072 return false;
00073 }
00074 break;
00075 }
00076 switch ($a_cmd)
00077 {
00078 case "eval_a":
00079 case "eval_stat":
00080 if (!ilObjTestAccess::_lookupCreationComplete($a_obj_id))
00081 {
00082 $ilAccess->addInfoItem(IL_NO_OBJECT_ACCESS, $lng->txt("tst_warning_test_not_complete"));
00083 return false;
00084 }
00085 break;
00086
00087 }
00088
00089 return true;
00090 }
00091
00102 function _getMaxPointsForTestPass($random, $user_id, $test_id, $pass)
00103 {
00104 global $ilDB;
00105 $max = 0;
00106
00107 if ($random)
00108 {
00109 $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",
00110 $ilDB->quote($test_id . ""),
00111 $ilDB->quote($pass . ""),
00112 $ilDB->quote($user_id . "")
00113 );
00114 $result = $ilDB->query($query);
00115 if ($result->numRows())
00116 {
00117 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00118 $max = $row["maxpoints"];
00119 }
00120 }
00121 else
00122 {
00123 $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",
00124 $ilDB->quote($test_id . "")
00125 );
00126 $result = $ilDB->query($query);
00127 if ($result->numRows())
00128 {
00129 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00130 $max = $row["maxpoints"];
00131 }
00132 }
00133 return $max;
00134 }
00135
00145 function _isPassed($user_id, $a_obj_id)
00146 {
00147 global $ilDB;
00148 $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",
00149 $ilDB->quote($user_id . ""),
00150 $ilDB->quote($a_obj_id . "")
00151 );
00152 $result = $ilDB->query($query);
00153 $points = array();
00154 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00155 {
00156 array_push($points, $row);
00157 }
00158 $reached = 0;
00159 $max = 0;
00160 if ($points[0]["pass_scoring"] == 0)
00161 {
00162 $reached = $points[count($points)-1]["points"];
00163 $max = ilObjTestAccess::_getMaxPointsForTestPass($points[count($points)-1]["random_test"], $user_id, $points[count($points)-1]["test_id"], $points[count($points)-1]["pass"]);
00164 if (!strlen($max))
00165 {
00166 include_once "./Modules/Test/classes/class.ilObjTest.php";
00167 $r = ilObjTest::_getCompleteEvaluationData($points[count($points)-1]["test_id"], false, $points[count($points)-1]["active_fi"]);
00168 $p = $r->getParticipants();
00169 if (!is_null($p))
00170 {
00171 $user = $p[$points[count($points)-1]["active_fi"]];
00172 if (!is_null($user))
00173 {
00174 return $user->getPassed();
00175 }
00176 }
00177 }
00178 }
00179 else
00180 {
00181 foreach ($points as $row)
00182 {
00183 if ($row["points"] > $reached)
00184 {
00185 $max = ilObjTestAccess::_getMaxPointsForTestPass($row["random_test"], $user_id, $row["test_id"], $row["pass"]);
00186 $reached = $row["points"];
00187 if (!strlen($max))
00188 {
00189 include_once "./Modules/Test/classes/class.ilObjTest.php";
00190 $r = ilObjTest::_getCompleteEvaluationData($points[count($points)-1]["test_id"], false, $points[count($points)-1]["active_fi"]);
00191 $p = $r->getParticipants();
00192 if (!is_null($p))
00193 {
00194 $user = $p[$points[count($points)-1]["active_fi"]];
00195 if (!is_null($user))
00196 {
00197 return $user->getPassed();
00198 }
00199 }
00200 }
00201 }
00202 }
00203 }
00204 include_once "./Modules/Test/classes/class.assMarkSchema.php";
00205 $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
00206 $mark = ASS_MarkSchema::_getMatchingMarkFromObjId($a_obj_id, $percentage);
00207 return ($mark["passed"]) ? TRUE : FALSE;
00208 }
00209
00215 function _checkCondition($a_obj_id, $a_operator, $a_value)
00216 {
00217 global $ilias;
00218 switch($a_operator)
00219 {
00220 case 'passed':
00221 return ilObjTestAccess::_isPassed($ilias->account->getId(), $a_obj_id);
00222 break;
00223
00224 case 'finished':
00225 return ilObjTestAccess::_hasFinished($ilias->account->getId(),$a_obj_id);
00226
00227 case 'not_finished':
00228 return !ilObjTestAccess::_hasFinished($ilias->account->getId(),$a_obj_id);
00229
00230 default:
00231 return true;
00232 }
00233 return true;
00234 }
00235
00248 function _getCommands()
00249 {
00250 $commands = array
00251 (
00252 array("permission" => "read", "cmd" => "infoScreen", "lang_var" => "tst_run",
00253 "default" => true),
00254 array("permission" => "write", "cmd" => "", "lang_var" => "edit"),
00255 array("permission" => "tst_statistics", "cmd" => "outEvaluation", "lang_var" => "tst_statistical_evaluation")
00256 );
00257
00258 return $commands;
00259 }
00260
00261
00262
00263
00264
00268 function _lookupCreationComplete($a_obj_id)
00269 {
00270 global $ilDB;
00271
00272 $q = sprintf("SELECT * FROM tst_tests WHERE obj_fi=%s",
00273 $ilDB->quote($a_obj_id)
00274 );
00275 $result = $ilDB->query($q);
00276 if ($result->numRows() == 1)
00277 {
00278 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
00279 }
00280
00281 if (!$row->complete)
00282 {
00283 return false;
00284 }
00285
00286 return true;
00287 }
00288
00298 function _hasFinished($a_user_id,$a_obj_id)
00299 {
00300 global $ilDB;
00301
00302 $query = sprintf("SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s AND tries > '0'",
00303 $ilDB->quote($a_user_id . ""),
00304 $ilDB->quote(ilObjTestAccess::_getTestIDFromObjectID($a_obj_id) . "")
00305 );
00306 $res = $ilDB->query($query);
00307
00308 return $res->numRows() ? true : false;
00309 }
00310
00320 function _getTestIDFromObjectID($object_id)
00321 {
00322 global $ilDB;
00323 $test_id = FALSE;
00324 $query = sprintf("SELECT test_id FROM tst_tests WHERE obj_fi = %s",
00325 $ilDB->quote($object_id . "")
00326 );
00327 $result = $ilDB->query($query);
00328 if ($result->numRows())
00329 {
00330 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00331 $test_id = $row["test_id"];
00332 }
00333 return $test_id;
00334 }
00335
00336 function &_getTestQuestions($active_id, $pass = NULL)
00337 {
00338 if (is_null($pass))
00339 {
00340 $pass = 0;
00341 }
00342 $questions = array();
00343
00344 global $ilDB;
00345 $query = sprintf("SELECT test_fi FROM tst_active WHERE active_id = %s",
00346 $ilDB->quote($active_id . "")
00347 );
00348 $result = $ilDB->query($query);
00349 $test_id = "";
00350 if ($result->numRows())
00351 {
00352 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00353 $test_id = $row["test_fi"];
00354 }
00355 else
00356 {
00357 return $questions;
00358 }
00359 $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",
00360 $ilDB->quote($test_id . "")
00361 );
00362 $result = $ilDB->query($query);
00363 if ($result->numRows())
00364 {
00365
00366 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00367 {
00368 array_push($questions, $row);
00369 }
00370 }
00371 else
00372 {
00373
00374 $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",
00375 $ilDB->quote($active_id . ""),
00376 $ilDB->quote($pass . "")
00377 );
00378 $result = $ilDB->query($query);
00379 if ($result->numRows())
00380 {
00381 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00382 {
00383 array_push($questions, $row);
00384 }
00385 }
00386 }
00387 return $questions;
00388 }
00389
00398 function _isComplete($a_obj_id)
00399 {
00400 global $ilDB;
00401
00402 $test_id = ilObjTestAccess::_getTestIDFromObjectID($a_obj_id);
00403 $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",
00404 $ilDB->quote($test_id . "")
00405 );
00406 $result = $ilDB->query($query);
00407 $found = $result->numRows();
00408 if ($found)
00409 {
00410 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00411
00412 if ((strlen($row["title"])) &&
00413 (strlen($row["author"])) &&
00414 ($found))
00415 {
00416
00417 if (ilObjTestAccess::_getQuestionCount($test_id) > 0)
00418 {
00419 return true;
00420 }
00421 else
00422 {
00423 return false;
00424 }
00425 }
00426 else
00427 {
00428 return false;
00429 }
00430 }
00431 else
00432 {
00433 return false;
00434 }
00435 $test = new ilObjTest($obj_id, false);
00436 $test->loadFromDb();
00437 if (($test->getTitle()) and ($test->author) and (count($test->mark_schema->mark_steps)) and (count($test->questions)))
00438 {
00439 return true;
00440 }
00441 else
00442 {
00443 return false;
00444 }
00445 }
00446
00456 function &_getTestData($test_id)
00457 {
00458 global $ilDB;
00459 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
00460 $ilDB->quote($test_id . "")
00461 );
00462 $result = $ilDB->query($query);
00463 if (!$result->numRows())
00464 {
00465 return 0;
00466 }
00467 $test = $result->fetchRow(DB_FETCHMODE_ASSOC);
00468 return $test;
00469 }
00470
00479 function _getQuestionCount($test_id)
00480 {
00481 global $ilDB;
00482
00483 $num = 0;
00484
00485 $test =& ilObjTestAccess::_getTestData($test_id);
00486
00487 if ($test["random_test"] == 1)
00488 {
00489 if ($test["random_question_count"] > 0)
00490 {
00491 $num = $test["random_question_count"];
00492 }
00493 else
00494 {
00495 $query = sprintf("SELECT SUM(num_of_q) AS questioncount FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
00496 $ilDB->quote($test_id . "")
00497 );
00498 $result = $ilDB->query($query);
00499 if ($result->numRows())
00500 {
00501 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00502 $num = $row["questioncount"];
00503 }
00504 }
00505 }
00506 else
00507 {
00508 $query = sprintf("SELECT test_question_id FROM tst_test_question WHERE test_fi = %s",
00509 $ilDB->quote($test_id . "")
00510 );
00511 $result = $ilDB->query($query);
00512 $num = $result->numRows();
00513 }
00514 return $num;
00515 }
00516
00525 function _lookupOnlineTestAccess($a_test_id, $a_user_id)
00526 {
00527 global $ilDB, $lng;
00528
00529 $query = sprintf("SELECT tst_tests.* FROM tst_tests WHERE tst_tests.obj_fi = %s",
00530 $ilDB->quote($a_test_id . "")
00531 );
00532 $result = $ilDB->query($query);
00533 if ($result->numRows())
00534 {
00535 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00536 if ($row["fixed_participants"])
00537 {
00538 $query = sprintf("SELECT * FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
00539 $ilDB->quote($row["test_id"] . ""),
00540 $ilDB->quote($a_user_id . "")
00541 );
00542 $result = $ilDB->query($query);
00543 if ($result->numRows())
00544 {
00545 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00546 if (strcmp($row["clientip"],"")!=0 && strcmp($row["clientip"],$_SERVER["REMOTE_ADDR"])!=0)
00547 {
00548 return $lng->txt("tst_user_wrong_clientip");
00549 }
00550 else
00551 {
00552 return true;
00553 }
00554 }
00555 else
00556 {
00557 return $lng->txt("tst_user_not_invited");
00558 }
00559 }
00560 else
00561 {
00562 return true;
00563 }
00564 }
00565 else
00566 {
00567 return true;
00568 }
00569 }
00570
00587 function &_getPassedUsers($a_obj_id)
00588 {
00589 global $ilDB;
00590
00591 $passed_users = array();
00592 $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",
00593 $ilDB->quote($a_obj_id . "")
00594 );
00595 $userresult = $ilDB->query($query);
00596 if ($userresult->numRows())
00597 {
00598 while ($userrow = $userresult->fetchRow(DB_FETCHMODE_ASSOC))
00599 {
00600 $user_id = $userrow["user_fi"];
00601 $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",
00602 $ilDB->quote($user_id . ""),
00603 $ilDB->quote($a_obj_id . "")
00604 );
00605 $result = $ilDB->query($query);
00606 $points = array();
00607 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00608 {
00609 array_push($points, $row);
00610 }
00611 $reached = 0;
00612 $max = 0;
00613 if ($points[0]["pass_scoring"] == 0)
00614 {
00615 $reached = $points[count($points)-1]["points"];
00616 $max = ilObjTestAccess::_getMaxPointsForTestPass($points[count($points)-1]["random_test"], $user_id, $points[count($points)-1]["test_id"], $points[count($points)-1]["pass"]);
00617 if (!strlen($max))
00618 {
00619 include_once "./Modules/Test/classes/class.ilObjTest.php";
00620 $r = ilObjTest::_getCompleteEvaluationData($points[count($points)-1]["test_id"], false, $points[count($points)-1]["active_fi"]);
00621 $p = $r->getParticipants();
00622 if (!is_null($p))
00623 {
00624 $user = $p[$points[count($points)-1]["active_fi"]];
00625 if (!is_null($user))
00626 {
00627 $max = $user->getMaxpoints();
00628 }
00629 }
00630 }
00631 }
00632 else
00633 {
00634 foreach ($points as $row)
00635 {
00636 if ($row["points"] > $reached)
00637 {
00638 $max = ilObjTestAccess::_getMaxPointsForTestPass($row["random_test"], $user_id, $row["test_id"], $row["pass"]);
00639 if (!strlen($max))
00640 {
00641 include_once "./Modules/Test/classes/class.ilObjTest.php";
00642 $r = ilObjTest::_getCompleteEvaluationData($points[count($points)-1]["test_id"], false, $points[count($points)-1]["active_fi"]);
00643 $p = $r->getParticipants();
00644 if (!is_null($p))
00645 {
00646 $user = $p[$points[count($points)-1]["active_fi"]];
00647 if (!is_null($user))
00648 {
00649 $max = $user->getMaxpoints();
00650 }
00651 }
00652 }
00653 $reached = $row["points"];
00654 }
00655 }
00656 }
00657 include_once "./Modules/Test/classes/class.assMarkSchema.php";
00658 $percentage = (!$max) ? 0 : ($reached / $max) * 100.0;
00659 $mark = ASS_MarkSchema::_getMatchingMarkFromObjId($a_obj_id, $percentage);
00660 array_push($passed_users,
00661 array(
00662 "user_id" => $user_id,
00663 "max_points" => $max,
00664 "reached_points" => $reached,
00665 "mark_short" => $mark["short_name"],
00666 "mark_official" => $mark["official_name"],
00667 "passed" => ($mark["passed"]) ? TRUE : FALSE,
00668 "failed" => (!$mark["passed"]) ? TRUE : FALSE
00669 )
00670 );
00671 }
00672 }
00673 return $passed_users;
00674 }
00675
00679 function _checkGoto($a_target)
00680 {
00681 global $ilAccess;
00682
00683 $t_arr = explode("_", $a_target);
00684
00685 if ($t_arr[0] != "tst" || ((int) $t_arr[1]) <= 0)
00686 {
00687 return false;
00688 }
00689
00690 if ($ilAccess->checkAccess("visible", "", $t_arr[1]))
00691 {
00692 return true;
00693 }
00694 return false;
00695 }
00696
00704 function _getParticipantData($active_id)
00705 {
00706 global $lng, $ilDB;
00707
00708 $query = sprintf("SELECT user_fi, test_fi FROM tst_active WHERE active_id = %s",
00709 $ilDB->quote($active_id)
00710 );
00711 $result = $ilDB->query($query);
00712 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00713 $user_id = $row["user_fi"];
00714 $test_id = $row["test_fi"];
00715
00716 $query = sprintf("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
00717 $ilDB->quote($test_id)
00718 );
00719 $result = $ilDB->query($query);
00720 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00721 $obj_id = $row["obj_fi"];
00722
00723 include_once "./Modules/Test/classes/class.ilObjTest.php";
00724 $is_anonymous = ilObjTest::_lookupAnonymity($obj_id);
00725
00726 include_once './Services/User/classes/class.ilObjUser.php';
00727 $uname = ilObjUser::_lookupName($user_id);
00728
00729 $name = "";
00730 if (strlen($uname["firstname"].$uname["lastname"]) == 0)
00731 {
00732 $name = $lng->txt("deleted_user");
00733 }
00734 else
00735 {
00736 if ($user_id == ANONYMOUS_USER_ID)
00737 {
00738 $name = $lastname;
00739 }
00740 else
00741 {
00742 $name = trim($uname["lastname"] . ", " . $uname["firstname"] . " " . $uname["title"]);
00743 }
00744 if ($is_anonymous)
00745 {
00746 $name = $lng->txt("anonymous");
00747 }
00748 }
00749 return $name;
00750 }
00751
00752 }
00753
00754 ?>