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 "./assessment/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
00097 function _checkCondition($a_obj_id, $a_operator, $a_value)
00098 {
00099 global $ilias;
00100 switch($a_operator)
00101 {
00102 case 'passed':
00103 include_once "./assessment/classes/class.ilObjTest.php";
00104 $test_id = ilObjTest::_getTestIDFromObjectID($a_obj_id);
00105 $active = ilObjTest::_getActiveTestUser($ilias->account->getId(), $test_id);
00106 if(!is_object($active))
00107 {
00108 return false;
00109 }
00110 $result = ilObjTestAccess::_getTestResult($active->active_id);
00111 if ($result["passed"] == 1)
00112 {
00113 return true;
00114 }
00115 else
00116 {
00117 return false;
00118 }
00119 break;
00120
00121 case 'finished':
00122 return ilObjTestAccess::_hasFinished($ilias->account->getId(),$a_obj_id);
00123
00124 case 'not_finished':
00125 return !ilObjTestAccess::_hasFinished($ilias->account->getId(),$a_obj_id);
00126
00127 default:
00128 return true;
00129 }
00130 return true;
00131 }
00132
00145 function _getCommands()
00146 {
00147 $commands = array
00148 (
00149 array("permission" => "read", "cmd" => "infoScreen", "lang_var" => "tst_run",
00150 "default" => true),
00151 array("permission" => "write", "cmd" => "", "lang_var" => "edit"),
00152 array("permission" => "write", "cmd" => "eval_stat", "lang_var" => "tst_statistical_evaluation")
00153 );
00154
00155 return $commands;
00156 }
00157
00158
00159
00160
00161
00165 function _lookupCreationComplete($a_obj_id)
00166 {
00167 global $ilDB;
00168
00169 $q = sprintf("SELECT * FROM tst_tests WHERE obj_fi=%s",
00170 $ilDB->quote($a_obj_id)
00171 );
00172 $result = $ilDB->query($q);
00173 if ($result->numRows() == 1)
00174 {
00175 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
00176 }
00177
00178 if (!$row->complete)
00179 {
00180 return false;
00181 }
00182
00183 return true;
00184 }
00185
00195 function _hasFinished($a_user_id,$a_obj_id)
00196 {
00197 global $ilDB;
00198
00199 $query = sprintf("SELECT active_id FROM tst_active WHERE user_fi = %s AND test_fi = %s AND tries > '0'",
00200 $ilDB->quote($a_user_id . ""),
00201 $ilDB->quote(ilObjTestAccess::_getTestIDFromObjectID($a_obj_id) . "")
00202 );
00203 $res = $ilDB->query($query);
00204
00205 return $res->numRows() ? true : false;
00206 }
00207
00217 function _getTestIDFromObjectID($object_id)
00218 {
00219 global $ilDB;
00220 $test_id = FALSE;
00221 $query = sprintf("SELECT test_id FROM tst_tests WHERE obj_fi = %s",
00222 $ilDB->quote($object_id . "")
00223 );
00224 $result = $ilDB->query($query);
00225 if ($result->numRows())
00226 {
00227 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00228 $test_id = $row["test_id"];
00229 }
00230 return $test_id;
00231 }
00232
00233 function &_getTestQuestions($active_id, $pass = NULL)
00234 {
00235 if (is_null($pass))
00236 {
00237 $pass = 0;
00238 }
00239 $questions = array();
00240
00241 global $ilDB;
00242 $query = sprintf("SELECT test_fi FROM tst_active WHERE active_id = %s",
00243 $ilDB->quote($active_id . "")
00244 );
00245 $result = $ilDB->query($query);
00246 $test_id = "";
00247 if ($result->numRows())
00248 {
00249 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00250 $test_id = $row["test_fi"];
00251 }
00252 else
00253 {
00254 return $questions;
00255 }
00256 $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",
00257 $ilDB->quote($test_id . "")
00258 );
00259 $result = $ilDB->query($query);
00260 if ($result->numRows())
00261 {
00262
00263 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00264 {
00265 array_push($questions, $row);
00266 }
00267 }
00268 else
00269 {
00270
00271 $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",
00272 $ilDB->quote($active_id . ""),
00273 $ilDB->quote($pass . "")
00274 );
00275 $result = $ilDB->query($query);
00276 if ($result->numRows())
00277 {
00278 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00279 {
00280 array_push($questions, $row);
00281 }
00282 }
00283 }
00284 return $questions;
00285 }
00286
00296 function &_getTestResult($active_id, $pass = NULL)
00297 {
00298 global $ilDB;
00299
00300 $test_result = array();
00301 $query = sprintf("SELECT tst_mark.*, tst_tests.* FROM tst_mark, tst_tests, tst_active WHERE tst_mark.test_fi = tst_tests.test_id AND tst_tests.test_id = tst_active.test_fi AND tst_active.active_id = %s ORDER BY tst_mark.minimum_level",
00302 $ilDB->quote($active_id . "")
00303 );
00304 $result = $ilDB->query($query);
00305 if ($result->numRows())
00306 {
00307 $test_result["marks"] = array();
00308 $min_passed_percentage = 100;
00309 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00310 {
00311 if (($row["passed"] == 1) && ($row["minimum_level"] < $min_passed_percentage))
00312 {
00313 $min_passed_percentage = $row["minimum_level"];
00314 }
00315 array_push($test_result["marks"], $row);
00316 }
00317
00318 $questions =& ilObjTestAccess::_getTestQuestions($active_id, $pass);
00319 $max_points = 0;
00320 $reached_points = 0;
00321 foreach ($questions as $row)
00322 {
00323 include_once "./assessment/classes/class.assQuestion.php";
00324 $preached = assQuestion::_getReachedPoints($active_id, $row["question_id"], $pass);
00325 $max_points += $row["points"];
00326 $reached_points += $preached;
00327 }
00328 switch ($test_result["marks"][0]["score_cutting"])
00329 {
00330 case 0:
00331 break;
00332 case 1:
00333 if ($reached_points < 0) $reached_points = 0;
00334 break;
00335 }
00336 $test_result["max_points"] = $max_points;
00337 $test_result["reached_points"] = $reached_points;
00338
00339 $solved = 0;
00340 if ($max_points > 0)
00341 {
00342 $solved = ($reached_points / $max_points) * 100.0;
00343 }
00344
00345 $mark_percentage = 0;
00346 $mark_value = null;
00347 foreach ($test_result["marks"] as $key => $value)
00348 {
00349 if (($value["minimum_level"] <= $solved) && ($mark_percentage < $value["minimum_level"]))
00350 {
00351 $mark_percentage = $value["minimum_level"];
00352 $mark_value = $value;
00353 }
00354 }
00355 $test_result["mark"] = $mark_value;
00356
00357 $test_result["passed"] = $test_result["mark"]["passed"];
00358 }
00359 return $test_result;
00360 }
00361
00370 function _isComplete($a_obj_id)
00371 {
00372 global $ilDB;
00373
00374 $test_id = ilObjTestAccess::_getTestIDFromObjectID($a_obj_id);
00375 $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",
00376 $ilDB->quote($test_id . "")
00377 );
00378 $result = $ilDB->query($query);
00379 $found = $result->numRows();
00380 if ($found)
00381 {
00382 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00383
00384 if ((strlen($row["title"])) &&
00385 (strlen($row["author"])) &&
00386 ($found))
00387 {
00388
00389 if (ilObjTestAccess::_getQuestionCount($test_id) > 0)
00390 {
00391 return true;
00392 }
00393 else
00394 {
00395 return false;
00396 }
00397 }
00398 else
00399 {
00400 return false;
00401 }
00402 }
00403 else
00404 {
00405 return false;
00406 }
00407 $test = new ilObjTest($obj_id, false);
00408 $test->loadFromDb();
00409 if (($test->getTitle()) and ($test->author) and (count($test->mark_schema->mark_steps)) and (count($test->questions)))
00410 {
00411 return true;
00412 }
00413 else
00414 {
00415 return false;
00416 }
00417 }
00418
00427 function _getQuestionCount($test_id)
00428 {
00429 global $ilDB;
00430
00431 $num = 0;
00432
00433 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
00434 $ilDB->quote($test_id . "")
00435 );
00436 $result = $ilDB->query($query);
00437 if (!$result->numRows())
00438 {
00439 return 0;
00440 }
00441 $test = $result->fetchRow(DB_FETCHMODE_ASSOC);
00442
00443 if ($test["random_test"] == 1)
00444 {
00445 if ($test["random_question_count"] > 0)
00446 {
00447 $num = $test["random_question_count"];
00448 }
00449 else
00450 {
00451 $query = sprintf("SELECT SUM(num_of_q) AS questioncount FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
00452 $ilDB->quote($test_id . "")
00453 );
00454 $result = $ilDB->query($query);
00455 if ($result->numRows())
00456 {
00457 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00458 $num = $row["questioncount"];
00459 }
00460 }
00461 }
00462 else
00463 {
00464 $query = sprintf("SELECT test_question_id FROM tst_test_question WHERE test_fi = %s",
00465 $ilDB->quote($test_id . "")
00466 );
00467 $result = $ilDB->query($query);
00468 $num = $result->numRows();
00469 }
00470 return $num;
00471 }
00472
00481 function _lookupOnlineTestAccess($a_test_id, $a_user_id)
00482 {
00483 global $ilDB, $lng;
00484
00485 $test_result = array();
00486 $query = sprintf("SELECT tst_tests.* FROM tst_tests WHERE tst_tests.obj_fi = %s",
00487 $ilDB->quote($a_test_id . "")
00488 );
00489 $result = $ilDB->query($query);
00490 if ($result->numRows())
00491 {
00492 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00493 if ($row["test_type_fi"] == 4)
00494 {
00495 $query = sprintf("SELECT * FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
00496 $ilDB->quote($row["test_id"] . ""),
00497 $ilDB->quote($a_user_id . "")
00498 );
00499 $result = $ilDB->query($query);
00500 if ($result->numRows())
00501 {
00502 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
00503 if (strcmp($row["clientip"],"")!=0 && strcmp($row["clientip"],$_SERVER["REMOTE_ADDR"])!=0)
00504 {
00505 return $lng->txt("tst_user_wrong_clientip");
00506 }
00507 else
00508 {
00509 return true;
00510 }
00511 }
00512 else
00513 {
00514 return $lng->txt("tst_user_not_invited");
00515 }
00516 }
00517 else
00518 {
00519 return true;
00520 }
00521 }
00522 else
00523 {
00524 return true;
00525 }
00526 }
00527
00544 function &_getPassedUsers($a_obj_id)
00545 {
00546 $passed_users = array();
00547 include_once 'assessment/classes/class.ilObjTest.php';
00548 $test_id = ilObjTest::_getTestIDFromObjectID($a_obj_id);
00549 $results =& ilObjTest::_getCompleteEvaluationData($test_id, FALSE);
00550 if (is_object($results))
00551 {
00552 $participants =& $results->getParticipants();
00553 foreach ($participants as $participant)
00554 {
00555 if (is_object($participant))
00556 {
00557 array_push($passed_users,
00558 array(
00559 "user_id" => $participant->getUserID(),
00560 "max_points" => $participant->getMaxpoints(),
00561 "reached_points" => $participant->getReached(),
00562 "mark_short" => $participant->getMark(),
00563 "mark_official" => $participant->getMarkOfficial(),
00564 "passed" => $participant->getPassed(),
00565 "failed" => (!$participant->getPassed())
00566 )
00567 );
00568 }
00569 }
00570 }
00571 return $passed_users;
00572 }
00573
00577 function _checkGoto($a_target)
00578 {
00579 global $ilAccess;
00580
00581 $t_arr = explode("_", $a_target);
00582
00583 if ($t_arr[0] != "tst" || ((int) $t_arr[1]) <= 0)
00584 {
00585 return false;
00586 }
00587
00588 if ($ilAccess->checkAccess("visible", "", $t_arr[1]))
00589 {
00590 return true;
00591 }
00592 return false;
00593 }
00594
00595 }
00596
00597 ?>