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 require_once "./classes/class.ilObject.php";
00036 require_once "./assessment/classes/class.assMarkSchema.php";
00037 require_once "./classes/class.ilMetaData.php";
00038 require_once "./assessment/classes/class.assQuestion.php";
00039 require_once "./assessment/classes/class.assClozeTest.php";
00040 require_once "./assessment/classes/class.assImagemapQuestion.php";
00041 require_once "./assessment/classes/class.assJavaApplet.php";
00042 require_once "./assessment/classes/class.assMatchingQuestion.php";
00043 require_once "./assessment/classes/class.assMultipleChoice.php";
00044 require_once "./assessment/classes/class.assOrderingQuestion.php";
00045 require_once "./classes/class.ilObjAssessmentFolder.php";
00046
00047 define("TEST_FIXED_SEQUENCE", 0);
00048 define("TEST_POSTPONE", 1);
00049
00050 define("REPORT_AFTER_QUESTION", 0);
00051 define("REPORT_AFTER_TEST", 1);
00052
00053 define("TYPE_ASSESSMENT", "1");
00054 define("TYPE_SELF_ASSESSMENT", "2");
00055 define("TYPE_NAVIGATION_CONTROLLING", "3");
00056
00057 class ilObjTest extends ilObject
00058 {
00066 var $test_id;
00067
00076 var $author;
00077
00085 var $metadata;
00086
00094 var $questions;
00095
00104 var $introduction;
00105
00113 var $mark_schema;
00114
00124 var $sequence_settings;
00125
00137 var $score_reporting;
00138
00149 var $reporting_date;
00150
00158 var $evaluation_data;
00159
00167 var $test_type;
00168
00177 var $nr_of_tries;
00178
00186 var $processing_time;
00187
00195 var $enable_processing_time;
00196
00204 var $starting_time;
00205
00213 var $ending_time;
00214
00222 var $ects_output;
00223
00231 var $ects_fx;
00232
00243 var $test_types;
00244
00252 var $ects_grades;
00253
00263 var $random_test;
00264
00272 var $random_question_count;
00273
00280 function ilObjTest($a_id = 0,$a_call_by_reference = true)
00281 {
00282 global $ilUser;
00283 $this->type = "tst";
00284 $this->mark_schema = new ASS_MarkSchema();
00285
00286 $this->retrieveTestTypes();
00287 $this->test_id = -1;
00288 $this->author = $ilUser->fullname;
00289 $this->introduction = "";
00290 $this->questions = array();
00291 $this->sequence_settings = TEST_FIXED_SEQUENCE;
00292 $this->score_reporting = REPORT_AFTER_TEST;
00293 $this->reporting_date = "";
00294 $this->nr_of_tries = 0;
00295 $this->starting_time = "";
00296 $this->ending_time = "";
00297 $this->processing_time = "00:00:00";
00298 $this->enable_processing_time = "0";
00299 $this->test_type = TYPE_ASSESSMENT;
00300 $this->ects_output = 0;
00301 $this->ects_fx = "";
00302 $this->random_test = 0;
00303 $this->random_question_count = "";
00304 global $lng;
00305 $lng->loadLanguageModule("assessment");
00306 $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);
00307 $this->ects_grades = array(
00308 "A" => 90,
00309 "B" => 65,
00310 "C" => 35,
00311 "D" => 10,
00312 "E" => 0
00313 );
00314 if ($a_id == 0)
00315 {
00316 $new_meta =& new ilMetaData();
00317 $this->assignMetaData($new_meta);
00318 }
00319 $this->ilObject($a_id, $a_call_by_reference);
00320 }
00321
00325 function create($a_upload = false)
00326 {
00327 parent::create();
00328 if (!$a_upload)
00329 {
00330 $this->meta_data->setId($this->getId());
00331 $this->meta_data->setType($this->getType());
00332 $this->meta_data->setTitle($this->getTitle());
00333 $this->meta_data->setDescription($this->getDescription());
00334 $this->meta_data->setObject($this);
00335 $this->meta_data->create();
00336 }
00337 }
00338
00345 function update()
00346 {
00347 if (!parent::update())
00348 {
00349 return false;
00350 }
00351
00352
00353
00354 return true;
00355 }
00356
00365 function createReference() {
00366 $result = parent::createReference();
00367 $this->saveToDb();
00368 return $result;
00369 }
00370
00376 function getCallingScript()
00377 {
00378 return "test.php";
00379 }
00380
00386 function read($a_force_db = false)
00387 {
00388 parent::read($a_force_db);
00389 $this->loadFromDb();
00390 $this->meta_data =& new ilMetaData($this->getType(), $this->getId());
00391 }
00392
00400 function ilClone($a_parent_ref)
00401 {
00402 global $rbacadmin;
00403
00404
00405 $new_ref_id = parent::ilClone($a_parent_ref);
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 return $new_ref_id;
00421 }
00422
00429 function delete()
00430 {
00431
00432 if (!parent::delete())
00433 {
00434 return false;
00435 }
00436
00437
00438 $this->deleteTest();
00439
00440 return true;
00441 }
00442
00450 function deleteTest()
00451 {
00452 $query = sprintf("SELECT active_id FROM tst_active WHERE test_fi = %s",
00453 $this->ilias->db->quote($this->getTestId())
00454 );
00455 $result = $this->ilias->db->query($query);
00456 $active_array = array();
00457 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00458 {
00459 array_push($active_array, $row["active_id"]);
00460 }
00461
00462 $query = sprintf("DELETE FROM tst_active WHERE test_fi = %s",
00463 $this->ilias->db->quote($this->getTestId())
00464 );
00465 $result = $this->ilias->db->query($query);
00466
00467 if (count($active_array))
00468 {
00469 foreach ($active_array as $active_id)
00470 {
00471 $query = sprintf("DELETE FROM tst_times WHERE active_fi = %s",
00472 $this->ilias->db->quote($active_id)
00473 );
00474 $result = $this->ilias->db->query($query);
00475 }
00476 }
00477
00478 $query = sprintf("DELETE FROM tst_mark WHERE test_fi = %s",
00479 $this->ilias->db->quote($this->getTestId())
00480 );
00481 $result = $this->ilias->db->query($query);
00482
00483 $query = sprintf("SELECT question_fi FROM tst_test_question WHERE test_fi = %s",
00484 $this->ilias->db->quote($this->getTestId())
00485 );
00486 $result = $this->ilias->db->query($query);
00487 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00488 {
00489 $this->removeQuestion($row->question_fi);
00490 }
00491
00492 $query = sprintf("DELETE FROM tst_tests WHERE test_id = %s",
00493 $this->ilias->db->quote($this->getTestId())
00494 );
00495 $result = $this->ilias->db->query($query);
00496
00497 $query = sprintf("DELETE FROM tst_test_random WHERE test_fi = %s",
00498 $this->ilias->db->quote($this->getTestId())
00499 );
00500 $result = $this->ilias->db->query($query);
00501
00502 $query = sprintf("DELETE FROM tst_test_random_question WHERE test_fi = %s",
00503 $this->ilias->db->quote($this->getTestId())
00504 );
00505 $result = $this->ilias->db->query($query);
00506
00507 $this->removeAllTestEditings();
00508
00509 $query = sprintf("DELETE FROM tst_test_question WHERE test_fi = %s",
00510 $this->ilias->db->quote($this->getTestId())
00511 );
00512 $result = $this->ilias->db->query($query);
00513
00514
00515 $tst_data_dir = ilUtil::getDataDir()."/tst_data";
00516 $directory = $tst_data_dir."/tst_".$this->getId();
00517 if (is_dir($directory))
00518 {
00519 $directory = escapeshellarg($directory);
00520 exec("rm -rf $directory");
00521 }
00522 }
00523
00533 function initDefaultRoles()
00534 {
00535 global $rbacadmin;
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 return $roles ? $roles : array();
00548 }
00549
00563 function notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params = 0)
00564 {
00565 global $tree;
00566
00567 switch ($a_event)
00568 {
00569 case "link":
00570
00571
00572
00573
00574 break;
00575
00576 case "cut":
00577
00578
00579
00580 break;
00581
00582 case "copy":
00583
00584
00585
00586
00587 break;
00588
00589 case "paste":
00590
00591
00592
00593 break;
00594
00595 case "new":
00596
00597
00598
00599 break;
00600 }
00601
00602
00603 if ($a_node_id==$_GET["ref_id"])
00604 {
00605 $parent_obj =& $this->ilias->obj_factory->getInstanceByRefId($a_node_id);
00606 $parent_type = $parent_obj->getType();
00607 if($parent_type == $this->getType())
00608 {
00609 $a_node_id = (int) $tree->getParentId($a_node_id);
00610 }
00611 }
00612
00613 parent::notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params);
00614 }
00615
00621 function createExportDirectory()
00622 {
00623 $tst_data_dir = ilUtil::getDataDir()."/tst_data";
00624 ilUtil::makeDir($tst_data_dir);
00625 if(!is_writable($tst_data_dir))
00626 {
00627 $this->ilias->raiseError("Test Data Directory (".$tst_data_dir
00628 .") not writeable.",$this->ilias->error_obj->MESSAGE);
00629 }
00630
00631
00632 $tst_dir = $tst_data_dir."/tst_".$this->getId();
00633 ilUtil::makeDir($tst_dir);
00634 if(!@is_dir($tst_dir))
00635 {
00636 $this->ilias->raiseError("Creation of Test Directory failed.",$this->ilias->error_obj->MESSAGE);
00637 }
00638
00639 $export_dir = $tst_dir."/export";
00640 ilUtil::makeDir($export_dir);
00641 if(!@is_dir($export_dir))
00642 {
00643 $this->ilias->raiseError("Creation of Export Directory failed.",$this->ilias->error_obj->MESSAGE);
00644 }
00645 }
00646
00654 function getExportDirectory()
00655 {
00656 $export_dir = ilUtil::getDataDir()."/tst_data"."/tst_".$this->getId()."/export";
00657
00658 return $export_dir;
00659 }
00660
00669 function getExportFiles($dir)
00670 {
00671
00672 if (!@is_dir($dir) or
00673 !is_writeable($dir))
00674 {
00675 return array();
00676 }
00677
00678
00679 $dir = dir($dir);
00680
00681
00682 $file = array();
00683
00684
00685 while ($entry = $dir->read())
00686 {
00687 if ($entry != "." and
00688 $entry != ".." and
00689 substr($entry, -4) == ".zip" and
00690 ereg("^[0-9]{10}_{2}[0-9]+_{2}(test__)*[0-9]+\.zip\$", $entry))
00691 {
00692 $file[] = $entry;
00693 }
00694 }
00695
00696
00697 $dir->close();
00698
00699
00700 sort ($file);
00701 reset ($file);
00702
00703 return $file;
00704 }
00705
00711 function createImportDirectory()
00712 {
00713 $tst_data_dir = ilUtil::getDataDir()."/tst_data";
00714 ilUtil::makeDir($tst_data_dir);
00715
00716 if(!is_writable($tst_data_dir))
00717 {
00718 $this->ilias->raiseError("Test Data Directory (".$tst_data_dir
00719 .") not writeable.",$this->ilias->error_obj->FATAL);
00720 }
00721
00722
00723 $tst_dir = $tst_data_dir."/tst_".$this->getId();
00724 ilUtil::makeDir($tst_dir);
00725 if(!@is_dir($tst_dir))
00726 {
00727 $this->ilias->raiseError("Creation of Test Directory failed.",$this->ilias->error_obj->FATAL);
00728 }
00729
00730
00731 $import_dir = $tst_dir."/import";
00732 ilUtil::makeDir($import_dir);
00733 if(!@is_dir($import_dir))
00734 {
00735 $this->ilias->raiseError("Creation of Import Directory failed.",$this->ilias->error_obj->FATAL);
00736 }
00737 }
00738
00747 function getImportDirectory()
00748 {
00749 $import_dir = ilUtil::getDataDir()."/tst_data".
00750 "/tst_".$this->getId()."/import";
00751 if(@is_dir($import_dir))
00752 {
00753 return $import_dir;
00754 }
00755 else
00756 {
00757 return false;
00758 }
00759 }
00760
00761
00771 function retrieveTestTypes()
00772 {
00773 global $ilDB;
00774
00775 $this->test_types = array();
00776 $query = "SELECT * FROM tst_test_type ORDER BY test_type_id";
00777 $result = $ilDB->query($query);
00778 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00779 {
00780 $this->test_types[$row->test_type_id] = $row->type_tag;
00781 }
00782 }
00783
00793 function testTitleExists($title)
00794 {
00795 $query = sprintf("SELECT * FROM object_data WHERE title = %s AND type = %s",
00796 $this->ilias->db->quote($title),
00797 $this->ilias->db->quote("tst")
00798 );
00799 $result = $this->ilias->db->query($query);
00800 if (strcmp(strtolower(get_class($result)), db_result) == 0) {
00801 if ($result->numRows() == 1) {
00802 return TRUE;
00803 }
00804 }
00805 return FALSE;
00806 }
00807
00815 function duplicate()
00816 {
00817 $clone = $this;
00818 $clone->set_id(-1);
00819 $counter = 2;
00820 while ($this->testTitleExists($this->get_title() . " ($counter)")) {
00821 $counter++;
00822 }
00823 $clone->set_title($this->get_title() . " ($counter)");
00824 $clone->set_owner($this->ilias->account->id);
00825 $clone->setAuthor($this->ilias->account->fullname);
00826 $clone->saveToDb($this->ilias->db);
00827
00828 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi = %s",
00829 $this->ilias->db->quote($this->getId())
00830 );
00831 $result = $this->ilias->db->query($query);
00832 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
00833 $query = sprintf("INSERT INTO tst_test_question (test_question_id, test_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
00834 $this->ilias->db->quote($clone->getId()),
00835 $this->ilias->db->quote($data->question_fi),
00836 $this->ilias->db->quote($data->sequence)
00837 );
00838 $insert_result = $this->ilias->db->query($query);
00839 }
00840 }
00841
00850 function isComplete()
00851 {
00852 if (($this->getTitle()) and ($this->author) and (count($this->mark_schema->mark_steps)) and (count($this->questions)))
00853 {
00854 return true;
00855 }
00856 else
00857 {
00858 if ($this->isRandomTest())
00859 {
00860 $arr = $this->getRandomQuestionpools();
00861 if (count($arr) && ($this->getRandomQuestionCount() > 0))
00862 {
00863 return true;
00864 }
00865 $count = 0;
00866 foreach ($arr as $array)
00867 {
00868 $count += $array["count"];
00869 }
00870 if ($count)
00871 {
00872 return true;
00873 }
00874 }
00875 return false;
00876 }
00877 }
00878
00887 function _isComplete($obj_id)
00888 {
00889 $test = new ilObjTest($obj_id, false);
00890 $test->loadFromDb();
00891 return $test->isComplete();
00892 }
00893
00901 function saveECTSStatus($ects_output = 0, $fx_support = "", $ects_a = 90, $ects_b = 65, $ects_c = 35, $ects_d = 10, $ects_e = 0)
00902 {
00903 global $ilDB;
00904 if ($this->test_id > 0) {
00905 $fx_support = preg_replace("/,/", ".", $fx_support);
00906 if (preg_match("/\d+/", $fx_support))
00907 {
00908 $fx_support = $fx_support;
00909 }
00910 else
00911 {
00912 $fx_support = "NULL";
00913 }
00914 $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",
00915 $ilDB->quote("$ects_output"),
00916 $ilDB->quote($ects_a . ""),
00917 $ilDB->quote($ects_b . ""),
00918 $ilDB->quote($ects_c . ""),
00919 $ilDB->quote($ects_d . ""),
00920 $ilDB->quote($ects_e . ""),
00921 $fx_support,
00922 $this->getTestId()
00923 );
00924 $result = $ilDB->query($query);
00925 $this->ects_output = $ects_output;
00926 $this->ects_fx = $fx_support;
00927 }
00928 }
00929
00937 function saveCompleteStatus()
00938 {
00939 global $ilias;
00940
00941 $db =& $ilias->db;
00942 $complete = 0;
00943 if ($this->isComplete()) {
00944 $complete = 1;
00945 }
00946 if ($this->test_id > 0) {
00947 $query = sprintf("UPDATE tst_tests SET complete = %s WHERE test_id = %s",
00948 $db->quote("$complete"),
00949 $db->quote($this->test_id)
00950 );
00951 $result = $db->query($query);
00952 }
00953 }
00954
00963 function saveToDb($properties_only = FALSE)
00964 {
00965 global $ilias;
00966 $db =& $ilias->db;
00967 $complete = 0;
00968 if ($this->isComplete()) {
00969 $complete = 1;
00970 }
00971 $ects_fx = "NULL";
00972 if (preg_match("/\d+/", $this->ects_fx))
00973 {
00974 $ects_fx = $this->ects_fx;
00975 }
00976 $random_question_count = "NULL";
00977 if ($this->random_question_count > 0)
00978 {
00979 $random_question_count = $this->ilias->db->quote($this->random_question_count . "");
00980 }
00981 if ($this->test_id == -1) {
00982
00983 $now = getdate();
00984 $created = sprintf("%04d%02d%02d%02d%02d%02d", $now['year'], $now['mon'], $now['mday'], $now['hours'], $now['minutes'], $now['seconds']);
00985 $query = sprintf("INSERT INTO tst_tests (test_id, obj_fi, author, test_type_fi, introduction, sequence_settings, score_reporting, nr_of_tries, 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, 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, NULL)",
00986 $db->quote($this->getId() . ""),
00987 $db->quote($this->author . ""),
00988 $db->quote($this->test_type . ""),
00989 $db->quote($this->introduction . ""),
00990 $db->quote($this->sequence_settings . ""),
00991 $db->quote($this->score_reporting . ""),
00992 $db->quote(sprintf("%d", $this->nr_of_tries) . ""),
00993 $db->quote($this->processing_time . ""),
00994 $db->quote("$this->enable_processing_time"),
00995 $db->quote($this->reporting_date . ""),
00996 $db->quote($this->starting_time . ""),
00997 $db->quote($this->ending_time . ""),
00998 $db->quote("$complete"),
00999 $db->quote($this->ects_output . ""),
01000 $db->quote($this->ects_grades["A"] . ""),
01001 $db->quote($this->ects_grades["B"] . ""),
01002 $db->quote($this->ects_grades["C"] . ""),
01003 $db->quote($this->ects_grades["D"] . ""),
01004 $db->quote($this->ects_grades["E"] . ""),
01005 $ects_fx,
01006 $db->quote(sprintf("%d", $this->random_test) . ""),
01007 $random_question_count,
01008 $db->quote($created)
01009 );
01010 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01011 {
01012 $this->logAction($this->lng->txt("log_create_new_test"));
01013 }
01014 $result = $db->query($query);
01015 if ($result == DB_OK) {
01016 $this->test_id = $this->ilias->db->getLastInsertId();
01017 }
01018 } else {
01019
01020 $oldrow = array();
01021 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01022 {
01023 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01024 $db->quote($this->test_id)
01025 );
01026 $result = $db->query($query);
01027 if ($result->numRows() == 1)
01028 {
01029 $oldrow = $result->fetchRow(DB_FETCHMODE_ASSOC);
01030 }
01031 }
01032 $query = sprintf("UPDATE tst_tests SET author = %s, test_type_fi = %s, introduction = %s, sequence_settings = %s, score_reporting = %s, nr_of_tries = %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 WHERE test_id = %s",
01033 $db->quote($this->author . ""),
01034 $db->quote($this->test_type . ""),
01035 $db->quote($this->introduction . ""),
01036 $db->quote($this->sequence_settings . ""),
01037 $db->quote($this->score_reporting . ""),
01038 $db->quote(sprintf("%d", $this->nr_of_tries) . ""),
01039 $db->quote($this->processing_time . ""),
01040 $db->quote("$this->enable_processing_time"),
01041 $db->quote($this->reporting_date . ""),
01042 $db->quote($this->starting_time . ""),
01043 $db->quote($this->ending_time . ""),
01044 $db->quote($this->ects_output . ""),
01045 $db->quote($this->ects_grades["A"] . ""),
01046 $db->quote($this->ects_grades["B"] . ""),
01047 $db->quote($this->ects_grades["C"] . ""),
01048 $db->quote($this->ects_grades["D"] . ""),
01049 $db->quote($this->ects_grades["E"] . ""),
01050 $ects_fx,
01051 $db->quote(sprintf("%d", $this->random_test) . ""),
01052 $db->quote("$complete"),
01053 $db->quote($this->test_id)
01054 );
01055 $result = $db->query($query);
01056 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01057 {
01058 $query = sprintf("SELECT * FROM tst_tests WHERE test_id = %s",
01059 $db->quote($this->test_id)
01060 );
01061 $logresult = $db->query($query);
01062 $newrow = array();
01063 if ($logresult->numRows() == 1)
01064 {
01065 $newrow = $logresult->fetchRow(DB_FETCHMODE_ASSOC);
01066 }
01067 $changed_fields = array();
01068 foreach ($oldrow as $key => $value)
01069 {
01070 if (strcmp($oldrow[$key], $newrow[$key]) != 0)
01071 {
01072 array_push($changed_fields, "$key: " . $oldrow[$key] . " => " . $newrow[$key]);
01073 }
01074 }
01075 $changes = join($changed_fields, ", ");
01076 if (count($changed_fields) == 0)
01077 {
01078 $changes = $this->lng->txt("log_no_test_fields_changed");
01079 }
01080 $this->logAction($this->lng->txt("log_modified_test") . " [".$changes."]");
01081 }
01082 }
01083 if (!$properties_only)
01084 {
01085 if ($result == DB_OK) {
01086 if (!$this->isRandomTest())
01087 {
01088 $this->saveQuestionsToDb();
01089 }
01090 $this->mark_schema->saveToDb($this->test_id);
01091 }
01092 }
01093 }
01094
01103 function saveQuestionsToDb()
01104 {
01105 $oldquestions = array();
01106 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01107 {
01108 $query = sprintf("SELECT question_fi FROM tst_test_question WHERE test_fi = %s ORDER BY sequence",
01109 $this->ilias->db->quote($this->getTestId())
01110 );
01111 $result = $this->ilias->db->query($query);
01112 if ($result->numRows() > 0)
01113 {
01114 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01115 {
01116 array_push($oldquestions, $row["question_fi"]);
01117 }
01118 }
01119 }
01120
01121
01122 $query = sprintf("DELETE FROM tst_test_question WHERE test_fi = %s",
01123 $this->ilias->db->quote($this->getTestId())
01124 );
01125 $result = $this->ilias->db->query($query);
01126
01127 foreach ($this->questions as $key => $value) {
01128 $query = sprintf("INSERT INTO tst_test_question (test_question_id, test_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
01129 $this->ilias->db->quote($this->getTestId() . ""),
01130 $this->ilias->db->quote($value . ""),
01131 $this->ilias->db->quote($key . "")
01132 );
01133 $result = $this->ilias->db->query($query);
01134 }
01135 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01136 {
01137 $query = sprintf("SELECT question_fi FROM tst_test_question WHERE test_fi = %s ORDER BY sequence",
01138 $this->ilias->db->quote($this->getTestId())
01139 );
01140 $result = $this->ilias->db->query($query);
01141 $newquestions = array();
01142 if ($result->numRows() > 0)
01143 {
01144 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01145 {
01146 array_push($newquestions, $row["question_fi"]);
01147 }
01148 }
01149 foreach ($oldquestions as $index => $question_id)
01150 {
01151 if (strcmp($newquestions[$index], $question_id) != 0)
01152 {
01153 $pos = array_search($question_id, $newquestions);
01154 if ($pos === FALSE)
01155 {
01156 $this->logAction($this->lng->txt("log_question_removed"), $question_id);
01157 }
01158 else
01159 {
01160 $this->logAction($this->lng->txt("log_question_position_changed") . ": " . ($index+1) . " => " . ($pos+1), $question_id);
01161 }
01162 }
01163 }
01164 foreach ($newquestions as $index => $question_id)
01165 {
01166 if (array_search($question_id, $oldquestions) === FALSE)
01167 {
01168 $this->logAction($this->lng->txt("log_question_added") . ": " . ($index+1), $question_id);
01169 }
01170 }
01171 }
01172 }
01173
01182 function saveRandomQuestion($question_id)
01183 {
01184 global $ilUser;
01185
01186 $query = sprintf("SELECT test_random_question_id FROM tst_test_random_question WHERE test_fi = %s AND user_fi = %s",
01187 $this->ilias->db->quote($this->getTestId() . ""),
01188 $this->ilias->db->quote($ilUser->id . "")
01189 );
01190 $result = $this->ilias->db->query($query);
01191
01192 $query = sprintf("INSERT INTO tst_test_random_question (test_random_question_id, test_fi, user_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, NULL)",
01193 $this->ilias->db->quote($this->getTestId() . ""),
01194 $this->ilias->db->quote($ilUser->id . ""),
01195 $this->ilias->db->quote($question_id . ""),
01196 $this->ilias->db->quote(($result->numRows()+1) . "")
01197 );
01198 $result = $this->ilias->db->query($query);
01199 }
01200
01209 function saveRandomQuestionCount($total_questions = "NULL")
01210 {
01211 if (strcmp($total_questions, "NULL") != 0)
01212 {
01213 $this->setRandomQuestionCount($total_questions);
01214 $total_questions = $this->ilias->db->quote($total_questions);
01215 }
01216 $query = sprintf("UPDATE tst_tests SET random_question_count = %s WHERE test_id = %s",
01217 $total_questions,
01218 $this->ilias->db->quote($this->getTestId() . "")
01219 );
01220 $result = $this->ilias->db->query($query);
01221 }
01222
01232 function saveRandomQuestionpools($qpl_array)
01233 {
01234
01235 $query = sprintf("DELETE FROM tst_test_random WHERE test_fi = %s",
01236 $this->ilias->db->quote($this->getTestId())
01237 );
01238 $result = $this->ilias->db->query($query);
01239
01240 foreach ($qpl_array as $key => $value) {
01241 if ($value["qpl"] > -1)
01242 {
01243 $count = ilObjQuestionPool::_getQuestionCount($value["qpl"]);
01244 if ($value["count"] > $count)
01245 {
01246 $value["count"] = $count;
01247 }
01248 $query = sprintf("INSERT INTO tst_test_random (test_random_id, test_fi, questionpool_fi, num_of_q, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
01249 $this->ilias->db->quote($this->getTestId() . ""),
01250 $this->ilias->db->quote($value["qpl"] . ""),
01251 $this->ilias->db->quote(sprintf("%d", $value["count"]) . "")
01252 );
01253 $result = $this->ilias->db->query($query);
01254 }
01255 }
01256 }
01257
01267 function &getRandomQuestionpools()
01268 {
01269 $qpls = array();
01270 $counter = 0;
01271 $query = sprintf("SELECT * FROM tst_test_random WHERE test_fi = %s ORDER BY test_random_id",
01272 $this->ilias->db->quote($this->getTestId() . "")
01273 );
01274 $result = $this->ilias->db->query($query);
01275 if ($result->numRows())
01276 {
01277 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01278 {
01279 $qpls[$counter] = array(
01280 "index" => $counter,
01281 "count" => $row["num_of_q"],
01282 "qpl" => $row["questionpool_fi"]
01283 );
01284 $counter++;
01285 }
01286 }
01287 return $qpls;
01288 }
01289
01299 function loadFromDb()
01300 {
01301 $db = $this->ilias->db;
01302
01303 $query = sprintf("SELECT * FROM tst_tests WHERE obj_fi = %s",
01304 $db->quote($this->getId())
01305 );
01306 $result = $db->query($query);
01307 if (strcmp(strtolower(get_class($result)), db_result) == 0)
01308 {
01309 if ($result->numRows() == 1)
01310 {
01311 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
01312 $this->test_id = $data->test_id;
01313 $this->author = $data->author;
01314 $this->test_type = $data->test_type_fi;
01315 $this->introduction = $data->introduction;
01316 $this->sequence_settings = $data->sequence_settings;
01317 $this->score_reporting = $data->score_reporting;
01318 $this->nr_of_tries = $data->nr_of_tries;
01319 $this->processing_time = $data->processing_time;
01320 $this->enable_processing_time = $data->enable_processing_time;
01321 $this->reporting_date = $data->reporting_date;
01322 $this->starting_time = $data->starting_time;
01323 $this->ending_time = $data->ending_time;
01324 $this->ects_output = $data->ects_output;
01325 $this->ects_grades = array(
01326 "A" => $data->ects_a,
01327 "B" => $data->ects_b,
01328 "C" => $data->ects_c,
01329 "D" => $data->ects_d,
01330 "E" => $data->ects_e
01331 );
01332 $this->ects_fx = $data->ects_fx;
01333 $this->random_test = $data->random_test;
01334 $this->random_question_count = $data->random_question_count;
01335 $this->mark_schema->flush();
01336 $this->mark_schema->loadFromDb($this->test_id);
01337 $this->loadQuestions();
01338 }
01339 }
01340 }
01341
01350 function loadQuestions($user_id = "")
01351 {
01352 global $ilUser;
01353
01354 $db = $this->ilias->db;
01355 $this->questions = array();
01356 if (strcmp($user_id, "") == 0)
01357 {
01358 $user_id = $ilUser->id;
01359 }
01360 if ($this->isRandomTest())
01361 {
01362 $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 ORDER BY sequence",
01363 $db->quote($this->test_id . ""),
01364 $db->quote($user_id . "")
01365 );
01366 }
01367 else
01368 {
01369 $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",
01370 $db->quote($this->test_id . "")
01371 );
01372 }
01373 $result = $db->query($query);
01374 $index = 1;
01375 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
01376 $this->questions[$index++] = $data->question_fi;
01377 }
01378 }
01379
01389 function setAuthor($author = "")
01390 {
01391 $this->author = $author;
01392 }
01393
01403 function setIntroduction($introduction = "")
01404 {
01405 $this->introduction = $introduction;
01406 }
01407
01417 function getAuthor()
01418 {
01419 return $this->author;
01420 }
01421
01431 function isRandomTest()
01432 {
01433 return $this->random_test;
01434 }
01435
01445 function getRandomQuestionCount()
01446 {
01447 return $this->random_question_count;
01448 }
01449
01459 function getIntroduction()
01460 {
01461 return $this->introduction;
01462 }
01463
01473 function getTestId()
01474 {
01475 return $this->test_id;
01476 }
01477
01487 function setSequenceSettings($sequence_settings = 0)
01488 {
01489 $this->sequence_settings = $sequence_settings;
01490 }
01491
01501 function setTestType($type = TYPE_ASSESSMENT)
01502 {
01503 $this->test_type = $type;
01504 }
01505
01515 function setScoreReporting($score_reporting = 0)
01516 {
01517 $this->score_reporting = $score_reporting;
01518 }
01519
01529 function setRandomTest($a_random_test = 0)
01530 {
01531 $this->random_test = $a_random_test;
01532 }
01533
01543 function setRandomQuestionCount($a_random_question_count = "")
01544 {
01545 $this->random_question_count = $a_random_question_count;
01546 }
01547
01557 function setReportingDate($reporting_date)
01558 {
01559 if (!$reporting_date)
01560 {
01561 $this->reporting_date = "";
01562 $this->ects_output = 0;
01563 }
01564 else
01565 {
01566 $this->reporting_date = $reporting_date;
01567 $this->score_reporting = REPORT_AFTER_TEST;
01568 }
01569 }
01570
01580 function getSequenceSettings()
01581 {
01582 return $this->sequence_settings;
01583 }
01584
01594 function getScoreReporting()
01595 {
01596 return $this->score_reporting;
01597 }
01598
01608 function getTestType()
01609 {
01610 return $this->test_type;
01611 }
01612
01622 function getReportingDate()
01623 {
01624 return $this->reporting_date;
01625 }
01626
01636 function getNrOfTries()
01637 {
01638 return $this->nr_of_tries;
01639 }
01640
01650 function getProcessingTime()
01651 {
01652 return $this->processing_time;
01653 }
01654
01664 function getProcessingTimeInSeconds()
01665 {
01666 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $this->getProcessingTime(), $matches))
01667 {
01668 return ($matches[1] * 3600) + ($matches[2] * 60) + $matches[3];
01669 }
01670 else
01671 {
01672 return 0;
01673 }
01674 }
01675
01685 function getEnableProcessingTime()
01686 {
01687 return $this->enable_processing_time;
01688 }
01689
01699 function getStartingTime()
01700 {
01701 return $this->starting_time;
01702 }
01703
01713 function getEndingTime()
01714 {
01715 return $this->ending_time;
01716 }
01717
01727 function setNrOfTries($nr_of_tries = 0)
01728 {
01729 $this->nr_of_tries = $nr_of_tries;
01730 }
01731
01741 function setProcessingTime($processing_time = "00:00:00")
01742 {
01743 $this->processing_time = $processing_time;
01744 }
01745
01755 function setEnableProcessingTime($enable = 0)
01756 {
01757 if ($enable) {
01758 $this->enable_processing_time = "1";
01759 } else {
01760 $this->enable_processing_time = "0";
01761 }
01762 }
01763
01773 function setStartingTime($starting_time = "")
01774 {
01775 $this->starting_time = $starting_time;
01776 }
01777
01787 function setEndingTime($ending_time = "")
01788 {
01789 $this->ending_time = $ending_time;
01790 }
01791
01801 function removeQuestion($question_id)
01802 {
01803 $question = new ASS_Question();
01804 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01805 {
01806 $this->logAction($this->lng->txt("log_question_removed"), $question_id);
01807 }
01808 $question->delete($question_id);
01809 $this->removeAllTestEditings($question_id);
01810 $this->loadQuestions();
01811 $this->saveQuestionsToDb();
01812 }
01813
01821 function clearEvalSelectedUsers()
01822 {
01823 $query = sprintf("DELETE FROM tst_eval_users WHERE test_fi = %s",
01824 $this->ilias->db->quote($this->getTestId())
01825 );
01826 $result = $this->ilias->db->query($query);
01827 }
01828
01836 function clearEvalSelectedGroups()
01837 {
01838 $query = sprintf("DELETE FROM tst_eval_groups WHERE test_fi = %s",
01839 $this->ilias->db->quote($this->getTestId())
01840 );
01841 $result = $this->ilias->db->query($query);
01842 }
01843
01855 function removeAllTestEditings($question_id = "")
01856 {
01857
01858 $this->deleteActiveTests();
01859
01860 $this->clearEvalSelectedUsers();
01861 $this->clearEvalSelectedGroups();
01862
01863
01864 if ($question_id) {
01865 $query = sprintf("DELETE FROM tst_solutions WHERE test_fi = %s AND question_fi = %s",
01866 $this->ilias->db->quote($this->getTestId()),
01867 $this->ilias->db->quote($question_id)
01868 );
01869 } else {
01870 $query = sprintf("DELETE FROM tst_solutions WHERE test_fi = %s",
01871 $this->ilias->db->quote($this->getTestId())
01872 );
01873 }
01874 $result = $this->ilias->db->query($query);
01875 if ($this->isRandomTest())
01876 {
01877 $query = sprintf("DELETE FROM tst_test_random_question WHERE test_fi = %s",
01878 $this->ilias->db->quote($this->getTestId())
01879 );
01880 $result = $this->ilias->db->query($query);
01881 }
01882 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01883 {
01884 $this->logAction($this->lng->txt("log_user_data_removed"));
01885 }
01886 }
01887
01896 function deleteActiveTests()
01897 {
01898 $query = sprintf("DELETE FROM tst_active WHERE test_fi = %s",
01899 $this->ilias->db->quote($this->getTestId())
01900 );
01901 $result = $this->ilias->db->query($query);
01902 }
01903
01914 function deleteResults($user_id = "",$a_delete_active = false)
01915 {
01916 if ($user_id) {
01917 $query = sprintf("DELETE FROM tst_solutions WHERE test_fi = %s AND user_fi = %s",
01918 $this->ilias->db->quote($this->getTestId()),
01919 $this->ilias->db->quote($user_id)
01920 );
01921 $result = $this->ilias->db->query($query);
01922 $sequence_arr = array_flip($this->questions);
01923 $sequence = join($sequence_arr, ",");
01924 $query = sprintf("UPDATE tst_active SET sequence = %s, lastindex = %s WHERE test_fi = %s and user_fi = %s",
01925 $this->ilias->db->quote($sequence),
01926 $this->ilias->db->quote("1"),
01927 $this->ilias->db->quote($this->getTestId()),
01928 $this->ilias->db->quote($user_id)
01929 );
01930 $result = $this->ilias->db->query($query);
01931
01932 if($a_delete_active)
01933 {
01934 $query = "DELETE FROM tst_active ".
01935 "WHERE user_fi = '".$user_id."' ".
01936 "AND test_fi = '".$this->getTestId()."'";
01937
01938 $this->ilias->db->query($query);
01939 }
01940 }
01941 }
01942
01952 function questionMoveUp($question_id)
01953 {
01954
01955 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND question_fi=%s",
01956 $this->ilias->db->quote($this->getTestId()),
01957 $this->ilias->db->quote($question_id)
01958 );
01959 $result = $this->ilias->db->query($query);
01960 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
01961 if ($data->sequence > 1) {
01962
01963 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND sequence=%s",
01964 $this->ilias->db->quote($this->getTestId()),
01965 $this->ilias->db->quote($data->sequence - 1)
01966 );
01967 $result = $this->ilias->db->query($query);
01968 $data_previous = $result->fetchRow(DB_FETCHMODE_OBJECT);
01969
01970 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
01971 $this->ilias->db->quote($data->sequence),
01972 $this->ilias->db->quote($data_previous->test_question_id)
01973 );
01974 $result = $this->ilias->db->query($query);
01975
01976 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
01977 $this->ilias->db->quote($data->sequence - 1),
01978 $this->ilias->db->quote($data->test_question_id)
01979 );
01980 $result = $this->ilias->db->query($query);
01981 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
01982 {
01983 $this->logAction($this->lng->txt("log_question_position_changed") . ": " . ($data->sequence) . " => " . ($data->sequence-1), $question_id);
01984 }
01985 }
01986 $this->loadQuestions();
01987 }
01988
01998 function questionMoveDown($question_id)
01999 {
02000
02001 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND question_fi=%s",
02002 $this->ilias->db->quote($this->getTestId()),
02003 $this->ilias->db->quote($question_id)
02004 );
02005 $result = $this->ilias->db->query($query);
02006 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
02007 $query = sprintf("SELECT * FROM tst_test_question WHERE test_fi=%s AND sequence=%s",
02008 $this->ilias->db->quote($this->getTestId()),
02009 $this->ilias->db->quote($data->sequence + 1)
02010 );
02011 $result = $this->ilias->db->query($query);
02012 if ($result->numRows() == 1)
02013 {
02014
02015 $data_next = $result->fetchRow(DB_FETCHMODE_OBJECT);
02016
02017 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
02018 $this->ilias->db->quote($data->sequence),
02019 $this->ilias->db->quote($data_next->test_question_id)
02020 );
02021 $result = $this->ilias->db->query($query);
02022
02023 $query = sprintf("UPDATE tst_test_question SET sequence=%s WHERE test_question_id=%s",
02024 $this->ilias->db->quote($data->sequence + 1),
02025 $this->ilias->db->quote($data->test_question_id)
02026 );
02027 $result = $this->ilias->db->query($query);
02028 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02029 {
02030 $this->logAction($this->lng->txt("log_question_position_changed") . ": " . ($data->sequence) . " => " . ($data->sequence+1), $question_id);
02031 }
02032 }
02033 $this->loadQuestions();
02034 }
02035
02045 function duplicateQuestionForTest($question_id)
02046 {
02047 global $ilUser;
02048
02049 $question =& ilObjTest::_instanciateQuestion($question_id);
02050 $duplicate_id = $question->duplicate(true);
02051
02052 return $duplicate_id;
02053 }
02054
02063 function insertQuestion($question_id)
02064 {
02065 $duplicate_id = $this->duplicateQuestionForTest($question_id);
02066
02067
02068 $query = sprintf("SELECT MAX(sequence) AS seq FROM tst_test_question WHERE test_fi=%s",
02069 $this->ilias->db->quote($this->getTestId())
02070 );
02071 $result = $this->ilias->db->query($query);
02072 $sequence = 1;
02073
02074 if ($result->numRows() == 1)
02075 {
02076 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
02077 $sequence = $data->seq + 1;
02078 }
02079
02080 $query = sprintf("INSERT INTO tst_test_question (test_question_id, test_fi, question_fi, sequence, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
02081 $this->ilias->db->quote($this->getTestId()),
02082 $this->ilias->db->quote($duplicate_id),
02083 $this->ilias->db->quote($sequence)
02084 );
02085 $result = $this->ilias->db->query($query);
02086 if ($result != DB_OK)
02087 {
02088
02089 }
02090 else
02091 {
02092 if (ilObjAssessmentFolder::_enabledAssessmentLogging())
02093 {
02094 $this->logAction($this->lng->txt("log_question_added") . ": " . $sequence, $duplicate_id);
02095 }
02096 }
02097
02098 $query = sprintf("DELETE FROM tst_active WHERE test_fi = %s",
02099 $this->ilias->db->quote($this->getTestId())
02100 );
02101 $result = $this->ilias->db->query($query);
02102 $this->loadQuestions();
02103 $this->saveCompleteStatus();
02104 }
02105
02115 function &getQuestionTitles()
02116 {
02117 $titles = array();
02118 if (!$this->isRandomTest())
02119 {
02120 global $ilDB;
02121 $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",
02122 $ilDB->quote($this->getTestId() . "")
02123 );
02124 $result = $ilDB->query($query);
02125 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02126 {
02127 array_push($titles, $row["title"]);
02128 }
02129 }
02130 return $titles;
02131 }
02132
02142 function getQuestionTitle($sequence)
02143 {
02144 global $ilUser;
02145 if ($ilUser->id > 0)
02146 {
02147 $active = $this->getActiveTestUser($ilUser->id);
02148 $seq = split(",", $active->sequence);
02149 $query = sprintf("SELECT title from qpl_questions WHERE question_id = %s",
02150 $this->ilias->db->quote($this->questions[$seq[$sequence-1]])
02151 );
02152 }
02153 else
02154 {
02155 $query = sprintf("SELECT title from qpl_questions WHERE question_id = %s",
02156 $this->ilias->db->quote($this->questions[$sequence])
02157 );
02158 }
02159 $result = $this->ilias->db->query($query);
02160 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
02161 return $row->title;
02162 }
02163
02174 function getQuestionDataset($question_id)
02175 {
02176 $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",
02177 $this->ilias->db->quote("$question_id")
02178 );
02179 $result = $this->ilias->db->query($query);
02180 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
02181 return $row;
02182 }
02183
02192 function &get_qpl_titles()
02193 {
02194 global $rbacsystem;
02195
02196 $qpl_titles = array();
02197
02198 $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";
02199 $result = $this->ilias->db->query($query);
02200 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
02201 {
02202 if ($rbacsystem->checkAccess("write", $row->ref_id) && ($this->_hasUntrashedReference($row->obj_id)))
02203 {
02204 $qpl_titles["$row->obj_id"] = $row->title;
02205 }
02206 }
02207 return $qpl_titles;
02208 }
02209
02218 function &getExistingQuestions()
02219 {
02220 global $ilUser;
02221 $existing_questions = array();
02222 if ($this->isRandomTest())
02223 {
02224 $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",
02225 $this->ilias->db->quote($this->getTestId() . ""),
02226 $this->ilias->db->quote($ilUser->id . "")
02227 );
02228 }
02229 else
02230 {
02231 $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",
02232 $this->ilias->db->quote($this->getTestId())
02233 );
02234 }
02235 $result = $this->ilias->db->query($query);
02236 while ($data = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
02237 array_push($existing_questions, $data->original_id);
02238 }
02239 return $existing_questions;
02240 }
02241
02251 function getQuestionType($question_id)
02252 {
02253 if ($question_id < 1)
02254 return -1;
02255 $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",
02256 $this->ilias->db->quote($question_id)
02257 );
02258 $result = $this->ilias->db->query($query);
02259 if ($result->numRows() == 1) {
02260 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
02261 return $data->type_tag;
02262 } else {
02263 return "";
02264 }
02265 }
02266
02275 function startWorkingTime ($user_id)
02276 {
02277 $result = "";
02278 if (!($result = $this->getActiveTestUser($user_id))) {
02279 $this->setActiveTestUser();
02280 $result = $this->getActiveTestUser($user_id);
02281 }
02282 $q = sprintf("INSERT INTO tst_times (times_id, active_fi, started, finished, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
02283 $this->ilias->db->quote($result->active_id),
02284 $this->ilias->db->quote(strftime("%Y-%m-%d %H:%M:%S")),
02285 $this->ilias->db->quote(strftime("%Y-%m-%d %H:%M:%S"))
02286 );
02287 $result = $this->ilias->db->query($q);
02288 return $this->ilias->db->getLastInsertId();
02289 }
02290
02299 function updateWorkingTime($times_id)
02300 {
02301 $q = sprintf("UPDATE tst_times SET finished = %s WHERE times_id = %s",
02302 $this->ilias->db->quote(strftime("%Y-%m-%d %H:%M:%S")),
02303 $this->ilias->db->quote($times_id)
02304 );
02305 $result = $this->ilias->db->query($q);
02306 }
02307
02317 function getQuestionIdFromActiveUserSequence($sequence)
02318 {
02319 global $ilUser;
02320
02321 $active = $this->getActiveTestUser();
02322 $sequence_array = split(",", $active->sequence);
02323
02324 return $this->questions[$sequence_array[$sequence-1]];
02325 }
02326
02335 function &getAllQuestionsForActiveUser()
02336 {
02337 $result_array = array();
02338 $active = $this->getActiveTestUser();
02339 $sequence_array = split(",", $active->sequence);
02340 $all_questions = &$this->getAllQuestions();
02341 $worked_questions = &$this->getWorkedQuestions();
02342 foreach ($sequence_array as $sequence)
02343 {
02344 if (in_array($this->questions[$sequence], $worked_questions))
02345 {
02346 $all_questions[$this->questions[$sequence]]["worked"] = 1;
02347 }
02348 else
02349 {
02350 $all_questions[$this->questions[$sequence]]["worked"] = 0;
02351 }
02352 array_push($result_array, $all_questions[$this->questions[$sequence]]);
02353 }
02354 return $result_array;
02355 }
02356
02357 function getWrongAnsweredQuestions()
02358 {
02359 global $ilUser;
02360
02361 foreach($all_questions =& $this->getAllQuestionsForActiveUser() as $question)
02362 {
02363 foreach($this->getTestResult($ilUser->getId()) as $result)
02364 {
02365 if($result['qid'] == $question['question_id'])
02366 {
02367 if($result['max'] != $result['reached'])
02368 {
02369 $wrong[] = $question;
02370 }
02371 }
02372 }
02373 }
02374 return $wrong ? $wrong : array();
02375 }
02383 function incrementSequenceByResult($a_sequence)
02384 {
02385 global $ilUser;
02386
02387 for($i = $a_sequence+1; $i <= $this->getQuestionCount(); $i++)
02388 {
02389 $qid = $this->getQuestionIdFromActiveUserSequence($i);
02390
02391 foreach($this->getTestResult($ilUser->getId()) as $result)
02392 {
02393 if($qid == $result['qid'])
02394 {
02395 if($result['max'] != $result['reached'])
02396 {
02397 return $i;
02398 }
02399 }
02400 }
02401 }
02402 return ($this->getQuestionCount()+1);
02403 }
02404
02405
02413 function decrementSequenceByResult($a_sequence)
02414 {
02415 for($i = $a_sequence; $i > 0; $i--)
02416 {
02417 $qid = $this->getQuestionIdFromActiveUserSequence($i);
02418
02419 foreach($this->getTestResult($ilUser->getId()) as $result)
02420 {
02421 if($qid == $result['qid'])
02422 {
02423 if($result['max'] != $result['reached'])
02424 {
02425 return $i;
02426 }
02427 }
02428 }
02429 }
02430 return 1;
02431 }
02432
02433 function getFirstSequence()
02434 {
02435 global $ilUser;
02436
02437 $results = $this->getTestResult($ilUser->getId());
02438
02439 for($i = 1; $i <= $this->getQuestionCount(); $i++)
02440 {
02441 $qid = $this->getQuestionIdFromActiveUserSequence($i);
02442
02443 foreach($results as $result)
02444 {
02445 if($qid == $result['qid'])
02446 {
02447 if(!$result['max'] or $result['max'] != $result['reached'])
02448 {
02449 return $i;
02450 }
02451 }
02452 }
02453 }
02454 return 0;
02455 }
02456
02457
02466 function &getWorkedQuestions()
02467 {
02468 global $ilUser;
02469 $query = sprintf("SELECT * FROM tst_solutions WHERE user_fi = %s AND test_fi = %s GROUP BY question_fi",
02470 $this->ilias->db->quote($ilUser->id),
02471 $this->ilias->db->quote($this->getTestId())
02472 );
02473 $result = $this->ilias->db->query($query);
02474 $result_array = array();
02475 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
02476 {
02477 array_push($result_array, $row->question_fi);
02478 }
02479 return $result_array;
02480 }
02481
02490 function &getAllQuestions()
02491 {
02492 global $ilUser;
02493
02494 if ($this->isRandomTest())
02495 {
02496 $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 qpl_questions.question_id IN (" . join($this->questions, ",") . ")",
02497 $this->ilias->db->quote($ilUser->id . "")
02498 );
02499 }
02500 else
02501 {
02502 $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, ",") . ")";
02503 }
02504 $result = $this->ilias->db->query($query);
02505 $result_array = array();
02506 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
02507 {
02508 $result_array[$row["question_id"]] = $row;
02509 }
02510 return $result_array;
02511 }
02512
02522 function getActiveTestUser($user_id = "")
02523 {
02524 global $ilDB;
02525 global $ilUser;
02526
02527 $db =& $ilDB->db;
02528 if (!$user_id) {
02529 $user_id = $ilUser->id;
02530 }
02531 $query = sprintf("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
02532 $db->quote($user_id),
02533 $db->quote($this->test_id)
02534 );
02535
02536 $result = $db->query($query);
02537 if ($result->numRows()) {
02538 return $result->fetchRow(DB_FETCHMODE_OBJECT);
02539 } else {
02540 return "";
02541 }
02542 }
02543
02554 function _getActiveTestUser($user_id = "", $test_id = "") {
02555 global $ilDB;
02556 global $ilUser;
02557
02558 $db =& $ilDB->db;
02559 if (!$user_id) {
02560 $user_id = $ilUser->id;
02561 }
02562 if (!$test_id)
02563 {
02564 return "";
02565 }
02566 $query = sprintf("SELECT * FROM tst_active WHERE user_fi = %s AND test_fi = %s",
02567 $db->quote($user_id),
02568 $db->quote($test_id)
02569 );
02570
02571 $result = $db->query($query);
02572 if ($result->numRows()) {
02573 return $result->fetchRow(DB_FETCHMODE_OBJECT);
02574 } else {
02575 return "";
02576 }
02577 }
02578
02591 function setActiveTestUser($lastindex = 1, $postpone = "", $addTries = false)
02592 {
02593 global $ilDB;
02594 global $ilUser;
02595
02596 $db =& $ilDB->db;
02597 $old_active = $this->getActiveTestUser();
02598 if ($old_active) {
02599 $sequence = $old_active->sequence;
02600 $postponed = $old_active->postponed;
02601 if ($postpone) {
02602 $sequence_array = split(",", $sequence);
02603 $postpone_sequence = $sequence_array[$postpone-1];
02604 $question_id = $this->questions[$postpone_sequence];
02605 unset($sequence_array[$postpone-1]);
02606 array_push($sequence_array, $postpone_sequence);
02607 $sequence = join(",", $sequence_array);
02608 $postponed .= ",$question_id";
02609 $postponed = preg_replace("/^,/", "", $postponed);
02610 }
02611 $tries = $old_active->tries;
02612 if ($addTries) {
02613 $tries++;
02614 }
02615 $query = sprintf("UPDATE tst_active SET lastindex = %s, sequence = %s, postponed = %s, tries = %s WHERE user_fi = %s AND test_fi = %s",
02616 $db->quote($lastindex),
02617 $db->quote($sequence),
02618 $db->quote($postponed),
02619 $db->quote($tries),
02620 $db->quote($ilUser->id),
02621 $db->quote($this->test_id)
02622 );
02623 } else {
02624 $sequence_arr = array_flip($this->questions);
02625 $sequence = join($sequence_arr, ",");
02626 $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)",
02627 $db->quote($ilUser->id),
02628 $db->quote($this->test_id),
02629 $db->quote($sequence),
02630 $db->quote(""),
02631 $db->quote($lastindex),
02632 $db->quote(0)
02633 );
02634 }
02635 $db->query($query);
02636 }
02637
02647 function &getTestResult($user_id)
02648 {
02649
02650 if ($this->isRandomTest())
02651 {
02652 $this->loadQuestions($user_id);
02653 }
02654 $add_parameter = "?ref_id=$this->ref_id&cmd=run";
02655 $total_max_points = 0;
02656 $total_reached_points = 0;
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667 $key = 1;
02668 $result_array = array();
02669 foreach ($this->questions as $value)
02670 {
02671
02672
02673 $question =& ilObjTest::_instanciateQuestion($value);
02674
02675 if (is_object($question))
02676 {
02677 $max_points = $question->getMaximumPoints();
02678 $total_max_points += $max_points;
02679 $reached_points = $question->getReachedPoints($user_id, $this->getTestId());
02680 $total_reached_points += $reached_points;
02681 if ($max_points > 0)
02682 {
02683 $percentvalue = $reached_points / $max_points;
02684 }
02685 else
02686 {
02687 $percentvalue = 0;
02688 }
02689 if (count($question->suggested_solutions) == 1)
02690 {
02691 $solution_array = $question->getSuggestedSolution(0);
02692 $href = ASS_Question::_getInternalLinkHref($solution_array["internal_link"]);
02693 }
02694 elseif (count($question->suggested_solutions) > 1)
02695 {
02696 $href = "see_details_for_further_information";
02697 }
02698 else
02699 {
02700 $href = "";
02701 }
02702 $row = array(
02703 "nr" => "$key",
02704 "title" => "<a href=\"" . $this->getCallingScript() . "$add_parameter&evaluation=" . $question->getId() . "\">" . $question->getTitle() . "</a>",
02705 "max" => sprintf("%d", $max_points),
02706 "reached" => sprintf("%d", $reached_points),
02707 "percent" => sprintf("%2.2f ", ($percentvalue) * 100) . "%",
02708 "solution" => $href,
02709 "type" => $question->getQuestionType(),
02710 "qid" => $question->getId()
02711 );
02712 array_push($result_array, $row);
02713 $key++;
02714 }
02715 }
02716 $result_array["test"]["total_max_points"] = $total_max_points;
02717 $result_array["test"]["total_reached_points"] = $total_reached_points;
02718 if ((!$total_reached_points) or (!$total_max_points))
02719 {
02720 $percentage = 0.0;
02721 }
02722 else
02723 {
02724 $percentage = ($total_reached_points / $total_max_points) * 100.0;
02725 }
02726 $mark_obj = $this->mark_schema->get_matching_mark($percentage);
02727 $passed = "";
02728 if ($mark_obj)
02729 {
02730 if ($mark_obj->get_passed())
02731 {
02732 $passed = 1;
02733 }
02734 else
02735 {
02736 $passed = 0;
02737 }
02738 }
02739 $result_array["test"]["passed"] = $passed;
02740 return $result_array;
02741 }
02742
02752 function &_getTestResult($user_id, $test_obj_id)
02753 {
02754 $test = new ilObjTest($test_obj_id, false);
02755 $test->loadFromDb();
02756 $result =& $test->getTestResult($user_id);
02757 return $result;
02758 }
02759
02772 function _checkCondition($a_exc_id,$a_operator,$a_value)
02773 {
02774 global $ilias;
02775
02776 switch($a_operator)
02777 {
02778 case 'passed':
02779 $result = ilObjTest::_getTestResult($ilias->account->getId(), $a_exc_id);
02780 if ($result["test"]["passed"])
02781 {
02782 return true;
02783 }
02784 else
02785 {
02786 return false;
02787 }
02788 break;
02789
02790 case 'finished':
02791 return ilObjTest::_hasFinished($ilias->account->getId(),$a_exc_id);
02792 case 'not_finished':
02793 return !ilObjTest::_hasFinished($ilias->account->getId(),$a_exc_id);
02794 default:
02795 return true;
02796 }
02797 return true;
02798 }
02799
02809 function _hasFinished($a_user_id,$a_test_id)
02810 {
02811 global $ilDB;
02812
02813 $tmp_test =& new ilObjTest($a_test_id,false);
02814
02815 $query = "SELECT * FROM tst_active ".
02816 "WHERE user_fi = '".$a_user_id."' ".
02817 "AND test_fi = '".$tmp_test->getTestId()."' ".
02818 "AND tries > '0'";
02819 $res = $ilDB->query($query);
02820
02821 return $res->numRows() ? true : false;
02822 }
02823
02834 function &_getMark($user_id, $test_obj_id)
02835 {
02836 $test = new ilObjTest($test_obj_id, false);
02837 $test->loadFromDb();
02838 $result =& $test->getTestResult($user_id);
02839 if ($result["test"]["total_max_points"] == 0)
02840 {
02841 $pct = 0;
02842 }
02843 else
02844 {
02845 $pct = ($result["test"]["total_reached_points"] / $result["test"]["total_max_points"]) * 100.0;
02846 }
02847 $mark = $test->mark_schema->get_matching_mark($pct);
02848 return $mark;
02849 }
02850
02856 function assignMetaData(&$a_meta_data)
02857 {
02858 $this->meta_data =& $a_meta_data;
02859 }
02860
02866 function &getMetaData()
02867 {
02868 return $this->meta_data;
02869 }
02870
02874 function initMeta()
02875 {
02876 if (!is_object($this->meta_data))
02877 {
02878 if ($this->getId())
02879 {
02880 $new_meta =& new ilMetaData($this->getType(), $this->getId());
02881 }
02882 else
02883 {
02884 $new_meta =& new ilMetaData();
02885 }
02886 $this->assignMetaData($new_meta);
02887 }
02888 }
02889
02898 function evalTotalPersons()
02899 {
02900 $q = sprintf("SELECT COUNT(*) as total FROM tst_active WHERE test_fi = %s",
02901 $this->ilias->db->quote($this->getTestId())
02902 );
02903 $result = $this->ilias->db->query($q);
02904 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
02905 return $row->total;
02906 }
02907
02916 function canViewResults()
02917 {
02918 $result = true;
02919 if ($this->getTestType() == TYPE_ASSESSMENT)
02920 {
02921 if ($this->getReportingDate())
02922 {
02923 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getReportingDate(), $matches);
02924 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
02925 $now = mktime();
02926 if ($now < $epoch_time)
02927 {
02928 $result = false;
02929 }
02930 }
02931 }
02932 return $result;
02933 }
02934
02943 function evalLoadStatisticalSettings($user_id)
02944 {
02945 $q = sprintf("SELECT * FROM tst_eval_settings WHERE user_fi = %s",
02946 $this->ilias->db->quote("$user_id")
02947 );
02948 $result = $this->ilias->db->query($q);
02949 if (!$result->numRows())
02950 {
02951 $row = array(
02952 "qworkedthrough" => "1",
02953 "pworkedthrough" => "1",
02954 "timeofwork" => "1",
02955 "atimeofwork" => "1",
02956 "firstvisit" => "1",
02957 "lastvisit" => "1",
02958 "resultspoints" => "1",
02959 "resultsmarks" => "1",
02960 "distancemedian" => "1"
02961 );
02962 }
02963 else
02964 {
02965 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02966 unset($row["eval_settings_id"]);
02967 }
02968 return $row;
02969 }
02970
02979 function evalSaveStatisticalSettings($settings_array, $user_id)
02980 {
02981 $q = sprintf("SELECT * FROM tst_eval_settings WHERE user_fi = %s",
02982 $this->ilias->db->quote("$user_id")
02983 );
02984 $result = $this->ilias->db->query($q);
02985 if ($result->numRows() > 0)
02986 {
02987 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
02988 }
02989 $update = $row["eval_settings_id"];
02990 if (!$update) {
02991 $q = sprintf("INSERT INTO tst_eval_settings ".
02992 "(eval_settings_id, user_fi, qworkedthrough, pworkedthrough, timeofwork, atimeofwork, firstvisit, " .
02993 "lastvisit, resultspoints, resultsmarks, distancemedian, TIMESTAMP) VALUES " .
02994 "(NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NULL)",
02995 $this->ilias->db->quote("$user_id"),
02996 $this->ilias->db->quote(sprintf("%01d", $settings_array["qworkedthrough"])),
02997 $this->ilias->db->quote(sprintf("%01d", $settings_array["pworkedthrough"])),
02998 $this->ilias->db->quote(sprintf("%01d", $settings_array["timeofwork"])),
02999 $this->ilias->db->quote(sprintf("%01d", $settings_array["atimeofwork"])),
03000 $this->ilias->db->quote(sprintf("%01d", $settings_array["firstvisit"])),
03001 $this->ilias->db->quote(sprintf("%01d", $settings_array["lastvisit"])),
03002 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultspoints"])),
03003 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultsmarks"])),
03004 $this->ilias->db->quote(sprintf("%01d", $settings_array["distancemedian"]))
03005 );
03006 }
03007 else
03008 {
03009 $q = sprintf("UPDATE tst_eval_settings SET ".
03010 "qworkedthrough = %s, pworkedthrough = %s, timeofwork = %s, atimeofwork = %s, firstvisit = %s, " .
03011 "lastvisit = %s, resultspoints = %s, resultsmarks = %s, distancemedian = %s " .
03012 "WHERE eval_settings_id = %s",
03013 $this->ilias->db->quote(sprintf("%01d", $settings_array["qworkedthrough"])),
03014 $this->ilias->db->quote(sprintf("%01d", $settings_array["pworkedthrough"])),
03015 $this->ilias->db->quote(sprintf("%01d", $settings_array["timeofwork"])),
03016 $this->ilias->db->quote(sprintf("%01d", $settings_array["atimeofwork"])),
03017 $this->ilias->db->quote(sprintf("%01d", $settings_array["firstvisit"])),
03018 $this->ilias->db->quote(sprintf("%01d", $settings_array["lastvisit"])),
03019 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultspoints"])),
03020 $this->ilias->db->quote(sprintf("%01d", $settings_array["resultsmarks"])),
03021 $this->ilias->db->quote(sprintf("%01d", $settings_array["distancemedian"])),
03022 $this->ilias->db->quote("$update")
03023 );
03024 }
03025 $result = $this->ilias->db->query($q);
03026 }
03027
03036 function getCompleteWorkingTime($user_id)
03037 {
03038 $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",
03039 $this->ilias->db->quote($this->getTestId()),
03040 $this->ilias->db->quote($user_id)
03041 );
03042 $result = $this->ilias->db->query($q);
03043 $time = 0;
03044 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03045 {
03046 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03047 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03048 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03049 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03050 $time += ($epoch_2 - $epoch_1);
03051 }
03052 return $time;
03053 }
03054
03063 function &evalStatistical($user_id)
03064 {
03065
03066
03067 $test_result =& $this->getTestResult($user_id);
03068 $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",
03069 $this->ilias->db->quote($this->getTestId()),
03070 $this->ilias->db->quote($user_id)
03071 );
03072 $result = $this->ilias->db->query($q);
03073 $times = array();
03074 $first_visit = "";
03075 $last_visit = "";
03076 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
03077 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03078 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03079 if (!$first_visit) {
03080 $first_visit = $epoch_1;
03081 }
03082 if ($epoch_1 < $first_visit) {
03083 $first_visit = $epoch_1;
03084 }
03085 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03086 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03087 if (!$last_visit) {
03088 $last_visit = $epoch_2;
03089 }
03090 if ($epoch_2 > $last_visit) {
03091 $last_visit = $epoch_2;
03092 }
03093 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
03094 }
03095 $max_time = 0;
03096 foreach ($times as $key => $value) {
03097 $max_time += $value;
03098 }
03099 if ((!$test_result["test"]["total_reached_points"]) or (!$test_result["test"]["total_max_points"])) {
03100 $percentage = 0.0;
03101 } else {
03102 $percentage = ($test_result["test"]["total_reached_points"] / $test_result["test"]["total_max_points"]) * 100.0;
03103 }
03104 $mark_obj = $this->mark_schema->get_matching_mark($percentage);
03105 $first_date = getdate($first_visit);
03106 $last_date = getdate($last_visit);
03107 $qworkedthrough = 0;
03108 $query_worked_through = sprintf("SELECT DISTINCT(question_fi) FROM tst_solutions WHERE user_fi = %s AND test_fi = %s",
03109 $this->ilias->db->quote("$user_id"),
03110 $this->ilias->db->quote($this->getTestId())
03111 );
03112 $worked_through_result = $this->ilias->db->query($query_worked_through);
03113 if (!$worked_through_result->numRows())
03114 {
03115 $atimeofwork = 0;
03116 }
03117 else
03118 {
03119 $atimeofwork = $max_time / $worked_through_result->numRows();
03120 }
03121 $result_mark = "";
03122 $passed = "";
03123 if ($mark_obj)
03124 {
03125 $result_mark = $mark_obj->get_short_name();
03126 if ($mark_obj->get_passed())
03127 {
03128 $passed = 1;
03129 }
03130 else
03131 {
03132 $passed = 0;
03133 }
03134 }
03135 $result_array = array(
03136 "qworkedthrough" => $worked_through_result->numRows(),
03137 "qmax" => count($this->questions),
03138 "pworkedthrough" => ($worked_through_result->numRows()) / count($this->questions),
03139 "timeofwork" => $max_time,
03140 "atimeofwork" => $atimeofwork,
03141 "firstvisit" => $first_date,
03142 "lastvisit" => $last_date,
03143 "resultspoints" => $test_result["test"]["total_reached_points"],
03144 "maxpoints" => $test_result["test"]["total_max_points"],
03145 "resultsmarks" => $result_mark,
03146 "passed" => $passed,
03147 "distancemedian" => "0"
03148 );
03149 foreach ($test_result as $key => $value)
03150 {
03151 if (preg_match("/\d+/", $key))
03152 {
03153 $result_array[$key] = $value;
03154 }
03155 }
03156 return $result_array;
03157 }
03158
03168 function &getTotalPointsArray()
03169 {
03170 $totalpoints_array = array();
03171 $all_users =& $this->evalTotalPersonsArray();
03172 foreach ($all_users as $user_id => $user_name)
03173 {
03174 $test_result =& $this->getTestResult($user_id);
03175 array_push($totalpoints_array, $test_result["test"]["total_reached_points"]);
03176 }
03177 return $totalpoints_array;
03178 }
03179
03189 function &getTotalPointsPassedArray()
03190 {
03191 $totalpoints_array = array();
03192 $all_users =& $this->evalTotalPersonsArray();
03193 foreach ($all_users as $user_id => $user_name)
03194 {
03195 $test_result =& $this->getTestResult($user_id);
03196 $reached = $test_result["test"]["total_reached_points"];
03197 $total = $test_result["test"]["total_max_points"];
03198 $percentage = $reached/$total;
03199 $mark = $this->mark_schema->get_matching_mark($percentage*100.0);
03200 if ($mark)
03201 {
03202 if ($mark->get_passed())
03203 {
03204 array_push($totalpoints_array, $test_result["test"]["total_reached_points"]);
03205 }
03206 }
03207 }
03208 return $totalpoints_array;
03209 }
03210
03219 function &evalTotalPersonsArray()
03220 {
03221 $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",
03222 $this->ilias->db->quote($this->getTestId())
03223 );
03224 $result = $this->ilias->db->query($q);
03225 $persons_array = array();
03226 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03227 {
03228 if (strlen($row->firstname.$row->lastname.$row->title) == 0)
03229 {
03230 $persons_array[$row->user_fi] = $this->lng->txt("deleted_user");
03231 }
03232 else
03233 {
03234 $persons_array[$row->user_fi] = trim("$row->lastname, $row->firstname $row->title");
03235 }
03236 }
03237 return $persons_array;
03238 }
03239
03248 function evalTotalFinished()
03249 {
03250 $q = sprintf("SELECT COUNT(*) as total FROM tst_active WHERE test_fi = %s AND tries > 0",
03251 $this->ilias->db->quote($this->getTestId())
03252 );
03253 $result = $this->ilias->db->query($q);
03254 $row = $result->fetchRow(DB_FETCHMODE_OBJECT);
03255 return $row->total;
03256 }
03257
03267 function evalTotalFinishedPassed()
03268 {
03269 $q = sprintf("SELECT * FROM tst_active WHERE test_fi = %s AND tries > 0",
03270 $this->ilias->db->quote($this->getTestId())
03271 );
03272 $result = $this->ilias->db->query($q);
03273 $points = array();
03274 $passed_tests = 0;
03275 $failed_tests = 0;
03276 $maximum_points = 0;
03277 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03278 {
03279 $res =& $this->getTestResult($row->user_fi);
03280 if ((!$res["test"]["total_reached_points"]) or (!$res["test"]["total_max_points"]))
03281 {
03282 $percentage = 0.0;
03283 }
03284 else
03285 {
03286 $percentage = ($res["test"]["total_reached_points"] / $res["test"]["total_max_points"]) * 100.0;
03287 }
03288 $mark_obj = $this->mark_schema->get_matching_mark($percentage);
03289 $maximum_points = $res["test"]["total_max_points"];
03290 if ($mark_obj)
03291 {
03292 if ($mark_obj->get_passed()) {
03293 $passed_tests++;
03294 array_push($points, $res["test"]["total_reached_points"]);
03295 }
03296 else
03297 {
03298 $failed_tests++;
03299 }
03300 }
03301 }
03302 $reached_points = 0;
03303 $counter = 0;
03304 foreach ($points as $key => $value)
03305 {
03306 $reached_points += $value;
03307 $counter++;
03308 }
03309 if ($counter)
03310 {
03311 $average_points = round($reached_points / $counter);
03312 }
03313 else
03314 {
03315 $average_points = 0;
03316 }
03317 return array(
03318 "total_passed" => $passed_tests,
03319 "total_failed" => $failed_tests,
03320 "average_points" => $average_points,
03321 "maximum_points" => $maximum_points
03322 );
03323 }
03324
03333 function evalTotalFinishedAverageTime()
03334 {
03335 $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",
03336 $this->ilias->db->quote($this->getTestId())
03337 );
03338 $result = $this->ilias->db->query($q);
03339 $times = array();
03340 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03341 {
03342 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->started, $matches);
03343 $epoch_1 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03344 preg_match("/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/", $row->finished, $matches);
03345 $epoch_2 = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03346 $times[$row->active_fi] += ($epoch_2 - $epoch_1);
03347 }
03348 $max_time = 0;
03349 $counter = 0;
03350 foreach ($times as $key => $value)
03351 {
03352 $max_time += $value;
03353 $counter++;
03354 }
03355 if ($counter)
03356 {
03357 $average_time = round($max_time / $counter);
03358 }
03359 else
03360 {
03361 $average_time = 0;
03362 }
03363 return $average_time;
03364 }
03365
03374 function &getForbiddenQuestionpools()
03375 {
03376 global $rbacsystem;
03377
03378 $forbidden_pools = array();
03379 $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'";
03380 $result = $this->ilias->db->query($query);
03381 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03382 {
03383 if (!$rbacsystem->checkAccess("write", $row->ref_id) || (!$this->_hasUntrashedReference($row->obj_id)))
03384 {
03385 array_push($forbidden_pools, $row->obj_id);
03386 }
03387 }
03388 return $forbidden_pools;
03389 }
03390
03399 function &getAvailableQuestionpoolIDs()
03400 {
03401 global $rbacsystem;
03402
03403 $result_array = array();
03404 $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'";
03405 $result = $this->ilias->db->query($query);
03406 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03407 {
03408 if ($rbacsystem->checkAccess("write", $row->ref_id) && ($this->_hasUntrashedReference($row->obj_id)))
03409 {
03410 array_push($result_array, $row->obj_id);
03411 }
03412 }
03413 return $result_array;
03414 }
03415
03424 function &getAvailableQuestionpools($use_object_id = false)
03425 {
03426 global $rbacsystem;
03427
03428 $result_array = array();
03429 $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";
03430 $result = $this->ilias->db->query($query);
03431 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
03432 {
03433 if ($rbacsystem->checkAccess("write", $row->ref_id) && ($this->_hasUntrashedReference($row->obj_id)))
03434 {
03435 if ($use_object_id)
03436 {
03437 $result_array[$row->obj_id] = $row->title;
03438 }
03439 else
03440 {
03441 $result_array[$row->ref_id] = $row->title;
03442 }
03443 }
03444 }
03445 return $result_array;
03446 }
03447
03456 function getEstimatedWorkingTime()
03457 {
03458 $time_in_seconds = 0;
03459 foreach ($this->questions as $question_id) {
03460 $question =& ilObjTest::_instanciateQuestion($question_id);
03461 $est_time = $question->getEstimatedWorkingTime();
03462 $time_in_seconds += $est_time["h"] * 3600 + $est_time["m"] * 60 + $est_time["s"];
03463 }
03464 $hours = (int)($time_in_seconds / 3600) ;
03465 $time_in_seconds = $time_in_seconds - ($hours * 3600);
03466 $minutes = (int)($time_in_seconds / 60);
03467 $time_in_seconds = $time_in_seconds - ($minutes * 60);
03468 $result = array("h" => $hours, "m" => $minutes, "s" => $time_in_seconds);
03469 return $result;
03470 }
03471
03484 function randomSelectQuestions($nr_of_questions, $questionpool, $use_obj_id = 0, $qpls = "")
03485 {
03486 global $rbacsystem;
03487
03488 if ($questionpool != 0)
03489 {
03490
03491 if (!$use_obj_id)
03492 {
03493 $query = sprintf("SELECT obj_id FROM object_reference WHERE ref_id = %s",
03494 $this->ilias->db->quote("$questionpool")
03495 );
03496 $result = $this->ilias->db->query($query);
03497 $row = $result->fetchRow(DB_FETCHMODE_ARRAY);
03498 $questionpool = $row[0];
03499 }
03500 }
03501
03502
03503 $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",
03504 $this->ilias->db->quote($this->getTestId() . "")
03505 );
03506 $result = $this->ilias->db->query($query);
03507 $original_ids = array();
03508 while ($row = $result->fetchRow(DB_FETCHMODE_ARRAY))
03509 {
03510 if (strcmp($row[0], "") != 0)
03511 {
03512 array_push($original_ids, $row[0]);
03513 }
03514 }
03515 $original_clause = "";
03516 if (count($original_ids))
03517 {
03518 $original_clause = " AND ISNULL(qpl_questions.original_id) AND qpl_questions.question_id NOT IN (" . join($original_ids, ",") . ")";
03519 }
03520
03521
03522 if (($questionpool == 0) && (!is_array($qpls)))
03523 {
03524 $available_pools =& $this->getAvailableQuestionpoolIDs();
03525 $available = "";
03526 $constraint_qpls = "";
03527 if (count($available_pools))
03528 {
03529 $available = " AND qpl_questions.obj_fi IN (" . join($available_pools, ",") . ")";
03530 }
03531 else
03532 {
03533 return array();
03534 }
03535 }
03536
03537 $result_array = array();
03538 if ($questionpool == 0)
03539 {
03540 if (is_array($qpls))
03541 {
03542 if (count($qpls) > 0)
03543 {
03544 $qplidx = array();
03545 foreach ($qpls as $idx => $arr)
03546 {
03547 array_push($qplidx, $arr["qpl"]);
03548 }
03549 $constraint_qpls = " AND qpl_questions.obj_fi IN (" . join($qplidx, ",") . ")";
03550 }
03551 }
03552 $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";
03553 }
03554 else
03555 {
03556 $query = sprintf("SELECT COUNT(question_id) FROM qpl_questions WHERE ISNULL(qpl_questions.original_id) AND obj_fi = %s$original_clause",
03557 $this->ilias->db->quote("$questionpool")
03558 );
03559 }
03560 $result = $this->ilias->db->query($query);
03561 $row = $result->fetchRow(DB_FETCHMODE_ARRAY);
03562 if (($row[0]) <= $nr_of_questions)
03563 {
03564
03565 if ($questionpool == 0)
03566 {
03567 $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";
03568 }
03569 else
03570 {
03571 $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",
03572 $this->ilias->db->quote("$questionpool")
03573 );
03574 }
03575 $result = $this->ilias->db->query($query);
03576 while ($row = $result->fetchRow(DB_FETCHMODE_ARRAY))
03577 {
03578 if ((!in_array($row[0], $this->questions)) && (strcmp($row[0], "") != 0))
03579 {
03580 $result_array[$row[0]] = $row[0];
03581 }
03582 }
03583 }
03584 else
03585 {
03586
03587 mt_srand((double)microtime()*1000000);
03588 $random_number = mt_rand(0, $row[0] - 1);
03589 $securitycounter = 500;
03590 while ((count($result_array) < $nr_of_questions) && ($securitycounter > 0))
03591 {
03592 if ($questionpool == 0)
03593 {
03594 $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";
03595 }
03596 else
03597 {
03598 $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",
03599 $this->ilias->db->quote("$questionpool")
03600 );
03601 }
03602 $result = $this->ilias->db->query($query);
03603 $result_row = $result->fetchRow(DB_FETCHMODE_ARRAY);
03604 if ((!in_array($result_row[0], $this->questions)) && (strcmp($result_row[0], "") != 0))
03605 {
03606 $result_array[$result_row[0]] = $result_row[0];
03607 }
03608 $random_number = mt_rand(0, $row[0] - 1);
03609 $securitycounter--;
03610 }
03611 }
03612 return $result_array;
03613 }
03614
03623 function getImagePath()
03624 {
03625 return CLIENT_WEB_DIR . "/assessment/" . $this->getId() . "/images/";
03626 }
03627
03636 function getImagePathWeb()
03637 {
03638 $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/" . $this->getId() . "/images/";
03639 return str_replace(ilUtil::removeTrailingPathSeparators(ILIAS_ABSOLUTE_PATH), ilUtil::removeTrailingPathSeparators(ILIAS_HTTP_PATH), $webdir);
03640 }
03641
03652 function &createQuestionGUI($question_type, $question_id = -1)
03653 {
03654 if ((!$question_type) and ($question_id > 0))
03655 {
03656 $question_type = $this->getQuestionType($question_id);
03657 }
03658 switch ($question_type)
03659 {
03660 case "qt_multiple_choice_sr":
03661 $question =& new ASS_MultipleChoiceGUI();
03662 $question->object->set_response(RESPONSE_SINGLE);
03663 break;
03664 case "qt_multiple_choice_mr":
03665 $question =& new ASS_MultipleChoiceGUI();
03666 $question->object->set_response(RESPONSE_MULTIPLE);
03667 break;
03668 case "qt_cloze":
03669 $question =& new ASS_ClozeTestGUI();
03670 break;
03671 case "qt_matching":
03672 $question =& new ASS_MatchingQuestionGUI();
03673 break;
03674 case "qt_ordering":
03675 $question =& new ASS_OrderingQuestionGUI();
03676 break;
03677 case "qt_imagemap":
03678 $question =& new ASS_ImagemapQuestionGUI();
03679 break;
03680 case "qt_javaapplet":
03681 $question =& new ASS_JavaAppletGUI();
03682 break;
03683 case "qt_text":
03684 $question =& new ASS_TextQuestionGUI();
03685 break;
03686 }
03687 if ($question_id > 0)
03688 {
03689 $question->object->loadFromDb($question_id);
03690 }
03691 return $question;
03692 }
03693
03703 function &_instanciateQuestion($question_id)
03704 {
03705 if (strcmp($question_id, "") != 0)
03706 {
03707 $question_type = ASS_Question::_getQuestionType($question_id);
03708
03709 switch ($question_type) {
03710 case "qt_cloze":
03711 $question = new ASS_ClozeTest();
03712 break;
03713 case "qt_matching":
03714 $question = new ASS_MatchingQuestion();
03715 break;
03716 case "qt_ordering":
03717 $question = new ASS_OrderingQuestion();
03718 break;
03719 case "qt_imagemap":
03720 $question = new ASS_ImagemapQuestion();
03721 break;
03722 case "qt_multiple_choice_sr":
03723 case "qt_multiple_choice_mr":
03724 $question = new ASS_MultipleChoice();
03725 break;
03726 case "qt_javaapplet":
03727 $question = new ASS_JavaApplet();
03728 break;
03729 case "qt_text":
03730 $question = new ASS_TextQuestion();
03731 break;
03732
03733 default:
03734
03735 return false;
03736 }
03737
03738 $question->loadFromDb($question_id);
03739 return $question;
03740 }
03741 }
03742
03753 function moveQuestions($move_questions, $target_index, $insert_mode)
03754 {
03755 $this->questions = array_values($this->questions);
03756 $array_pos = array_search($target_index, $this->questions);
03757 if ($insert_mode == 0)
03758 {
03759 $part1 = array_slice($this->questions, 0, $array_pos);
03760 $part2 = array_slice($this->questions, $array_pos);
03761 }
03762 else if ($insert_mode == 1)
03763 {
03764 $part1 = array_slice($this->questions, 0, $array_pos + 1);
03765 $part2 = array_slice($this->questions, $array_pos + 1);
03766 }
03767 foreach ($move_questions as $question_id)
03768 {
03769 if (!(array_search($question_id, $part1) === FALSE))
03770 {
03771 unset($part1[array_search($question_id, $part1)]);
03772 }
03773 if (!(array_search($question_id, $part2) === FALSE))
03774 {
03775 unset($part2[array_search($question_id, $part2)]);
03776 }
03777 }
03778 $part1 = array_values($part1);
03779 $part2 = array_values($part2);
03780 $new_array = array_values(array_merge($part1, $move_questions, $part2));
03781 $this->questions = array();
03782 $counter = 1;
03783 foreach ($new_array as $question_id)
03784 {
03785 $this->questions[$counter] = $question_id;
03786 $counter++;
03787 }
03788 $this->saveQuestionsToDb();
03789 }
03790
03791
03801 function startingTimeReached()
03802 {
03803 if ($this->getTestType() == TYPE_ASSESSMENT)
03804 {
03805 if ($this->getStartingTime())
03806 {
03807 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartingTime(), $matches);
03808 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03809 $now = mktime();
03810 if ($now < $epoch_time)
03811 {
03812
03813 return false;
03814 }
03815 }
03816 }
03817 return true;
03818 }
03819
03829 function endingTimeReached()
03830 {
03831 if ($this->getTestType() == TYPE_ASSESSMENT)
03832 {
03833 if ($this->getEndingTime())
03834 {
03835 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndingTime(), $matches);
03836 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
03837 $now = mktime();
03838 if ($now > $epoch_time)
03839 {
03840
03841 return true;
03842 }
03843 }
03844 }
03845 return false;
03846 }
03847
03855 function getQuestionsTable($sortoptions, $filter_text, $sel_filter_type, $startrow = 0, $completeonly = 0, $filter_question_type = "", $filter_questionpool = "")
03856 {
03857 global $ilUser;
03858 $where = "";
03859 if (strlen($filter_text) > 0) {
03860 switch($sel_filter_type) {
03861 case "title":
03862 $where = " AND qpl_questions.title LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
03863 break;
03864 case "comment":
03865 $where = " AND qpl_questions.comment LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
03866 break;
03867 case "author":
03868 $where = " AND qpl_questions.author LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
03869 break;
03870 }
03871 }
03872
03873 if ($filter_question_type && (strcmp($filter_question_type, "all") != 0))
03874 {
03875 $where .= " AND qpl_question_type.type_tag = " . $this->ilias->db->quote($filter_question_type);
03876 }
03877
03878 if ($filter_questionpool && (strcmp($filter_questionpool, "all") != 0))
03879 {
03880 $where .= " AND qpl_questions.obj_fi = $filter_questionpool";
03881 }
03882
03883
03884 $order = "";
03885 $images = array();
03886 if (count($sortoptions)) {
03887 foreach ($sortoptions as $key => $value) {
03888 switch($key) {
03889 case "title":
03890 $order = " ORDER BY title $value";
03891 $images["title"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
03892 break;
03893 case "comment":
03894 $order = " ORDER BY comment $value";
03895 $images["comment"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
03896 break;
03897 case "type":
03898 $order = " ORDER BY question_type_id $value";
03899 $images["type"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
03900 break;
03901 case "author":
03902 $order = " ORDER BY author $value";
03903 $images["author"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
03904 break;
03905 case "created":
03906 $order = " ORDER BY created $value";
03907 $images["created"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
03908 break;
03909 case "updated":
03910 $order = " ORDER BY TIMESTAMP14 $value";
03911 $images["updated"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
03912 break;
03913 case "qpl":
03914 $order = " ORDER BY obj_fi $value";
03915 $images["qpl"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
03916 break;
03917 }
03918 }
03919 }
03920 $maxentries = $ilUser->prefs["hits_per_page"];
03921 if ($maxentries < 1)
03922 {
03923 $maxentries = 9999;
03924 }
03925 $available_pools =& $this->getAvailableQuestionpoolIDs();
03926 $available = "";
03927 if (count($available_pools))
03928 {
03929 $available = " AND qpl_questions.obj_fi IN (" . join($available_pools, ",") . ")";
03930 }
03931 else
03932 {
03933 return array();
03934 }
03935 if ($completeonly)
03936 {
03937 $available .= " AND qpl_questions.complete = " . $this->ilias->db->quote("1");
03938 }
03939
03940
03941 $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",
03942 $this->ilias->db->quote($this->getTestId() . "")
03943 );
03944 $result = $this->ilias->db->query($query);
03945 $original_ids = array();
03946 while ($row = $result->fetchRow(DB_FETCHMODE_ARRAY))
03947 {
03948 if (strcmp($row[0], "") != 0)
03949 {
03950 array_push($original_ids, $row[0]);
03951 }
03952 }
03953 $original_clause = " ISNULL(qpl_questions.original_id)";
03954 if (count($original_ids))
03955 {
03956 $original_clause = " ISNULL(qpl_questions.original_id) AND qpl_questions.question_id NOT IN (" . join($original_ids, ",") . ")";
03957 }
03958
03959 $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";
03960 $query_result = $this->ilias->db->query($query);
03961 $max = $query_result->numRows();
03962 if ($startrow > $max -1)
03963 {
03964 $startrow = $max - ($max % $maxentries);
03965 }
03966 else if ($startrow < 0)
03967 {
03968 $startrow = 0;
03969 }
03970 $limit = " LIMIT $startrow, $maxentries";
03971 $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";
03972 $query_result = $this->ilias->db->query($query);
03973 $rows = array();
03974 if ($query_result->numRows())
03975 {
03976 while ($row = $query_result->fetchRow(DB_FETCHMODE_ASSOC))
03977 {
03978 array_push($rows, $row);
03979 }
03980 }
03981 $nextrow = $startrow + $maxentries;
03982 if ($nextrow > $max - 1)
03983 {
03984 $nextrow = $startrow;
03985 }
03986 $prevrow = $startrow - $maxentries;
03987 if ($prevrow < 0)
03988 {
03989 $prevrow = 0;
03990 }
03991 return array(
03992 "rows" => $rows,
03993 "images" => $images,
03994 "startrow" => $startrow,
03995 "nextrow" => $nextrow,
03996 "prevrow" => $prevrow,
03997 "step" => $maxentries,
03998 "rowcount" => $max
03999 );
04000 }
04001
04011 function _getTestType($test_id)
04012 {
04013 global $ilDB;
04014
04015 $result = "";
04016 $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",
04017 $ilDB->quote($test_id)
04018 );
04019 $query_result = $ilDB->query($query);
04020 if ($query_result->numRows())
04021 {
04022 $row = $query_result->fetchRow(DB_FETCHMODE_ASSOC);
04023 $result = $row["type_tag"];
04024 }
04025 return $result;
04026 }
04027
04036 function &_getQuestiontypes()
04037 {
04038 global $ilDB;
04039
04040 $questiontypes = array();
04041 $query = "SELECT * FROM qpl_question_type ORDER BY type_tag";
04042 $query_result = $ilDB->query($query);
04043 while ($row = $query_result->fetchRow(DB_FETCHMODE_ASSOC))
04044 {
04045 array_push($questiontypes, $row["type_tag"]);
04046 }
04047 return $questiontypes;
04048 }
04049
04058 function to_xml()
04059 {
04060 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<questestinterop></questestinterop>\n";
04061 $domxml = domxml_open_mem($xml_header);
04062 $root = $domxml->document_element();
04063
04064 $qtiAssessment = $domxml->create_element("assessment");
04065 $qtiAssessment->set_attribute("ident", "il_".IL_INST_ID."_tst_".$this->getTestId());
04066 $qtiAssessment->set_attribute("title", $this->getTitle());
04067
04068
04069 $qtiComment = $domxml->create_element("qticomment");
04070 $qtiCommentText = $domxml->create_text_node($this->getDescription());
04071 $qtiComment->append_child($qtiCommentText);
04072 $qtiAssessment->append_child($qtiComment);
04073
04074
04075 if ($this->enable_processing_time)
04076 {
04077 $qtiDuration = $domxml->create_element("duration");
04078 preg_match("/(\d+):(\d+):(\d+)/", $this->processing_time, $matches);
04079 $qtiDurationText = $domxml->create_text_node(sprintf("P0Y0M0DT%dH%dM%dS", $matches[1], $matches[2], $matches[3]));
04080 $qtiDuration->append_child($qtiDurationText);
04081 $qtiAssessment->append_child($qtiDuration);
04082 }
04083
04084
04085 $qtiMetadata = $domxml->create_element("qtimetadata");
04086
04087 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04088 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04089 $qtiFieldLabelText = $domxml->create_text_node("ILIAS_VERSION");
04090 $qtiFieldLabel->append_child($qtiFieldLabelText);
04091 $qtiFieldEntry = $domxml->create_element("fieldentry");
04092 $qtiFieldEntryText = $domxml->create_text_node($this->ilias->getSetting("ilias_version"));
04093 $qtiFieldEntry->append_child($qtiFieldEntryText);
04094 $qtiMetadatafield->append_child($qtiFieldLabel);
04095 $qtiMetadatafield->append_child($qtiFieldEntry);
04096 $qtiMetadata->append_child($qtiMetadatafield);
04097
04098 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04099 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04100 $qtiFieldLabelText = $domxml->create_text_node("test_type");
04101 $qtiFieldLabel->append_child($qtiFieldLabelText);
04102 $qtiFieldEntry = $domxml->create_element("fieldentry");
04103 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getTestType()));
04104 $qtiFieldEntry->append_child($qtiFieldEntryText);
04105 $qtiMetadatafield->append_child($qtiFieldLabel);
04106 $qtiMetadatafield->append_child($qtiFieldEntry);
04107 $qtiMetadata->append_child($qtiMetadatafield);
04108
04109 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04110 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04111 $qtiFieldLabelText = $domxml->create_text_node("sequence_settings");
04112 $qtiFieldLabel->append_child($qtiFieldLabelText);
04113 $qtiFieldEntry = $domxml->create_element("fieldentry");
04114 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getSequenceSettings()));
04115 $qtiFieldEntry->append_child($qtiFieldEntryText);
04116 $qtiMetadatafield->append_child($qtiFieldLabel);
04117 $qtiMetadatafield->append_child($qtiFieldEntry);
04118 $qtiMetadata->append_child($qtiMetadatafield);
04119
04120 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04121 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04122 $qtiFieldLabelText = $domxml->create_text_node("author");
04123 $qtiFieldLabel->append_child($qtiFieldLabelText);
04124 $qtiFieldEntry = $domxml->create_element("fieldentry");
04125 $qtiFieldEntryText = $domxml->create_text_node($this->getAuthor());
04126 $qtiFieldEntry->append_child($qtiFieldEntryText);
04127 $qtiMetadatafield->append_child($qtiFieldLabel);
04128 $qtiMetadatafield->append_child($qtiFieldEntry);
04129 $qtiMetadata->append_child($qtiMetadatafield);
04130
04131 if ($this->getReportingDate())
04132 {
04133 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04134 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04135 $qtiFieldLabelText = $domxml->create_text_node("reporting_date");
04136 $qtiFieldLabel->append_child($qtiFieldLabelText);
04137 $qtiFieldEntry = $domxml->create_element("fieldentry");
04138 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->reporting_date, $matches);
04139 $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]));
04140 $qtiFieldEntry->append_child($qtiFieldEntryText);
04141 $qtiMetadatafield->append_child($qtiFieldLabel);
04142 $qtiMetadatafield->append_child($qtiFieldEntry);
04143 $qtiMetadata->append_child($qtiMetadatafield);
04144 }
04145
04146 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04147 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04148 $qtiFieldLabelText = $domxml->create_text_node("nr_of_tries");
04149 $qtiFieldLabel->append_child($qtiFieldLabelText);
04150 $qtiFieldEntry = $domxml->create_element("fieldentry");
04151 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getNrOfTries()));
04152 $qtiFieldEntry->append_child($qtiFieldEntryText);
04153 $qtiMetadatafield->append_child($qtiFieldLabel);
04154 $qtiMetadatafield->append_child($qtiFieldEntry);
04155 $qtiMetadata->append_child($qtiMetadatafield);
04156
04157 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04158 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04159 $qtiFieldLabelText = $domxml->create_text_node("random_test");
04160 $qtiFieldLabel->append_child($qtiFieldLabelText);
04161 $qtiFieldEntry = $domxml->create_element("fieldentry");
04162 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->isRandomTest()));
04163 $qtiFieldEntry->append_child($qtiFieldEntryText);
04164 $qtiMetadatafield->append_child($qtiFieldLabel);
04165 $qtiMetadatafield->append_child($qtiFieldEntry);
04166 $qtiMetadata->append_child($qtiMetadatafield);
04167
04168 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04169 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04170 $qtiFieldLabelText = $domxml->create_text_node("random_question_count");
04171 $qtiFieldLabel->append_child($qtiFieldLabelText);
04172 $qtiFieldEntry = $domxml->create_element("fieldentry");
04173 $qtiFieldEntryText = $domxml->create_text_node(sprintf("%d", $this->getRandomQuestionCount()));
04174 $qtiFieldEntry->append_child($qtiFieldEntryText);
04175 $qtiMetadatafield->append_child($qtiFieldLabel);
04176 $qtiMetadatafield->append_child($qtiFieldEntry);
04177 $qtiMetadata->append_child($qtiMetadatafield);
04178
04179 if ($this->getStartingTime())
04180 {
04181 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04182 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04183 $qtiFieldLabelText = $domxml->create_text_node("starting_time");
04184 $qtiFieldLabel->append_child($qtiFieldLabelText);
04185 $qtiFieldEntry = $domxml->create_element("fieldentry");
04186 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->starting_time, $matches);
04187 $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]));
04188 $qtiFieldEntry->append_child($qtiFieldEntryText);
04189 $qtiMetadatafield->append_child($qtiFieldLabel);
04190 $qtiMetadatafield->append_child($qtiFieldEntry);
04191 $qtiMetadata->append_child($qtiMetadatafield);
04192 }
04193
04194 if ($this->getEndingTime())
04195 {
04196 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04197 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04198 $qtiFieldLabelText = $domxml->create_text_node("ending_time");
04199 $qtiFieldLabel->append_child($qtiFieldLabelText);
04200 $qtiFieldEntry = $domxml->create_element("fieldentry");
04201 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->ending_time, $matches);
04202 $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]));
04203 $qtiFieldEntry->append_child($qtiFieldEntryText);
04204 $qtiMetadatafield->append_child($qtiFieldLabel);
04205 $qtiMetadatafield->append_child($qtiFieldEntry);
04206 $qtiMetadata->append_child($qtiMetadatafield);
04207 }
04208 foreach ($this->mark_schema->mark_steps as $index => $mark)
04209 {
04210
04211 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
04212 $qtiFieldLabel = $domxml->create_element("fieldlabel");
04213 $qtiFieldLabelText = $domxml->create_text_node("mark_step_$index");
04214 $qtiFieldLabel->append_child($qtiFieldLabelText);
04215 $qtiFieldEntry = $domxml->create_element("fieldentry");
04216 $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()));
04217 $qtiFieldEntry->append_child($qtiFieldEntryText);
04218 $qtiMetadatafield->append_child($qtiFieldLabel);
04219 $qtiMetadatafield->append_child($qtiFieldEntry);
04220 $qtiMetadata->append_child($qtiMetadatafield);
04221 }
04222 $qtiAssessment->append_child($qtiMetadata);
04223
04224
04225 $qtiObjectives = $domxml->create_element("objectives");
04226 $qtiMaterial = $domxml->create_element("material");
04227 $qtiMaterial->set_attribute("label", "introduction");
04228 $qtiMatText = $domxml->create_element("mattext");
04229 $qtiMatTextText = $domxml->create_text_node($this->getIntroduction());
04230 $qtiMatText->append_child($qtiMatTextText);
04231 $qtiMaterial->append_child($qtiMatText);
04232 $qtiObjectives->append_child($qtiMaterial);
04233 $qtiAssessment->append_child($qtiObjectives);
04234
04235
04236 $qtiAssessmentcontrol = $domxml->create_element("assessmentcontrol");
04237 $score_reporting = "No";
04238 switch ($this->getScoreReporting())
04239 {
04240 case "1":
04241 $score_reporting = "Yes";
04242 break;
04243 }
04244 $qtiAssessmentcontrol->set_attribute("solutionswitch", $score_reporting);
04245 $qtiAssessment->append_child($qtiAssessmentcontrol);
04246
04247 $qtiSection = $domxml->create_element("section");
04248 $qtiSection->set_attribute("ident", "1");
04249 $qtiAssessment->append_child($qtiSection);
04250
04251 $root->append_child($qtiAssessment);
04252 $xml = $domxml->dump_mem(true);
04253 $domxml->free();
04254 foreach ($this->questions as $question_id) {
04255 $question =& ilObjTest::_instanciateQuestion($question_id);
04256 $qti_question = $question->to_xml(false);
04257 $qti_question = preg_replace("/<questestinterop>/", "", $qti_question);
04258 $qti_question = preg_replace("/<\/questestinterop>/", "", $qti_question);
04259 if (strpos($xml, "</section>") !== false)
04260 {
04261 $xml = str_replace("</section>", "$qti_question</section>", $xml);
04262 }
04263 else
04264 {
04265 $xml = str_replace("<section ident=\"1\"/>", "<section ident=\"1\">\n$qti_question</section>", $xml);
04266 }
04267 }
04268 return $xml;
04269 }
04270
04277 function exportPagesXML(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
04278 {
04279 global $ilBench;
04280
04281 $this->mob_ids = array();
04282 $this->file_ids = array();
04283
04284 $attrs = array();
04285 $attrs["Type"] = "Test";
04286 $a_xml_writer->xmlStartTag("ContentObject", $attrs);
04287
04288
04289 $this->exportXMLMetaData($a_xml_writer);
04290
04291
04292 $expLog->write(date("[y-m-d H:i:s] ")."Start Export Page Objects");
04293 $ilBench->start("ContentObjectExport", "exportPageObjects");
04294 $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog);
04295 $ilBench->stop("ContentObjectExport", "exportPageObjects");
04296 $expLog->write(date("[y-m-d H:i:s] ")."Finished Export Page Objects");
04297
04298
04299 $expLog->write(date("[y-m-d H:i:s] ")."Start Export Media Objects");
04300 $ilBench->start("ContentObjectExport", "exportMediaObjects");
04301 $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
04302 $ilBench->stop("ContentObjectExport", "exportMediaObjects");
04303 $expLog->write(date("[y-m-d H:i:s] ")."Finished Export Media Objects");
04304
04305
04306 $expLog->write(date("[y-m-d H:i:s] ")."Start Export File Items");
04307 $ilBench->start("ContentObjectExport", "exportFileItems");
04308 $this->exportFileItems($a_target_dir, $expLog);
04309 $ilBench->stop("ContentObjectExport", "exportFileItems");
04310 $expLog->write(date("[y-m-d H:i:s] ")."Finished Export File Items");
04311
04312 $a_xml_writer->xmlEndTag("ContentObject");
04313 }
04314
04321 function exportXMLMetaData(&$a_xml_writer)
04322 {
04323 $nested = new ilNestedSetXML();
04324 $nested->setParameterModifier($this, "modifyExportIdentifier");
04325 $a_xml_writer->appendXML($nested->export($this->getId(),
04326 $this->getType()));
04327 }
04328
04336 function modifyExportIdentifier($a_tag, $a_param, $a_value)
04337 {
04338 if ($a_tag == "Identifier" && $a_param == "Entry")
04339 {
04340 $a_value = ilUtil::insertInstIntoID($a_value);
04341 }
04342
04343 return $a_value;
04344 }
04345
04346
04353 function exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog)
04354 {
04355 global $ilBench;
04356
04357 include_once "./content/classes/class.ilLMPageObject.php";
04358
04359 foreach ($this->questions as $question_id)
04360 {
04361 $ilBench->start("ContentObjectExport", "exportPageObject");
04362 $expLog->write(date("[y-m-d H:i:s] ")."Page Object ".$question_id);
04363
04364 $attrs = array();
04365 $a_xml_writer->xmlStartTag("PageObject", $attrs);
04366
04367
04368
04369 $ilBench->start("ContentObjectExport", "exportPageObject_XML");
04370 $page_object = new ilPageObject("qpl", $question_id);
04371 $page_object->buildDom();
04372 $page_object->insertInstIntoIDs($a_inst);
04373 $mob_ids = $page_object->collectMediaObjects(false);
04374 $file_ids = $page_object->collectFileItems();
04375 $xml = $page_object->getXMLFromDom(false, false, false, "", true);
04376 $xml = str_replace("&","&", $xml);
04377 $a_xml_writer->appendXML($xml);
04378 $page_object->freeDom();
04379 unset ($page_object);
04380
04381 $ilBench->stop("ContentObjectExport", "exportPageObject_XML");
04382
04383
04384 $ilBench->start("ContentObjectExport", "exportPageObject_CollectMedia");
04385
04386 foreach($mob_ids as $mob_id)
04387 {
04388 $this->mob_ids[$mob_id] = $mob_id;
04389 }
04390 $ilBench->stop("ContentObjectExport", "exportPageObject_CollectMedia");
04391
04392
04393 $ilBench->start("ContentObjectExport", "exportPageObject_CollectFileItems");
04394
04395 foreach($file_ids as $file_id)
04396 {
04397 $this->file_ids[$file_id] = $file_id;
04398 }
04399 $ilBench->stop("ContentObjectExport", "exportPageObject_CollectFileItems");
04400
04401 $a_xml_writer->xmlEndTag("PageObject");
04402
04403
04404 $ilBench->stop("ContentObjectExport", "exportPageObject");
04405
04406
04407 }
04408 }
04409
04416 function exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
04417 {
04418 include_once("content/classes/Media/class.ilObjMediaObject.php");
04419
04420 foreach ($this->mob_ids as $mob_id)
04421 {
04422 $expLog->write(date("[y-m-d H:i:s] ")."Media Object ".$mob_id);
04423 $media_obj = new ilObjMediaObject($mob_id);
04424 $media_obj->exportXML($a_xml_writer, $a_inst);
04425 $media_obj->exportFiles($a_target_dir);
04426 unset($media_obj);
04427 }
04428 }
04429
04434 function exportFileItems($a_target_dir, &$expLog)
04435 {
04436 include_once("classes/class.ilObjFile.php");
04437
04438 foreach ($this->file_ids as $file_id)
04439 {
04440 $expLog->write(date("[y-m-d H:i:s] ")."File Item ".$file_id);
04441 $file_obj = new ilObjFile($file_id, false);
04442 $file_obj->export($a_target_dir);
04443 unset($file_obj);
04444 }
04445 }
04446
04455 function from_xml($xml_text)
04456 {
04457 $result = false;
04458 $this->mark_schema->flush();
04459 $xml_text = preg_replace("/>\s*?</", "><", $xml_text);
04460 $domxml = domxml_open_mem($xml_text);
04461 if (!empty($domxml))
04462 {
04463 $root = $domxml->document_element();
04464 $this->setTitle($root->get_attribute("title"));
04465 $item = $root;
04466 $itemnodes = $item->child_nodes();
04467 foreach ($itemnodes as $index => $node)
04468 {
04469 switch ($node->node_name())
04470 {
04471 case "qticomment":
04472 $comment = $node->get_content();
04473 if (strpos($comment, "Author=") !== false)
04474 {
04475 $comment = str_replace("Author=", "", $comment);
04476 $this->setAuthor($comment);
04477 }
04478 elseif (strpos($comment, "ILIAS Version=") !== false)
04479 {
04480 }
04481 else
04482 {
04483 $this->setDescription($comment);
04484 }
04485 break;
04486 case "duration":
04487 $iso8601period = $node->get_content();
04488 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
04489 {
04490 $this->enable_processing_time = 1;
04491 $this->setProcessingTime(sprintf("%02d:%02d:%02d", $matches[4], $matches[5], $matches[6]));
04492 }
04493 break;
04494 case "assessmentcontrol":
04495 $score_reporting = $node->get_attribute("solutionswitch");
04496 switch (strtolower($score_reporting))
04497 {
04498 case "1":
04499 case "yes":
04500 $score_reporting = 1;
04501 break;
04502 default:
04503 $score_reporting = 0;
04504 break;
04505 }
04506 $this->setScoreReporting($score_reporting);
04507 break;
04508 case "objectives":
04509 $material = $node->first_child();
04510 if (strcmp($material->get_attribute("label"), "introduction") == 0)
04511 {
04512 $mattext = $material->first_child();
04513 $this->setIntroduction($mattext->get_content());
04514 }
04515 break;
04516 case "qtimetadata":
04517 $metadata_fields = $node->child_nodes();
04518 foreach ($metadata_fields as $index => $metadata_field)
04519 {
04520 $fieldlabel = $metadata_field->first_child();
04521 $fieldentry = $fieldlabel->next_sibling();
04522 switch ($fieldlabel->get_content())
04523 {
04524 case "sequence_settings":
04525 $this->setSequenceSettings($fieldentry->get_content());
04526 break;
04527 case "author":
04528 $this->setAuthor($fieldentry->get_content());
04529 break;
04530 case "test_type":
04531 $this->setTestType($fieldentry->get_content());
04532 break;
04533 case "reporting_date":
04534 $iso8601period = $fieldentry->get_content();
04535 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
04536 {
04537 $this->setReportingDate(sprintf("%02d%02d%02d%02d%02d%02d", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
04538 }
04539 break;
04540 case "nr_of_tries":
04541 $this->setNrOfTries($fieldentry->get_content());
04542 break;
04543 case "random_test":
04544 $this->setRandomTest($fieldentry->get_content());
04545 break;
04546 case "random_question_count":
04547 $this->setRandomQuestionCount($fieldentry->get_content());
04548 break;
04549 case "starting_time":
04550 $iso8601period = $fieldentry->get_content();
04551 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
04552 {
04553 $this->setStartingTime(sprintf("%02d%02d%02d%02d%02d%02d", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
04554 }
04555 break;
04556 case "ending_time":
04557 $iso8601period = $fieldentry->get_content();
04558 if (preg_match("/P(\d+)Y(\d+)M(\d+)DT(\d+)H(\d+)M(\d+)S/", $iso8601period, $matches))
04559 {
04560 $this->setEndingTime(sprintf("%02d%02d%02d%02d%02d%02d", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
04561 }
04562 break;
04563 }
04564 if (preg_match("/mark_step_\d+/", $fieldlabel->get_content()))
04565 {
04566 $xmlmark = $fieldentry->get_content();
04567 preg_match("/<short>(.*?)<\/short>/", $xmlmark, $matches);
04568 $mark_short = $matches[1];
04569 preg_match("/<official>(.*?)<\/official>/", $xmlmark, $matches);
04570 $mark_official = $matches[1];
04571 preg_match("/<percentage>(.*?)<\/percentage>/", $xmlmark, $matches);
04572 $mark_percentage = $matches[1];
04573 preg_match("/<passed>(.*?)<\/passed>/", $xmlmark, $matches);
04574 $mark_passed = $matches[1];
04575 $this->mark_schema->add_mark_step($mark_short, $mark_official, $mark_percentage, $mark_passed);
04576 }
04577 }
04578 break;
04579 }
04580 }
04581 $result = true;
04582 }
04583 return $result;
04584 }
04585
04594 function importObject($source, $questionpool_id)
04595 {
04596 $ilias_version = "";
04597 $error = 0;
04598 if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK)
04599 {
04600 $this->ilias->raiseError("No file selected!",$this->ilias->error_obj->FATAL);
04601 $error = 1;
04602 }
04603
04604
04605 if (!$error)
04606 {
04607
04608 $fh = fopen($source, "r");
04609 if (!$fh)
04610 {
04611 $this->ilias->raiseError("Error opening the file!",$this->ilias->error_obj->FATAL);
04612 $error = 1;
04613 return $error;
04614 }
04615
04616 $xml = fread($fh, filesize($source));
04617 $result = fclose($fh);
04618 if (!$result)
04619 {
04620 $this->ilias->raiseError("Error closing the file!",$this->ilias->error_obj->FATAL);
04621 $error = 1;
04622 return $error;
04623 }
04624
04625 $assessment_part = "";
04626 if (preg_match("/ILIAS Version\=(\d+)\.(\d+)\.?(\d?)/", $xml, $matches))
04627 {
04628 $major_version = $matches[1];
04629 unset($matches[0]);
04630 $ilias_version = join($matches, ".");
04631 if ($major_version == 2)
04632 {
04633 $this->setTestType(TYPE_SELF_ASSESSMENT);
04634 global $lng;
04635 $lng->loadLanguageModule("assessment");
04636 $this->setTitle($lng->txt("imported_test"));
04637 $assessment_part = $this->to_xml();
04638 if (preg_match("/(<assessment[^>]*>.*?<\/assessment>)/si", $assessment_part, $matches))
04639 {
04640 $assessment_part = $matches[1];
04641 }
04642 }
04643 }
04644
04645 $found_assessment = preg_match("/(<assessment[^>]*>.*?<\/assessment>)/si", $xml, $matches);
04646 if ($found_assessment or $assessment_part)
04647 {
04648 if ((!$found_assessment) and ($assessment_part))
04649 {
04650 $matches[1] = $assessment_part;
04651 }
04652
04653 $succeeded = $this->from_xml($matches[1]);
04654
04655 if (!$succeeded)
04656 {
04657
04658 $error = 1;
04659 return $error;
04660 }
04661 }
04662 else
04663 {
04664
04665 $error = 1;
04666 return $error;
04667 }
04668
04669 $question_counter = 1;
04670
04671 $this->import_mapping = array();
04672
04673 if (preg_match_all("/(<item[^>]*>.*?<\/item>)/si", $xml, $matches))
04674 {
04675
04676 foreach ($matches[1] as $index => $item)
04677 {
04678
04679 if (preg_match("/(<item[^>]*>)/is", $item, $start_tag))
04680 {
04681 if (preg_match("/(ident=\"([^\"]*)\")/is", $start_tag[1], $ident))
04682 {
04683 $ident = $ident[2];
04684 }
04685 }
04686
04687 $question = "";
04688 $qt = "";
04689 if (preg_match("/<fieldlabel>QUESTIONTYPE<\/fieldlabel>\s*<fieldentry>(.*?)<\/fieldentry>/is", $item, $questiontype))
04690 {
04691 $qt = $questiontype[1];
04692 }
04693 if (preg_match("/<qticomment>Questiontype\=(.*?)<\/qticomment>/is", $item, $questiontype))
04694 {
04695 $qt = $questiontype[1];
04696 }
04697 if (strlen($qt))
04698 {
04699 switch ($qt)
04700 {
04701 case CLOZE_TEST_IDENTIFIER:
04702 $question = new ASS_ClozeTest();
04703 break;
04704 case IMAGEMAP_QUESTION_IDENTIFIER:
04705 $question = new ASS_ImagemapQuestion();
04706 break;
04707 case MATCHING_QUESTION_IDENTIFIER:
04708 $question = new ASS_MatchingQuestion();
04709 break;
04710 case MULTIPLE_CHOICE_QUESTION_IDENTIFIER:
04711 $question = new ASS_MultipleChoice();
04712 break;
04713 case ORDERING_QUESTION_IDENTIFIER:
04714 $question = new ASS_OrderingQuestion();
04715 break;
04716 case JAVAAPPLET_QUESTION_IDENTIFIER:
04717 $question = new ASS_JavaApplet();
04718 break;
04719 case TEXT_QUESTION_IDENTIFIER:
04720 $question = new ASS_TextQuestion();
04721 break;
04722 }
04723 if ($question)
04724 {
04725 $question->setObjId($questionpool_id);
04726 if ($question->from_xml("<questestinterop>$item</questestinterop>"))
04727 {
04728 $question->saveToDb();
04729 $q_1_id = $question->getId();
04730 $question_id = $question->duplicate(true);
04731 $this->questions[$question_counter++] = $question_id;
04732 $this->import_mapping[$ident] = array(
04733 "pool" => $q_1_id, "test" => $question_id);
04734 }
04735 else
04736 {
04737 $this->ilias->raiseError($this->lng->txt("error_importing_question"), $this->ilias->error_obj->MESSAGE);
04738 }
04739 }
04740 }
04741 }
04742 }
04743 }
04744
04745 $result = array(
04746 "error" => $error,
04747 "version" => $ilias_version
04748 );
04749 return $result;
04750 }
04751
04756 function getImportMapping()
04757 {
04758 if (!is_array($this->import_mapping))
04759 {
04760 return array();
04761 }
04762 else
04763 {
04764 return $this->import_mapping;
04765 }
04766 }
04767
04768 function getECTSGrade($reached_points, $max_points)
04769 {
04770 require_once "./classes/class.ilStatistics.php";
04771
04772 $passed_statistics = new ilStatistics();
04773 $passed_array =& $this->getTotalPointsPassedArray();
04774 $passed_statistics->setData($passed_array);
04775 $ects_percentiles = array
04776 (
04777 "A" => $passed_statistics->quantile($this->ects_grades["A"]),
04778 "B" => $passed_statistics->quantile($this->ects_grades["B"]),
04779 "C" => $passed_statistics->quantile($this->ects_grades["C"]),
04780 "D" => $passed_statistics->quantile($this->ects_grades["D"]),
04781 "E" => $passed_statistics->quantile($this->ects_grades["E"])
04782 );
04783 if (count($passed_array) && ($reached_points >= $ects_percentiles["A"]))
04784 {
04785 return "A";
04786 }
04787 else if (count($passed_array) && ($reached_points >= $ects_percentiles["B"]))
04788 {
04789 return "B";
04790 }
04791 else if (count($passed_array) && ($reached_points >= $ects_percentiles["C"]))
04792 {
04793 return "C";
04794 }
04795 else if (count($passed_array) && ($reached_points >= $ects_percentiles["D"]))
04796 {
04797 return "D";
04798 }
04799 else if (count($passed_array) && ($reached_points >= $ects_percentiles["E"]))
04800 {
04801 return "E";
04802 }
04803 else if (strcmp($this->ects_fx, "") != 0)
04804 {
04805 if ($max_points > 0)
04806 {
04807 $percentage = ($reached_points / $max_points) * 100.0;
04808 }
04809 else
04810 {
04811 $percentage = 0.0;
04812 }
04813 if ($percentage >= $this->ects_fx)
04814 {
04815 return "FX";
04816 }
04817 else
04818 {
04819 return "F";
04820 }
04821 }
04822 else
04823 {
04824 return "F";
04825 }
04826 }
04827
04828 function checkMarks()
04829 {
04830 return $this->mark_schema->checkMarks();
04831 }
04832
04836 function updateTitleAndDescription()
04837 {
04838 $this->initMeta();
04839 $this->meta_data->updateTitleAndDescription($this->getTitle(), $this->getDescription());
04840 }
04841
04845 function updateMetaData()
04846 {
04847 $this->initMeta();
04848 $this->meta_data->update();
04849 if ($this->meta_data->section != "General")
04850 {
04851 $meta = $this->meta_data->getElement("Title", "General");
04852 $this->meta_data->setTitle($meta[0]["value"]);
04853 $meta = $this->meta_data->getElement("Description", "General");
04854 $this->meta_data->setDescription($meta[0]["value"]);
04855 }
04856 else
04857 {
04858 $this->setTitle($this->meta_data->getTitle());
04859 $this->setDescription($this->meta_data->getDescription());
04860 }
04861 parent::update();
04862 }
04863
04872 function &_getAvailableTests($use_object_id = false)
04873 {
04874 global $rbacsystem;
04875 global $ilDB;
04876
04877 $result_array = array();
04878 $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";
04879 $result = $ilDB->query($query);
04880 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
04881 {
04882 if ($rbacsystem->checkAccess("write", $row->ref_id) && (ilObject::_hasUntrashedReference($row->obj_id)))
04883 {
04884 if ($use_object_id)
04885 {
04886 $result_array[$row->obj_id] = $row->title;
04887 }
04888 else
04889 {
04890 $result_array[$row->ref_id] = $row->title;
04891 }
04892 }
04893 }
04894 return $result_array;
04895 }
04896
04905 function cloneRandomQuestions($new_id)
04906 {
04907 if ($new_id > 0)
04908 {
04909 $query = sprintf("SELECT * FROM tst_test_random WHERE test_fi = %s",
04910 $this->ilias->db->quote($this->getTestId() . "")
04911 );
04912 $result = $this->ilias->db->query($query);
04913 if ($result->numRows())
04914 {
04915 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
04916 {
04917 $query = sprintf("INSERT INTO tst_test_random (test_random_id, test_fi, questionpool_fi, num_of_q, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
04918 $this->ilias->db->quote($new_id . ""),
04919 $this->ilias->db->quote($row["questionpool_fi"] . ""),
04920 $this->ilias->db->quote($row["num_of_q"] . "")
04921 );
04922 $insertresult = $this->ilias->db->query($query);
04923 }
04924 }
04925 }
04926 }
04927
04928
04936 function _clone($obj_id)
04937 {
04938 $original = new ilObjTest($obj_id, false);
04939 $original->loadFromDb();
04940
04941 $newObj = new ilObjTest();
04942 $newObj->setType("tst");
04943 $counter = 2;
04944 while ($newObj->testTitleExists($newObj->getTitle() . " ($counter)"))
04945 {
04946 $counter++;
04947 }
04948 $newObj->setTitle($original->getTitle() . " ($counter)");
04949 $newObj->setDescription($original->getDescription());
04950 $newObj->create(true);
04951 $newObj->createReference();
04952 $newObj->putInTree($_GET["ref_id"]);
04953 $newObj->setPermissions($_GET["ref_id"]);
04954
04955
04956 $newObj->$author = $original->getAuthor();
04957 $newObj->introduction = $original->getIntroduction();
04958 $newObj->mark_schema = $original->mark_schema;
04959 $newObj->sequence_settings = $original->getSequenceSettings();
04960 $newObj->score_reporting = $original->getScoreReporting();
04961 $newObj->reporting_date = $original->getReportingDate();
04962 $newObj->test_type = $original->getTestType();
04963 $newObj->nr_of_tries = $original->getNrOfTries();
04964 $newObj->processing_time = $original->getProcessingTime();
04965 $newObj->enable_processing_time = $original->getEnableProcessingTime();
04966 $newObj->starting_time = $original->getStartingTime();
04967 $newObj->ending_time = $original->getEndingTime();
04968 $newObj->ects_output = $original->ects_output;
04969 $newObj->ects_fx = $original->ects_fx;
04970 $newObj->ects_grades = $original->ects_grades;
04971 $newObj->random_test = $original->random_test;
04972 $newObj->random_question_count = $original->random_question_count;
04973 $newObj->saveToDb();
04974 if ($original->isRandomTest())
04975 {
04976 $newObj->saveRandomQuestionCount($newObj->random_question_count);
04977 $original->cloneRandomQuestions($newObj->getTestId());
04978 }
04979 else
04980 {
04981
04982 foreach ($original->questions as $key => $question_id)
04983 {
04984 $question = ilObjTest::_instanciateQuestion($question_id);
04985 $newObj->questions[$key] = $question->duplicate();
04986
04987 $original_id = ASS_Question::_getOriginalId($question_id);
04988 $question = ilObjTest::_instanciateQuestion($newObj->questions[$key]);
04989 $question->saveToDb($original_id);
04990 }
04991 }
04992
04993 $newObj->saveToDb();
04994
04995 $meta_data =& new ilMetaData($original->getType(), $original->getId());
04996 include_once("./classes/class.ilNestedSetXML.php");
04997 $nested = new ilNestedSetXML();
04998 $nested->dom = domxml_open_mem($meta_data->nested_obj->dom->dump_mem(0));
04999 $nodes = $nested->getDomContent("//MetaData/General", "Identifier");
05000 if (is_array($nodes))
05001 {
05002 $nodes[0]["Entry"] = "il__" . $newObj->getType() . "_" . $newObj->getId();
05003 $nested->updateDomContent("//MetaData/General", "Identifier", 0, $nodes[0]);
05004 }
05005 $xml = $nested->dom->dump_mem(0);
05006 $nested->import($xml, $newObj->getId(), $newObj->getType());
05007 }
05008
05009 function _getRefIdFromObjId($obj_id)
05010 {
05011 global $ilDB;
05012
05013 $query = sprintf("SELECT ref_id FROM object_reference WHERE obj_id=%s",
05014 $ilDB->quote($obj_id)
05015
05016 );
05017 $result = $ilDB->query($query);
05018 if ($result->numRows())
05019 {
05020 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05021 return $row["ref_id"];
05022 }
05023 return 0;
05024 }
05025
05026 function createRandomSolutionsForAllUsers()
05027 {
05028 global $ilDB;
05029 global $ilUser;
05030
05031 $db =& $ilDB->db;
05032 $sequence_arr = array_flip($this->questions);
05033 $sequence = join($sequence_arr, ",");
05034 require_once("./classes/class.ilObjUser.php");
05035 $logins = ilObjUser::_getAllUserData(array("login"));
05036
05037 foreach ($logins as $login)
05038 {
05039 $user_id = $login["usr_id"];
05040 $old_active = $this->getActiveTestUser($user_id);
05041 if ($old_active) {
05042 $query = sprintf("UPDATE tst_active SET lastindex = %s, sequence = %s, postponed = %s, tries = %s WHERE user_fi = %s AND test_fi = %s",
05043 $db->quote("0"),
05044 $db->quote($sequence),
05045 $db->quote(""),
05046 $db->quote("1"),
05047 $db->quote($user_id),
05048 $db->quote($this->getTestId())
05049 );
05050 } else {
05051 $sequence_arr = array_flip($this->questions);
05052 $sequence = join($sequence_arr, ",");
05053 $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)",
05054 $db->quote($user_id),
05055 $db->quote($this->getTestId()),
05056 $db->quote($sequence),
05057 $db->quote(""),
05058 $db->quote("0"),
05059 $db->quote("1")
05060 );
05061 }
05062 $db->query($query);
05063 }
05064 foreach ($this->questions as $question_id) {
05065 $question =& ilObjTest::_instanciateQuestion($question_id);
05066 foreach ($logins as $login)
05067 {
05068 $question->createRandomSolution($this->getTestId(), $login["usr_id"]);
05069 }
05070 }
05071 }
05072
05080 function &getEvaluationUsers($user_id)
05081 {
05082 $users = array();
05083 $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",
05084 $this->ilias->db->quote($this->getTestId() . ""),
05085 $this->ilias->db->quote($user_id . "")
05086 );
05087 $result = $this->ilias->db->query($query);
05088 if ($result->numRows())
05089 {
05090 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
05091 {
05092 $users[$row["user_fi"]] = trim($row["firstname"] ." " . $row["lastname"]);
05093 }
05094 }
05095 return $users;
05096 }
05097
05105 function &getEvaluationGroups($user_id)
05106 {
05107 $groups = array();
05108 $query = sprintf("SELECT group_fi FROM tst_eval_groups WHERE test_fi = %s AND evaluator_fi = %s",
05109 $this->ilias->db->quote($this->getTestId() . ""),
05110 $this->ilias->db->quote($user_id . "")
05111 );
05112 $result = $this->ilias->db->query($query);
05113 if ($result->numRows())
05114 {
05115 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
05116 {
05117 $groups[$row["group_fi"]] = $row["group_fi"];
05118 }
05119 }
05120 return $groups;
05121 }
05122
05131 function removeSelectedUser($user_id, $evaluator_id)
05132 {
05133 $query = sprintf("DELETE FROM tst_eval_users WHERE test_fi = %s AND user_fi = %s AND evaluator_fi = %s",
05134 $this->ilias->db->quote($this->getTestId() . ""),
05135 $this->ilias->db->quote($user_id . ""),
05136 $this->ilias->db->quote($evaluator_id . "")
05137 );
05138 $result = $this->ilias->db->query($query);
05139 }
05140
05149 function addSelectedUser($user_id, $evaluator_id)
05150 {
05151 $query = sprintf("SELECT user_fi FROM tst_eval_users WHERE test_fi = %s AND evaluator_fi = %s AND user_fi = %s",
05152 $this->ilias->db->quote($this->getTestId() . ""),
05153 $this->ilias->db->quote($evaluator_id . ""),
05154 $this->ilias->db->quote($user_id . "")
05155 );
05156 $result = $this->ilias->db->query($query);
05157 if ($result->numRows() < 1)
05158 {
05159 $query = sprintf("INSERT INTO tst_eval_users (eval_users_id, test_fi, evaluator_fi, user_fi, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
05160 $this->ilias->db->quote($this->getTestId() . ""),
05161 $this->ilias->db->quote($evaluator_id . ""),
05162 $this->ilias->db->quote($user_id . "")
05163 );
05164 $result = $this->ilias->db->query($query);
05165 }
05166 }
05167
05176 function removeSelectedGroup($group_id, $evaluator_id)
05177 {
05178 $query = sprintf("DELETE FROM tst_eval_groups WHERE test_fi = %s AND group_fi = %s AND evaluator_fi = %s",
05179 $this->ilias->db->quote($this->getTestId() . ""),
05180 $this->ilias->db->quote($group_id . ""),
05181 $this->ilias->db->quote($evaluator_id . "")
05182 );
05183 $result = $this->ilias->db->query($query);
05184 }
05185
05194 function addSelectedGroup($group_id, $evaluator_id)
05195 {
05196 $query = sprintf("SELECT group_fi FROM tst_eval_groups WHERE test_fi = %s AND evaluator_fi = %s AND group_fi = %s",
05197 $this->ilias->db->quote($this->getTestId() . ""),
05198 $this->ilias->db->quote($evaluator_id . ""),
05199 $this->ilias->db->quote($group_id . "")
05200 );
05201 $result = $this->ilias->db->query($query);
05202 if ($result->numRows() < 1)
05203 {
05204 $query = sprintf("INSERT INTO tst_eval_groups (eval_groups_id, test_fi, evaluator_fi, group_fi, TIMESTAMP) VALUES (NULL, %s, %s, %s, NULL)",
05205 $this->ilias->db->quote($this->getTestId() . ""),
05206 $this->ilias->db->quote($evaluator_id . ""),
05207 $this->ilias->db->quote($group_id . "")
05208 );
05209 $result = $this->ilias->db->query($query);
05210 }
05211 }
05212
05221 function getQuestionCount()
05222 {
05223 $num = 0;
05224
05225 if ($this->isRandomTest())
05226 {
05227 if ($this->getRandomQuestionCount())
05228 {
05229 $num = $this->getRandomQuestionCount();
05230 }
05231 else
05232 {
05233 $qpls =& $this->getRandomQuestionpools();
05234 foreach ($qpls as $data)
05235 {
05236 $num += $data["count"];
05237 }
05238 }
05239 }
05240 else
05241 {
05242 $num = count($this->questions);
05243 }
05244 return $num;
05245 }
05246
05255 function _goto($a_target)
05256 {
05257 global $rbacsystem, $ilErr, $lng;
05258
05259 include_once 'classes/class.ilSearch.php';
05260
05261
05262
05263 if ($rbacsystem->checkAccess("read", $a_target) and ilSearch::_checkParentConditions($a_target))
05264 {
05265 ilUtil::redirect("assessment/test.php?cmd=run&ref_id=$a_target");
05266 }
05267 else
05268 {
05269 $ilErr->raiseError($lng->txt("msg_no_perm_read_lm"), $ilErr->FATAL);
05270 }
05271 }
05272
05280 function removeNonRandomTestData()
05281 {
05282
05283 $this->removeAllTestEditings();
05284 $query = sprintf("DELETE FROM tst_test_question WHERE test_fi = %s",
05285 $this->ilias->db->quote($this->getTestId())
05286 );
05287 $result = $this->ilias->db->query($query);
05288 $this->questions = array();
05289 $this->saveCompleteStatus();
05290 }
05291
05299 function removeRandomTestData()
05300 {
05301
05302 $this->removeAllTestEditings();
05303 $query = sprintf("DELETE FROM tst_test_random WHERE test_fi = %s",
05304 $this->ilias->db->quote($this->getTestId())
05305 );
05306 $result = $this->ilias->db->query($query);
05307 $this->questions = array();
05308 $this->saveCompleteStatus();
05309 }
05310
05320 function logAction($logtext = "", $question_id = "")
05321 {
05322 global $ilUser;
05323
05324 $original_id = "";
05325 if (strcmp($question_id, "") == 0)
05326 {
05327 $question_id = "NULL";
05328 }
05329 else
05330 {
05331 $original_id = ASS_Question::_getOriginalId($question_id);
05332 $question_id = $this->ilias->db->quote($question_id . "");
05333 }
05334 if (strcmp($original_id, "") == 0)
05335 {
05336 $original_id = "NULL";
05337 }
05338 else
05339 {
05340 $original_id = $this->ilias->db->quote($original_id . "");
05341 }
05342 $query = sprintf("INSERT INTO ass_log (ass_log_id, user_fi, obj_fi, logtext, question_fi, original_fi, TIMESTAMP) VALUES (NULL, %s, %s, %s, %s, %s, NULL)",
05343 $this->ilias->db->quote($ilUser->id . ""),
05344 $this->ilias->db->quote($this->getId() . ""),
05345 $this->ilias->db->quote($logtext . ""),
05346 $question_id,
05347 $original_id
05348 );
05349 $result = $this->ilias->db->query($query);
05350 }
05351
05361 function _getObjectIDFromTestID($test_id)
05362 {
05363 global $ilDB;
05364 $object_id = FALSE;
05365 $query = sprintf("SELECT obj_fi FROM tst_tests WHERE test_id = %s",
05366 $ilDB->quote($test_id . "")
05367 );
05368 $result = $ilDB->query($query);
05369 if ($result->numRows())
05370 {
05371 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05372 $object_id = $row["obj_fi"];
05373 }
05374 return $object_id;
05375 }
05376
05386 function _getTestIDFromObjectID($object_id)
05387 {
05388 global $ilDB;
05389 $test_id = FALSE;
05390 $query = sprintf("SELECT test_id FROM tst_tests WHERE obj_fi = %s",
05391 $ilDB->quote($object_id . "")
05392 );
05393 $result = $ilDB->query($query);
05394 if ($result->numRows())
05395 {
05396 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05397 $test_id = $row["test_id"];
05398 }
05399 return $test_id;
05400 }
05401
05412 function getTextAnswer($user_id, $question_id)
05413 {
05414 $res = "";
05415 if (($user_id) && ($question_id))
05416 {
05417 $query = sprintf("SELECT value1 FROM tst_solutions WHERE user_fi = %s AND test_fi = %s AND question_fi = %s",
05418 $this->ilias->db->quote($user_id . ""),
05419 $this->ilias->db->quote($this->getTestId() . ""),
05420 $this->ilias->db->quote($question_id . "")
05421 );
05422 $result = $this->ilias->db->query($query);
05423 if ($result->numRows() == 1)
05424 {
05425 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05426 $res = $row["value1"];
05427 }
05428 }
05429 return $res;
05430 }
05431
05441 function getQuestiontext($question_id)
05442 {
05443 $res = "";
05444 if ($question_id)
05445 {
05446 $query = sprintf("SELECT question_text FROM qpl_questions WHERE question_id = %s",
05447 $this->ilias->db->quote($question_id . "")
05448 );
05449 $result = $this->ilias->db->query($query);
05450 if ($result->numRows() == 1)
05451 {
05452 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
05453 $res = $row["question_text"];
05454 }
05455 }
05456 return $res;
05457 }
05458
05471 function &processCSVRow($row, $quoteAll = FALSE, $separator = ";")
05472 {
05473 $resultarray = array();
05474 foreach ($row as $rowindex => $entry)
05475 {
05476 $surround = FALSE;
05477 if ($quoteAll)
05478 {
05479 $surround = TRUE;
05480 }
05481 if (strpos($entry, "\"") !== FALSE)
05482 {
05483 $entry = str_replace("\"", "\"\"", $entry);
05484 $surround = TRUE;
05485 }
05486 if (strpos($entry, $separator) !== FALSE)
05487 {
05488 $surround = TRUE;
05489 }
05490
05491 $entry = str_replace(chr(13).chr(10), chr(10), $entry);
05492 if ($surround)
05493 {
05494 $resultarray[$rowindex] = utf8_decode("\"" . $entry . "\"");
05495 }
05496 else
05497 {
05498 $resultarray[$rowindex] = utf8_decode($entry);
05499 }
05500 }
05501 return $resultarray;
05502 }
05503
05504 }
05505 ?>