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.ilObjectGUI.php";
00036
00037 require_once "./survey/classes/class.SurveyNominalQuestion.php";
00038 require_once "./survey/classes/class.SurveyTextQuestion.php";
00039 require_once "./survey/classes/class.SurveyMetricQuestion.php";
00040 require_once "./survey/classes/class.SurveyOrdinalQuestion.php";
00041 require_once "./survey/classes/class.SurveyQuestion.php";
00042
00043 class ilObjSurveyQuestionPool extends ilObject
00044 {
00051 function ilObjSurveyQuestionPool($a_id = 0,$a_call_by_reference = true)
00052 {
00053 $this->type = "spl";
00054 $this->ilObject($a_id,$a_call_by_reference);
00055
00056
00057
00058
00059
00060
00061
00062 }
00063
00067 function create($a_upload = false)
00068 {
00069 parent::create();
00070 $this->createMetaData();
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 }
00083
00090 function update()
00091 {
00092 $this->updateMetaData();
00093 if (!parent::update())
00094 {
00095 return false;
00096 }
00097
00098
00099
00100 return true;
00101 }
00102
00108 function read($a_force_db = false)
00109 {
00110 parent::read($a_force_db);
00111
00112 }
00113
00121 function ilClone($a_parent_ref)
00122 {
00123 global $rbacadmin;
00124
00125
00126 $new_ref_id = parent::ilClone($a_parent_ref);
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 return $new_ref_id;
00142 }
00143
00150 function delete()
00151 {
00152 $remove = parent::delete();
00153
00154 if (!$remove)
00155 {
00156 return false;
00157 }
00158
00159
00160 $this->deleteAllData();
00161
00162
00163 $this->deleteMetaData();
00164
00165 return true;
00166 }
00167
00168 function deleteAllData()
00169 {
00170 $query = sprintf("SELECT question_id FROM survey_question WHERE obj_fi = %s",
00171 $this->ilias->db->quote($this->getId())
00172 );
00173 $result = $this->ilias->db->query($query);
00174 $found_questions = array();
00175 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00176 {
00177 $this->removeQuestion($row["question_id"]);
00178 }
00179
00180
00181 $spl_data_dir = ilUtil::getDataDir()."/spl_data";
00182 $directory = $spl_data_dir."/spl_".$this->getId();
00183 if (is_dir($directory))
00184 {
00185 $directory = escapeshellarg($directory);
00186 exec("rm -rf $directory");
00187 }
00188 }
00189
00199 function initDefaultRoles()
00200 {
00201 global $rbacadmin;
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 return $roles ? $roles : array();
00214 }
00215
00229 function notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params = 0)
00230 {
00231 global $tree;
00232
00233 switch ($a_event)
00234 {
00235 case "link":
00236
00237
00238
00239
00240 break;
00241
00242 case "cut":
00243
00244
00245
00246 break;
00247
00248 case "copy":
00249
00250
00251
00252
00253 break;
00254
00255 case "paste":
00256
00257
00258
00259 break;
00260
00261 case "new":
00262
00263
00264
00265 break;
00266 }
00267
00268
00269 if ($a_node_id==$_GET["ref_id"])
00270 {
00271 $parent_obj =& $this->ilias->obj_factory->getInstanceByRefId($a_node_id);
00272 $parent_type = $parent_obj->getType();
00273 if($parent_type == $this->getType())
00274 {
00275 $a_node_id = (int) $tree->getParentId($a_node_id);
00276 }
00277 }
00278
00279 parent::notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params);
00280 }
00281
00287 function getTitle()
00288 {
00289
00290 return parent::getTitle();
00291
00292 }
00293
00297 function setTitle($a_title)
00298 {
00299 parent::setTitle($a_title);
00300
00301 }
00302
00308
00309
00310
00311
00312
00313
00314
00320
00321
00322
00323
00324
00325
00326
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00380 function removeQuestion($question_id)
00381 {
00382 if ($question_id < 1)
00383 return;
00384
00385 $question = new SurveyQuestion();
00386 $question->delete($question_id);
00387 }
00388
00398 function getQuestiontype($question_id)
00399 {
00400 if ($question_id < 1)
00401 return;
00402
00403 $query = sprintf("SELECT survey_questiontype.type_tag FROM survey_question, survey_questiontype WHERE survey_question.questiontype_fi = survey_questiontype.questiontype_id AND survey_question.question_id = %s",
00404 $this->ilias->db->quote($question_id)
00405 );
00406 $result = $this->ilias->db->query($query);
00407 if ($result->numRows() == 1) {
00408 $data = $result->fetchRow(DB_FETCHMODE_OBJECT);
00409 return $data->type_tag;
00410 } else {
00411 return;
00412 }
00413 }
00414
00424 function isInUse($question_id)
00425 {
00426
00427 $query = sprintf("SELECT answer_id FROM survey_answer WHERE question_fi = %s",
00428 $this->ilias->db->quote($question_id)
00429 );
00430 $result = $this->ilias->db->query($query);
00431 $answered = $result->numRows();
00432
00433
00434 $query = sprintf("SELECT survey_survey.* FROM survey_survey, survey_survey_question WHERE survey_survey_question.survey_fi = survey_survey.survey_id AND survey_survey_question.question_fi = %s",
00435 $this->ilias->db->quote($question_id)
00436 );
00437 $result = $this->ilias->db->query($query);
00438 $inserted = $result->numRows();
00439 if (($inserted + $answered) == 0)
00440 {
00441 return false;
00442 }
00443 $result_array = array();
00444 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00445 {
00446 array_push($result_array, $row);
00447 }
00448 return $result_array;
00449 }
00450
00459 function paste($question_id)
00460 {
00461 $this->duplicateQuestion($question_id, $this->getId());
00462 }
00463
00473 function &getQuestionsInfo($question_array)
00474 {
00475 $result_array = array();
00476 $query = sprintf("SELECT survey_question.*, survey_questiontype.type_tag FROM survey_question, survey_questiontype WHERE survey_question.questiontype_fi = survey_questiontype.questiontype_id AND survey_question.question_id IN (%s)",
00477 join($question_array, ",")
00478 );
00479 $result = $this->ilias->db->query($query);
00480 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00481 {
00482 array_push($result_array, $row);
00483 }
00484 return $result_array;
00485 }
00486
00495 function duplicateQuestion($question_id, $obj_id = "") {
00496 global $ilUser;
00497
00498 $questiontype = $this->getQuestiontype($question_id);
00499 switch ($questiontype)
00500 {
00501 case "qt_nominal":
00502 $question = new SurveyNominalQuestion();
00503 break;
00504 case "qt_ordinal":
00505 $question = new SurveyOrdinalQuestion();
00506 break;
00507 case "qt_metric":
00508 $question = new SurveyMetricQuestion();
00509 break;
00510 case "qt_text":
00511 $question = new SurveyTextQuestion();
00512 break;
00513 }
00514 $question->loadFromDb($question_id);
00515 $counter = 2;
00516 while ($question->questionTitleExists($question->getTitle() . " ($counter)")) {
00517 $counter++;
00518 }
00519 if ($obj_id)
00520 {
00521 $question->setObjId($obj_id);
00522 }
00523 $question->duplicate(false, $question->getTitle() . " ($counter)", $ilUser->fullname, $ilUser->id);
00524 }
00525
00534 function deletePhrases($phrase_array)
00535 {
00536 $query = "DELETE FROM survey_phrase WHERE phrase_id IN (" . join($phrase_array, ",") . ")";
00537 $result = $this->ilias->db->query($query);
00538 $query = "DELETE FROM survey_phrase_category WHERE phrase_fi IN (" . join($phrase_array, ",") . ")";
00539 $result = $this->ilias->db->query($query);
00540 }
00541
00549 function getQuestionsTable($sortoptions, $filter_text, $sel_filter_type, $startrow = 0)
00550 {
00551 global $ilUser;
00552 $where = "";
00553 if (strlen($filter_text) > 0) {
00554 switch($sel_filter_type) {
00555 case "title":
00556 $where = " AND survey_question.title LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
00557 break;
00558 case "description":
00559 $where = " AND survey_question.description LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
00560 break;
00561 case "author":
00562 $where = " AND survey_question.author LIKE " . $this->ilias->db->quote("%" . $filter_text . "%");
00563 break;
00564 }
00565 }
00566
00567
00568 $order = "";
00569 $images = array();
00570 if (count($sortoptions)) {
00571 foreach ($sortoptions as $key => $value) {
00572 switch($key) {
00573 case "title":
00574 $order = " ORDER BY title $value";
00575 $images["title"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
00576 break;
00577 case "description":
00578 $order = " ORDER BY description $value";
00579 $images["description"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
00580 break;
00581 case "type":
00582 $order = " ORDER BY questiontype_id $value";
00583 $images["type"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
00584 break;
00585 case "author":
00586 $order = " ORDER BY author $value";
00587 $images["author"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
00588 break;
00589 case "created":
00590 $order = " ORDER BY created $value";
00591 $images["created"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
00592 break;
00593 case "updated":
00594 $order = " ORDER BY TIMESTAMP14 $value";
00595 $images["updated"] = " <img src=\"" . ilUtil::getImagePath(strtolower($value) . "_order.png", true) . "\" alt=\"" . strtolower($value) . "ending order\" />";
00596 break;
00597 }
00598 }
00599 }
00600 $maxentries = $ilUser->prefs["hits_per_page"];
00601 if ($maxentries < 1)
00602 {
00603 $maxentries = 9999;
00604 }
00605 $query = "SELECT survey_question.question_id, survey_question.TIMESTAMP + 0 AS TIMESTAMP14 FROM survey_question, survey_questiontype WHERE survey_question.questiontype_fi = survey_questiontype.questiontype_id AND survey_question.obj_fi = " . $this->getId() . " AND ISNULL(survey_question.original_id) $where$order$limit";
00606 $query_result = $this->ilias->db->query($query);
00607 $max = $query_result->numRows();
00608 if ($startrow > $max -1)
00609 {
00610 $startrow = $max - ($max % $maxentries);
00611 }
00612 else if ($startrow < 0)
00613 {
00614 $startrow = 0;
00615 }
00616 $limit = " LIMIT $startrow, $maxentries";
00617 $query = "SELECT survey_question.*, survey_question.TIMESTAMP + 0 AS TIMESTAMP14, survey_questiontype.type_tag FROM survey_question, survey_questiontype WHERE survey_question.questiontype_fi = survey_questiontype.questiontype_id AND survey_question.obj_fi = " . $this->getId() . " AND ISNULL(survey_question.original_id) $where$order$limit";
00618 $query_result = $this->ilias->db->query($query);
00619 $rows = array();
00620 if ($query_result->numRows())
00621 {
00622 while ($row = $query_result->fetchRow(DB_FETCHMODE_ASSOC))
00623 {
00624 array_push($rows, $row);
00625 }
00626 }
00627 $nextrow = $startrow + $maxentries;
00628 if ($nextrow > $max - 1)
00629 {
00630 $nextrow = $startrow;
00631 }
00632 $prevrow = $startrow - $maxentries;
00633 if ($prevrow < 0)
00634 {
00635 $prevrow = 0;
00636 }
00637 return array(
00638 "rows" => $rows,
00639 "images" => $images,
00640 "startrow" => $startrow,
00641 "nextrow" => $nextrow,
00642 "prevrow" => $prevrow,
00643 "step" => $maxentries,
00644 "rowcount" => $max
00645 );
00646 }
00647
00653 function createExportDirectory()
00654 {
00655 $spl_data_dir = ilUtil::getDataDir()."/spl_data";
00656 ilUtil::makeDir($spl_data_dir);
00657 if(!is_writable($spl_data_dir))
00658 {
00659 $this->ilias->raiseError("Survey Questionpool Data Directory (".$spl_data_dir
00660 .") not writeable.",$this->ilias->error_obj->FATAL);
00661 }
00662
00663
00664 $spl_dir = $spl_data_dir."/spl_".$this->getId();
00665 ilUtil::makeDir($spl_dir);
00666 if(!@is_dir($spl_dir))
00667 {
00668 $this->ilias->raiseError("Creation of Survey Questionpool Directory failed.",$this->ilias->error_obj->FATAL);
00669 }
00670
00671 $export_dir = $spl_dir."/export";
00672 ilUtil::makeDir($export_dir);
00673 if(!@is_dir($export_dir))
00674 {
00675 $this->ilias->raiseError("Creation of Export Directory failed.",$this->ilias->error_obj->FATAL);
00676 }
00677 }
00678
00682 function getExportDirectory()
00683 {
00684 $export_dir = ilUtil::getDataDir()."/spl_data"."/spl_".$this->getId()."/export";
00685
00686 return $export_dir;
00687 }
00688
00692 function getExportFiles($dir)
00693 {
00694
00695 if (!@is_dir($dir) or
00696 !is_writeable($dir))
00697 {
00698 return array();
00699 }
00700
00701
00702 $dir = dir($dir);
00703
00704
00705 $file = array();
00706
00707
00708 while ($entry = $dir->read())
00709 {
00710 if ($entry != "." and
00711 $entry != ".." and
00712 substr($entry, -4) == ".xml" and
00713 ereg("^[0-9]{10}_{2}[0-9]+_{2}(spl__)*[0-9]+\.xml\$", $entry))
00714 {
00715 $file[] = $entry;
00716 }
00717 }
00718
00719
00720 $dir->close();
00721
00722 sort ($file);
00723 reset ($file);
00724
00725 return $file;
00726 }
00727
00733 function createImportDirectory()
00734 {
00735 $spl_data_dir = ilUtil::getDataDir()."/spl_data";
00736 ilUtil::makeDir($spl_data_dir);
00737
00738 if(!is_writable($spl_data_dir))
00739 {
00740 $this->ilias->raiseError("Survey Questionpool Data Directory (".$spl_data_dir
00741 .") not writeable.",$this->ilias->error_obj->FATAL);
00742 }
00743
00744
00745 $spl_dir = $spl_data_dir."/spl_".$this->getId();
00746 ilUtil::makeDir($spl_dir);
00747 if(!@is_dir($spl_dir))
00748 {
00749 $this->ilias->raiseError("Creation of Survey Questionpool Directory failed.",$this->ilias->error_obj->FATAL);
00750 }
00751
00752
00753 $import_dir = $spl_dir."/import";
00754 ilUtil::makeDir($import_dir);
00755 if(!@is_dir($import_dir))
00756 {
00757 $this->ilias->raiseError("Creation of Import Directory failed.",$this->ilias->error_obj->FATAL);
00758 }
00759 }
00760
00764 function getImportDirectory()
00765 {
00766 $import_dir = ilUtil::getDataDir()."/spl_data".
00767 "/spl_".$this->getId()."/import";
00768 if(@is_dir($import_dir))
00769 {
00770 return $import_dir;
00771 }
00772 else
00773 {
00774 return false;
00775 }
00776 }
00777
00781 function to_xml($questions)
00782 {
00783 if (!is_array($questions))
00784 {
00785 $questions =& $this->getQuestions();
00786 }
00787 if (count($questions) == 0)
00788 {
00789 $questions =& $this->getQuestions();
00790 }
00791 $xml = "";
00792
00793 foreach ($questions as $key => $value)
00794 {
00795 $questiontype = $this->getQuestiontype($value);
00796 switch ($questiontype)
00797 {
00798 case "qt_nominal":
00799 $question = new SurveyNominalQuestion();
00800 break;
00801 case "qt_ordinal":
00802 $question = new SurveyOrdinalQuestion();
00803 break;
00804 case "qt_metric":
00805 $question = new SurveyMetricQuestion();
00806 break;
00807 case "qt_text":
00808 $question = new SurveyTextQuestion();
00809 break;
00810 }
00811 $question->loadFromDb($value);
00812 $xml .= $question->to_xml(false);
00813 }
00814 if (count($questions) > 1)
00815 {
00816 $xml = preg_replace("/<\/questestinterop>\s*<questestinterop>/", "", $xml);
00817 }
00818 $xml = str_replace("<questestinterop>", "", $xml);
00819 $xml = str_replace("</questestinterop>", "", $xml);
00820
00821
00822 $xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00823 $xml_header .= "<questestinterop></questestinterop>\n";
00824 $domxml = domxml_open_mem($xml_header);
00825 $root = $domxml->document_element();
00826
00827
00828 $qtiSection = $domxml->create_element("section");
00829 $qtiSection->set_attribute("ident", "qpl_" . $this->getId());
00830 $qtiSection->set_attribute("title", $this->getTitle());
00831
00832
00833 $qtiMetadata = $domxml->create_element("qtimetadata");
00834 $qtiMetadatafield = $domxml->create_element("qtimetadatafield");
00835 $qtiFieldlabel = $domxml->create_element("fieldlabel");
00836 $qtiFieldlabelText = $domxml->create_text_node("SCORM");
00837 $qtiFieldlabel->append_child($qtiFieldlabelText);
00838 $qtiFieldentry = $domxml->create_element("fieldentry");
00839
00840
00841
00842
00843
00844
00845 $qtiFieldentryText = $domxml->create_CDATA_Section($metadata);
00846 $qtiFieldentry->append_child($qtiFieldentryText);
00847 $qtiMetadatafield->append_child($qtiFieldlabel);
00848 $qtiMetadatafield->append_child($qtiFieldentry);
00849 $qtiMetadata->append_child($qtiMetadatafield);
00850 $qtiSection->append_child($qtiMetadata);
00851 $root->append_child($qtiSection);
00852 $qtixml = $domxml->dump_mem(true);
00853 $qtixml = str_replace("</section>", $xml . "\n</section>", $qtixml);
00854 $domxml->free();
00855 return $qtixml;
00856 }
00857
00858 function &getQuestions()
00859 {
00860 $questions = array();
00861 $query = sprintf("SELECT question_id FROM survey_question WHERE obj_fi = %s AND ISNULL(original_id)",
00862 $this->ilias->db->quote($this->getId() . "")
00863 );
00864 $result = $this->ilias->db->query($query);
00865 if ($result->numRows())
00866 {
00867 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
00868 {
00869 array_push($questions, $row["question_id"]);
00870 }
00871 }
00872 return $questions;
00873 }
00874
00875 function importObject($source)
00876 {
00877 $metadata = "";
00878 if (is_file($source))
00879 {
00880 $fh = fopen($source, "r") or die("");
00881 $xml = fread($fh, filesize($source));
00882 fclose($fh) or die("");
00883
00884
00885 $xml = preg_replace("/>\s*?</", "><", $xml);
00886 $domxml = domxml_open_mem($xml);
00887 if (!empty($domxml))
00888 {
00889 $nodeList = $domxml->get_elements_by_tagname("fieldlabel");
00890 foreach ($nodeList as $node)
00891 {
00892 switch ($node->get_content())
00893 {
00894 case "SCORM":
00895 $metanode = $node->next_sibling();
00896 if (strcmp($metanode->node_name(), "fieldentry") == 0)
00897 {
00898 $metadata = $metanode->get_content();
00899 }
00900 }
00901 }
00902 $domxml->free();
00903 }
00904
00905
00906 if (preg_match_all("/(<item[^>]*>.*?<\/item>)/si", $xml, $matches))
00907 {
00908 foreach ($matches[1] as $index => $item)
00909 {
00910
00911 if (preg_match("/(<item[^>]*>)/is", $item, $start_tag))
00912 {
00913 if (preg_match("/(ident=\"([^\"]*)\")/is", $start_tag[1], $ident))
00914 {
00915 $ident = $ident[2];
00916 }
00917 }
00918 $question = "";
00919 if (preg_match("/<qticomment>Questiontype\=(.*?)<\/qticomment>/is", $item, $questiontype))
00920 {
00921 switch ($questiontype[1])
00922 {
00923 case NOMINAL_QUESTION_IDENTIFIER:
00924 $question = new SurveyNominalQuestion();
00925 break;
00926 case ORDINAL_QUESTION_IDENTIFIER:
00927 $question = new SurveyOrdinalQuestion();
00928 break;
00929 case METRIC_QUESTION_IDENTIFIER:
00930 $question = new SurveyMetricQuestion();
00931 break;
00932 case TEXT_QUESTION_IDENTIFIER:
00933 $question = new SurveyTextQuestion();
00934 break;
00935 }
00936 if ($question)
00937 {
00938 $question->setObjId($this->getId());
00939 if ($question->from_xml("<questestinterop>$item</questestinterop>"))
00940 {
00941 $question->saveToDb();
00942 }
00943 else
00944 {
00945 $this->ilias->raiseError($this->lng->txt("error_importing_question"), $this->ilias->error_obj->MESSAGE);
00946 }
00947 }
00948 }
00949 }
00950 }
00951
00952 if ($metadata)
00953 {
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 }
00979
00980 }
00981 }
00982
00992 function _isWriteable($object_id, $user_id)
00993 {
00994 global $rbacsystem;
00995 global $ilDB;
00996
00997 $result_array = array();
00998 $query = sprintf("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.obj_id = %s",
00999 $ilDB->quote($object_id . "")
01000 );
01001 $result = $ilDB->query($query);
01002 while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))
01003 {
01004 include_once "./classes/class.ilObject.php";
01005 if ($rbacsystem->checkAccess("write", $row["ref_id"]) && (ilObject::_hasUntrashedReference($row["obj_id"])))
01006 {
01007 return true;
01008 }
01009 }
01010 return false;
01011 }
01012
01013 }
01014 ?>