00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00035 include_once "./classes/class.ilObject.php";
00036 include_once "./assessment/classes/inc.AssessmentConstants.php";
00037
00038 class ilObjTest extends ilObject
00039 {
00047 var $test_id;
00048
00056 var $invitation = INVITATION_OFF;
00057
00058
00067 var $author;
00068
00076 var $metadata;
00077
00085 var $questions;
00086
00095 var $introduction;
00096
00104 var $mark_schema;
00105
00115 var $sequence_settings;
00116
00128 var $score_reporting;
00129
00140 var $reporting_date;
00141
00149 var $evaluation_data;
00150
00158 var $test_type;
00159
00168 var $nr_of_tries;
00169
00178 var $hide_previous_results;
00179
00187 var $hide_title_points;
00188
00196 var $processing_time;
00197
00205 var $enable_processing_time;
00206
00214 var $starting_time;
00215
00223 var $ending_time;
00224
00232 var $ects_output;
00233
00241 var $ects_fx;
00242
00253 var $test_types;
00254
00262 var $ects_grades;
00263
00273 var $random_test;
00274
00282 var $random_question_count;
00283
00290 var $count_system;
00291
00297 var $mc_scoring;
00298
00304 var $pass_scoring;
00305
00312 function ilObjTest($a_id = 0,$a_call_by_reference = true)
00313 {
00314 global $ilUser;
00315 $this->type = "tst";
00316 include_once "./assessment/classes/class.assMarkSchema.php";
00317 $this->mark_schema = new ASS_MarkSchema();
00318
00319 $this->retrieveTestTypes();
00320 $this->test_id = -1;
00321 $this->author = $ilUser->fullname;
00322 $this->introduction = "";
00323 $this->questions = array();
00324 $this->sequence_settings = TEST_FIXED_SEQUENCE;
00325 $this->score_reporting = REPORT_AFTER_TEST;
00326 $this->reporting_date = "";
00327 $this->nr_of_tries = 0;
00328 $this->hide_previous_results = 0;
00329 $this->hide_title_points = 0;
00330 $this->starting_time = "";
00331 $this->ending_time = "";
00332 $this->processing_time = "00:00:00";
00333 $this->enable_processing_time = "0";
00334 $this->test_type = TYPE_ASSESSMENT;
00335 $this->ects_output = 0;
00336 $this->ects_fx = "";
00337 $this->random_test = 0;
00338 $this->random_question_count = "";
00339 $this->count_system = COUNT_PARTIAL_SOLUTIONS;
00340 $this->mc_scoring = SCORE_ZERO_POINTS_WHEN_UNANSWERED;
00341 $this->pass_scoring = SCORE_LAST_PASS;
00342 global $lng;
00343 $lng->loadLanguageModule("assessment");
00344 $this->mark_schema->create_simple_schema($lng->txt("failed_short"), $lng->txt("failed_official"), 0, 0, $lng->txt("passed_short"), $lng->txt("passed_official"), 50, 1);
00345 $this->ects_grades = array(
00346 "A" => 90,
00347 "B" => 65,
00348 "C" => 35,
00349 "D" => 10,
00350 "E" => 0
00351 );
00352 $this->ilObject($a_id, $a_call_by_reference);
00353 }
00354
00358 function create($a_upload = false)
00359 {
00360 parent::create();
00361
00362
00363
00364 if (!$a_upload)
00365 {
00366 $this->createMetaData();
00367 }
00368 }
00369
00376 function update()
00377 {
00378 $this->updateMetaData();
00379 if (!parent::update())
00380 {
00381 return false;
00382 }
00383
00384
00385
00386 return true;
00387 }
00388
00397 function createReference() {
00398 $result = parent::createReference();
00399 $this->saveToDb();
00400 return $result;
00401 }
00402
00408 function read($a_force_db = false)
00409 {
00410 parent::read($a_force_db);
00411 $this->loadFromDb();
00412 }
00413
00421 function ilClone($a_parent_ref)
00422 {
00423 global $rbacadmin;
00424
00425
00426 $new_ref_id = parent::ilClone($a_parent_ref);
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 return $new_ref_id;
00442 }
00443
00450 function delete()
00451 {
00452
00453 if (!parent::delete())
00454 {
00455 return false;
00456 }
00457
00458
00459 $this->deleteMetaData();
00460
00461
00462 $this->deleteTest();
00463
00464 return true;
00465 }
00466
00474 function deleteTest()
00475 {
00476 $query = sprintf("SELECT active_id FROM tst_active WHERE test_fi = %s",
00477 $this->ilias->db->quote($this->getTestId())
00478 );
00479 $result = $this->ilias->db->query($query);
00480 $active_array = array();
00481 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00482 {
00483 array_push($active_array, $row["active_id"]);
00484 }
00485
00486 $query = sprintf("DELETE FROM tst_active WHERE test_fi = %s",
00487 $this->ilias->db->quote($this->getTestId())
00488 );
00489 $result = $this->ilias->db->query($query);
00490
00491 if (count($active_array))
00492 {
00493 foreach ($active_array as $active_id)
00494 {
00495 $query = sprintf("DELETE FROM tst_times WHERE active_fi = %s",
00496 $this->ilias->db->quote($active_id)
00497 );
00498 $result = $this->ilias->db->query($query);
00499 }
00500 }
00501
00502 $query = sprintf("DELETE FROM tst_mark WHERE test_fi = %s",
00503 $this->ilias->db->quote($this->getTestId())
00504 );
00505 $result = $this->ilias->db->query($query);
00506
00507 $query = sprintf("SELECT question_fi FROM tst_test_question WHERE test_fi = %s",
00508 $this->ilias->db->quote($this->getTestId())
00509 );
00510 $result = $this->ilias->db->query($query);
00511 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00512 {
00513 $this->removeQuestion($row->question_fi);
00514 }
00515
00516 $query = sprintf("DELETE FROM tst_tests WHERE test_id = %s",
00517 $this->ilias->db->quote($this->getTestId())
00518 );
00519 $result = $this->ilias->db->query($query);
00520
00521 $query = sprintf("DELETE FROM tst_test_random WHERE test_fi = %s",
00522 $this->ilias->db->quote($this->getTestId())
00523 );
00524 $result = $this->ilias->db->query($query);
00525
00526 $query = sprintf("DELETE FROM tst_test_random_question WHERE test_fi = %s",
00527 $this->ilias->db->quote($this->getTestId())
00528 );
00529 $result = $this->ilias->db->query($query);
00530
00531 $this->removeAllTestEditings();
00532
00533 $query = sprintf("DELETE FROM tst_test_question WHERE test_fi = %s",
00534 $this->ilias->db->quote($this->getTestId())
00535 );
00536 $result = $this->ilias->db->query($query);
00537
00538
00539 include_once "./classes/class.ilUtil.php";
00540 $tst_data_dir = ilUtil::getDataDir()."/tst_data";
00541 $directory = $tst_data_dir."/tst_".$this->getId();
00542 if (is_dir($directory))
00543 {
00544 include_once "./classes/class.ilUtil.php";
00545 ilUtil::delDir($directory);
00546 }
00547 }
00548
00558 function initDefaultRoles()
00559 {
00560 global $rbacadmin;
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 return $roles ? $roles : array();
00573 }
00574
00588 function notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params = 0)
00589 {
00590 global $tree;
00591
00592 switch ($a_event)
00593 {
00594 case "link":
00595
00596
00597
00598
00599 break;
00600
00601 case "cut":
00602
00603
00604
00605 break;
00606
00607 case "copy":
00608
00609
00610
00611
00612 break;
00613
00614 case "paste":
00615
00616
00617
00618 break;
00619
00620 case "new":
00621
00622
00623
00624 break;
00625 }
00626
00627
00628 if ($a_node_id==$_GET["ref_id"])
00629 {
00630 $parent_obj =& $this->ilias->obj_factory->getInstanceByRefId($a_node_id);
00631 $parent_type = $parent_obj->getType();
00632 if($parent_type == $this->getType())
00633 {
00634 $a_node_id = (int) $tree->getParentId($a_node_id);
00635 }
00636 }
00637
00638 parent::notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params);
00639 }
00640
00646 function createExportDirectory()
00647 {
00648 include_once "./classes/class.ilUtil.php";
00649 $tst_data_dir = ilUtil::getDataDir()."/tst_data";
00650 ilUtil::makeDir($tst_data_dir);
00651 if(!is_writable($tst_data_dir))
00652 {
00653 $this->ilias->raiseError("Test Data Directory (".$tst_data_dir
00654 .") not writeable.",$this->ilias->error_obj->MESSAGE);
00655 }
00656
00657
00658 $tst_dir = $tst_data_dir."/tst_".$this->getId();
00659 ilUtil::makeDir($tst_dir);
00660 if(!@is_dir($tst_dir))
00661 {
00662 $this->ilias->raiseError("Creation of Test Directory failed.",$this->ilias->error_obj->MESSAGE);
00663 }
00664
00665 $export_dir = $tst_dir."/export";
00666 ilUtil::makeDir($export_dir);
00667 if(!@is_dir($export_dir))
00668 {
00669 $this->ilias->raiseError("Creation of Export Directory failed.",$this->ilias->error_obj->MESSAGE);
00670 }
00671 }
00672
00680 function getExportDirectory()
00681 {
00682 include_once "./classes/class.ilUtil.php";
00683 $export_dir = ilUtil::getDataDir()."/tst_data"."/tst_".$this->getId()."/export";
00684 return $export_dir;
00685 }
00686
00695 function getExportFiles($dir)
00696 {
00697
00698 if (!@is_dir($dir) or
00699 !is_writeable($dir))
00700 {
00701 return array();
00702 }
00703
00704
00705 $dir = dir($dir);
00706
00707
00708 $file = array();
00709
00710
00711 while ($entry = $dir->read())
00712 {
00713 if ($entry != "." and
00714 $entry != ".." and
00715
00716 ereg("^[0-9]{10}_{2}[0-9]+_{2}(test(__results)?__)*[0-9]+\.[a-z]{1,3}\$", $entry))
00717 {
00718 $file[] = $entry;
00719 }
00720 }
00721
00722
00723 $dir->close();
00724
00725
00726 sort ($file);
00727 reset ($file);
00728
00729 return $file;
00730 }
00731
00732
00738 function _createImportDirectory()
00739 {
00740 global $ilias;
00741
00742 include_once "./classes/class.ilUtil.php";
00743 $tst_data_dir = ilUtil::getDataDir()."/tst_data";
00744 ilUtil::makeDir($tst_data_dir);
00745
00746 if(!is_writable($tst_data_dir))
00747 {
00748 $ilias->raiseError("Test data directory (".$tst_data_dir
00749 .") not writeable.",$ilias->error_obj->FATAL);
00750 }
00751
00752
00753 $tst_dir = $tst_data_dir."/tst_import";
00754 ilUtil::makeDir($tst_dir);
00755 if(!@is_dir($tst_dir))
00756 {
00757 $ilias->raiseError("Creation of test import directory failed.",$ilias->error_obj->FATAL);
00758 }
00759 }
00760
00769 function _getImportDirectory()
00770 {
00771 include_once "./classes/class.ilUtil.php";
00772 $import_dir = ilUtil::getDataDir()."/tst_data/tst_import";
00773 if(@is_dir($import_dir))
00774 {
00775 return $import_dir;
00776 }
00777 else
00778 {
00779 return false;
00780 }
00781 }
00782
00788 function createImportDirectory()
00789 {
00790 include_once "./classes/class.ilUtil.php";
00791 $tst_data_dir = ilUtil::getDataDir()."/tst_data";
00792 ilUtil::makeDir($tst_data_dir);
00793
00794 if(!is_writable($tst_data_dir))
00795 {
00796 $this->ilias->raiseError("Test Data Directory (".$tst_data_dir
00797 .") not writeable.",$this->ilias->error_obj->FATAL);
00798 }
00799
00800
00801 $tst_dir = $tst_data_dir."/tst_import";
00802 ilUtil::makeDir($tst_dir);
00803 if(!@is_dir($tst_dir))
00804 {
00805 $ilias->raiseError("Creation of test import directory failed.",$ilias->error_obj->FATAL);
00806 }
00807 }
00808
00817 function getImportDirectory()
00818 {
00819 include_once "./classes/class.ilUtil.php";
00820 $import_dir = ilUtil::getDataDir()."/tst_data/tst_import";
00821 if(@is_dir($import_dir))
00822 {
00823 return $import_dir;
00824 }
00825 else
00826 {
00827 return false;
00828 }
00829 }
00830
00831
00841 function retrieveTestTypes()
00842 {
00843 global $ilDB;
00844
00845 $this->test_types = array();
00846 $query = "SELECT * FROM tst_test_type ORDER BY test_type_id";
00847 $result = $ilDB->query($query);
00848 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00849 {
00850 $this->test_types[$row->test_type_id] = $row->type_tag;
00851 }
00852 }
00853
00863 function testTitleExists($title)
00864 {
00865 $query = sprintf("SELECT * FROM object_data WHERE title = %s AND type = %s",
00866 $this->ilias->db->quote($title),
00867 $this->ilias->db->quote("tst")
00868 );
00869 $result = $this->ilias->db->query($query);
00870 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00871 if ($result->numRows() == 1) {
00872 return TRUE;
00873 }
00874 }
00875 return FALSE;
00876 }
00877
00885 function duplicate()
00886 {
00887 $clone = $this;
00888 $clone->set_id(-1);
00889 $counter = 2;
00890 while ($this->testTitleExists($this->get_title() . " ($counter)")) {
00891 $counter++;
00892 }
00893 $clone->set_title($this->get_title() . " ($counter)");
00894 $clone->set_owner($this->ilias->account->id);
00895 $clone->setAuthor($this->ilias->account->fullname);
00896 $clone->saveToDb($this->ilias->db);
00897
00898 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi = %s",
00899 $this->ilias->db->quote($this->getId())
00900 );
00901 $result = $this->ilias->db->query($query);
00902 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
00903 $query = sprintf("INSERT INTO tst_test_question (test_question_id, test_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
00904 $this->ilias->db->quote($clone->getId()),
00905 $this->ilias->db->quote($data->question_fi),
00906 $this->ilias->db->quote($data->sequence)
00907 );
00908 $insert_result = $this->ilias->db->query($query);
00909 }
00910 }
00911
00920 function isComplete()
00921 {
00922 if (($this->getTitle()) and ($this->author) and (count($this->mark_schema->mark_steps)) and (count($this->questions)))
00923 {
00924 return true;
00925 }
00926 else
00927 {
00928 if ($this->isRandomTest())
00929 {
00930 $arr = $this->getRandomQuestionpools();
00931 if (count($arr) && ($this->getRandomQuestionCount() > 0))
00932 {
00933 return true;
00934 }
00935 $count = 0;
00936 foreach ($arr as $array)
00937 {
00938 $count += $array["count"];
00939 }
00940 if ($count)
00941 {
00942 return true;
00943 }
00944 }
00945 return false;
00946 }
00947 }
00948
00957 function _isComplete($obj_id)
00958 {
00959 $test = new ilObjTest($obj_id, false);
00960 $test->loadFromDb();
00961 return $test->isComplete();
00962 }
00963
00971 function saveECTSStatus($ects_output = 0, $fx_support = "", $ects_a = 90, $ects_b = 65, $ects_c = 35, $ects_d = 10, $ects_e = 0)
00972 {
00973 global $ilDB;
00974 if ($this->test_id > 0) {
00975 $fx_support = preg_replace("/,/", ".", $fx_support);
00976 if (preg_match("/\d+/", $fx_support))
00977 {
00978 $fx_support = $fx_support;
00979 }
00980 else
00981 {
00982 $fx_support = "NULL";
00983 }
00984 $query = sprintf("UPDATE tst_tests SET ects_output = %s, ects_a = %s, ects_b = %s, ects_c = %s, ects_d = %s, ects_e = %s, ects_fx = %s WHERE test_id = %s",
00985 $ilDB->quote("$ects_output"),
00986 $ilDB->quote($ects_a . ""),
00987 $ilDB->quote($ects_b . ""),
00988 $ilDB->quote($ects_c . ""),
00989 $ilDB->quote($ects_d . ""),
00990 $ilDB->quote($ects_e . ""),
00991 $fx_support,
00992 $this->getTestId()
00993 );
00994 $result = $ilDB->query($query);
00995 $this->ects_output = $ects_output;
00996 $this->ects_fx = $fx_support;
00997 }
00998 }
00999
01007 function saveCompleteStatus()
01008 {
01009 global $ilias;
01010
01011 $db =& $ilias->db;
01012 $complete = 0;
01013 if ($this->isComplete()) {
01014 $complete = 1;
01015 }
01016 if ($this->test_id > 0) {
01017 $query = sprintf("UPDATE tst_tests SET complete = %s WHERE test_id = %s",
01018 $db->quote("$complete"),
01019 $db->quote($this->test_id)
01020 );
01021 $result = $db->query($query);
01022 }
01023 }
01024
01033 function saveToDb($properties_only = FALSE)
01034 {
01035 global $ilias;
01036 $db =& $ilias->db;
01037 $complete = 0;
01038 if ($this->isComplete()) {
01039 $complete = 1;
01040 }
01041 $ects_fx = "NULL";
01042 if (preg_match("/\d+/", $this->ects_fx))
01043 {
01044 $ects_fx = $this->ects_fx;
01045 }
01046 $random_question_count = "NULL";
01047 if ($this->random_question_count > 0)
01048 {
01049 $random_question_count = $this->ilias->db->quote($this->random_question_count . "");
01050 }
01051 include_once ("./classes/class.ilObjAssessmentFolder.php");
01052 if ($this->test_id == -1)
01053 {
01054
01055 $now = getdate();
01056 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
01057 $query = sprintf("INSERT INTO tst_tests (test_id, obj_fi, author, test_type_fi, introduction, sequence_settings, score_reporting, nr_of_tries, hide_previous_results, hide_title_points, processing_time, enable_processing_time, reporting_date, starting_time, ending_time, complete, ects_output, ects_a, ects_b, ects_c, ects_d, ects_e, ects_fx, random_test, random_question_count, count_system, mc_scoring, pass_scoring, created, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
01058 $db->quote($this->getId() . ""),
01059 $db->quote($this->author . ""),
01060 $db->quote($this->test_type . ""),
01061 $db->quote($this->introduction . ""),
01062 $db->quote($this->sequence_settings . ""),
01063 $db->quote($this->score_reporting . ""),
01064 $db->quote(sprintf("%d", $this->nr_of_tries) . ""),
01065 $db->quote(sprintf("%d", $this->getHidePreviousResults() . "")),
01066 $db->quote(sprintf("%d", $this->getHideTitlePoints() . "")),
01067 $db->quote($this->processing_time . ""),
01068 $db->quote("$this->enable_processing_time"),
01069 $db->quote($this->reporting_date . ""),
01070 $db->quote($this->starting_time . ""),
01071 $db->quote($this->ending_time . ""),
01072 $db->quote("$complete"),
01073 $db->quote($this->ects_output . ""),
01074 $db->quote($this->ects_grades["A"] . ""),
01075 $db->quote($this->ects_grades["B"] . ""),
01076 $db->quote($this->ects_grades["C"] . ""),
01077 $db->quote($this->ects_grades["D"] . ""),
01078 $db->quote($this->ects_grades["E"] . ""),
01079 $ects_fx,
01080 $db->quote(sprintf("%d", $this->random_test) . ""),
01081 $random_question_count,
01082 $db->quote($this->count_system . ""),
01083 $db->quote($this->mc_scoring . ""),
01084 $db->quote($this->getPassScoring() . ""),
01085 $db->quote($created)
01086 );
01087
01088 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01089 {
01090 $this->logAction($this->lng->txtlng("assessment", "log_create_new_test", ilObjAssessmentFolder::_getLogLanguage()));
01091 }
01092 $result = $db->query($query);
01093 if ($result == DB_OK) {
01094 $this->test_id = $this->ilias->db->getLastInsertId();
01095 }
01096 }
01097 else
01098 {
01099
01100 $oldrow = array();
01101 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01102 {
01103 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01104 $db->quote($this->test_id)
01105 );
01106 $result = $db->query($query);
01107 if ($result->numRows() == 1)
01108 {
01109 $oldrow = $result->fetchRow(DB_FETCHMODE_ASSOC);
01110 }
01111 }
01112 $query = sprintf("UPDATE tst_tests SET author = %s, test_type_fi = %s, introduction = %s, sequence_settings = %s, score_reporting = %s, nr_of_tries = %s, hide_previous_results = %s, hide_title_points = %s, processing_time = %s, enable_processing_time = %s, reporting_date = %s, starting_time = %s, ending_time = %s, ects_output = %s, ects_a = %s, ects_b = %s, ects_c = %s, ects_d = %s, ects_e = %s, ects_fx = %s, random_test = %s, complete = %s, count_system = %s, mc_scoring = %s, pass_scoring = %s WHERE test_id = %s",
01113 $db->quote($this->author . ""),
01114 $db->quote($this->test_type . ""),
01115 $db->quote($this->introduction . ""),
01116 $db->quote($this->sequence_settings . ""),
01117 $db->quote($this->score_reporting . ""),
01118 $db->quote(sprintf("%d", $this->nr_of_tries) . ""),
01119 $db->quote(sprintf("%d", $this->getHidePreviousResults() . "")),
01120 $db->quote(sprintf("%d", $this->getHideTitlePoints() . "")),
01121 $db->quote($this->processing_time . ""),
01122 $db->quote("$this->enable_processing_time"),
01123 $db->quote($this->reporting_date . ""),
01124 $db->quote($this->starting_time . ""),
01125 $db->quote($this->ending_time . ""),
01126 $db->quote($this->ects_output . ""),
01127 $db->quote($this->ects_grades["A"] . ""),
01128 $db->quote($this->ects_grades["B"] . ""),
01129 $db->quote($this->ects_grades["C"] . ""),
01130 $db->quote($this->ects_grades["D"] . ""),
01131 $db->quote($this->ects_grades["E"] . ""),
01132 $ects_fx,
01133 $db->quote(sprintf("%d", $this->random_test) . ""),
01134 $db->quote("$complete"),
01135 $db->quote($this->count_system . ""),
01136 $db->quote($this->mc_scoring . ""),
01137 $db->quote($this->getPassScoring() . ""),
01138 $db->quote($this->test_id)
01139 );
01140 $result = $db->query($query);
01141 include_once ("./classes/class.ilObjAssessmentFolder.php");
01142 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01143 {
01144 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01145 $db->quote($this->test_id)
01146 );
01147 $logresult = $db->query($query);
01148 $newrow = array();
01149 if ($logresult->numRows() == 1)
01150 {
01151 $newrow = $logresult->fetchRow(DB_FETCHMODE_ASSOC);
01152 }
01153 $changed_fields = array();
01154 foreach ($oldrow as $key => $value)
01155 {
01156 if (strcmp($oldrow[$key], $newrow[$key]) != 0)
01157 {
01158 array_push($changed_fields, "$key: " . $oldrow[$key] . " => " . $newrow[$key]);
01159 }
01160 }
01161 $changes = join($changed_fields, ", ");
01162 if (count($changed_fields) == 0)
01163 {
01164 $changes = $this->lng->txtlng("assessment", "log_no_test_fields_changed", ilObjAssessmentFolder::_getLogLanguage());
01165 }
01166 $this->logAction($this->lng->txtlng("assessment", "log_modified_test", ilObjAssessmentFolder::_getLogLanguage()) . " [".$changes."]");
01167 }
01168 }
01169 if (!$properties_only)
01170 {
01171 if ($result == DB_OK) {
01172 if (!$this->isRandomTest())
01173 {
01174 $this->saveQuestionsToDb();
01175 }
01176 $this->mark_schema->saveToDb($this->test_id);
01177 }
01178 }
01179 }
01180
01189 function saveQuestionsToDb()
01190 {
01191 $oldquestions = array();
01192 include_once "./classes/class.ilObjAssessmentFolder.php";
01193 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01194 {
01195 $query = sprintf("SELECT question_fi FROM tst_test_question WHERE test_fi = %s ORDER BY sequence",
01196 $this->ilias->db->quote($this->getTestId())
01197 );
01198 $result = $this->ilias->db->query($query);
01199 if ($result->numRows() > 0)
01200 {
01201 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01202 {
01203 array_push($oldquestions, $row["question_fi"]);
01204 }
01205 }
01206 }
01207
01208
01209 $query = sprintf("DELETE FROM tst_test_question WHERE test_fi = %s",
01210 $this->ilias->db->quote($this->getTestId())
01211 );
01212 $result = $this->ilias->db->query($query);
01213
01214 foreach ($this->questions as $key => $value) {
01215 $query = sprintf("INSERT INTO tst_test_question (test_question_id, test_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
01216 $this->ilias->db->quote($this->getTestId() . ""),
01217 $this->ilias->db->quote($value . ""),
01218 $this->ilias->db->quote($key . "")
01219 );
01220 $result = $this->ilias->db->query($query);
01221 }
01222 include_once ("./classes/class.ilObjAssessmentFolder.php");
01223 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01224 {
01225 $query = sprintf("SELECT question_fi FROM tst_test_question WHERE test_fi = %s ORDER BY sequence",
01226 $this->ilias->db->quote($this->getTestId())
01227 );
01228 $result = $this->ilias->db->query($query);
01229 $newquestions = array();
01230 if ($result->numRows() > 0)
01231 {
01232 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01233 {
01234 array_push($newquestions, $row["question_fi"]);
01235 }
01236 }
01237 foreach ($oldquestions as $index => $question_id)
01238 {
01239 if (strcmp($newquestions[$index], $question_id) != 0)
01240 {
01241 $pos = array_search($question_id, $newquestions);
01242 if ($pos === FALSE)
01243 {
01244 $this->logAction($this->lng->txtlng("assessment", "log_question_removed", ilObjAssessmentFolder::_getLogLanguage()), $question_id);
01245 }
01246 else
01247 {
01248 $this->logAction($this->lng->txtlng("assessment", "log_question_position_changed", ilObjAssessmentFolder::_getLogLanguage()) . ": " . ($index+1) . " => " . ($pos+1), $question_id);
01249 }
01250 }
01251 }
01252 foreach ($newquestions as $index => $question_id)
01253 {
01254 if (array_search($question_id, $oldquestions) === FALSE)
01255 {
01256 $this->logAction($this->lng->txtlng("assessment", "log_question_added", ilObjAssessmentFolder::_getLogLanguage()) . ": " . ($index+1), $question_id);
01257 }
01258 }
01259 }
01260 }
01261
01270 function saveRandomQuestion($question_id, $pass = NULL)
01271 {
01272 global $ilUser;
01273
01274 if (is_null($pass)) $pass = 0;
01275 $query = sprintf("SELECT test_random_question_id FROM tst_test_random_question WHERE test_fi = %s AND user_fi = %s AND pass = %s",
01276 $this->ilias->db->quote($this->getTestId() . ""),
01277 $this->ilias->db->quote($ilUser->id . ""),
01278 $this->ilias->db->quote($pass . "")
01279 );
01280 $result = $this->ilias->db->query($query);
01281
01282 $query = sprintf("INSERT INTO tst_test_random_question (test_random_question_id, test_fi, user_fi, question_fi, sequence, pass, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
01283 $this->ilias->db->quote($this->getTestId() . ""),
01284 $this->ilias->db->quote($ilUser->id . ""),
01285 $this->ilias->db->quote($question_id . ""),
01286 $this->ilias->db->quote(($result->numRows()+1) . ""),
01287 $this->ilias->db->quote($pass . "")
01288 );
01289 $result = $this->ilias->db->query($query);
01290 }
01291
01299 function getNrOfResultsForPass($user_id, $pass)
01300 {
01301 $query = sprintf("SELECT test_result_id FROM tst_test_result WHERE test_fi = %s AND user_fi = %s AND pass = %s",
01302 $this->ilias->db->quote($this->getTestId() . ""),
01303 $this->ilias->db->quote($user_id . ""),
01304 $this->ilias->db->quote($pass . "")
01305 );
01306 $result = $this->ilias->db->query($query);
01307 return $result->numRows();
01308 }
01309
01318 function generateRandomQuestions($pass = NULL)
01319 {
01320 global $ilUser;
01321 $this->loadQuestions($ilUser->getId(), $pass);
01322 if (count($this->questions) > 0)
01323 {
01324
01325
01326 return;
01327 }
01328 if ($pass > 0)
01329 {
01330 if ($this->getNrOfResultsForPass($ilUser->getId(), $pass - 1) == 0)
01331 {
01332
01333
01334
01335 return;
01336 }
01337 }
01338 if ($this->getRandomQuestionCount() > 0)
01339 {
01340 $qpls =& $this->getRandomQuestionpools();
01341 $rndquestions = $this->randomSelectQuestions($this->getRandomQuestionCount(), 0, 1, $qpls, $pass);
01342 $allquestions = array();
01343 foreach ($rndquestions as $question_id)
01344 {
01345 array_push($allquestions, $question_id);
01346 }
01347 srand ((float)microtime()*1000000);
01348 shuffle($allquestions);
01349 foreach ($allquestions as $question_id)
01350 {
01351 $this->saveRandomQuestion($question_id, $pass);
01352 }
01353 }
01354 else
01355 {
01356 $qpls =& $this->getRandomQuestionpools();
01357 $allquestions = array();
01358 foreach ($qpls as $key => $value)
01359 {
01360 if ($value["count"] > 0)
01361 {
01362 $rndquestions = $this->randomSelectQuestions($value["count"], $value["qpl"], 1, $pass);
01363 foreach ($rndquestions as $question_id)
01364 {
01365 array_push($allquestions, $question_id);
01366 }
01367 }
01368 }
01369 srand ((float)microtime()*1000000);
01370 shuffle($allquestions);
01371 foreach ($allquestions as $question_id)
01372 {
01373 $this->saveRandomQuestion($question_id, $pass);
01374 }
01375 }
01376 return;
01377 }
01378
01387 function saveRandomQuestionCount($total_questions = "NULL")
01388 {
01389 if (strcmp($total_questions, "NULL") != 0)
01390 {
01391 $this->setRandomQuestionCount($total_questions);
01392 $total_questions = $this->ilias->db->quote($total_questions);
01393 }
01394 $query = sprintf("UPDATE tst_tests SET random_question_count = %s WHERE test_id = %s",
01395 $total_questions,
01396 $this->ilias->db->quote($this->getTestId() . "")
01397 );
01398 $result = $this->ilias->db->query($query);
01399 }
01400
01410 function saveRandomQuestionpools($qpl_array)
01411 {
01412
01413 $query = sprintf("DELETE FROM tst_test_random WHERE test_fi = %s",
01414 $this->ilias->db->quote($this->getTestId())
01415 );
01416 $result = $this->ilias->db->query($query);
01417
01418 foreach ($qpl_array as $key => $value) {
01419 if ($value["qpl"] > -1)
01420 {
01421 include_once "./assessment/classes/class.ilObjQuestionPool.php";
01422 $count = ilObjQuestionPool::_getQuestionCount($value["qpl"]);
01423 if ($value["count"] > $count)
01424 {
01425 $value["count"] = $count;
01426 }
01427 $query = sprintf("INSERT INTO tst_test_random (test_random_id, test_fi, questionpool_fi, num_of_q, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
01428 $this->ilias->db->quote($this->getTestId() . ""),
01429 $this->ilias->db->quote($value["qpl"] . ""),
01430 $this->ilias->db->quote(sprintf("%d", $value["count"]) . "")
01431 );
01432 $result = $this->ilias->db->query($query);
01433 }
01434 }
01435 }
01436
01446 function &getRandomQuestionpools()
01447 {
01448 $qpls = array();
01449 $counter = 0;
01450 $query = sprintf("SELECT * FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
01451 $this->ilias->db->quote($this->getTestId() . "")
01452 );
01453 $result = $this->ilias->db->query($query);
01454 if ($result->numRows())
01455 {
01456 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01457 {
01458 $qpls[$counter] = array(
01459 "index" => $counter,
01460 "count" => $row["num_of_q"],
01461 "qpl" => $row["questionpool_fi"]
01462 );
01463 $counter++;
01464 }
01465 }
01466 return $qpls;
01467 }
01468
01478 function loadFromDb()
01479 {
01480 $db = $this->ilias->db;
01481
01482 $query = sprintf("SELECT * FROM tst_tests WHERE obj_fi = %s",
01483 $db->quote($this->getId())
01484 );
01485 $result = $db->query($query);
01486 if (strcmp(strtolower(get_class($result)), db_result) == 0)
01487 {
01488 if ($result->numRows() == 1)
01489 {
01490 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
01491 $this->test_id = $data->test_id;
01492 $this->author = $data->author;
01493 $this->test_type = $data->test_type_fi;
01494 $this->introduction = $data->introduction;
01495 $this->sequence_settings = $data->sequence_settings;
01496 $this->score_reporting = $data->score_reporting;
01497 $this->nr_of_tries = $data->nr_of_tries;
01498 $this->setHidePreviousResults($data->hide_previous_results);
01499 $this->setHideTitlePoints($data->hide_title_points);
01500 $this->processing_time = $data->processing_time;
01501 $this->enable_processing_time = $data->enable_processing_time;
01502 $this->reporting_date = $data->reporting_date;
01503 $this->starting_time = $data->starting_time;
01504 $this->ending_time = $data->ending_time;
01505 $this->ects_output = $data->ects_output;
01506 $this->ects_grades = array(
01507 "A" => $data->ects_a,
01508 "B" => $data->ects_b,
01509 "C" => $data->ects_c,
01510 "D" => $data->ects_d,
01511 "E" => $data->ects_e
01512 );
01513 $this->ects_fx = $data->ects_fx;
01514 $this->random_test = $data->random_test;
01515 $this->random_question_count = $data->random_question_count;
01516 $this->mark_schema->flush();
01517 $this->mark_schema->loadFromDb($this->test_id);
01518 $this->count_system = $data->count_system;
01519 $this->mc_scoring = $data->mc_scoring;
01520 $this->setPassScoring($data->pass_scoring);
01521 $this->loadQuestions();
01522 }
01523 }
01524 }
01525
01534 function loadQuestions($user_id = "", $pass = NULL)
01535 {
01536 global $ilUser;
01537
01538 $db = $this->ilias->db;
01539 $this->questions = array();
01540 if (strcmp($user_id, "") == 0)
01541 {
01542 $user_id = $ilUser->id;
01543 }
01544 if ($this->isRandomTest())
01545 {
01546 if (is_null($pass))
01547 {
01548 if ($this->getTestType() == TYPE_VARYING_RANDOMTEST)
01549 {
01550 $pass = $this->_getPass($ilUser->id, $this->getTestId());
01551 }
01552 else
01553 {
01554
01555 $pass = 0;
01556 }
01557 }
01558 $query = sprintf("SELECT tst_test_random_question.* FROM tst_test_random_question, qpl_questions WHERE tst_test_random_question.test_fi = %s AND tst_test_random_question.user_fi = %s AND qpl_questions.question_id = tst_test_random_question.question_fi AND tst_test_random_question.pass = %s ORDER BY sequence",
01559 $db->quote($this->test_id . ""),
01560 $db->quote($user_id . ""),
01561 $db->quote($pass . "")
01562 );
01563 }
01564 else
01565 {
01566 $query = sprintf("SELECT tst_test_question.* FROM tst_test_question, qpl_questions WHERE tst_test_question.test_fi = %s AND qpl_questions.question_id = tst_test_question.question_fi ORDER BY sequence",
01567 $db->quote($this->test_id . "")
01568 );
01569 }
01570 $result = $db->query($query);
01571 $index = 1;
01572 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT))
01573 {
01574 $this->questions[$index++] = $data->question_fi;
01575 }
01576 }
01577
01587 function setAuthor($author = "")
01588 {
01589 $this->author = $author;
01590 }
01591
01601 function setIntroduction($introduction = "")
01602 {
01603 $this->introduction = $introduction;
01604 }
01605
01615 function getAuthor()
01616 {
01617 return $this->author;
01618 }
01619
01629 function isRandomTest()
01630 {
01631 return $this->random_test;
01632 }
01633
01643 function getRandomQuestionCount()
01644 {
01645 return $this->random_question_count;
01646 }
01647
01657 function getIntroduction()
01658 {
01659 return $this->introduction;
01660 }
01661
01671 function getTestId()
01672 {
01673 return $this->test_id;
01674 }
01675
01685 function setSequenceSettings($sequence_settings = 0)
01686 {
01687 $this->sequence_settings = $sequence_settings;
01688 }
01689
01699 function setTestType($type = TYPE_ASSESSMENT)
01700 {
01701 $this->test_type = $type;
01702 }
01703
01713 function setScoreReporting($score_reporting = 0)
01714 {
01715 $this->score_reporting = $score_reporting;
01716 }
01717
01727 function setRandomTest($a_random_test = 0)
01728 {
01729 $this->random_test = $a_random_test;
01730 }
01731
01741 function setRandomQuestionCount($a_random_question_count = "")
01742 {
01743 $this->random_question_count = $a_random_question_count;
01744 }
01745
01755 function setReportingDate($reporting_date)
01756 {
01757 if (!$reporting_date)
01758 {
01759 $this->reporting_date = "";
01760 $this->ects_output = 0;
01761 }
01762 else
01763 {
01764 $this->reporting_date = $reporting_date;
01765 $this->score_reporting = REPORT_AFTER_TEST;
01766 }
01767 }
01768
01778 function getSequenceSettings()
01779 {
01780 return $this->sequence_settings;
01781 }
01782
01792 function getScoreReporting()
01793 {
01794 return $this->score_reporting;
01795 }
01796
01806 function getCountSystem()
01807 {
01808 return $this->count_system;
01809 }
01810
01820 function _getCountSystem($test_id)
01821 {
01822 global $ilDB;
01823 $query = sprintf("SELECT count_system FROM tst_tests WHERE test_id = %s",
01824 $ilDB->quote($test_id)
01825 );
01826 $result = $ilDB->query($query);
01827 if ($result->numRows())
01828 {
01829 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01830 return $row["count_system"];
01831 }
01832 return FALSE;
01833 }
01834
01844 function getMCScoring()
01845 {
01846 return $this->mc_scoring;
01847 }
01848
01858 function getPassScoring()
01859 {
01860 return $this->pass_scoring;
01861 }
01862
01872 function _getPassScoring($test_id)
01873 {
01874 global $ilDB;
01875 $query = sprintf("SELECT pass_scoring FROM tst_tests WHERE test_id = %s",
01876 $ilDB->quote($test_id . "")
01877 );
01878 $result = $ilDB->query($query);
01879 if ($result->numRows())
01880 {
01881 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01882 return $row["pass_scoring"];
01883 }
01884 return 0;
01885 }
01886
01896 function _getMCScoring($test_id)
01897 {
01898 global $ilDB;
01899 $query = sprintf("SELECT mc_scoring FROM tst_tests WHERE test_id = %s",
01900 $ilDB->quote($test_id)
01901 );
01902 $result = $ilDB->query($query);
01903 if ($result->numRows())
01904 {
01905 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
01906 return $row["mc_scoring"];
01907 }
01908 return FALSE;
01909 }
01910
01920 function getTestType()
01921 {
01922 return $this->test_type;
01923 }
01924
01934 function getReportingDate()
01935 {
01936 return $this->reporting_date;
01937 }
01938
01948 function getNrOfTries()
01949 {
01950 return $this->nr_of_tries;
01951 }
01952
01962 function getHidePreviousResults()
01963 {
01964 return $this->hide_previous_results;
01965 }
01966
01976 function getHideTitlePoints()
01977 {
01978 return $this->hide_title_points;
01979 }
01980
01991 function _getHideTitlePoints($test_id)
01992 {
01993 global $ilDB;
01994
01995 $query = sprintf("SELECT hide_title_points FROM tst_tests WHERE test_id = %s",
01996 $ilDB->quote($test_id . "")
01997 );
01998 $result = $ilDB->query($query);
01999 if ($result->numRows())
02000 {
02001 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02002 return $row["hide_title_points"];
02003 }
02004 return 0;
02005 }
02006
02018 function _getHidePreviousResults($test_id, $user_active_user_setting = false)
02019 {
02020 global $ilDB;
02021 global $ilUser;
02022
02023 $user_hide_previous_results = 0;
02024 if ($user_active_user_setting)
02025 {
02026 if (array_key_exists("tst_hide_previous_results", $ilUser->prefs))
02027 {
02028 $user_hide_previous_results = $ilUser->prefs["tst_hide_previous_results"];
02029 }
02030 }
02031 $query = sprintf("SELECT hide_previous_results FROM tst_tests WHERE test_id = %s",
02032 $ilDB->quote($test_id . "")
02033 );
02034 $result = $ilDB->query($query);
02035 if ($result->numRows())
02036 {
02037 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02038 if ($row["hide_previous_results"] != 1)
02039 {
02040 return $row["hide_previous_results"] | $user_hide_previous_results;
02041 }
02042 else
02043 {
02044 return $row["hide_previous_results"];
02045 }
02046 }
02047 return 0;
02048 }
02049
02059 function getProcessingTime()
02060 {
02061 return $this->processing_time;
02062 }
02063
02073 function getProcessingTimeInSeconds()
02074 {
02075 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $this->getProcessingTime(), $matches))
02076 {
02077 return ($matches[1] * 3600) + ($matches[2] * 60) + $matches[3];
02078 }
02079 else
02080 {
02081 return 0;
02082 }
02083 }
02084
02094 function getEnableProcessingTime()
02095 {
02096 return $this->enable_processing_time;
02097 }
02098
02108 function getStartingTime()
02109 {
02110 return $this->starting_time;
02111 }
02112
02122 function getEndingTime()
02123 {
02124 return $this->ending_time;
02125 }
02126
02136 function setNrOfTries($nr_of_tries = 0)
02137 {
02138 $this->nr_of_tries = $nr_of_tries;
02139 }
02140
02150 function setHidePreviousResults($hide_previous_results = 0)
02151 {
02152 if ($hide_previous_results)
02153 {
02154 $this->hide_previous_results = 1;
02155 }
02156 else
02157 {
02158 $this->hide_previous_results = 0;
02159 }
02160 }
02161
02171 function setHideTitlePoints($hide_title_points = 0)
02172 {
02173 if ($hide_title_points)
02174 {
02175 $this->hide_title_points = 1;
02176 }
02177 else
02178 {
02179 $this->hide_title_points = 0;
02180 }
02181 }
02182
02192 function setProcessingTime($processing_time = "00:00:00")
02193 {
02194 $this->processing_time = $processing_time;
02195 }
02196
02206 function setEnableProcessingTime($enable = 0)
02207 {
02208 if ($enable) {
02209 $this->enable_processing_time = "1";
02210 } else {
02211 $this->enable_processing_time = "0";
02212 }
02213 }
02214
02224 function setStartingTime($starting_time = "")
02225 {
02226 $this->starting_time = $starting_time;
02227 }
02228
02238 function setEndingTime($ending_time = "")
02239 {
02240 $this->ending_time = $ending_time;
02241 }
02242
02252 function setCountSystem($a_count_system = COUNT_PARTIAL_SOLUTIONS)
02253 {
02254 $this->count_system = $a_count_system;
02255 }
02256
02266 function setMCScoring($a_mc_scoring = SCORE_ZERO_POINTS_WHEN_UNANSWERED)
02267 {
02268 $this->mc_scoring = $a_mc_scoring;
02269 }
02270
02280 function setPassScoring($a_pass_scoring = SCORE_LAST_PASS)
02281 {
02282 switch ($a_pass_scoring)
02283 {
02284 case SCORE_BEST_PASS:
02285 $this->pass_scoring = SCORE_BEST_PASS;
02286 break;
02287 default:
02288 $this->pass_scoring = SCORE_LAST_PASS;
02289 break;
02290 }
02291 }
02292
02302 function removeQuestion($question_id)
02303 {
02304 include_once "./assessment/classes/class.assQuestion.php";
02305 $question = new ASS_Question();
02306 include_once ("./classes/class.ilObjAssessmentFolder.php");
02307 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02308 {
02309 $this->logAction($this->lng->txtlng("assessment", "log_question_removed", ilObjAssessmentFolder::_getLogLanguage()), $question_id);
02310 }
02311 $question->delete($question_id);
02312 $this->removeAllTestEditings($question_id);
02313 $this->loadQuestions();
02314 $this->saveQuestionsToDb();
02315 }
02316
02324 function clearEvalSelectedUsers()
02325 {
02326 $query = sprintf("DELETE FROM tst_eval_users WHERE test_fi = %s",
02327 $this->ilias->db->quote($this->getTestId())
02328 );
02329 $result = $this->ilias->db->query($query);
02330 }
02331
02343 function removeAllTestEditings($question_id = "")
02344 {
02345
02346 $this->deleteActiveTests();
02347
02348 $this->clearEvalSelectedUsers();
02349
02350
02351 if ($question_id)
02352 {
02353 $query = sprintf("DELETE FROM tst_solutions WHERE test_fi = %s AND question_fi = %s",
02354 $this->ilias->db->quote($this->getTestId()),
02355 $this->ilias->db->quote($question_id)
02356 );
02357 $query2 = sprintf("DELETE FROM tst_active_qst_sol_settings WHERE test_fi = %s AND question_fi=%s",
02358 $this->ilias->db->quote($this->getTestId()),
02359 $this->ilias->db->quote($question_id)
02360 );
02361 $query3 = sprintf("DELETE FROM tst_test_result WHERE test_fi = %s AND question_fi = %s",
02362 $this->ilias->db->quote($this->getTestId()),
02363 $this->ilias->db->quote($question_id)
02364 );
02365 } else {
02366 $query = sprintf("DELETE FROM tst_solutions WHERE test_fi = %s",
02367 $this->ilias->db->quote($this->getTestId())
02368 );
02369 $query2 = sprintf("DELETE FROM tst_active_qst_sol_settings WHERE test_fi = %s",
02370 $this->ilias->db->quote($this->getTestId())
02371 );
02372 $query3 = sprintf("DELETE FROM tst_test_result WHERE test_fi = %s",
02373 $this->ilias->db->quote($this->getTestId())
02374 );
02375 }
02376 $result = $this->ilias->db->query($query);
02377 $result = $this->ilias->db->query($query2);
02378 $result = $this->ilias->db->query($query3);
02379
02380 if ($this->isRandomTest())
02381 {
02382 $query = sprintf("DELETE FROM tst_test_random_question WHERE test_fi = %s",
02383 $this->ilias->db->quote($this->getTestId())
02384 );
02385 $result = $this->ilias->db->query($query);
02386 }
02387 include_once ("./classes/class.ilObjAssessmentFolder.php");
02388 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02389 {
02390 $this->logAction($this->lng->txtlng("assessment", "log_user_data_removed", ilObjAssessmentFolder::_getLogLanguage()));
02391 }
02392 }
02393
02405 function removeSelectedTestResults($user_ids)
02406 {
02407 global $ilDB;
02408
02409
02410 foreach ($user_ids as $user_id)
02411 {
02412 $query = sprintf("DELETE FROM tst_active WHERE user_fi = %s AND test_fi = %s",
02413 $ilDB->quote($user_id . ""),
02414 $ilDB->quote($this->getTestId() . "")
02415 );
02416 $result = $ilDB->query($query);
02417 }
02418
02419
02420 $this->clearEvalSelectedUsers();
02421
02422
02423 foreach ($user_ids as $user_id)
02424 {
02425 $query = sprintf("DELETE FROM tst_solutions WHERE test_fi = %s AND user_fi = %s",
02426 $ilDB->quote($this->getTestId() . ""),
02427 $ilDB->quote($user_id . "")
02428 );
02429 $query2 = sprintf("DELETE FROM tst_active_qst_sol_settings WHERE test_fi = %s AND user_fi = %s",
02430 $ilDB->quote($this->getTestId() . ""),
02431 $ilDB->quote($user_id . "")
02432 );
02433 $query3 = sprintf("DELETE FROM tst_test_result WHERE test_fi = %s AND user_fi = %s",
02434 $ilDB->quote($this->getTestId() . ""),
02435 $ilDB->quote($user_id . "")
02436 );
02437 $result = $ilDB->query($query);
02438 $result = $ilDB->query($query2);
02439 $result = $ilDB->query($query3);
02440
02441 if ($this->isRandomTest())
02442 {
02443 $query = sprintf("DELETE FROM tst_test_random_question WHERE test_fi = %s AND user_fi = %s",
02444 $ilDB->quote($this->getTestId() . ""),
02445 $ilDB->quote($user_id . "")
02446 );
02447 $result = $ilDB->query($query);
02448 }
02449 include_once ("./classes/class.ilObjAssessmentFolder.php");
02450 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02451 {
02452 include_once ("./classes/class.ilObjUser.php");
02453 $uname = ilObjUser::_lookupName($user_id);
02454 $this->logAction(sprintf($this->lng->txtlng("assessment", "log_selected_user_data_removed", ilObjAssessmentFolder::_getLogLanguage()), trim($uname["title"] . " " . $uname["firstname"] . " " . $uname["lastname"] . " (" . $uname["user_id"] . ")")));
02455 }
02456 }
02457 }
02458
02467 function deleteActiveTests()
02468 {
02469 $query = sprintf("DELETE FROM tst_active WHERE test_fi = %s",
02470 $this->ilias->db->quote($this->getTestId())
02471 );
02472 $result = $this->ilias->db->query($query);
02473 }
02474
02485 function deleteResults($user_id = "")
02486 {
02487 if ($user_id)
02488 {
02489 $pass = $this->_getPass($user_id, $this->getTestId());
02490 $query = sprintf("DELETE FROM tst_solutions WHERE test_fi = %s AND user_fi = %s AND pass = %s",
02491 $this->ilias->db->quote($this->getTestId() . ""),
02492 $this->ilias->db->quote($user_id . ""),
02493 $this->ilias->db->quote($pass . "")
02494 );
02495 $result = $this->ilias->db->query($query);
02496 $query = sprintf("DELETE FROM tst_test_result WHERE test_fi = %s AND user_fi = %s AND pass = %s",
02497 $this->ilias->db->quote($this->getTestId() . ""),
02498 $this->ilias->db->quote($user_id . ""),
02499 $this->ilias->db->quote($pass . "")
02500 );
02501 $result = $this->ilias->db->query($query);
02502 $sequence_arr = array_flip($this->questions);
02503 $sequence = join($sequence_arr, ",");
02504 $query = sprintf("UPDATE tst_active SET sequence = %s, lastindex = %s WHERE test_fi = %s and user_fi = %s",
02505 $this->ilias->db->quote($sequence),
02506 $this->ilias->db->quote("1"),
02507 $this->ilias->db->quote($this->getTestId()),
02508 $this->ilias->db->quote($user_id)
02509 );
02510 $result = $this->ilias->db->query($query);
02511
02512 $query = sprintf("DELETE FROM tst_active_qst_sol_settings WHERE test_fi = %s AND user_fi = %s",
02513 $this->ilias->db->quote($this->getTestId()),
02514 $this->ilias->db->quote($user_id)
02515 );
02516 $result = $this->ilias->db->query($query);
02517 }
02518 }
02519
02529 function questionMoveUp($question_id)
02530 {
02531
02532 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND question_fi=%s",
02533 $this->ilias->db->quote($this->getTestId()),
02534 $this->ilias->db->quote($question_id)
02535 );
02536 $result = $this->ilias->db->query($query);
02537 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
02538 if ($data->sequence > 1) {
02539
02540 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND sequence=%s",
02541 $this->ilias->db->quote($this->getTestId()),
02542 $this->ilias->db->quote($data->sequence - 1)
02543 );
02544 $result = $this->ilias->db->query($query);
02545 $data_previous = $result->fetchRow(DB_FETCHMODE_OBJECT);
02546
02547 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
02548 $this->ilias->db->quote($data->sequence),
02549 $this->ilias->db->quote($data_previous->test_question_id)
02550 );
02551 $result = $this->ilias->db->query($query);
02552
02553 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
02554 $this->ilias->db->quote($data->sequence - 1),
02555 $this->ilias->db->quote($data->test_question_id)
02556 );
02557 $result = $this->ilias->db->query($query);
02558 include_once ("./classes/class.ilObjAssessmentFolder.php");
02559 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02560 {
02561 $this->logAction($this->lng->txtlng("assessment", "log_question_position_changed", ilObjAssessmentFolder::_getLogLanguage()) . ": " . ($data->sequence) . " => " . ($data->sequence-1), $question_id);
02562 }
02563 }
02564 $this->loadQuestions();
02565 }
02566
02576 function questionMoveDown($question_id)
02577 {
02578
02579 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND question_fi=%s",
02580 $this->ilias->db->quote($this->getTestId()),
02581 $this->ilias->db->quote($question_id)
02582 );
02583 $result = $this->ilias->db->query($query);
02584 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
02585 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND sequence=%s",
02586 $this->ilias->db->quote($this->getTestId()),
02587 $this->ilias->db->quote($data->sequence + 1)
02588 );
02589 $result = $this->ilias->db->query($query);
02590 if ($result->numRows() == 1)
02591 {
02592
02593 $data_next = $result->fetchRow(DB_FETCHMODE_OBJECT);
02594
02595 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
02596 $this->ilias->db->quote($data->sequence),
02597 $this->ilias->db->quote($data_next->test_question_id)
02598 );
02599 $result = $this->ilias->db->query($query);
02600
02601 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
02602 $this->ilias->db->quote($data->sequence + 1),
02603 $this->ilias->db->quote($data->test_question_id)
02604 );
02605 $result = $this->ilias->db->query($query);
02606 include_once ("./classes/class.ilObjAssessmentFolder.php");
02607 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02608 {
02609 $this->logAction($this->lng->txtlng("assessment", "log_question_position_changed", ilObjAssessmentFolder::_getLogLanguage()) . ": " . ($data->sequence) . " => " . ($data->sequence+1), $question_id);
02610 }
02611 }
02612 $this->loadQuestions();
02613 }
02614
02624 function duplicateQuestionForTest($question_id)
02625 {
02626 global $ilUser;
02627 $question =& ilObjTest::_instanciateQuestion($question_id);
02628 $duplicate_id = $question->duplicate(true);
02629
02630 return $duplicate_id;
02631 }
02632
02641 function insertQuestion($question_id)
02642 {
02643 $duplicate_id = $this->duplicateQuestionForTest($question_id);
02644
02645
02646 $query = sprintf("SELECT MAX(sequence) AS seq FROM tst_test_question WHERE test_fi=%s",
02647 $this->ilias->db->quote($this->getTestId())
02648 );
02649 $result = $this->ilias->db->query($query);
02650 $sequence = 1;
02651
02652 if ($result->numRows() == 1)
02653 {
02654 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
02655 $sequence = $data->seq + 1;
02656 }
02657
02658 $query = sprintf("INSERT INTO tst_test_question (test_question_id, test_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
02659 $this->ilias->db->quote($this->getTestId()),
02660 $this->ilias->db->quote($duplicate_id),
02661 $this->ilias->db->quote($sequence)
02662 );
02663 $result = $this->ilias->db->query($query);
02664 if ($result != DB_OK)
02665 {
02666
02667 }
02668 else
02669 {
02670 include_once ("./classes/class.ilObjAssessmentFolder.php");
02671 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02672 {
02673 $this->logAction($this->lng->txtlng("assessment", "log_question_added", ilObjAssessmentFolder::_getLogLanguage()) . ": " . $sequence, $duplicate_id);
02674 }
02675 }
02676
02677 $query = sprintf("DELETE FROM tst_active WHERE test_fi = %s",
02678 $this->ilias->db->quote($this->getTestId())
02679 );
02680 $result = $this->ilias->db->query($query);
02681 $this->loadQuestions();
02682 $this->saveCompleteStatus();
02683 }
02684
02694 function &getQuestionTitles()
02695 {
02696 $titles = array();
02697 if (!$this->isRandomTest())
02698 {
02699 global $ilDB;
02700 $query = sprintf("SELECT qpl_questions.title FROM tst_test_question, qpl_questions WHERE tst_test_question.test_fi = %s AND tst_test_question.question_fi = qpl_questions.question_id ORDER BY tst_test_question.sequence",
02701 $ilDB->quote($this->getTestId() . "")
02702 );
02703 $result = $ilDB->query($query);
02704 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02705 {
02706 array_push($titles, $row["title"]);
02707 }
02708 }
02709 return $titles;
02710 }
02711
02722 function getQuestionDataset($question_id)
02723 {
02724 $query = sprintf("SELECT qpl_questions.*, qpl_question_type.type_tag FROM qpl_questions, qpl_question_type WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_question_type.question_type_id",
02725 $this->ilias->db->quote("$question_id")
02726 );
02727 $result = $this->ilias->db->query($query);
02728 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
02729 return $row;
02730 }
02731
02740 function &get_qpl_titles()
02741 {
02742 global $rbacsystem;
02743
02744 $qpl_titles = array();
02745
02746 $query = "SELECT object_data.*, object_data.obj_id, object_reference.ref_id FROM object_data, object_reference WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'qpl' ORDER BY object_data.title";
02747 $result = $this->ilias->db->query($query);
02748 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
02749 {
02750 if ($rbacsystem->checkAccess("write", $row->ref_id) && ($this->_hasUntrashedReference($row->obj_id)))
02751 {
02752 include_once("./assessment/classes/class.ilObjQuestionPool.php");
02753 if (ilObjQuestionPool::_lookupOnline($row->obj_id))
02754 {
02755 $qpl_titles["$row->obj_id"] = $row->title;
02756 }
02757 }
02758 }
02759 return $qpl_titles;
02760 }
02761
02770 function &getExistingQuestions($pass = NULL)
02771 {
02772 global $ilUser;
02773 $existing_questions = array();
02774 if ($this->isRandomTest())
02775 {
02776 if (is_null($pass)) $pass = 0;
02777 $query = sprintf("SELECT qpl_questions.original_id FROM qpl_questions, tst_test_random_question WHERE tst_test_random_question.test_fi = %s AND tst_test_random_question.user_fi = %s AND tst_test_random_question.question_fi = qpl_questions.question_id AND tst_test_random_question.pass = %s",
02778 $this->ilias->db->quote($this->getTestId() . ""),
02779 $this->ilias->db->quote($ilUser->id . ""),
02780 $this->ilias->db->quote($pass . "")
02781 );
02782 }
02783 else
02784 {
02785 $query = sprintf("SELECT qpl_questions.original_id FROM qpl_questions, tst_test_question WHERE tst_test_question.test_fi = %s AND tst_test_question.question_fi = qpl_questions.question_id",
02786 $this->ilias->db->quote($this->getTestId())
02787 );
02788 }
02789 $result = $this->ilias->db->query($query);
02790 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
02791 array_push($existing_questions, $data->original_id);
02792 }
02793 return $existing_questions;
02794 }
02795
02805 function getQuestionType($question_id)
02806 {
02807 if ($question_id < 1)
02808 return -1;
02809 $query = sprintf("SELECT type_tag FROM qpl_questions, qpl_question_type WHERE qpl_questions.question_id = %s AND qpl_questions.question_type_fi = qpl_question_type.question_type_id",
02810 $this->ilias->db->quote($question_id)
02811 );
02812 $result = $this->ilias->db->query($query);
02813 if ($result->numRows() == 1) {
02814 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
02815 return $data->type_tag;
02816 } else {
02817 return "";
02818 }
02819 }
02820
02829 function startWorkingTime($user_id)
02830 {
02831 $result = "";
02832 if (!($result = $this->getActiveTestUser($user_id))) {
02833 $this->setActiveTestUser();
02834 $result = $this->getActiveTestUser($user_id);
02835 }
02836 $q = sprintf("INSERT INTO tst_times (times_id, active_fi, started, finished, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
02837 $this->ilias->db->quote($result->active_id),
02838 $this->ilias->db->quote(strftime("%Y-%m-%d %H:%M:%S")),
02839 $this->ilias->db->quote(strftime("%Y-%m-%d %H:%M:%S"))
02840 );
02841 $result = $this->ilias->db->query($q);
02842 return $this->ilias->db->getLastInsertId();
02843 }
02844
02853 function updateWorkingTime($times_id)
02854 {
02855 $q = sprintf("UPDATE tst_times SET finished = %s WHERE times_id = %s",
02856 $this->ilias->db->quote(strftime("%Y-%m-%d %H:%M:%S")),
02857 $this->ilias->db->quote($times_id)
02858 );
02859 $result = $this->ilias->db->query($q);
02860 }
02861
02871 function getQuestionIdFromActiveUserSequence($sequence)
02872 {
02873 global $ilUser;
02874
02875 $active = $this->getActiveTestUser();
02876 $sequence_array = split(",", $active->sequence);
02877 return $this->questions[$sequence_array[$sequence-1]];
02878 }
02879
02888 function &getAllQuestionsForActiveUser()
02889 {
02890 $result_array = array();
02891 $active = $this->getActiveTestUser();
02892 $sequence_array = split(",", $active->sequence);
02893 $all_questions = &$this->getAllQuestions();
02894 $worked_questions = &$this->getWorkedQuestions();
02895 foreach ($sequence_array as $sequence)
02896 {
02897 if (in_array($this->questions[$sequence], $worked_questions))
02898 {
02899 $all_questions[$this->questions[$sequence]]["worked"] = 1;
02900 }
02901 else
02902 {
02903 $all_questions[$this->questions[$sequence]]["worked"] = 0;
02904 }
02905 array_push($result_array, $all_questions[$this->questions[$sequence]]);
02906 }
02907 return $result_array;
02908 }
02909
02910 function getWrongAnsweredQuestions()
02911 {
02912 global $ilUser;
02913
02914 foreach($all_questions =& $this->getAllQuestionsForActiveUser() as $question)
02915 {
02916 foreach($this->getTestResult($ilUser->getId()) as $result)
02917 {
02918 if($result['qid'] == $question['question_id'])
02919 {
02920 if($result['max'] != $result['reached'])
02921 {
02922 $wrong[] = $question;
02923 }
02924 }
02925 }
02926 }
02927 return $wrong ? $wrong : array();
02928 }
02929
02930
02931 function getFirstSequence()
02932 {
02933 global $ilUser;
02934
02935 $results = $this->getTestResult($ilUser->getId());
02936
02937 for($i = 1; $i <= $this->getQuestionCount(); $i++)
02938 {
02939 $qid = $this->getQuestionIdFromActiveUserSequence($i);
02940
02941 foreach($results as $result)
02942 {
02943 if($qid == $result['qid'])
02944 {
02945 if(!$result['max'] or $result['max'] != $result['reached'])
02946 {
02947 return $i;
02948 }
02949 }
02950 }
02951 }
02952 return 0;
02953 }
02954
02955
02964 function &getWorkedQuestions($pass = NULL)
02965 {
02966 global $ilUser;
02967 if (is_null($pass))
02968 {
02969 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND pass = 0 GROUP BY question_fi",
02970 $this->ilias->db->quote($ilUser->id),
02971 $this->ilias->db->quote($this->getTestId())
02972 );
02973 }
02974 else
02975 {
02976 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND pass = %s GROUP BY question_fi",
02977 $this->ilias->db->quote($ilUser->id . ""),
02978 $this->ilias->db->quote($this->getTestId() . ""),
02979 $this->ilias->db->quote($pass . "")
02980 );
02981 }
02982 $result = $this->ilias->db->query($query);
02983 $result_array = array();
02984 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
02985 {
02986 array_push($result_array, $row->question_fi);
02987 }
02988 return $result_array;
02989 }
02990
02999 function &getAllQuestions($pass = NULL)
03000 {
03001 global $ilUser;
03002
03003 if ($this->isRandomTest())
03004 {
03005 if (is_null($pass)) $pass = 0;
03006 $query = sprintf("SELECT qpl_questions.* FROM qpl_questions, tst_test_random_question WHERE tst_test_random_question.question_fi = qpl_questions.question_id AND tst_test_random_question.user_fi = %s AND tst_test_random_question.pass = %s AND qpl_questions.question_id IN (" . join($this->questions, ",") . ")",
03007 $this->ilias->db->quote($ilUser->id . ""),
03008 $this->ilias->db->quote($pass . "")
03009 );
03010 }
03011 else
03012 {
03013 $query = "SELECT qpl_questions.* FROM qpl_questions, tst_test_question WHERE tst_test_question.question_fi = qpl_questions.question_id AND qpl_questions.question_id IN (" . join($this->questions, ",") . ")";
03014 }
03015 $result = $this->ilias->db->query($query);
03016 $result_array = array();
03017 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
03018 {
03019 $result_array[$row["question_id"]] = $row;
03020 }
03021 return $result_array;
03022 }
03023
03033 function getActiveTestUser($user_id = "")
03034 {
03035 global $ilDB;
03036 global $ilUser;
03037 $db =& $ilDB->db;
03038 if (!$user_id)
03039 {
03040 $user_id = $ilUser->id;
03041 }
03042 $query = sprintf("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
03043 $db->quote($user_id),
03044 $db->quote($this->test_id)
03045 );
03046
03047 $result = $db->query($query);
03048 if ($result->numRows()) {
03049 $this->active = $result->fetchRow(DB_FETCHMODE_OBJECT);
03050 }
03051 else
03052 {
03053 $this->active = null;
03054 }
03055 return $this->active;
03056 }
03057
03068 function _getActiveTestUser($user_id = "", $test_id = "") {
03069 global $ilDB;
03070 global $ilUser;
03071
03072 $db =& $ilDB->db;
03073 if (!$user_id) {
03074 $user_id = $ilUser->id;
03075 }
03076 if (!$test_id)
03077 {
03078 return "";
03079 }
03080 $query = sprintf("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
03081 $db->quote($user_id),
03082 $db->quote($test_id)
03083 );
03084
03085 $result = $db->query($query);
03086 if ($result->numRows()) {
03087 return $result->fetchRow(DB_FETCHMODE_OBJECT);
03088 } else {
03089 return "";
03090 }
03091 }
03092
03105 function setActiveTestUser($lastindex = 1, $postpone = "", $addTries = false)
03106 {
03107 global $ilDB;
03108 global $ilUser;
03109
03110 if ($lastindex < 1) $lastindex = 1;
03111 $db =& $ilDB->db;
03112 $old_active = $this->getActiveTestUser();
03113 if ($old_active)
03114 {
03115 $sequence = $old_active->sequence;
03116 $postponed = $old_active->postponed;
03117 if ($postpone)
03118 {
03119 $sequence_array = split(",", $sequence);
03120 $postpone_sequence = $sequence_array[$postpone-1];
03121 $question_id = $this->questions[$postpone_sequence];
03122 unset($sequence_array[$postpone-1]);
03123 array_push($sequence_array, $postpone_sequence);
03124 $sequence = join(",", $sequence_array);
03125 $postponed .= ",$question_id";
03126 $postponed = preg_replace("/^,/", "", $postponed);
03127 }
03128 $tries = $old_active->tries;
03129 if ($addTries && ($this->getNrOfResultsForPass($ilUser->getId(), $old_active->tries) > 0))
03130 {
03131
03132
03133 $tries++;
03134 }
03135 $query = sprintf("UPDATE tst_active SET lastindex = %s, sequence = %s, postponed = %s, tries = %s WHERE user_fi = %s AND test_fi = %s",
03136 $db->quote($lastindex),
03137 $db->quote($sequence),
03138 $db->quote($postponed),
03139 $db->quote($tries),
03140 $db->quote($ilUser->id),
03141 $db->quote($this->test_id)
03142 );
03143 }
03144 else
03145 {
03146 $sequence_arr = array_flip($this->questions);
03147 $sequence = join($sequence_arr, ",");
03148 $query = sprintf("INSERT INTO tst_active (active_id, user_fi, test_fi, sequence, postponed, lastindex, tries, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
03149 $db->quote($ilUser->id),
03150 $db->quote($this->test_id),
03151 $db->quote($sequence),
03152 $db->quote(""),
03153 $db->quote($lastindex),
03154 $db->quote(0)
03155 );
03156 }
03157 $db->query($query);
03158 }
03159
03169 function &getTestResult($user_id, $pass = NULL)
03170 {
03171
03172 if ($this->isRandomTest())
03173 {
03174 $this->loadQuestions($user_id, $pass);
03175 }
03176 $total_max_points = 0;
03177 $total_reached_points = 0;
03178
03179 $key = 1;
03180 $result_array = array();
03181 include_once "./assessment/classes/class.assQuestion.php";
03182 $workedthrough = 0;
03183 foreach ($this->questions as $value)
03184 {
03185 $max_points = ASS_Question::_getMaximumPoints($value);
03186 $total_max_points += $max_points;
03187 $reached_points = ASS_Question::_getReachedPoints($user_id, $this->getTestId(), $value, $pass);
03188 if (ASS_Question::_isWorkedThrough($user_id, $this->getTestId(), $value, $pass))
03189 {
03190 $workedthrough = 1;
03191 }
03192 else
03193 {
03194 $workedthrough = 0;
03195 }
03196 $total_reached_points += $reached_points;
03197 if ($max_points > 0)
03198 {
03199 $percentvalue = $reached_points / $max_points;
03200 }
03201 else
03202 {
03203 $percentvalue = 0;
03204 }
03205 if (ASS_Question::_getSuggestedSolutionCount($value) == 1)
03206 {
03207 $solution_array =& ASS_Question::_getSuggestedSolution($value, 0);
03208 $href = ASS_Question::_getInternalLinkHref($solution_array["internal_link"]);
03209 }
03210 elseif (ASS_Question::_getSuggestedSolutionCount($value) > 1)
03211 {
03212 $href = "see_details_for_further_information";
03213 }
03214 else
03215 {
03216 $href = "";
03217 }
03218 $info =& ASS_Question::_getQuestionInfo($value);
03219 include_once "./classes/class.ilUtil.php";
03220 $row = array(
03221 "nr" => "$key",
03222 "title" => ilUtil::prepareFormOutput($info["title"]),
03223 "max" => sprintf("%d", $max_points),
03224 "reached" => sprintf("%d", $reached_points),
03225 "percent" => sprintf("%2.2f ", ($percentvalue) * 100) . "%",
03226 "solution" => $href,
03227 "type" => $info["type_tag"],
03228 "qid" => $value,
03229 "workedthrough" => $workedthrough
03230 );
03231 array_push($result_array, $row);
03232 $key++;
03233 }
03234 $result_array["test"]["total_max_points"] = $total_max_points;
03235 $result_array["test"]["total_reached_points"] = $total_reached_points;
03236 if ((!$total_reached_points) or (!$total_max_points))
03237 {
03238 $percentage = 0.0;
03239 }
03240 else
03241 {
03242 $percentage = ($total_reached_points / $total_max_points) * 100.0;
03243 }
03244 $mark_obj = $this->mark_schema->get_matching_mark($percentage);
03245 $passed = "";
03246 if ($mark_obj)
03247 {
03248 if ($mark_obj->get_passed())
03249 {
03250 $passed = 1;
03251 }
03252 else
03253 {
03254 $passed = 0;
03255 }
03256 }
03257 $result_array["test"]["passed"] = $passed;
03258 return $result_array;
03259 }
03260
03261
03270 function &getTestSummary($user_id, $pass = NULL)
03271 {
03272 global $ilDB;
03273 if ($this->isRandomTest())
03274 {
03275 $this->loadQuestions($user_id, $pass);
03276 }
03277
03278 $key = 1;
03279 $result_array = array();
03280
03281 $active = $this->getActiveTestUser();
03282 $solved_questions = ilObjTest::_getSolvedQuestions($this->test_id, $user_id);
03283 include_once "./classes/class.ilObjUser.php";
03284 $user = new ilObjUser($user_id);
03285 foreach ($this->questions as $val)
03286 {
03287 $question =& ilObjTest::_instanciateQuestion($val);
03288 if (is_object($question))
03289 {
03290 $answers = $question->getSolutionValues($this->test_id, $user);
03291 $visited = count($answers);
03292 $solved = 0;
03293 if (array_key_exists($question->getId(),$solved_questions)) {
03294 $solved = $solved_questions[$question->getId()]->solved;
03295 }
03296
03297 $row = array(
03298 "nr" => "$key",
03299 "title" => $question->getTitle(),
03300 "qid" => $question->getId(),
03301 "visited" => $visited,
03302 "solved" => (($solved)?"1":"0"),
03303 "description" => $question->getComment(),
03304 "points" => $question->getMaximumPoints()
03305 );
03306 array_push($result_array, $row);
03307 $key++;
03308 }
03309 }
03310
03311 return $result_array;
03312 }
03313
03314
03324 function &_getTestResult($user_id, $test_obj_id, $pass = NULL)
03325 {
03326 $test = new ilObjTest($test_obj_id, false);
03327 $test->loadFromDb();
03328 $result =& $test->getTestResult($user_id, $pass);
03329 return $result;
03330 }
03331
03340 function evalTotalPersons()
03341 {
03342 $q = sprintf("SELECT COUNT(*) as total FROM tst_active WHERE test_fi = %s",
03343 $this->ilias->db->quote($this->getTestId())
03344 );
03345 $result = $this->ilias->db->query($q);
03346 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
03347 return $row->total;
03348 }
03349
03358 function canViewResults()
03359 {
03360 $result = true;
03361 if ($this->getTestType() != TYPE_SELF_ASSESSMENT)
03362 {
03363 if ($this->getReportingDate())
03364 {
03365 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getReportingDate(), $matches))
03366 {
03367 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03368 $now = mktime();
03369 if ($now < $epoch_time)
03370 {
03371 $result = false;
03372 }
03373 }
03374 }
03375 }
03376 return $result;
03377 }
03378
03387 function evalLoadStatisticalSettings($user_id)
03388 {
03389 $q = sprintf("SELECT * FROM tst_eval_settings WHERE user_fi = %s",
03390 $this->ilias->db->quote("$user_id")
03391 );
03392 $result = $this->ilias->db->query($q);
03393 if (!$result->numRows())
03394 {
03395 $row = array(
03396 "qworkedthrough" => "1",
03397 "pworkedthrough" => "1",
03398 "timeofwork" => "1",
03399 "atimeofwork" => "1",
03400 "firstvisit" => "1",
03401 "lastvisit" => "1",
03402 "resultspoints" => "1",
03403 "resultsmarks" => "1",
03404 "distancemedian" => "1"
03405 );
03406 }
03407 else
03408 {
03409 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
03410 unset($row["eval_settings_id"]);
03411 }
03412 return $row;
03413 }
03414
03423 function evalSaveStatisticalSettings($settings_array, $user_id)
03424 {
03425 $q = sprintf("SELECT * FROM tst_eval_settings WHERE user_fi = %s",
03426 $this->ilias->db->quote("$user_id")
03427 );
03428 $result = $this->ilias->db->query($q);
03429 if ($result->numRows() > 0)
03430 {
03431 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
03432 }
03433 $update = $row["eval_settings_id"];
03434 if (!$update) {
03435 $q = sprintf("INSERT INTO tst_eval_settings ".
03436 "(eval_settings_id, user_fi, qworkedthrough, pworkedthrough, timeofwork, atimeofwork, firstvisit, " .
03437 "lastvisit, resultspoints, resultsmarks, distancemedian, TIMESTAMP) VALUES " .
03438 "(NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
03439 $this->ilias->db->quote("$user_id"),
03440 $this->ilias->db->quote(sprintf("%01d", $settings_array["qworkedthrough"])),
03441 $this->ilias->db->quote(sprintf("%01d", $settings_array["pworkedthrough"])),
03442 $this->ilias->db->quote(sprintf("%01d", $settings_array["timeofwork"])),
03443 $this->ilias->db->quote(sprintf("%01d", $settings_array["atimeofwork"])),
03444 $this->ilias->db->quote(sprintf("%01d", $settings_array["firstvisit"])),
03445 $this->ilias->db->quote(sprintf("%01d", $settings_array["lastvisit"])),
03446 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultspoints"])),
03447 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultsmarks"])),
03448 $this->ilias->db->quote(sprintf("%01d", $settings_array["distancemedian"]))
03449 );
03450 }
03451 else
03452 {
03453 $q = sprintf("UPDATE tst_eval_settings SET ".
03454 "qworkedthrough = %s, pworkedthrough = %s, timeofwork = %s, atimeofwork = %s, firstvisit = %s, " .
03455 "lastvisit = %s, resultspoints = %s, resultsmarks = %s, distancemedian = %s " .
03456 "WHERE eval_settings_id = %s",
03457 $this->ilias->db->quote(sprintf("%01d", $settings_array["qworkedthrough"])),
03458 $this->ilias->db->quote(sprintf("%01d", $settings_array["pworkedthrough"])),
03459 $this->ilias->db->quote(sprintf("%01d", $settings_array["timeofwork"])),
03460 $this->ilias->db->quote(sprintf("%01d", $settings_array["atimeofwork"])),
03461 $this->ilias->db->quote(sprintf("%01d", $settings_array["firstvisit"])),
03462 $this->ilias->db->quote(sprintf("%01d", $settings_array["lastvisit"])),
03463 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultspoints"])),
03464 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultsmarks"])),
03465 $this->ilias->db->quote(sprintf("%01d", $settings_array["distancemedian"])),
03466 $this->ilias->db->quote("$update")
03467 );
03468 }
03469 $result = $this->ilias->db->query($q);
03470 }
03471
03480 function getCompleteWorkingTime($user_id)
03481 {
03482 $q = sprintf("SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi AND tst_active.user_fi = %s",
03483 $this->ilias->db->quote($this->getTestId()),
03484 $this->ilias->db->quote($user_id)
03485 );
03486 $result = $this->ilias->db->query($q);
03487 $time = 0;
03488 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03489 {
03490 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03491 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03492 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03493 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03494 $time += ($epoch_2 - $epoch_1);
03495 }
03496 return $time;
03497 }
03498
03507 function &evalStatistical($user_id)
03508 {
03509
03510 $pass = ilObjTest::_getResultPass($user_id, $this->getTestId());
03511 $test_result =& $this->getTestResult($user_id, $pass);
03512 $q = sprintf("SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi AND tst_active.user_fi = %s",
03513 $this->ilias->db->quote($this->getTestId()),
03514 $this->ilias->db->quote($user_id)
03515 );
03516 $result = $this->ilias->db->query($q);
03517 $times = array();
03518 $first_visit = 0;
03519 $last_visit = 0;
03520 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
03521 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03522 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03523 if (!$first_visit) {
03524 $first_visit = $epoch_1;
03525 }
03526 if ($epoch_1 < $first_visit) {
03527 $first_visit = $epoch_1;
03528 }
03529 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03530 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03531 if (!$last_visit) {
03532 $last_visit = $epoch_2;
03533 }
03534 if ($epoch_2 > $last_visit) {
03535 $last_visit = $epoch_2;
03536 }
03537 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
03538 }
03539 $max_time = 0;
03540 foreach ($times as $key => $value) {
03541 $max_time += $value;
03542 }
03543 if ((!$test_result["test"]["total_reached_points"]) or (!$test_result["test"]["total_max_points"])) {
03544 $percentage = 0.0;
03545 } else {
03546 $percentage = ($test_result["test"]["total_reached_points"] / $test_result["test"]["total_max_points"]) * 100.0;
03547 }
03548 $mark_obj = $this->mark_schema->get_matching_mark($percentage);
03549 $first_date = getdate($first_visit);
03550 $last_date = getdate($last_visit);
03551 $qworkedthrough = 0;
03552 foreach ($test_result as $key => $value)
03553 {
03554 if (preg_match("/\d+/", $key))
03555 {
03556 $qworkedthrough += $value["workedthrough"];
03557 }
03558 }
03559 if (!$qworkedthrough)
03560 {
03561 $atimeofwork = 0;
03562 }
03563 else
03564 {
03565 $atimeofwork = $max_time / $qworkedthrough;
03566 }
03567 $result_mark = "";
03568 $passed = "";
03569 if ($mark_obj)
03570 {
03571 $result_mark = $mark_obj->get_short_name();
03572 if ($mark_obj->get_passed())
03573 {
03574 $passed = 1;
03575 }
03576 else
03577 {
03578 $passed = 0;
03579 }
03580 }
03581 $result_array = array(
03582 "qworkedthrough" => $qworkedthrough,
03583 "qmax" => count($this->questions),
03584 "pworkedthrough" => $qworkedthrough / count($this->questions),
03585 "timeofwork" => $max_time,
03586 "atimeofwork" => $atimeofwork,
03587 "firstvisit" => $first_date,
03588 "lastvisit" => $last_date,
03589 "resultspoints" => $test_result["test"]["total_reached_points"],
03590 "maxpoints" => $test_result["test"]["total_max_points"],
03591 "resultsmarks" => $result_mark,
03592 "passed" => $passed,
03593 "distancemedian" => "0"
03594 );
03595 foreach ($test_result as $key => $value)
03596 {
03597 if (preg_match("/\d+/", $key))
03598 {
03599 $result_array[$key] = $value;
03600 }
03601 }
03602 return $result_array;
03603 }
03604
03614 function &getTotalPointsArray()
03615 {
03616 $totalpoints_array = array();
03617 $all_users =& $this->evalTotalPersonsArray();
03618 foreach ($all_users as $user_id => $user_name)
03619 {
03620 $test_result =& $this->getTestResult($user_id);
03621 array_push($totalpoints_array, $test_result["test"]["total_reached_points"]);
03622 }
03623 return $totalpoints_array;
03624 }
03625
03635 function &getTotalPointsPassedArray()
03636 {
03637 $totalpoints_array = array();
03638 $all_users =& $this->evalTotalPersonsArray();
03639 foreach ($all_users as $user_id => $user_name)
03640 {
03641 $test_result =& $this->getTestResult($user_id);
03642 $reached = $test_result["test"]["total_reached_points"];
03643 $total = $test_result["test"]["total_max_points"];
03644 $percentage = $reached/$total;
03645 $mark = $this->mark_schema->get_matching_mark($percentage*100.0);
03646 if ($mark)
03647 {
03648 if ($mark->get_passed())
03649 {
03650 array_push($totalpoints_array, $test_result["test"]["total_reached_points"]);
03651 }
03652 }
03653 }
03654 return $totalpoints_array;
03655 }
03656
03665 function &evalTotalPersonsArray($name_sort_order = "asc")
03666 {
03667 $q = sprintf("SELECT tst_active.user_fi, usr_data.firstname, usr_data.lastname, usr_data.title FROM tst_active LEFT JOIN usr_data ON tst_active.user_fi = usr_data.usr_id WHERE tst_active.test_fi = %s ORDER BY usr_data.lastname " . strtoupper($name_sort_order),
03668 $this->ilias->db->quote($this->getTestId())
03669 );
03670 $result = $this->ilias->db->query($q);
03671 $persons_array = array();
03672 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03673 {
03674 if (strlen($row->firstname.$row->lastname.$row->title) == 0)
03675 {
03676 $persons_array[$row->user_fi] = array("fullname" => $this->lng->txt("deleted_user"), "firstname" => "", "lastname" => $this->lng->txt("deleted_user"));
03677 }
03678 else
03679 {
03680 $persons_array[$row->user_fi] = array("fullname" => trim("$row->lastname, $row->firstname $row->title"), "firstname" => $row->firstname, "lastname" => $row->lastname);
03681 }
03682 if ($this->getTestType() == TYPE_SELF_ASSESSMENT)
03683 {
03684 $persons_array[$row->user_fi] = array("fullname" => $this->lng->txt("unknown"), "firstname" => $this->lng->txt("unknown"), "lastname" => $this->lng->txt("unknown"));
03685 }
03686 }
03687 return $persons_array;
03688 }
03689
03698 function evalTotalFinished()
03699 {
03700 $q = sprintf("SELECT COUNT(*) as total FROM tst_active WHERE test_fi = %s AND tries > 0",
03701 $this->ilias->db->quote($this->getTestId())
03702 );
03703 $result = $this->ilias->db->query($q);
03704 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
03705 return $row->total;
03706 }
03707
03717 function evalTotalFinishedPassed()
03718 {
03719 $q = sprintf("SELECT * FROM tst_active WHERE test_fi = %s",
03720 $this->ilias->db->quote($this->getTestId())
03721 );
03722 $result = $this->ilias->db->query($q);
03723 $points = array();
03724 $passed_tests = 0;
03725 $failed_tests = 0;
03726 $maximum_points = 0;
03727 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03728 {
03729 $pass = ilObjTest::_getResultPass($row->user_fi, $this->getTestId());
03730 $res =& $this->getTestResult($row->user_fi, $pass);
03731 if ((!$res["test"]["total_reached_points"]) or (!$res["test"]["total_max_points"]))
03732 {
03733 $percentage = 0.0;
03734 }
03735 else
03736 {
03737 $percentage = ($res["test"]["total_reached_points"] / $res["test"]["total_max_points"]) * 100.0;
03738 }
03739 $mark_obj = $this->mark_schema->get_matching_mark($percentage);
03740 $maximum_points = $res["test"]["total_max_points"];
03741 if ($mark_obj)
03742 {
03743 if ($mark_obj->get_passed()) {
03744 $passed_tests++;
03745 array_push($points, $res["test"]["total_reached_points"]);
03746 }
03747 else
03748 {
03749 $failed_tests++;
03750 }
03751 }
03752 }
03753 $reached_points = 0;
03754 $counter = 0;
03755 foreach ($points as $key => $value)
03756 {
03757 $reached_points += $value;
03758 $counter++;
03759 }
03760 if ($counter)
03761 {
03762 $average_points = ($reached_points / $counter);
03763 }
03764 else
03765 {
03766 $average_points = 0;
03767 }
03768 return array(
03769 "total_passed" => $passed_tests,
03770 "total_failed" => $failed_tests,
03771 "average_points" => $average_points,
03772 "maximum_points" => $maximum_points
03773 );
03774 }
03775
03784 function evalTotalFinishedAverageTime()
03785 {
03786 $q = sprintf("SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.tries > 0 AND tst_active.active_id = tst_times.active_fi",
03787 $this->ilias->db->quote($this->getTestId())
03788 );
03789 $result = $this->ilias->db->query($q);
03790 $times = array();
03791 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03792 {
03793 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03794 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03795 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03796 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03797 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
03798 }
03799 $max_time = 0;
03800 $counter = 0;
03801 foreach ($times as $key => $value)
03802 {
03803 $max_time += $value;
03804 $counter++;
03805 }
03806 if ($counter)
03807 {
03808 $average_time = round($max_time / $counter);
03809 }
03810 else
03811 {
03812 $average_time = 0;
03813 }
03814 return $average_time;
03815 }
03816
03825 function evalTotalStartedAverageTime()
03826 {
03827 $q = sprintf("SELECT tst_times.* FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi",
03828 $this->ilias->db->quote($this->getTestId())
03829 );
03830 $result = $this->ilias->db->query($q);
03831 $times = array();
03832 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03833 {
03834 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03835 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03836 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03837 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03838 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
03839 }
03840 $max_time = 0;
03841 $counter = 0;
03842 foreach ($times as $key => $value)
03843 {
03844 $max_time += $value;
03845 $counter++;
03846 }
03847 if ($counter)
03848 {
03849 $average_time = round($max_time / $counter);
03850 }
03851 else
03852 {
03853 $average_time = 0;
03854 }
03855 return $average_time;
03856 }
03857
03866 function evalTotalPassedAverageTime()
03867 {
03868 include_once "./assessment/classes/class.ilObjTestAccess.php";
03869 $passed_users =& ilObjTest::_getPassedUsers($this->getId());
03870 $q = sprintf("SELECT tst_times.*, tst_active.user_fi FROM tst_active, tst_times WHERE tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi",
03871 $this->ilias->db->quote($this->getTestId())
03872 );
03873 $result = $this->ilias->db->query($q);
03874 $times = array();
03875 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03876 {
03877 if (in_array($row->user_fi, $passed_users))
03878 {
03879 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03880 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03881 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03882 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03883 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
03884 }
03885 }
03886 $max_time = 0;
03887 $counter = 0;
03888 foreach ($times as $key => $value)
03889 {
03890 $max_time += $value;
03891 $counter++;
03892 }
03893 if ($counter)
03894 {
03895 $average_time = round($max_time / $counter);
03896 }
03897 else
03898 {
03899 $average_time = 0;
03900 }
03901 return $average_time;
03902 }
03903
03912 function &getAvailableQuestionpoolIDs()
03913 {
03914 global $rbacsystem;
03915
03916 $result_array = array();
03917 $query = "SELECT object_data.*, object_data.obj_id, object_reference.ref_id FROM object_data, object_reference WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'qpl'";
03918 $result = $this->ilias->db->query($query);
03919 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03920 {
03921 if ($rbacsystem->checkAccess("write", $row->ref_id) && ($this->_hasUntrashedReference($row->obj_id)))
03922 {
03923 include_once("./assessment/classes/class.ilObjQuestionPool.php");
03924 if (ilObjQuestionPool::_lookupOnline($row->obj_id))
03925 {
03926 array_push($result_array, $row->obj_id);
03927 }
03928 }
03929 }
03930 return $result_array;
03931 }
03932
03941 function &getAvailableQuestionpools($use_object_id = false, $equal_points = false, $could_be_offline = false)
03942 {
03943 global $rbacsystem;
03944
03945 $result_array = array();
03946 $query = "SELECT object_data.*, object_data.obj_id, object_reference.ref_id FROM object_data, object_reference WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'qpl' ORDER BY object_data.title";
03947 $result = $this->ilias->db->query($query);
03948 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03949 {
03950 if ($rbacsystem->checkAccess("write", $row->ref_id) && ($this->_hasUntrashedReference($row->obj_id)))
03951 {
03952 include_once("./assessment/classes/class.ilObjQuestionPool.php");
03953 if (ilObjQuestionPool::_lookupOnline($row->obj_id) || $could_be_offline)
03954 {
03955 if ((!$equal_points) || (($equal_points) && (ilObjQuestionPool::_hasEqualPoints($row->obj_id))))
03956 {
03957 if ($use_object_id)
03958 {
03959 $result_array[$row->obj_id] = $row->title;
03960 }
03961 else
03962 {
03963 $result_array[$row->ref_id] = $row->title;
03964 }
03965 }
03966 }
03967 }
03968 }
03969 return $result_array;
03970 }
03971
03980 function getEstimatedWorkingTime()
03981 {
03982 $time_in_seconds = 0;
03983 foreach ($this->questions as $question_id)
03984 {
03985 $question =& ilObjTest::_instanciateQuestion($question_id);
03986 $est_time = $question->getEstimatedWorkingTime();
03987 $time_in_seconds += $est_time["h"] * 3600 + $est_time["m"] * 60 + $est_time["s"];
03988 }
03989 $hours = (int)($time_in_seconds / 3600) ;
03990 $time_in_seconds = $time_in_seconds - ($hours * 3600);
03991 $minutes = (int)($time_in_seconds / 60);
03992 $time_in_seconds = $time_in_seconds - ($minutes * 60);
03993 $result = array("h" => $hours, "m" => $minutes, "s" => $time_in_seconds);
03994 return $result;
03995 }
03996
04009 function randomSelectQuestions($nr_of_questions, $questionpool, $use_obj_id = 0, $qpls = "", $pass = NULL)
04010 {
04011 global $rbacsystem;
04012
04013 if ($questionpool != 0)
04014 {
04015
04016 if (!$use_obj_id)
04017 {
04018 $query = sprintf("SELECT obj_id FROM object_reference WHERE ref_id = %s",
04019 $this->ilias->db->quote("$questionpool")
04020 );
04021 $result = $this->ilias->db->query($query);
04022 $row = $result->fetchRow(DB_FETCHMODE_ARRAY);
04023 $questionpool = $row[0];
04024 }
04025 }
04026
04027
04028 $query = sprintf("SELECT qpl_questions.original_id FROM qpl_questions, tst_test_question WHERE qpl_questions.question_id = tst_test_question.question_fi AND tst_test_question.test_fi = %s",
04029 $this->ilias->db->quote($this->getTestId() . "")
04030 );
04031 $result = $this->ilias->db->query($query);
04032 $original_ids = array();
04033 while ($row = $result->fetchRow(DB_FETCHMODE_ARRAY))
04034 {
04035 if (strcmp($row[0], "") != 0)
04036 {
04037 array_push($original_ids, $row[0]);
04038 }
04039 }
04040 $original_clause = "";
04041 if (count($original_ids))
04042 {
04043 $original_clause = " AND ISNULL(qpl_questions.original_id) AND qpl_questions.question_id NOT IN (" . join($original_ids, ",") . ")";
04044 }
04045
04046
04047 if (($questionpool == 0) && (!is_array($qpls)))
04048 {
04049 $available_pools =& $this->getAvailableQuestionpoolIDs();
04050 $available = "";
04051 $constraint_qpls = "";
04052 if (count($available_pools))
04053 {
04054 $available = " AND qpl_questions.obj_fi IN (" . join($available_pools, ",") . ")";
04055 }
04056 else
04057 {
04058 return array();
04059 }
04060 }
04061
04062 $result_array = array();
04063 if ($questionpool == 0)
04064 {
04065 if (is_array($qpls))
04066 {
04067 if (count($qpls) > 0)
04068 {
04069 $qplidx = array();
04070 foreach ($qpls as $idx => $arr)
04071 {
04072 array_push($qplidx, $arr["qpl"]);
04073 }
04074 $constraint_qpls = " AND qpl_questions.obj_fi IN (" . join($qplidx, ",") . ")";
04075 }
04076 }
04077 $query = "SELECT COUNT(question_id) FROM qpl_questions, object_data WHERE ISNULL(qpl_questions.original_id) AND object_data.type = 'qpl' AND object_data.obj_id = qpl_questions.obj_fi$available$constraint_qpls AND qpl_questions.complete = '1'$original_clause";
04078 }
04079 else
04080 {
04081 $query = sprintf("SELECT COUNT(question_id) FROM qpl_questions WHERE ISNULL(qpl_questions.original_id) AND obj_fi = %s$original_clause",
04082 $this->ilias->db->quote("$questionpool")
04083 );
04084 }
04085 $result = $this->ilias->db->query($query);
04086 $row = $result->fetchRow(DB_FETCHMODE_ARRAY);
04087 if (($row[0]) <= $nr_of_questions)
04088 {
04089
04090 if ($questionpool == 0)
04091 {
04092 $query = "SELECT question_id FROM qpl_questions, object_data WHERE ISNULL(qpl_questions.original_id) AND object_data.type = 'qpl' AND object_data.obj_id = qpl_questions.obj_fi$available$constraint_qpls AND qpl_questions.complete = '1'$original_clause";
04093 }
04094 else
04095 {
04096 $query = sprintf("SELECT question_id FROM qpl_questions WHERE ISNULL(qpl_questions.original_id) AND obj_fi = %s AND qpl_questions.complete = '1'$original_clause",
04097 $this->ilias->db->quote("$questionpool")
04098 );
04099 }
04100 $result = $this->ilias->db->query($query);
04101 while ($row = $result->fetchRow(DB_FETCHMODE_ARRAY))
04102 {
04103 if ((!in_array($row[0], $this->questions)) && (strcmp($row[0], "") != 0))
04104 {
04105 $result_array[$row[0]] = $row[0];
04106 }
04107 }
04108 }
04109 else
04110 {
04111
04112 mt_srand((double)microtime()*1000000);
04113 $random_number = mt_rand(0, $row[0] - 1);
04114 $securitycounter = 500;
04115 while ((count($result_array) < $nr_of_questions) && ($securitycounter > 0))
04116 {
04117 if ($questionpool == 0)
04118 {
04119 $query = "SELECT question_id FROM qpl_questions, object_data WHERE ISNULL(qpl_questions.original_id) AND object_data.type = 'qpl' AND object_data.obj_id = qpl_questions.obj_fi$available$constraint_qpls AND qpl_questions.complete = '1'$original_clause LIMIT $random_number, 1";
04120 }
04121 else
04122 {
04123 $query = sprintf("SELECT question_id FROM qpl_questions WHERE ISNULL(qpl_questions.original_id) AND obj_fi = %s AND qpl_questions.complete = '1'$original_clause LIMIT $random_number, 1",
04124 $this->ilias->db->quote("$questionpool")
04125 );
04126 }
04127 $result = $this->ilias->db->query($query);
04128 $result_row = $result->fetchRow(DB_FETCHMODE_ARRAY);
04129 if ((!in_array($result_row[0], $this->questions)) && (strcmp($result_row[0], "") != 0))
04130 {
04131 $result_array[$result_row[0]] = $result_row[0];
04132 }
04133 $random_number = mt_rand(0, $row[0] - 1);
04134 $securitycounter--;
04135 }
04136 }
04137 return $result_array;
04138 }
04139
04148 function getImagePath()
04149 {
04150 return CLIENT_WEB_DIR . "/assessment/" . $this->getId() . "/images/";
04151 }
04152
04161 function getImagePathWeb()
04162 {
04163 include_once "./classes/class.ilUtil.php";
04164 $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/" . $this->getId() . "/images/";
04165 return str_replace(ilUtil::removeTrailingPathSeparators(ILIAS_ABSOLUTE_PATH), ilUtil::removeTrailingPathSeparators(ILIAS_HTTP_PATH), $webdir);
04166 }
04167
04178 function &createQuestionGUI($question_type, $question_id = -1)
04179 {
04180 if ((!$question_type) and ($question_id > 0))
04181 {
04182 $question_type = $this->getQuestionType($question_id);
04183 }
04184 switch ($question_type)
04185 {
04186 case "qt_multiple_choice_sr":
04187 include_once "./assessment/classes/class.assMultipleChoiceGUI.php";
04188 $question =& new ASS_MultipleChoiceGUI();
04189 $question->object->set_response(RESPONSE_SINGLE);
04190 break;
04191 case "qt_multiple_choice_mr":
04192 include_once "./assessment/classes/class.assMultipleChoiceGUI.php";
04193 $question =& new ASS_MultipleChoiceGUI();
04194 $question->object->set_response(RESPONSE_MULTIPLE);
04195 break;
04196 case "qt_cloze":
04197 include_once "./assessment/classes/class.assClozeTestGUI.php";
04198 $question =& new ASS_ClozeTestGUI();
04199 break;
04200 case "qt_matching":
04201 include_once "./assessment/classes/class.assMatchingQuestionGUI.php";
04202 $question =& new ASS_MatchingQuestionGUI();
04203 break;
04204 case "qt_ordering":
04205 include_once "./assessment/classes/class.assOrderingQuestionGUI.php";
04206 $question =& new ASS_OrderingQuestionGUI();
04207 break;
04208 case "qt_imagemap":
04209 include_once "./assessment/classes/class.assImagemapQuestionGUI.php";
04210 $question =& new ASS_ImagemapQuestionGUI();
04211 break;
04212 case "qt_javaapplet":
04213 include_once "./assessment/classes/class.assJavaAppletGUI.php";
04214 $question =& new ASS_JavaAppletGUI();
04215 break;
04216 case "qt_text":
04217 include_once "./assessment/classes/class.assTextQuestionGUI.php";
04218 $question =& new ASS_TextQuestionGUI();
04219 break;
04220 }
04221 if ($question_id > 0)
04222 {
04223 $question->object->loadFromDb($question_id);
04224 }
04225 return $question;
04226 }
04227
04237 function &_instanciateQuestion($question_id)
04238 {
04239 if (strcmp($question_id, "") != 0)
04240 {
04241 include_once "./assessment/classes/class.assQuestion.php";
04242 $question_type = ASS_Question::_getQuestionType($question_id);
04243
04244 switch ($question_type) {
04245 case "qt_cloze":
04246 include_once "./assessment/classes/class.assClozeTest.php";
04247 $question = new ASS_ClozeTest();
04248 break;
04249 case "qt_matching":
04250 include_once "./assessment/classes/class.assMatchingQuestion.php";
04251 $question = new ASS_MatchingQuestion();
04252 break;
04253 case "qt_ordering":
04254 include_once "./assessment/classes/class.assOrderingQuestion.php";
04255 $question = new ASS_OrderingQuestion();
04256 break;
04257 case "qt_imagemap":
04258 include_once "./assessment/classes/class.assImagemapQuestion.php";
04259 $question = new ASS_ImagemapQuestion();
04260 break;
04261 case "qt_multiple_choice_sr":
04262 case "qt_multiple_choice_mr":
04263 include_once "./assessment/classes/class.assMultipleChoice.php";
04264 $question = new ASS_MultipleChoice();
04265 break;
04266 case "qt_javaapplet":
04267 include_once "./assessment/classes/class.assJavaApplet.php";
04268 $question = new ASS_JavaApplet();
04269 break;
04270 case "qt_text":
04271 include_once "./assessment/classes/class.assTextQuestion.php";
04272 $question = new ASS_TextQuestion();
04273 break;
04274
04275 default:
04276
04277 return false;
04278 }
04279
04280 $question->loadFromDb($question_id);
04281 return $question;
04282 }
04283 }
04284
04295 function moveQuestions($move_questions, $target_index, $insert_mode)
04296 {
04297 $this->questions = array_values($this->questions);
04298 $array_pos = array_search($target_index, $this->questions);
04299 if ($insert_mode == 0)
04300 {
04301 $part1 = array_slice($this->questions, 0, $array_pos);
04302 $part2 = array_slice($this->questions, $array_pos);
04303 }
04304 else if ($insert_mode == 1)
04305 {
04306 $part1 = array_slice($this->questions, 0, $array_pos + 1);
04307 $part2 = array_slice($this->questions, $array_pos + 1);
04308 }
04309 foreach ($move_questions as $question_id)
04310 {
04311 if (!(array_search($question_id, $part1) === FALSE))
04312 {
04313 unset($part1[array_search($question_id, $part1)]);
04314 }
04315 if (!(array_search($question_id, $part2) === FALSE))
04316 {
04317 unset($part2[array_search($question_id, $part2)]);
04318 }
04319 }
04320 $part1 = array_values($part1);
04321 $part2 = array_values($part2);
04322 $new_array = array_values(array_merge($part1, $move_questions, $part2));
04323 $this->questions = array();
04324 $counter = 1;
04325 foreach ($new_array as $question_id)
04326 {
04327 $this->questions[$counter] = $question_id;
04328 $counter++;
04329 }
04330 $this->saveQuestionsToDb();
04331 }
04332
04333
04343 function startingTimeReached()
04344 {
04345 if ($this->getTestType() == TYPE_ASSESSMENT || $this->getTestType() == TYPE_ONLINE_TEST || $this->getTestType() == TYPE_VARYING_RANDOMTEST)
04346 {
04347 if ($this->getStartingTime())
04348 {
04349 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartingTime(), $matches))
04350 {
04351 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
04352 $now = mktime();
04353 if ($now < $epoch_time)
04354 {
04355
04356 return false;
04357 }
04358 }
04359 }
04360 }
04361 return true;
04362 }
04363
04373 function endingTimeReached()
04374 {
04375 if ($this->getTestType() == TYPE_ASSESSMENT || $this->getTestType() == TYPE_ONLINE_TEST || $this->getTestType() == TYPE_VARYING_RANDOMTEST)
04376 {
04377 if ($this->getEndingTime())
04378 {
04379 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndingTime(), $matches))
04380 {
04381 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
04382 $now = mktime();
04383 if ($now > $epoch_time)
04384 {
04385
04386 return true;
04387 }
04388 }
04389 }
04390 }
04391 return false;
04392 }
04393
04401 function getQuestionsTable($sortoptions, $filter_text, $sel_filter_type, $startrow = 0, $completeonly = 0, $filter_question_type = "", $filter_questionpool = "")
04402 {
04403 global $ilUser;
04404 $where = "";
04405 if (strlen($filter_text) > 0) {
04406 switch($sel_filter_type) {
04407 case "title":
04408 $where = " AND qpl_questions.title LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
04409 break;
04410 case "comment":
04411 $where = " AND qpl_questions.comment LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
04412 break;
04413 case "author":
04414 $where = " AND qpl_questions.author LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
04415 break;
04416 }
04417 }
04418
04419 if ($filter_question_type && (strcmp($filter_question_type, "all") != 0))
04420 {
04421 $where .= " AND qpl_question_type.type_tag = " . $this->ilias->db->quote($filter_question_type);
04422 }
04423
04424 if ($filter_questionpool && (strcmp($filter_questionpool, "all") != 0))
04425 {
04426 $where .= " AND qpl_questions.obj_fi = $filter_questionpool";
04427 }
04428
04429
04430 $order = "";
04431 $images = array();
04432 if (count($sortoptions))
04433 {
04434 include_once "./classes/class.ilUtil.php";
04435 foreach ($sortoptions as $key => $value)
04436 {
04437 switch($key) {
04438 case "title":
04439 $order = " ORDER BY title $value";
04440 $images["title"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . $this->lng->txt(strtolower($value) . "ending_order")."\" />";
04441 break;
04442 case "comment":
04443 $order = " ORDER BY comment $value";
04444 $images["comment"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . $this->lng->txt(strtolower($value) . "ending_order")."\" />";
04445 break;
04446 case "type":
04447 $order = " ORDER BY question_type_id $value";
04448 $images["type"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . $this->lng->txt(strtolower($value) . "ending_order")."\" />";
04449 break;
04450 case "author":
04451 $order = " ORDER BY author $value";
04452 $images["author"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . $this->lng->txt(strtolower($value) . "ending_order")."\" />";
04453 break;
04454 case "created":
04455 $order = " ORDER BY created $value";
04456 $images["created"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . $this->lng->txt(strtolower($value) . "ending_order")."\" />";
04457 break;
04458 case "updated":
04459 $order = " ORDER BY TIMESTAMP14 $value";
04460 $images["updated"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . $this->lng->txt(strtolower($value) . "ending_order")."\" />";
04461 break;
04462 case "qpl":
04463 $order = " ORDER BY obj_fi $value";
04464 $images["qpl"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . $this->lng->txt(strtolower($value) . "ending_order")."\" />";
04465 break;
04466 }
04467 }
04468 }
04469 $maxentries = $ilUser->prefs["hits_per_page"];
04470 if ($maxentries < 1)
04471 {
04472 $maxentries = 9999;
04473 }
04474 $available_pools =& $this->getAvailableQuestionpoolIDs();
04475 $available = "";
04476 if (count($available_pools))
04477 {
04478 $available = " AND qpl_questions.obj_fi IN (" . join($available_pools, ",") . ")";
04479 }
04480 else
04481 {
04482 return array();
04483 }
04484 if ($completeonly)
04485 {
04486 $available .= " AND qpl_questions.complete = " . $this->ilias->db->quote("1");
04487 }
04488
04489
04490 $query = sprintf("SELECT qpl_questions.original_id, qpl_questions.TIMESTAMP + 0 AS TIMESTAMP14 FROM qpl_questions, tst_test_question WHERE qpl_questions.question_id = tst_test_question.question_fi AND tst_test_question.test_fi = %s",
04491 $this->ilias->db->quote($this->getTestId() . "")
04492 );
04493 $result = $this->ilias->db->query($query);
04494 $original_ids = array();
04495 while ($row = $result->fetchRow(DB_FETCHMODE_ARRAY))
04496 {
04497 if (strcmp($row[0], "") != 0)
04498 {
04499 array_push($original_ids, $row[0]);
04500 }
04501 }
04502 $original_clause = " ISNULL(qpl_questions.original_id)";
04503 if (count($original_ids))
04504 {
04505 $original_clause = " ISNULL(qpl_questions.original_id) AND qpl_questions.question_id NOT IN (" . join($original_ids, ",") . ")";
04506 }
04507
04508 $query = "SELECT qpl_questions.question_id, qpl_questions.TIMESTAMP + 0 AS TIMESTAMP14 FROM qpl_questions, qpl_question_type WHERE $original_clause$available AND qpl_questions.question_type_fi = qpl_question_type.question_type_id $where$order$limit";
04509 $query_result = $this->ilias->db->query($query);
04510 $max = $query_result->numRows();
04511 if ($startrow > $max -1)
04512 {
04513 $startrow = $max - ($max % $maxentries);
04514 }
04515 else if ($startrow < 0)
04516 {
04517 $startrow = 0;
04518 }
04519 $limit = " LIMIT $startrow, $maxentries";
04520 $query = "SELECT qpl_questions.*, qpl_questions.TIMESTAMP + 0 AS TIMESTAMP14, qpl_question_type.type_tag FROM qpl_questions, qpl_question_type WHERE $original_clause $available AND qpl_questions.question_type_fi = qpl_question_type.question_type_id $where$order$limit";
04521 $query_result = $this->ilias->db->query($query);
04522 $rows = array();
04523 if ($query_result->numRows())
04524 {
04525 while ($row = $query_result->fetchRow(DB_FETCHMODE_ASSOC))
04526 {
04527 array_push($rows, $row);
04528 }
04529 }
04530 $nextrow = $startrow + $maxentries;
04531 if ($nextrow > $max - 1)
04532 {
04533 $nextrow = $startrow;
04534 }
04535 $prevrow = $startrow - $maxentries;
04536 if ($prevrow < 0)
04537 {
04538 $prevrow = 0;
04539 }
04540 return array(
04541 "rows" => $rows,
04542 "images" => $images,
04543 "startrow" => $startrow,
04544 "nextrow" => $nextrow,
04545 "prevrow" => $prevrow,
04546 "step" => $maxentries,
04547 "rowcount" => $max
04548 );
04549 }
04550
04560 function _getTestType($test_id)
04561 {
04562 global $ilDB;
04563
04564 $result = "";
04565 $query = sprintf("SELECT tst_test_type.type_tag FROM tst_test_type, tst_tests WHERE tst_test_type.test_type_id = tst_tests.test_type_fi AND tst_tests.test_id = %s",
04566 $ilDB->quote($test_id)
04567 );
04568 $query_result = $ilDB->query($query);
04569 if ($query_result->numRows())
04570 {
04571 $row = $query_result->fetchRow(DB_FETCHMODE_ASSOC);
04572 $result = $row["type_tag"];
04573 }
04574 return $result;
04575 }
04576
04585 function &_getQuestiontypes()
04586 {
04587 global $ilDB;
04588
04589 $questiontypes = array();
04590 $query = "SELECT * FROM qpl_question_type ORDER BY type_tag";
04591 $query_result = $ilDB->query($query);
04592 while ($row = $query_result->fetchRow(DB_FETCHMODE_ASSOC))
04593 {
04594 array_push($questiontypes, $row["type_tag"]);
04595 }
04596 return $questiontypes;
04597 }
04598
04607 function to_xml()
04608 {
04609 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
04610 $domxml = domxml_open_mem($xml_header);
04611 $root = $domxml->document_element();
04612
04613 $qtiAssessment = $domxml->create_element("assessment");
04614 $qtiAssessment->set_attribute("ident", "il_".IL_INST_ID."_tst_".$this->getTestId());
04615 $qtiAssessment->set_attribute("title", $this->getTitle());
04616
04617
04618 $qtiComment = $domxml->create_element("qticomment");
04619 $qtiCommentText = $domxml->create_text_node($this->getDescription());
04620 $qtiComment->append_child($qtiCommentText);
04621 $qtiAssessment->append_child($qtiComment);
04622
04623
04624 if ($this->enable_processing_time)
04625 {
04626 $qtiDuration = $domxml->create_element("duration");
04627 preg_match("/(\d+):(\d+):(\d+)/", $this->processing_time, $matches);
04628 $qtiDurationText = $domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $matches[1], $matches[2], $matches[3]));
04629 $qtiDuration->append_child($qtiDurationText);
04630 $qtiAssessment->append_child($qtiDuration);
04631 }
04632
04633
04634 $qtiMetadata = $domxml->create_element("qtimetadata");
04635
04636 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04637 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04638 $qtiFieldLabelText = $domxml->create_text_node("ILIAS_VERSION");
04639 $qtiFieldLabel->append_child($qtiFieldLabelText);
04640 $qtiFieldEntry = $domxml->create_element("fieldentry");
04641 $qtiFieldEntryText = $domxml->create_text_node($this->ilias->getSetting("ilias_version"));
04642 $qtiFieldEntry->append_child($qtiFieldEntryText);
04643 $qtiMetadatafield->append_child($qtiFieldLabel);
04644 $qtiMetadatafield->append_child($qtiFieldEntry);
04645 $qtiMetadata->append_child($qtiMetadatafield);
04646
04647 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04648 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04649 $qtiFieldLabelText = $domxml->create_text_node("test_type");
04650 $qtiFieldLabel->append_child($qtiFieldLabelText);
04651 $qtiFieldEntry = $domxml->create_element("fieldentry");
04652 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getTestType()));
04653 $qtiFieldEntry->append_child($qtiFieldEntryText);
04654 $qtiMetadatafield->append_child($qtiFieldLabel);
04655 $qtiMetadatafield->append_child($qtiFieldEntry);
04656 $qtiMetadata->append_child($qtiMetadatafield);
04657
04658 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04659 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04660 $qtiFieldLabelText = $domxml->create_text_node("sequence_settings");
04661 $qtiFieldLabel->append_child($qtiFieldLabelText);
04662 $qtiFieldEntry = $domxml->create_element("fieldentry");
04663 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getSequenceSettings()));
04664 $qtiFieldEntry->append_child($qtiFieldEntryText);
04665 $qtiMetadatafield->append_child($qtiFieldLabel);
04666 $qtiMetadatafield->append_child($qtiFieldEntry);
04667 $qtiMetadata->append_child($qtiMetadatafield);
04668
04669 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04670 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04671 $qtiFieldLabelText = $domxml->create_text_node("author");
04672 $qtiFieldLabel->append_child($qtiFieldLabelText);
04673 $qtiFieldEntry = $domxml->create_element("fieldentry");
04674 $qtiFieldEntryText = $domxml->create_text_node($this->getAuthor());
04675 $qtiFieldEntry->append_child($qtiFieldEntryText);
04676 $qtiMetadatafield->append_child($qtiFieldLabel);
04677 $qtiMetadatafield->append_child($qtiFieldEntry);
04678 $qtiMetadata->append_child($qtiMetadatafield);
04679
04680 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04681 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04682 $qtiFieldLabelText = $domxml->create_text_node("count_system");
04683 $qtiFieldLabel->append_child($qtiFieldLabelText);
04684 $qtiFieldEntry = $domxml->create_element("fieldentry");
04685 $qtiFieldEntryText = $domxml->create_text_node($this->getCountSystem());
04686 $qtiFieldEntry->append_child($qtiFieldEntryText);
04687 $qtiMetadatafield->append_child($qtiFieldLabel);
04688 $qtiMetadatafield->append_child($qtiFieldEntry);
04689 $qtiMetadata->append_child($qtiMetadatafield);
04690
04691 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04692 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04693 $qtiFieldLabelText = $domxml->create_text_node("mc_scoring");
04694 $qtiFieldLabel->append_child($qtiFieldLabelText);
04695 $qtiFieldEntry = $domxml->create_element("fieldentry");
04696 $qtiFieldEntryText = $domxml->create_text_node($this->getMCScoring());
04697 $qtiFieldEntry->append_child($qtiFieldEntryText);
04698 $qtiMetadatafield->append_child($qtiFieldLabel);
04699 $qtiMetadatafield->append_child($qtiFieldEntry);
04700 $qtiMetadata->append_child($qtiMetadatafield);
04701
04702 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04703 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04704 $qtiFieldLabelText = $domxml->create_text_node("pass_scoring");
04705 $qtiFieldLabel->append_child($qtiFieldLabelText);
04706 $qtiFieldEntry = $domxml->create_element("fieldentry");
04707 $qtiFieldEntryText = $domxml->create_text_node($this->getPassScoring());
04708 $qtiFieldEntry->append_child($qtiFieldEntryText);
04709 $qtiMetadatafield->append_child($qtiFieldLabel);
04710 $qtiMetadatafield->append_child($qtiFieldEntry);
04711 $qtiMetadata->append_child($qtiMetadatafield);
04712
04713 if ($this->getReportingDate())
04714 {
04715 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04716 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04717 $qtiFieldLabelText = $domxml->create_text_node("reporting_date");
04718 $qtiFieldLabel->append_child($qtiFieldLabelText);
04719 $qtiFieldEntry = $domxml->create_element("fieldentry");
04720 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->reporting_date, $matches);
04721 $qtiFieldEntryText = $domxml->create_text_node(sprintf("P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
04722 $qtiFieldEntry->append_child($qtiFieldEntryText);
04723 $qtiMetadatafield->append_child($qtiFieldLabel);
04724 $qtiMetadatafield->append_child($qtiFieldEntry);
04725 $qtiMetadata->append_child($qtiMetadatafield);
04726 }
04727
04728 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04729 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04730 $qtiFieldLabelText = $domxml->create_text_node("nr_of_tries");
04731 $qtiFieldLabel->append_child($qtiFieldLabelText);
04732 $qtiFieldEntry = $domxml->create_element("fieldentry");
04733 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getNrOfTries()));
04734 $qtiFieldEntry->append_child($qtiFieldEntryText);
04735 $qtiMetadatafield->append_child($qtiFieldLabel);
04736 $qtiMetadatafield->append_child($qtiFieldEntry);
04737 $qtiMetadata->append_child($qtiMetadatafield);
04738
04739 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04740 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04741 $qtiFieldLabelText = $domxml->create_text_node("hide_previous_results");
04742 $qtiFieldLabel->append_child($qtiFieldLabelText);
04743 $qtiFieldEntry = $domxml->create_element("fieldentry");
04744 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getHidePreviousResults()));
04745 $qtiFieldEntry->append_child($qtiFieldEntryText);
04746 $qtiMetadatafield->append_child($qtiFieldLabel);
04747 $qtiMetadatafield->append_child($qtiFieldEntry);
04748 $qtiMetadata->append_child($qtiMetadatafield);
04749
04750 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04751 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04752 $qtiFieldLabelText = $domxml->create_text_node("hide_title_points");
04753 $qtiFieldLabel->append_child($qtiFieldLabelText);
04754 $qtiFieldEntry = $domxml->create_element("fieldentry");
04755 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getHideTitlePoints()));
04756 $qtiFieldEntry->append_child($qtiFieldEntryText);
04757 $qtiMetadatafield->append_child($qtiFieldLabel);
04758 $qtiMetadatafield->append_child($qtiFieldEntry);
04759 $qtiMetadata->append_child($qtiMetadatafield);
04760
04761 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04762 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04763 $qtiFieldLabelText = $domxml->create_text_node("random_test");
04764 $qtiFieldLabel->append_child($qtiFieldLabelText);
04765 $qtiFieldEntry = $domxml->create_element("fieldentry");
04766 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->isRandomTest()));
04767 $qtiFieldEntry->append_child($qtiFieldEntryText);
04768 $qtiMetadatafield->append_child($qtiFieldLabel);
04769 $qtiMetadatafield->append_child($qtiFieldEntry);
04770 $qtiMetadata->append_child($qtiMetadatafield);
04771
04772 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04773 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04774 $qtiFieldLabelText = $domxml->create_text_node("random_question_count");
04775 $qtiFieldLabel->append_child($qtiFieldLabelText);
04776 $qtiFieldEntry = $domxml->create_element("fieldentry");
04777 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getRandomQuestionCount()));
04778 $qtiFieldEntry->append_child($qtiFieldEntryText);
04779 $qtiMetadatafield->append_child($qtiFieldLabel);
04780 $qtiMetadatafield->append_child($qtiFieldEntry);
04781 $qtiMetadata->append_child($qtiMetadatafield);
04782
04783 if ($this->getStartingTime())
04784 {
04785 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04786 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04787 $qtiFieldLabelText = $domxml->create_text_node("starting_time");
04788 $qtiFieldLabel->append_child($qtiFieldLabelText);
04789 $qtiFieldEntry = $domxml->create_element("fieldentry");
04790 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->starting_time, $matches);
04791 $qtiFieldEntryText = $domxml->create_text_node(sprintf("P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
04792 $qtiFieldEntry->append_child($qtiFieldEntryText);
04793 $qtiMetadatafield->append_child($qtiFieldLabel);
04794 $qtiMetadatafield->append_child($qtiFieldEntry);
04795 $qtiMetadata->append_child($qtiMetadatafield);
04796 }
04797
04798 if ($this->getEndingTime())
04799 {
04800 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04801 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04802 $qtiFieldLabelText = $domxml->create_text_node("ending_time");
04803 $qtiFieldLabel->append_child($qtiFieldLabelText);
04804 $qtiFieldEntry = $domxml->create_element("fieldentry");
04805 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->ending_time, $matches);
04806 $qtiFieldEntryText = $domxml->create_text_node(sprintf("P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
04807 $qtiFieldEntry->append_child($qtiFieldEntryText);
04808 $qtiMetadatafield->append_child($qtiFieldLabel);
04809 $qtiMetadatafield->append_child($qtiFieldEntry);
04810 $qtiMetadata->append_child($qtiMetadatafield);
04811 }
04812 foreach ($this->mark_schema->mark_steps as $index => $mark)
04813 {
04814
04815 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04816 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04817 $qtiFieldLabelText = $domxml->create_text_node("mark_step_$index");
04818 $qtiFieldLabel->append_child($qtiFieldLabelText);
04819 $qtiFieldEntry = $domxml->create_element("fieldentry");
04820 $qtiFieldEntryText = $domxml->create_text_node(sprintf("<short>%s</short><official>%s</official><percentage>%.2f</percentage><passed>%d</passed>", $mark->get_short_name(), $mark->get_official_name(), $mark->get_minimum_level(), $mark->get_passed()));
04821 $qtiFieldEntry->append_child($qtiFieldEntryText);
04822 $qtiMetadatafield->append_child($qtiFieldLabel);
04823 $qtiMetadatafield->append_child($qtiFieldEntry);
04824 $qtiMetadata->append_child($qtiMetadatafield);
04825 }
04826 $qtiAssessment->append_child($qtiMetadata);
04827
04828
04829 $qtiObjectives = $domxml->create_element("objectives");
04830 $qtiMaterial = $domxml->create_element("material");
04831 $qtiMaterial->set_attribute("label", "introduction");
04832 $qtiMatText = $domxml->create_element("mattext");
04833 $qtiMatTextText = $domxml->create_text_node($this->getIntroduction());
04834 $qtiMatText->append_child($qtiMatTextText);
04835 $qtiMaterial->append_child($qtiMatText);
04836 $qtiObjectives->append_child($qtiMaterial);
04837 $qtiAssessment->append_child($qtiObjectives);
04838
04839
04840 $qtiAssessmentcontrol = $domxml->create_element("assessmentcontrol");
04841 $score_reporting = "No";
04842 switch ($this->getScoreReporting())
04843 {
04844 case "1":
04845 $score_reporting = "Yes";
04846 break;
04847 }
04848 $qtiAssessmentcontrol->set_attribute("solutionswitch", $score_reporting);
04849 $qtiAssessment->append_child($qtiAssessmentcontrol);
04850
04851 $qtiSection = $domxml->create_element("section");
04852 $qtiSection->set_attribute("ident", "1");
04853 $qtiAssessment->append_child($qtiSection);
04854
04855 $root->append_child($qtiAssessment);
04856 $xml = $domxml->dump_mem(true);
04857 $domxml->free();
04858 foreach ($this->questions as $question_id)
04859 {
04860 $question =& ilObjTest::_instanciateQuestion($question_id);
04861 $qti_question = $question->to_xml(false);
04862 $qti_question = preg_replace("/<questestinterop>/", "", $qti_question);
04863 $qti_question = preg_replace("/<\/questestinterop>/", "", $qti_question);
04864 if (strpos($xml, "</section>") !== false)
04865 {
04866 $xml = str_replace("</section>", "$qti_question</section>", $xml);
04867 }
04868 else
04869 {
04870 $xml = str_replace("<section ident=\"1\"/>", "<section ident=\"1\">\n$qti_question</section>", $xml);
04871 }
04872 }
04873 return $xml;
04874 }
04875
04882 function exportPagesXML(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
04883 {
04884 global $ilBench;
04885
04886 $this->mob_ids = array();
04887 $this->file_ids = array();
04888
04889 $attrs = array();
04890 $attrs["Type"] = "Test";
04891 $a_xml_writer->xmlStartTag("ContentObject", $attrs);
04892
04893
04894 $this->exportXMLMetaData($a_xml_writer);
04895
04896
04897 $expLog->write(date("[y-m-d H:i:s] ")."Start Export Page Objects");
04898 $ilBench->start("ContentObjectExport", "exportPageObjects");
04899 $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog);
04900 $ilBench->stop("ContentObjectExport", "exportPageObjects");
04901 $expLog->write(date("[y-m-d H:i:s] ")."Finished Export Page Objects");
04902
04903
04904 $expLog->write(date("[y-m-d H:i:s] ")."Start Export Media Objects");
04905 $ilBench->start("ContentObjectExport", "exportMediaObjects");
04906 $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
04907 $ilBench->stop("ContentObjectExport", "exportMediaObjects");
04908 $expLog->write(date("[y-m-d H:i:s] ")."Finished Export Media Objects");
04909
04910
04911 $expLog->write(date("[y-m-d H:i:s] ")."Start Export File Items");
04912 $ilBench->start("ContentObjectExport", "exportFileItems");
04913 $this->exportFileItems($a_target_dir, $expLog);
04914 $ilBench->stop("ContentObjectExport", "exportFileItems");
04915 $expLog->write(date("[y-m-d H:i:s] ")."Finished Export File Items");
04916
04917 $a_xml_writer->xmlEndTag("ContentObject");
04918 }
04919
04926 function exportXMLMetaData(&$a_xml_writer)
04927 {
04928 include_once "./Services/MetaData/classes/class.ilMD2XML.php";
04929 $md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
04930 $md2xml->setExportMode(true);
04931 $md2xml->startExport();
04932 $a_xml_writer->appendXML($md2xml->getXML());
04933 }
04934
04942 function modifyExportIdentifier($a_tag, $a_param, $a_value)
04943 {
04944 if ($a_tag == "Identifier" && $a_param == "Entry")
04945 {
04946 include_once "./classes/class.ilUtil.php";
04947 $a_value = ilUtil::insertInstIntoID($a_value);
04948 }
04949
04950 return $a_value;
04951 }
04952
04953
04960 function exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog)
04961 {
04962 global $ilBench;
04963
04964 include_once "./content/classes/class.ilLMPageObject.php";
04965
04966 foreach ($this->questions as $question_id)
04967 {
04968 $ilBench->start("ContentObjectExport", "exportPageObject");
04969 $expLog->write(date("[y-m-d H:i:s] ")."Page Object ".$question_id);
04970
04971 $attrs = array();
04972 $a_xml_writer->xmlStartTag("PageObject", $attrs);
04973
04974
04975
04976 $ilBench->start("ContentObjectExport", "exportPageObject_XML");
04977 $page_object = new ilPageObject("qpl", $question_id);
04978 $page_object->buildDom();
04979 $page_object->insertInstIntoIDs($a_inst);
04980 $mob_ids = $page_object->collectMediaObjects(false);
04981 $file_ids = $page_object->collectFileItems();
04982 $xml = $page_object->getXMLFromDom(false, false, false, "", true);
04983 $xml = str_replace("&","&", $xml);
04984 $a_xml_writer->appendXML($xml);
04985 $page_object->freeDom();
04986 unset ($page_object);
04987
04988 $ilBench->stop("ContentObjectExport", "exportPageObject_XML");
04989
04990
04991 $ilBench->start("ContentObjectExport", "exportPageObject_CollectMedia");
04992
04993 foreach($mob_ids as $mob_id)
04994 {
04995 $this->mob_ids[$mob_id] = $mob_id;
04996 }
04997 $ilBench->stop("ContentObjectExport", "exportPageObject_CollectMedia");
04998
04999
05000 $ilBench->start("ContentObjectExport", "exportPageObject_CollectFileItems");
05001
05002 foreach($file_ids as $file_id)
05003 {
05004 $this->file_ids[$file_id] = $file_id;
05005 }
05006 $ilBench->stop("ContentObjectExport", "exportPageObject_CollectFileItems");
05007
05008 $a_xml_writer->xmlEndTag("PageObject");
05009
05010
05011 $ilBench->stop("ContentObjectExport", "exportPageObject");
05012
05013
05014 }
05015 }
05016
05023 function exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
05024 {
05025 include_once "./content/classes/Media/class.ilObjMediaObject.php";
05026
05027 foreach ($this->mob_ids as $mob_id)
05028 {
05029 $expLog->write(date("[y-m-d H:i:s] ")."Media Object ".$mob_id);
05030 $media_obj = new ilObjMediaObject($mob_id);
05031 $media_obj->exportXML($a_xml_writer, $a_inst);
05032 $media_obj->exportFiles($a_target_dir);
05033 unset($media_obj);
05034 }
05035 }
05036
05041 function exportFileItems($a_target_dir, &$expLog)
05042 {
05043 include_once "./classes/class.ilObjFile.php";
05044
05045 foreach ($this->file_ids as $file_id)
05046 {
05047 $expLog->write(date("[y-m-d H:i:s] ")."File Item ".$file_id);
05048 $file_obj = new ilObjFile($file_id, false);
05049 $file_obj->export($a_target_dir);
05050 unset($file_obj);
05051 }
05052 }
05053
05058 function getImportMapping()
05059 {
05060 if (!is_array($this->import_mapping))
05061 {
05062 return array();
05063 }
05064 else
05065 {
05066 return $this->import_mapping;
05067 }
05068 }
05069
05080 function getECTSGrade($reached_points, $max_points)
05081 {
05082 include_once "./classes/class.ilStatistics.php";
05083
05084 $passed_statistics = new ilStatistics();
05085 $passed_array =& $this->getTotalPointsPassedArray();
05086 $passed_statistics->setData($passed_array);
05087 $ects_percentiles = array
05088 (
05089 "A" => $passed_statistics->quantile($this->ects_grades["A"]),
05090 "B" => $passed_statistics->quantile($this->ects_grades["B"]),
05091 "C" => $passed_statistics->quantile($this->ects_grades["C"]),
05092 "D" => $passed_statistics->quantile($this->ects_grades["D"]),
05093 "E" => $passed_statistics->quantile($this->ects_grades["E"])
05094 );
05095 if (count($passed_array) && ($reached_points >= $ects_percentiles["A"]))
05096 {
05097 return "A";
05098 }
05099 else if (count($passed_array) && ($reached_points >= $ects_percentiles["B"]))
05100 {
05101 return "B";
05102 }
05103 else if (count($passed_array) && ($reached_points >= $ects_percentiles["C"]))
05104 {
05105 return "C";
05106 }
05107 else if (count($passed_array) && ($reached_points >= $ects_percentiles["D"]))
05108 {
05109 return "D";
05110 }
05111 else if (count($passed_array) && ($reached_points >= $ects_percentiles["E"]))
05112 {
05113 return "E";
05114 }
05115 else if (strcmp($this->ects_fx, "") != 0)
05116 {
05117 if ($max_points > 0)
05118 {
05119 $percentage = ($reached_points / $max_points) * 100.0;
05120 }
05121 else
05122 {
05123 $percentage = 0.0;
05124 }
05125 if ($percentage >= $this->ects_fx)
05126 {
05127 return "FX";
05128 }
05129 else
05130 {
05131 return "F";
05132 }
05133 }
05134 else
05135 {
05136 return "F";
05137 }
05138 }
05139
05140 function checkMarks()
05141 {
05142 return $this->mark_schema->checkMarks();
05143 }
05144
05145 function updateMetaData()
05146 {
05147 global $ilUser;
05148 include_once "./Services/MetaData/classes/class.ilMD.php";
05149 $md =& new ilMD($this->getId(), 0, $this->getType());
05150 $md_gen =& $md->getGeneral();
05151 if ($md_gen == false)
05152 {
05153 include_once "./Services/MetaData/classes/class.ilMDCreator.php";
05154 $md_creator = new ilMDCreator($this->getId(),0,$this->getType());
05155 $md_creator->setTitle($this->getTitle());
05156 $md_creator->setTitleLanguage($ilUser->getPref('language'));
05157 $md_creator->create();
05158 }
05159 parent::updateMetaData();
05160 }
05161
05170 function &_getAvailableTests($use_object_id = false)
05171 {
05172 global $rbacsystem;
05173 global $ilDB;
05174
05175 $result_array = array();
05176 $query = "SELECT object_data.*, object_data.obj_id, object_reference.ref_id FROM object_data, object_reference WHERE object_data.obj_id = object_reference.obj_id AND object_data.type = 'tst' ORDER BY object_data.title";
05177 $result = $ilDB->query($query);
05178 include_once "./classes/class.ilObject.php";
05179 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
05180 {
05181 if ($rbacsystem->checkAccess("write", $row->ref_id) && (ilObject::_hasUntrashedReference($row->obj_id)))
05182 {
05183 if ($use_object_id)
05184 {
05185 $result_array[$row->obj_id] = $row->title;
05186 }
05187 else
05188 {
05189 $result_array[$row->ref_id] = $row->title;
05190 }
05191 }
05192 }
05193 return $result_array;
05194 }
05195
05204 function cloneRandomQuestions($new_id)
05205 {
05206 if ($new_id > 0)
05207 {
05208 $query = sprintf("SELECT * FROM tst_test_random WHERE test_fi = %s",
05209 $this->ilias->db->quote($this->getTestId() . "")
05210 );
05211 $result = $this->ilias->db->query($query);
05212 if ($result->numRows())
05213 {
05214 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
05215 {
05216 $query = sprintf("INSERT INTO tst_test_random (test_random_id, test_fi, questionpool_fi, num_of_q, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
05217 $this->ilias->db->quote($new_id . ""),
05218 $this->ilias->db->quote($row["questionpool_fi"] . ""),
05219 $this->ilias->db->quote($row["num_of_q"] . "")
05220 );
05221 $insertresult = $this->ilias->db->query($query);
05222 }
05223 }
05224 }
05225 }
05226
05227
05235 function _clone($obj_id)
05236 {
05237 $original = new ilObjTest($obj_id, false);
05238 $original->loadFromDb();
05239
05240 $newObj = new ilObjTest();
05241 $newObj->setType("tst");
05242 $counter = 2;
05243 while ($newObj->testTitleExists($newObj->getTitle() . " ($counter)"))
05244 {
05245 $counter++;
05246 }
05247
05248 $newObj->setAuthor($original->getAuthor());
05249 $newObj->setHideTitlePoints($original->getHideTitlePoints());
05250 $newObj->setPassScoring($original->getPassScoring());
05251 $newObj->setTitle($original->getTitle() . " ($counter)");
05252 $newObj->setDescription($original->getDescription());
05253 $newObj->create(true);
05254 $newObj->createReference();
05255 $newObj->putInTree($_GET["ref_id"]);
05256 $newObj->setPermissions($_GET["ref_id"]);
05257 $newObj->author = $original->getAuthor();
05258 $newObj->introduction = $original->getIntroduction();
05259 $newObj->mark_schema = $original->mark_schema;
05260 $newObj->sequence_settings = $original->getSequenceSettings();
05261 $newObj->score_reporting = $original->getScoreReporting();
05262 $newObj->reporting_date = $original->getReportingDate();
05263 $newObj->test_type = $original->getTestType();
05264 $newObj->nr_of_tries = $original->getNrOfTries();
05265 $newObj->setHidePreviousResults($original->getHidePreviousResults());
05266 $newObj->processing_time = $original->getProcessingTime();
05267 $newObj->enable_processing_time = $original->getEnableProcessingTime();
05268 $newObj->starting_time = $original->getStartingTime();
05269 $newObj->ending_time = $original->getEndingTime();
05270 $newObj->ects_output = $original->ects_output;
05271 $newObj->ects_fx = $original->ects_fx;
05272 $newObj->ects_grades = $original->ects_grades;
05273 $newObj->random_test = $original->random_test;
05274 $newObj->random_question_count = $original->random_question_count;
05275 $newObj->setCountSystem($original->getCountSystem());
05276 $newObj->setMCScoring($original->getMCScoring());
05277 $newObj->saveToDb();
05278 if ($original->isRandomTest())
05279 {
05280 $newObj->saveRandomQuestionCount($newObj->random_question_count);
05281 $original->cloneRandomQuestions($newObj->getTestId());
05282 }
05283 else
05284 {
05285
05286 include_once "./assessment/classes/class.assQuestion.php";
05287 foreach ($original->questions as $key => $question_id)
05288 {
05289 $question = ilObjTest::_instanciateQuestion($question_id);
05290 $newObj->questions[$key] = $question->duplicate();
05291
05292 $original_id = ASS_Question::_getOriginalId($question_id);
05293 $question = ilObjTest::_instanciateQuestion($newObj->questions[$key]);
05294 $question->saveToDb($original_id);
05295 }
05296 }
05297
05298 $newObj->saveToDb();
05299
05300
05301 include_once "./Services/MetaData/classes/class.ilMD.php";
05302 $md = new ilMD($original->getId(),0,$original->getType());
05303 $new_md =& $md->cloneMD($newObj->getId(),0,$newObj->getType());
05304 return $newObj->getRefId();
05305 }
05306
05307 function _getRefIdFromObjId($obj_id)
05308 {
05309 global $ilDB;
05310
05311 $query = sprintf("SELECT ref_id FROM object_reference WHERE obj_id=%s",
05312 $ilDB->quote($obj_id)
05313
05314 );
05315 $result = $ilDB->query($query);
05316 if ($result->numRows())
05317 {
05318 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05319 return $row["ref_id"];
05320 }
05321 return 0;
05322 }
05323
05324 function createRandomSolutionsForAllUsers()
05325 {
05326 global $ilDB;
05327 global $ilUser;
05328
05329 $db =& $ilDB->db;
05330 $sequence_arr = array_flip($this->questions);
05331 $sequence = join($sequence_arr, ",");
05332 include_once("./classes/class.ilObjUser.php");
05333 $logins = ilObjUser::_getAllUserData(array("login"));
05334
05335 foreach ($logins as $login)
05336 {
05337 $user_id = $login["usr_id"];
05338 $old_active = $this->getActiveTestUser($user_id);
05339 if ($old_active) {
05340 $query = sprintf("UPDATE tst_active SET lastindex = %s, sequence = %s, postponed = %s, tries = %s WHERE user_fi = %s AND test_fi = %s",
05341 $db->quote("0"),
05342 $db->quote($sequence),
05343 $db->quote(""),
05344 $db->quote("1"),
05345 $db->quote($user_id),
05346 $db->quote($this->getTestId())
05347 );
05348 } else {
05349 $sequence_arr = array_flip($this->questions);
05350 $sequence = join($sequence_arr, ",");
05351 $query = sprintf("INSERT INTO tst_active (active_id, user_fi, test_fi, sequence, postponed, lastindex, tries, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, %s, NULL)",
05352 $db->quote($user_id),
05353 $db->quote($this->getTestId()),
05354 $db->quote($sequence),
05355 $db->quote(""),
05356 $db->quote("0"),
05357 $db->quote("1")
05358 );
05359 }
05360 $db->query($query);
05361 }
05362 foreach ($this->questions as $question_id)
05363 {
05364 $question =& ilObjTest::_instanciateQuestion($question_id);
05365 foreach ($logins as $login)
05366 {
05367 $question->createRandomSolution($this->getTestId(), $login["usr_id"]);
05368 }
05369 }
05370 }
05371
05379 function &getEvaluationUsers($user_id, $sort_name_option = "asc")
05380 {
05381 $users = array();
05382 $query = sprintf("SELECT tst_eval_users.user_fi, usr_data.firstname, usr_data.lastname FROM tst_eval_users, usr_data WHERE tst_eval_users.test_fi = %s AND tst_eval_users.evaluator_fi = %s AND tst_eval_users.user_fi = usr_data.usr_id ORDER BY usr_data.lastname " . strtoupper($sort_name_option),
05383 $this->ilias->db->quote($this->getTestId() . ""),
05384 $this->ilias->db->quote($user_id . "")
05385 );
05386 $result = $this->ilias->db->query($query);
05387 if ($result->numRows())
05388 {
05389 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
05390 {
05391 $name = array("fullname" => trim($row["lastname"].", ".$row["firstname"] . " " . $row["title"]), "firstname" => $row["firstname"], "lastname" => $row["lastname"]);
05392 if ($this->getTestType() == TYPE_SELF_ASSESSMENT)
05393 {
05394 $name = array("fullname" => $this->lng->txt("unknown"), "firstname" => $this->lng->txt("unknown"), "lastname" => $this->lng->txt("unknown"));
05395 }
05396 $users[$row["user_fi"]] = $name;
05397 }
05398 }
05399 return $users;
05400 }
05401
05410 function removeSelectedUser($user_id, $evaluator_id)
05411 {
05412 $query = sprintf("DELETE FROM tst_eval_users WHERE test_fi = %s AND user_fi = %s AND evaluator_fi = %s",
05413 $this->ilias->db->quote($this->getTestId() . ""),
05414 $this->ilias->db->quote($user_id . ""),
05415 $this->ilias->db->quote($evaluator_id . "")
05416 );
05417 $result = $this->ilias->db->query($query);
05418 }
05419
05428 function addSelectedUser($user_id, $evaluator_id)
05429 {
05430 $query = sprintf("SELECT user_fi FROM tst_active WHERE test_fi = %s AND user_fi = %s",
05431 $this->ilias->db->quote($this->getTestId() . ""),
05432 $this->ilias->db->quote($user_id . "")
05433 );
05434 $result = $this->ilias->db->query($query);
05435 if ($result->numRows() == 1)
05436 {
05437 $query = sprintf("REPLACE INTO tst_eval_users (test_fi, evaluator_fi, user_fi) VALUES (%s, %s, %s)",
05438 $this->ilias->db->quote($this->getTestId() . ""),
05439 $this->ilias->db->quote($evaluator_id . ""),
05440 $this->ilias->db->quote($user_id . "")
05441 );
05442 $result = $this->ilias->db->query($query);
05443 }
05444 }
05445
05454 function addSelectedGroup($group_id, $evaluator_id)
05455 {
05456 include_once "./classes/class.ilObjGroup.php";
05457 $group = new ilObjGroup($group_id);
05458 $members = $group->getGroupMemberIds();
05459 foreach ($members as $user_id)
05460 {
05461 $this->addSelectedUser($user_id, $evaluator_id);
05462 }
05463 }
05464
05473 function addSelectedRole($role_id, $evaluator_id)
05474 {
05475 global $rbacreview;
05476 $members = $rbacreview->assignedUsers($role_id,"usr_id");
05477 foreach ($members as $user_id)
05478 {
05479 $this->addSelectedUser($user_id, $evaluator_id);
05480 }
05481 }
05482
05491 function getQuestionCount()
05492 {
05493 $num = 0;
05494
05495 if ($this->isRandomTest())
05496 {
05497 if ($this->getRandomQuestionCount())
05498 {
05499 $num = $this->getRandomQuestionCount();
05500 }
05501 else
05502 {
05503 $qpls =& $this->getRandomQuestionpools();
05504 foreach ($qpls as $data)
05505 {
05506 $num += $data["count"];
05507 }
05508 }
05509 }
05510 else
05511 {
05512 $num = count($this->questions);
05513 }
05514 return $num;
05515 }
05516
05525 function _getQuestionCount($test_id, $user_id)
05526 {
05527 global $ilDB;
05528
05529 $num = 0;
05530
05531 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
05532 $ilDB->quote($test_id . "")
05533 );
05534 $result = $ilDB->query($query);
05535 if (!$result->numRows())
05536 {
05537 return 0;
05538 }
05539 $test = $result->fetchRow(DB_FETCHMODE_ASSOC);
05540
05541 if ($test["random_test"] == 1)
05542 {
05543 $query = sprintf("SELECT test_random_question_id FROM tst_test_random_question WHERE test_fi = %s AND user_fi = %s AND pass = 0",
05544 $ilDB->quote($test_id . ""),
05545 $ilDB->quote($user_id . "")
05546 );
05547 $result = $ilDB->query($query);
05548 $num = $result->numRows();
05549 }
05550 else
05551 {
05552 $query = sprintf("SELECT test_question_id FROM tst_test_question WHERE test_fi = %s",
05553 $ilDB->quote($test_id . "")
05554 );
05555 $result = $ilDB->query($query);
05556 $num = $result->numRows();
05557 }
05558 return $num;
05559 }
05560
05569 function _goto($a_target)
05570 {
05571 global $rbacsystem, $ilErr, $lng;
05572
05573 include_once "./classes/class.ilSearch.php";
05574
05575
05576
05577 if ($rbacsystem->checkAccess("read", $a_target) and ilSearch::_checkParentConditions($a_target))
05578 {
05579 include_once "./classes/class.ilUtil.php";
05580 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=infoScreen&ref_id=$a_target");
05581 }
05582 else
05583 {
05584 $ilErr->raiseError($lng->txt("msg_no_perm_read_lm"), $ilErr->FATAL);
05585 }
05586 }
05587
05595 function removeNonRandomTestData()
05596 {
05597
05598 $this->removeAllTestEditings();
05599 $query = sprintf("DELETE FROM tst_test_question WHERE test_fi = %s",
05600 $this->ilias->db->quote($this->getTestId())
05601 );
05602 $result = $this->ilias->db->query($query);
05603 $this->questions = array();
05604 $this->saveCompleteStatus();
05605 }
05606
05614 function removeRandomTestData()
05615 {
05616
05617 $this->removeAllTestEditings();
05618 $query = sprintf("DELETE FROM tst_test_random WHERE test_fi = %s",
05619 $this->ilias->db->quote($this->getTestId())
05620 );
05621 $result = $this->ilias->db->query($query);
05622 $this->questions = array();
05623 $this->saveCompleteStatus();
05624 }
05625
05635 function logAction($logtext = "", $question_id = "")
05636 {
05637 global $ilUser;
05638
05639 $original_id = "";
05640 if (strcmp($question_id, "") != 0)
05641 {
05642 include_once "./assessment/classes/class.assQuestion.php";
05643 $original_id = ASS_Question::_getOriginalId($question_id);
05644 }
05645 include_once "./classes/class.ilObjAssessmentFolder.php";
05646 ilObjAssessmentFolder::_addLog($ilUser->id, $this->getId(), $logtext, $question_id, $original_id);
05647 }
05648
05658 function _getObjectIDFromTestID($test_id)
05659 {
05660 global $ilDB;
05661 $object_id = FALSE;
05662 $query = sprintf("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
05663 $ilDB->quote($test_id . "")
05664 );
05665 $result = $ilDB->query($query);
05666 if ($result->numRows())
05667 {
05668 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05669 $object_id = $row["obj_fi"];
05670 }
05671 return $object_id;
05672 }
05673
05683 function _getTestIDFromObjectID($object_id)
05684 {
05685 global $ilDB;
05686 $test_id = FALSE;
05687 $query = sprintf("SELECT test_id FROM tst_tests WHERE obj_fi = %s",
05688 $ilDB->quote($object_id . "")
05689 );
05690 $result = $ilDB->query($query);
05691 if ($result->numRows())
05692 {
05693 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05694 $test_id = $row["test_id"];
05695 }
05696 return $test_id;
05697 }
05698
05709 function getTextAnswer($user_id, $question_id, $pass = NULL)
05710 {
05711 $res = "";
05712 if (($user_id) && ($question_id))
05713 {
05714 if (is_null($pass))
05715 {
05716 include_once "./assessment/classes/class.assQuestion.php";
05717 $pass = ASS_Question::_getSolutionMaxPass($question_id, $user_id, $this->getTestId());
05718 }
05719 $query = sprintf("SELECT value1 FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s AND pass = %s",
05720 $this->ilias->db->quote($user_id . ""),
05721 $this->ilias->db->quote($this->getTestId() . ""),
05722 $this->ilias->db->quote($question_id . ""),
05723 $this->ilias->db->quote($pass . "")
05724 );
05725 $result = $this->ilias->db->query($query);
05726 if ($result->numRows() == 1)
05727 {
05728 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05729 $res = $row["value1"];
05730 }
05731 }
05732 return $res;
05733 }
05734
05744 function getQuestiontext($question_id)
05745 {
05746 $res = "";
05747 if ($question_id)
05748 {
05749 $query = sprintf("SELECT question_text FROM qpl_questions WHERE question_id = %s",
05750 $this->ilias->db->quote($question_id . "")
05751 );
05752 $result = $this->ilias->db->query($query);
05753 if ($result->numRows() == 1)
05754 {
05755 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05756 $res = $row["question_text"];
05757 }
05758 }
05759 return $res;
05760 }
05761
05770 function &getInvitedUsers($user_id="", $order="login, lastname, firstname")
05771 {
05772 global $ilDB;
05773
05774 $result_array = array();
05775
05776 if (is_numeric($user_id))
05777 {
05778 $query = sprintf("SELECT usr_id, login, lastname, firstname, tst_invited_user.clientip, " .
05779 "tst_active.submitted as test_finished, matriculation, IF(tst_active.active_id IS NULL,0,1) as test_started " .
05780 "FROM usr_data, tst_invited_user " .
05781 "LEFT JOIN tst_active ON tst_active.user_fi = tst_invited_user.user_fi AND tst_active.test_fi = tst_invited_user.test_fi " .
05782 "WHERE tst_invited_user.test_fi = %s and tst_invited_user.user_fi=usr_data.usr_id AND usr_data.usr_id=%s " .
05783 "ORDER BY %s",
05784 $ilDB->quote($this->test_id),
05785 $user_id,
05786 $order
05787 );
05788
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798 }
05799 else
05800 {
05801 $query = sprintf("SELECT usr_id, login, lastname, firstname, tst_invited_user.clientip, " .
05802 "tst_active.submitted as test_finished, matriculation, IF(tst_active.active_id IS NULL,0,1) as test_started " .
05803 "FROM usr_data, tst_invited_user " .
05804 "LEFT JOIN tst_active ON tst_active.user_fi = tst_invited_user.user_fi AND tst_active.test_fi = tst_invited_user.test_fi " .
05805 "WHERE tst_invited_user.test_fi = %s and tst_invited_user.user_fi=usr_data.usr_id " .
05806 "ORDER BY %s",
05807 $ilDB->quote($this->test_id),
05808 $order
05809 );
05810
05811
05812
05813
05814
05815
05816
05817
05818
05819 }
05820
05821 return $this->getArrayData($query, "usr_id");
05822 }
05823
05833 function &getUserData($ids)
05834 {
05835 if (!is_array($ids) || count($ids) ==0)
05836 return array();
05837
05838 $result_array = array();
05839
05840 $query = sprintf("SELECT usr_id, login, lastname, firstname, client_ip as clientip FROM usr_data WHERE usr_id IN (%s) ORDER BY login",
05841 join ($ids,",")
05842 );
05843
05844 return $this->getArrayData ($query, "usr_id");
05845 }
05846
05857 function &getArrayData($query, $id_field)
05858 {
05859 return ilObjTest::_getArrayData ($query, $id_field);
05860 }
05861
05862 function &_getArrayData($query, $id_field)
05863 {
05864 global $ilDB;
05865 $result = $ilDB->query($query);
05866 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
05867 {
05868 $result_array[$row->$id_field]= $row;
05869 }
05870 return ($result_array)?$result_array:array();
05871 }
05872
05873 function &getGroupData($ids)
05874 {
05875 if (!is_array($ids) || count($ids) ==0)
05876 return array();
05877
05878 $result_array = array();
05879
05880 $query = sprintf("SELECT ref_id, title, description FROM `grp_data` g, object_data o, object_reference r WHERE o.obj_id=grp_id AND o.obj_id = r.obj_id AND ref_id IN (%s)",
05881 join ($ids,",")
05882 );
05883
05884 return $this->getArrayData ($query, "ref_id");
05885 }
05886
05887 function &getRoleData($ids)
05888 {
05889 if (!is_array($ids) || count($ids) ==0)
05890 return array();
05891
05892 $result_array = array();
05893
05894 $query = sprintf("SELECT obj_id, description, title FROM role_data, object_data o WHERE o.obj_id=role_id AND role_id IN (%s)",
05895 join ($ids,",")
05896 );
05897
05898 return $this->getArrayData ($query, "obj_id");
05899 }
05900
05901
05910 function inviteGroup($group_id)
05911 {
05912 include_once "./classes/class.ilObjGroup.php";
05913 $group = new ilObjGroup($group_id);
05914 $members = $group->getGroupMemberIds();
05915 include_once "./classes/class.ilObjUser.php";
05916 foreach ($members as $user_id)
05917 {
05918 $this->inviteUser($user_id, ilObjUser::_lookupClientIP($user_id));
05919 }
05920 }
05921
05930 function inviteRole($role_id)
05931 {
05932 global $rbacreview;
05933 $members = $rbacreview->assignedUsers($role_id,"usr_id");
05934 include_once "./classes/class.ilObjUser.php";
05935 foreach ($members as $user_id)
05936 {
05937 $this->inviteUser($user_id, ilObjUser::_lookupClientIP($user_id));
05938 }
05939 }
05940
05941
05942
05951 function disinviteUser($user_id)
05952 {
05953 $query = sprintf("DELETE FROM tst_invited_user WHERE test_fi = %s AND user_fi = %s",
05954 $this->ilias->db->quote($this->test_id),
05955 $this->ilias->db->quote($user_id)
05956 );
05957 $result = $this->ilias->db->query($query);
05958 }
05959
05968 function inviteUser($user_id, $client_ip="")
05969 {
05970 $query = sprintf("INSERT IGNORE INTO tst_invited_user (test_fi, user_fi, clientip) VALUES (%s, %s, %s)",
05971 $this->ilias->db->quote($this->test_id),
05972 $this->ilias->db->quote($user_id),
05973 $this->ilias->db->quote($client_ip)
05974 );
05975
05976 $result = $this->ilias->db->query($query);
05977 }
05978
05979
05980 function setClientIP($user_id, $client_ip) {
05981 $query = sprintf("UPDATE tst_invited_user SET clientip=%s WHERE test_fi=%s and user_fi=%s",
05982 $this->ilias->db->quote($client_ip),
05983 $this->ilias->db->quote($this->test_id),
05984 $this->ilias->db->quote($user_id)
05985 );
05986 $insertresult = $this->ilias->db->query($query);
05987 }
05988
05995 function isOnlineTest()
05996 {
05997 return $this->getTestType()==TYPE_ONLINE_TEST;
05998 }
05999
06000
06001
06007 function _getSolvedQuestions($test_fi, $user_fi, $question_fi = null)
06008 {
06009 global $ilDB;
06010 if (is_numeric($question_fi))
06011 $query = sprintf("SELECT question_fi, solved FROM tst_active_qst_sol_settings " .
06012 "WHERE user_fi = %s AND test_fi = %s AND question_fi=%s",
06013 $ilDB->quote($user_fi),
06014 $ilDB->quote($test_fi),
06015 $question_fi
06016 );
06017 else $query = sprintf("SELECT question_fi, solved FROM tst_active_qst_sol_settings " .
06018 "WHERE user_fi = %s AND test_fi = %s",
06019 $ilDB->quote($user_fi),
06020 $ilDB->quote($test_fi)
06021 );
06022 return ilObjTest::_getArrayData ($query, "question_fi");
06023 }
06024
06025
06029 function setQuestionSetSolved ($value, $question_id, $user_id)
06030 {
06031 $query = sprintf("REPLACE INTO tst_active_qst_sol_settings SET solved=%s, question_fi=%s, test_fi=%s, user_fi=%s",
06032 $this->ilias->db->quote($value),
06033 $this->ilias->db->quote($question_id),
06034 $this->ilias->db->quote($this->test_id),
06035 $this->ilias->db->quote($user_id)
06036 );
06037
06038 $this->ilias->db->query($query);
06039 }
06040
06041
06045 function setActiveTestSubmitted($user_id)
06046 {
06047 $query = sprintf("UPDATE tst_active SET submitted=1, tries=1, submittimestamp=NOW() WHERE test_fi=%s AND user_fi=%s",
06048 $this->ilias->db->quote($this->test_id),
06049 $this->ilias->db->quote($user_id)
06050 );
06051 $this->ilias->db->query($query);
06052
06053 }
06054
06058 function isActiveTestSubmitted($user_id = null)
06059 {
06060 global $ilUser;
06061 if (!is_numeric($user_id))
06062 $user_id = $ilUser->getId();
06063
06064 $query = sprintf("SELECT submitted FROM tst_active WHERE test_fi=%s AND user_fi=%s AND submitted=1",
06065 $this->ilias->db->quote($this->test_id),
06066 $this->ilias->db->quote($user_id)
06067 );
06068 $result = $this->ilias->db->query($query);
06069
06070 return $result->numRows() == 1;
06071
06072 }
06076 function hasNrOfTriesRestriction()
06077 {
06078 return $this->getNrOfTries() != 0;
06079 }
06080
06081
06086 function isNrOfTriesReached($tries)
06087 {
06088 return $tries >= (int) $this->getNrOfTries();
06089 }
06090
06091
06095 function getAllTestResults()
06096 {
06097 $participants = $this->getInvitedUsers("matriculation");
06098 $results = array();
06099 $row = array("matriculation" => $this->lng->txt("matriculation"),
06100 "lastname" => $this->lng->txt("lastname"),
06101 "firstname" => $this->lng->txt("firstname"),
06102 "reached_points" => $this->lng->txt("tst_reached_points"),
06103 "max_points" => $this->lng->txt("tst_maximum_points"),
06104 "percent_value" => $this->lng->txt("tst_percent_solved"),
06105 "mark" => $this->lng->txt("tst_mark"),
06106 "ects" => $this->lng->txt("ects_grade"));
06107
06108 $results[] = $row;
06109 foreach ($participants as $user_id => $user_rec)
06110 {
06111 $row = array();
06112 $reached_points = 0;
06113 $max_points = 0;
06114
06115 foreach ($this->questions as $value)
06116 {
06117
06118
06119 $question =& ilObjTest::_instanciateQuestion($value);
06120
06121 if (is_object($question))
06122 {
06123 $max_points += $question->getMaximumPoints();
06124 $reached_points += $question->getReachedPoints($user_id, $this->getTestId());
06125 }
06126 }
06127
06128 if ($max_points > 0)
06129 {
06130 $percentvalue = $reached_points / $max_points;
06131 }
06132 else
06133 {
06134 $percentvalue = 0;
06135 }
06136 $mark_obj = $this->mark_schema->get_matching_mark($percentvalue * 100);
06137 $passed = "";
06138 if ($mark_obj)
06139 {
06140 $mark = $mark_obj->get_official_name();
06141 $ects_mark = $this->getECTSGrade($reached_points, $max_points);
06142 }
06143
06144 $row = array(
06145 "matriculation" => $user_rec->matriculation,
06146 "lastname" => $user_rec->lastname,
06147 "firstname" => $user_rec->firstname,
06148 "reached_points" => $reached_points,
06149 "max_points" => $max_points,
06150 "percent_value" => $percentvalue,
06151 "mark" => $mark,
06152 "ects" => $ects_mark);
06153 $results[] = $this->processCSVRow ($row, true);
06154 }
06155 return $results;
06156 }
06157
06170 function &processCSVRow($row, $quoteAll = FALSE, $separator = ";")
06171 {
06172 $resultarray = array();
06173 foreach ($row as $rowindex => $entry)
06174 {
06175 $surround = FALSE;
06176 if ($quoteAll)
06177 {
06178 $surround = TRUE;
06179 }
06180 if (strpos($entry, "\"") !== FALSE)
06181 {
06182 $entry = str_replace("\"", "\"\"", $entry);
06183 $surround = TRUE;
06184 }
06185 if (strpos($entry, $separator) !== FALSE)
06186 {
06187 $surround = TRUE;
06188 }
06189
06190 $entry = str_replace(chr(13).chr(10), chr(10), $entry);
06191 if ($surround)
06192 {
06193 $resultarray[$rowindex] = utf8_decode("\"" . $entry . "\"");
06194 }
06195 else
06196 {
06197 $resultarray[$rowindex] = utf8_decode($entry);
06198 }
06199 }
06200 return $resultarray;
06201 }
06202
06213 function _getPass($user_id, $test_id)
06214 {
06215 global $ilDB;
06216 $query = sprintf("SELECT tries FROM tst_active WHERE user_fi = %s AND test_fi = %s",
06217 $ilDB->quote($user_id . ""),
06218 $ilDB->quote($test_id . "")
06219 );
06220 $result = $ilDB->query($query);
06221 if ($result->numRows())
06222 {
06223 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
06224 return $row["tries"];
06225 }
06226 else
06227 {
06228 return 0;
06229 }
06230 }
06231
06242 function _getBestPass($user_id, $test_id)
06243 {
06244 global $ilDB;
06245 $lastpass = ilObjTest::_getPass($user_id, $test_id);
06246 $bestpass = 0;
06247 $maxpoints = 0;
06248 for ($i = 0; $i <= $lastpass; $i++)
06249 {
06250 $query = sprintf("SELECT SUM(points) AS maxpoints FROM tst_test_result WHERE user_fi = %s AND test_fi = %s AND pass = %s",
06251 $ilDB->quote($user_id . ""),
06252 $ilDB->quote($test_id . ""),
06253 $ilDB->quote($i . "")
06254 );
06255 $result = $ilDB->query($query);
06256 if ($result->numRows())
06257 {
06258 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
06259 if ($row["maxpoints"] > $maxpoints)
06260 {
06261 $maxpoints = $row["maxpoints"];
06262 $bestpass = $i;
06263 }
06264 }
06265 }
06266 return $bestpass;
06267 }
06268
06279 function _getResultPass($user_id, $test_id)
06280 {
06281 $counted_pass = NULL;
06282 if (strcmp(ilObjTest::_getTestType($test_id), "tt_varying_randomtest") == 0)
06283 {
06284 if (ilObjTest::_getPassScoring($test_id) == SCORE_BEST_PASS)
06285 {
06286 $counted_pass = ilObjTest::_getBestPass($user_id, $test_id);
06287 }
06288 else
06289 {
06290 $counted_pass = ilObjTest::_getPass($user_id, $test_id);
06291 global $ilDB;
06292 $query = sprintf("SELECT test_result_id FROM tst_test_result WHERE user_fi = %s AND test_fi = %s AND pass = %s",
06293 $ilDB->quote($user_id . ""),
06294 $ilDB->quote($test_id . ""),
06295 $ilDB->quote($counted_pass . "")
06296 );
06297 $result = $ilDB->query($query);
06298 if ($result->numRows() == 0)
06299 {
06300
06301
06302 $counted_pass -= 1;
06303 }
06304 if ($counted_pass < 0) $counted_pass = 0;
06305 }
06306 }
06307 return $counted_pass;
06308 }
06309
06321 function getAnsweredQuestionCount($user_id, $test_id, $pass = NULL)
06322 {
06323 if ($this->isRandomTest())
06324 {
06325 $this->loadQuestions($user_id, $pass);
06326 }
06327 include_once "./assessment/classes/class.assQuestion.php";
06328 $workedthrough = 0;
06329 foreach ($this->questions as $value)
06330 {
06331 if (ASS_Question::_isWorkedThrough($user_id, $this->getTestId(), $value, $pass))
06332 {
06333 $workedthrough += 1;
06334 }
06335 }
06336 return $workedthrough;
06337 }
06338
06350 function getPassFinishDate($user_id, $test_id, $pass)
06351 {
06352 global $ilDB;
06353 if (is_null($pass)) $pass = 0;
06354 $query = sprintf("SELECT tst_test_result.TIMESTAMP + 0 AS TIMESTAMP14 FROM tst_test_result WHERE user_fi = %s AND test_fi = %s AND pass = %s ORDER BY tst_test_result.TIMESTAMP DESC",
06355 $ilDB->quote($user_id . ""),
06356 $ilDB->quote($test_id . ""),
06357 $ilDB->quote($pass . "")
06358 );
06359 $result = $ilDB->query($query);
06360 if ($result->numRows())
06361 {
06362 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
06363 return $row["TIMESTAMP14"];
06364 }
06365 else
06366 {
06367 return 0;
06368 }
06369 }
06370
06380 function isExecutable($user_id)
06381 {
06382 $result = array(
06383 "executable" => true,
06384 "errormessage" => ""
06385 );
06386 if (!$this->startingTimeReached())
06387 {
06388 $result["executable"] = false;
06389 $result["errormessage"] = sprintf($this->lng->txt("detail_starting_time_not_reached"), ilFormat::ftimestamp2datetimeDB($this->getStartingTime()));
06390 return $result;
06391 }
06392 if ($this->endingTimeReached())
06393 {
06394 $result["executable"] = false;
06395 $result["errormessage"] = sprintf($this->lng->txt("detail_ending_time_reached"), ilFormat::ftimestamp2datetimeDB($this->getEndingTime()));
06396 return $result;
06397 }
06398 if ($this->getEnableProcessingTime())
06399 {
06400 $starting_time = $this->getStartingTimeOfUser($user_id);
06401 if ($starting_time !== FALSE)
06402 {
06403 if ($this->isMaxProcessingTimeReached($starting_time))
06404 {
06405 $result["executable"] = false;
06406 $result["errormessage"] = $this->lng->txt("detail_max_processing_time_reached");
06407 return $result;
06408 }
06409 }
06410 }
06411
06412 $active = $this->getActiveTestUser($user_id);
06413 if ($this->hasNrOfTriesRestriction() && is_object($active) && $this->isNrOfTriesReached($active->tries))
06414 {
06415 $result["executable"] = false;
06416 if ($this->isOnlineTest())
06417 {
06418
06419
06420 $result["errormessage"] = "";
06421 }
06422 else
06423 {
06424 $result["errormessage"] = $this->lng->txt("maximum_nr_of_tries_reached");
06425 }
06426 return $result;
06427 }
06428
06429
06430
06431 return $result;
06432 }
06433
06434 function canShowTestResults($user_id)
06435 {
06436 $active = $this->getActiveTestUser($user_id);
06437 $starting_time = $this->getStartingTimeOfUser($user_id);
06438 $notimeleft = FALSE;
06439 if ($starting_time !== FALSE)
06440 {
06441 if ($this->isMaxProcessingTimeReached($starting_time))
06442 {
06443 $notimeleft = TRUE;
06444 }
06445 }
06446 $result = (($active->tries > 0) || ($this->endingTimeReached()) || $notimeleft) && $this->canViewResults();
06447 if ($this->getTestType() == TYPE_ONLINE_TEST)
06448 {
06449 return $result && $this->isActiveTestSubmitted();
06450 }
06451 return $result;
06452 }
06453
06454 function canEditMarks()
06455 {
06456 $total = $this->evalTotalPersons();
06457 if ($total > 0)
06458 {
06459 if ($this->getReportingDate())
06460 {
06461 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getReportingDate(), $matches))
06462 {
06463 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
06464 $now = mktime();
06465 if ($now < $epoch_time)
06466 {
06467 return true;
06468 }
06469 }
06470 }
06471 return false;
06472 }
06473 else
06474 {
06475 return true;
06476 }
06477 }
06478
06488 function getStartingTimeOfUser($user_id)
06489 {
06490 global $ilDB;
06491
06492 if ($user_id < 1) return FALSE;
06493 $query = sprintf("SELECT tst_times.started FROM tst_times, tst_active WHERE tst_active.user_fi = %s AND tst_active.test_fi = %s AND tst_active.active_id = tst_times.active_fi ORDER BY tst_times.started",
06494 $ilDB->quote($user_id . ""),
06495 $ilDB->quote($this->getTestId() . "")
06496 );
06497 $result = $ilDB->query($query);
06498 if ($result->numRows())
06499 {
06500 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
06501 if (preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row["started"], $matches))
06502 {
06503 return mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
06504 }
06505 else
06506 {
06507 return FALSE;
06508 }
06509 }
06510 else
06511 {
06512 return FALSE;
06513 }
06514 }
06515
06526 function isMaxProcessingTimeReached($starting_time)
06527 {
06528 if ($this->getEnableProcessingTime())
06529 {
06530 $processing_time = $this->getProcessingTimeInSeconds();
06531 $now = mktime();
06532 if ($now > ($starting_time + $processing_time))
06533 {
06534 return TRUE;
06535 }
06536 else
06537 {
06538 return FALSE;
06539 }
06540 }
06541 else
06542 {
06543 return FALSE;
06544 }
06545 }
06546
06558 function &_getPassedUsers($a_obj_id)
06559 {
06560 global $ilDB;
06561
06562 $passed_users = array();
06563 $query = sprintf("SELECT tst_active.* FROM tst_active, tst_tests ".
06564 "WHERE tst_tests.obj_fi = %s ".
06565 "AND tst_active.test_fi = tst_tests.test_id",
06566 $ilDB->quote($a_obj_id . "")
06567 );
06568 $result = $ilDB->query($query);
06569 if ($result->numRows())
06570 {
06571 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
06572 {
06573 $user_id = $row["user_fi"];
06574 $test_id = $row["test_fi"];
06575 $pass = ilObjTest::_getResultPass($user_id, $test_id);
06576 include_once "./assessment/classes/class.ilObjTestAccess.php";
06577 $testres =& ilObjTestAccess::_getTestResult($user_id, $a_obj_id, $pass);
06578 if ((bool) $testres['passed'])
06579 {
06580 array_push($passed_users, $user_id);
06581 }
06582 }
06583 }
06584 return $passed_users;
06585 }
06586
06587 }
06588
06589 ?>