ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilObjQuestionPool.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
5
17{
23 public $online;
24
30 private $showTaxonomies = null;
31
37 private $navTaxonomyId = null;
38
43
48 private $import_dir;
49
56 public function __construct($a_id = 0, $a_call_by_reference = true)
57 {
58 $this->type = "qpl";
59 parent::__construct($a_id, $a_call_by_reference);
60 $this->setOnline(0);
61
62 $this->skillServiceEnabled = false;
63 }
64
68 public function create($a_upload = false)
69 {
70 parent::create();
71
72 // meta data will be created by
73 // import parser
74 if (!$a_upload) {
75 $this->createMetaData();
76 }
77 }
78
85 public function createReference()
86 {
87 $result = parent::createReference();
88 $this->saveToDb();
89 return $result;
90 }
91
98 public function update()
99 {
100 $this->updateMetaData();
101 if (!parent::update()) {
102 return false;
103 }
104
105 // put here object specific stuff
106
107 return true;
108 }
109
110 public function updateMetaData()
111 {
112 global $DIC;
113 $ilUser = $DIC['ilUser'];
114 include_once "./Services/MetaData/classes/class.ilMD.php";
115 $md = new ilMD($this->getId(), 0, $this->getType());
116 $md_gen = &$md->getGeneral();
117 if ($md_gen == false) {
118 include_once "./Services/MetaData/classes/class.ilMDCreator.php";
119 $md_creator = new ilMDCreator($this->getId(), 0, $this->getType());
120 $md_creator->setTitle($this->getTitle());
121 $md_creator->setTitleLanguage($ilUser->getPref('language'));
122 $md_creator->create();
123 }
124 parent::updateMetaData();
125 }
126
132 public function read($a_force_db = false)
133 {
134 parent::read($a_force_db);
135 $this->loadFromDb();
136 }
137
138
145 public function delete()
146 {
147 // always call parent delete function first!!
148 if (!parent::delete()) {
149 return false;
150 }
151
152 // delete meta data
153 $this->deleteMetaData();
154
155 //put here your module specific stuff
156 $this->deleteQuestionpool();
157
158 require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionSkillAssignmentImportFails.php';
159 $qsaImportFails = new ilAssQuestionSkillAssignmentImportFails($this->getId());
160 $qsaImportFails->deleteRegisteredImportFails();
161
162 return true;
163 }
164
165 public function deleteQuestionpool()
166 {
167 $questions = &$this->getAllQuestions();
168
169 if (count($questions)) {
170 foreach ($questions as $question_id) {
171 $this->deleteQuestion($question_id);
172 }
173 }
174
175 // delete export files
176 include_once "./Services/Utilities/classes/class.ilUtil.php";
177 $qpl_data_dir = ilUtil::getDataDir() . "/qpl_data";
178 $directory = $qpl_data_dir . "/qpl_" . $this->getId();
179 if (is_dir($directory)) {
180 include_once "./Services/Utilities/classes/class.ilUtil.php";
181 ilUtil::delDir($directory);
182 }
183 }
184
191 public function deleteQuestion($question_id)
192 {
193 include_once "./Modules/Test/classes/class.ilObjTest.php";
194 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
195
196 $question = assQuestion::_instanciateQuestion($question_id);
197 $this->addQuestionChangeListeners($question);
198 $question->delete($question_id);
199 }
200
204 public function addQuestionChangeListeners(assQuestion $question)
205 {
206 global $DIC;
207 $ilDB = $DIC['ilDB'];
208
209 foreach (ilObjTest::getPoolQuestionChangeListeners($ilDB, $this->getId()) as $listener) {
210 $question->addQuestionChangeListener($listener);
211 }
212 }
213
219 public function loadFromDb()
220 {
221 global $DIC;
222 $ilDB = $DIC['ilDB'];
223
224 $result = $ilDB->queryF(
225 "SELECT * FROM qpl_questionpool WHERE obj_fi = %s",
226 array('integer'),
227 array($this->getId())
228 );
229 if ($result->numRows() == 1) {
230 $row = $ilDB->fetchAssoc($result);
231 $this->setOnline($row['isonline']);
232 $this->setShowTaxonomies($row['show_taxonomies']);
233 $this->setNavTaxonomyId($row['nav_taxonomy']);
234 $this->setSkillServiceEnabled($row['skill_service']);
235 }
236 }
237
243 public function saveToDb()
244 {
245 global $DIC;
246 $ilDB = $DIC['ilDB'];
247
248 $result = $ilDB->queryF(
249 "SELECT id_questionpool FROM qpl_questionpool WHERE obj_fi = %s",
250 array('integer'),
251 array($this->getId())
252 );
253
254 if ($result->numRows() == 1) {
255 $result = $ilDB->update(
256 'qpl_questionpool',
257 array(
258 'isonline' => array('text', $this->getOnline()),
259 'show_taxonomies' => array('integer', (int) $this->getShowTaxonomies()),
260 'nav_taxonomy' => array('integer', (int) $this->getNavTaxonomyId()),
261 'skill_service' => array('integer', (int) $this->isSkillServiceEnabled()),
262 'tstamp' => array('integer', time())
263 ),
264 array(
265 'obj_fi' => array('integer', $this->getId())
266 )
267 );
268 } else {
269 $next_id = $ilDB->nextId('qpl_questionpool');
270
271 $result = $ilDB->insert('qpl_questionpool', array(
272 'id_questionpool' => array('integer', $next_id),
273 'isonline' => array('text', $this->getOnline()),
274 'show_taxonomies' => array('integer', (int) $this->getShowTaxonomies()),
275 'nav_taxonomy' => array('integer', (int) $this->getNavTaxonomyId()),
276 'skill_service' => array('integer', (int) $this->isSkillServiceEnabled()),
277 'tstamp' => array('integer', time()),
278 'obj_fi' => array('integer', $this->getId())
279 ));
280 }
281 }
282
290 public function getQuestiontype($question_id)
291 {
292 global $DIC;
293 $ilDB = $DIC['ilDB'];
294
295 if ($question_id < 1) {
296 return;
297 }
298
299 $result = $ilDB->queryF(
300 "SELECT qpl_qst_type.type_tag FROM qpl_questions, qpl_qst_type WHERE qpl_questions.question_type_fi = qpl_qst_type.question_type_id AND qpl_questions.question_id = %s",
301 array('integer'),
302 array($question_id)
303 );
304 if ($result->numRows() == 1) {
305 $data = $ilDB->fetchAssoc($result);
306 return $data["type_tag"];
307 } else {
308 return;
309 }
310 }
311
317 public function getDescription()
318 {
319 return parent::getDescription();
320 }
321
325 public function setDescription($a_description)
326 {
327 parent::setDescription($a_description);
328 }
329
335 public function getTitle()
336 {
337 return parent::getTitle();
338 }
339
343 public function setTitle($a_title)
344 {
345 parent::setTitle($a_title);
346 }
347
355 public function isInUse($question_id)
356 {
357 global $DIC;
358 $ilDB = $DIC['ilDB'];
359
360 $result = $ilDB->queryF(
361 "SELECT COUNT(solution_id) solution_count FROM tst_solutions WHERE question_fi = %s",
362 array('integer'),
363 array($question_id)
364 );
365 $row = $ilDB->fetchAssoc($result);
366 return $row["solution_count"];
367 }
368
369 public function &createQuestion($question_type, $question_id = -1)
370 {
371 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
372 if ($question_id > 0) {
373 return assQuestion::_instanciateQuestionGUI($question_id);
374 }
375 assQuestion::_includeClass($question_type, 1);
376 $question_type_gui = $question_type . "GUI";
377 $question_gui = new $question_type_gui();
378 return $question_gui;
379 }
380
387 public function duplicateQuestion($question_id)
388 {
389 $question = &$this->createQuestion("", $question_id);
390 $newtitle = $question->object->getTitle();
391 if ($question->object->questionTitleExists($this->getId(), $question->object->getTitle())) {
392 $counter = 2;
393 while ($question->object->questionTitleExists($this->getId(), $question->object->getTitle() . " ($counter)")) {
394 $counter++;
395 }
396 $newtitle = $question->object->getTitle() . " ($counter)";
397 }
398 $new_id = $question->object->duplicate(false, $newtitle);
399 // update question count of question pool
401 return $new_id;
402 }
403
411 public function copyQuestion($question_id, $questionpool_to)
412 {
413 $question_gui = &$this->createQuestion("", $question_id);
414 if ($question_gui->object->getObjId() == $questionpool_to) {
415 // the question is copied into the same question pool
416 return $this->duplicateQuestion($question_id);
417 } else {
418 // the question is copied into another question pool
419 $newtitle = $question_gui->object->getTitle();
420 if ($question_gui->object->questionTitleExists($this->getId(), $question_gui->object->getTitle())) {
421 $counter = 2;
422 while ($question_gui->object->questionTitleExists($this->getId(), $question_gui->object->getTitle() . " ($counter)")) {
423 $counter++;
424 }
425 $newtitle = $question_gui->object->getTitle() . " ($counter)";
426 }
427 return $question_gui->object->copyObject($this->getId(), $newtitle);
428 }
429 }
430
436 public function getPrintviewQuestions()
437 {
438 global $DIC;
439 $ilDB = $DIC['ilDB'];
440
441 $query_result = $ilDB->queryF(
442 "SELECT qpl_questions.*, qpl_qst_type.type_tag, qpl_qst_type.plugin, qpl_questions.tstamp updated FROM qpl_questions, qpl_qst_type WHERE qpl_questions.original_id IS NULL AND qpl_questions.tstamp > 0 AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id AND qpl_questions.obj_fi = %s",
443 array('integer'),
444 array($this->getId())
445 );
446 $rows = array();
447 $types = $this->getQuestionTypeTranslations();
448 if ($query_result->numRows()) {
449 while ($row = $ilDB->fetchAssoc($query_result)) {
450 $row['ttype'] = $types[$row['type_tag']];
451 if ($row["plugin"]) {
452 if ($this->isPluginActive($row["type_tag"])) {
453 array_push($rows, $row);
454 }
455 } else {
456 array_push($rows, $row);
457 }
458 }
459 }
460 return $rows;
461 }
462
466 private function exportXMLSettings($xmlWriter)
467 {
468 $xmlWriter->xmlStartTag('Settings');
469
470 $xmlWriter->xmlElement('ShowTaxonomies', null, (int) $this->getShowTaxonomies());
471 $xmlWriter->xmlElement('NavTaxonomy', null, (int) $this->getNavTaxonomyId());
472 $xmlWriter->xmlElement('SkillService', null, (int) $this->isSkillServiceEnabled());
473
474 $xmlWriter->xmlEndTag('Settings');
475 }
476
483 public function objectToXmlWriter(ilXmlWriter &$a_xml_writer, $a_inst, $a_target_dir, &$expLog, $questions)
484 {
485 global $DIC;
486 $ilBench = $DIC['ilBench'];
487
488 $this->mob_ids = array();
489 $this->file_ids = array();
490
491 $attrs = array();
492 $attrs["Type"] = "Questionpool_Test";
493 $a_xml_writer->xmlStartTag("ContentObject", $attrs);
494
495 // MetaData
496 $this->exportXMLMetaData($a_xml_writer);
497
498 // Settings
499 $this->exportXMLSettings($a_xml_writer);
500
501 // PageObjects
502 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Page Objects");
503 $ilBench->start("ContentObjectExport", "exportPageObjects");
504 $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog, $questions);
505 $ilBench->stop("ContentObjectExport", "exportPageObjects");
506 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Page Objects");
507
508 // MediaObjects
509 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Media Objects");
510 $ilBench->start("ContentObjectExport", "exportMediaObjects");
511 $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
512 $ilBench->stop("ContentObjectExport", "exportMediaObjects");
513 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Media Objects");
514
515 // FileItems
516 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export File Items");
517 $ilBench->start("ContentObjectExport", "exportFileItems");
518 $this->exportFileItems($a_target_dir, $expLog);
519 $ilBench->stop("ContentObjectExport", "exportFileItems");
520 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export File Items");
521
522 // skill assignments
523 $this->populateQuestionSkillAssignmentsXml($a_xml_writer, $questions);
524
525 $a_xml_writer->xmlEndTag("ContentObject");
526 }
527
532 protected function populateQuestionSkillAssignmentsXml(ilXmlWriter &$a_xml_writer, $questions)
533 {
534 global $DIC;
535 $ilDB = $DIC['ilDB'];
536
537 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
538 $assignmentList = new ilAssQuestionSkillAssignmentList($ilDB);
539 $assignmentList->setParentObjId($this->getId());
540 $assignmentList->loadFromDb();
541 $assignmentList->loadAdditionalSkillData();
542
543 require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionSkillAssignmentExporter.php';
544 $skillQuestionAssignmentExporter = new ilAssQuestionSkillAssignmentExporter();
545 $skillQuestionAssignmentExporter->setXmlWriter($a_xml_writer);
546 $skillQuestionAssignmentExporter->setQuestionIds($questions);
547 $skillQuestionAssignmentExporter->setAssignmentList($assignmentList);
548 $skillQuestionAssignmentExporter->export();
549 }
550
557 public function exportXMLMetaData(&$a_xml_writer)
558 {
559 include_once("Services/MetaData/classes/class.ilMD2XML.php");
560 $md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
561 $md2xml->setExportMode(true);
562 $md2xml->startExport();
563 $a_xml_writer->appendXML($md2xml->getXML());
564 }
565
566 public function modifyExportIdentifier($a_tag, $a_param, $a_value)
567 {
568 if ($a_tag == "Identifier" && $a_param == "Entry") {
569 include_once "./Services/Utilities/classes/class.ilUtil.php";
570 $a_value = ilUtil::insertInstIntoID($a_value);
571 }
572
573 return $a_value;
574 }
575
576
583 public function exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog, $questions)
584 {
585 global $DIC;
586 $ilBench = $DIC['ilBench'];
587
588 include_once "./Modules/LearningModule/classes/class.ilLMPageObject.php";
589
590 foreach ($questions as $question_id) {
591 $ilBench->start("ContentObjectExport", "exportPageObject");
592 $expLog->write(date("[y-m-d H:i:s] ") . "Page Object " . $question_id);
593
594 $attrs = array();
595 $a_xml_writer->xmlStartTag("PageObject", $attrs);
596
597
598 // export xml to writer object
599 $ilBench->start("ContentObjectExport", "exportPageObject_XML");
600 include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php");
601 $page_object = new ilAssQuestionPage($question_id);
602 $page_object->buildDom();
603 $page_object->insertInstIntoIDs($a_inst);
604 $mob_ids = $page_object->collectMediaObjects(false);
605 require_once 'Services/COPage/classes/class.ilPCFileList.php';
606 $file_ids = ilPCFileList::collectFileItems($page_object, $page_object->getDomDoc());
607 $xml = $page_object->getXMLFromDom(false, false, false, "", true);
608 $xml = str_replace("&", "&amp;", $xml);
609 $a_xml_writer->appendXML($xml);
610 $page_object->freeDom();
611 unset($page_object);
612
613 $ilBench->stop("ContentObjectExport", "exportPageObject_XML");
614
615 // collect media objects
616 $ilBench->start("ContentObjectExport", "exportPageObject_CollectMedia");
617 foreach ($mob_ids as $mob_id) {
618 $this->mob_ids[$mob_id] = $mob_id;
619 }
620 $ilBench->stop("ContentObjectExport", "exportPageObject_CollectMedia");
621
622 // collect all file items
623 $ilBench->start("ContentObjectExport", "exportPageObject_CollectFileItems");
624 //$file_ids = $page_obj->getFileItemIds();
625 foreach ($file_ids as $file_id) {
626 $this->file_ids[$file_id] = $file_id;
627 }
628 $ilBench->stop("ContentObjectExport", "exportPageObject_CollectFileItems");
629
630 $a_xml_writer->xmlEndTag("PageObject");
631
632 $ilBench->stop("ContentObjectExport", "exportPageObject");
633 }
634 }
635
642 public function exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
643 {
644 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
645
646 foreach ($this->mob_ids as $mob_id) {
647 $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
648 if (ilObjMediaObject::_exists($mob_id)) {
649 $media_obj = new ilObjMediaObject($mob_id);
650 $media_obj->exportXML($a_xml_writer, $a_inst);
651 $media_obj->exportFiles($a_target_dir);
652 unset($media_obj);
653 }
654 }
655 }
656
661 public function exportFileItems($target_dir, &$expLog) : void
662 {
663 include_once("./Modules/File/classes/class.ilObjFile.php");
664
665 foreach ($this->file_ids as $file_id) {
666 $expLog->write(date("[y-m-d H:i:s] ") . "File Item " . $file_id);
667 $file_dir = $target_dir . '/objects/il_' . IL_INST_ID . '_file_' . $file_id;
668 ilUtil::makeDir($file_dir);
669 $file_obj = new ilObjFile($file_id, false);
670 $source_file = $file_obj->getFile($file_obj->getVersion());
671 if (!is_file($source_file)) {
672 $source_file = $file_obj->getFile();
673 }
674 if (is_file($source_file)) {
675 copy($source_file, $file_dir . '/' . $file_obj->getFileName());
676 }
677 unset($file_obj);
678 }
679 }
680
686 public function createExportDirectory()
687 {
688 include_once "./Services/Utilities/classes/class.ilUtil.php";
689 $qpl_data_dir = ilUtil::getDataDir() . "/qpl_data";
690 ilUtil::makeDir($qpl_data_dir);
691 if (!is_writable($qpl_data_dir)) {
692 $this->ilias->raiseError("Questionpool Data Directory (" . $qpl_data_dir
693 . ") not writeable.", $this->ilias->error_obj->FATAL);
694 }
695
696 // create learning module directory (data_dir/lm_data/lm_<id>)
697 $qpl_dir = $qpl_data_dir . "/qpl_" . $this->getId();
698 ilUtil::makeDir($qpl_dir);
699 if (!@is_dir($qpl_dir)) {
700 $this->ilias->raiseError("Creation of Questionpool Directory failed.", $this->ilias->error_obj->FATAL);
701 }
702 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
703 ilUtil::makeDir($this->getExportDirectory('xls'));
704 if (!@is_dir($this->getExportDirectory('xls'))) {
705 $this->ilias->raiseError("Creation of Export Directory failed.", $this->ilias->error_obj->FATAL);
706 }
707 ilUtil::makeDir($this->getExportDirectory('zip'));
708 if (!@is_dir($this->getExportDirectory('zip'))) {
709 $this->ilias->raiseError("Creation of Export Directory failed.", $this->ilias->error_obj->FATAL);
710 }
711 }
712
716 public function getExportDirectory($type = "")
717 {
718 include_once "./Services/Utilities/classes/class.ilUtil.php";
719 switch ($type) {
720 case 'xml':
721 include_once("./Services/Export/classes/class.ilExport.php");
722 $export_dir = ilExport::_getExportDirectory($this->getId(), $type, $this->getType());
723 break;
724 case 'xls':
725 case 'zip':
726 $export_dir = ilUtil::getDataDir() . "/qpl_data" . "/qpl_" . $this->getId() . "/export_$type";
727 break;
728 default:
729 $export_dir = ilUtil::getDataDir() . "/qpl_data" . "/qpl_" . $this->getId() . "/export";
730 break;
731 }
732 return $export_dir;
733 }
734
740 public static function _createImportDirectory()
741 {
742 global $DIC;
743 $ilias = $DIC['ilias'];
744
745 include_once "./Services/Utilities/classes/class.ilUtil.php";
746 $qpl_data_dir = ilUtil::getDataDir() . "/qpl_data";
747 ilUtil::makeDir($qpl_data_dir);
748
749 if (!is_writable($qpl_data_dir)) {
750 $ilias->raiseError("Questionpool Data Directory (" . $qpl_data_dir
751 . ") not writeable.", $ilias->error_obj->FATAL);
752 }
753
754 // create questionpool directory (data_dir/qpl_data/qpl_import)
755 $qpl_dir = $qpl_data_dir . "/qpl_import";
756 ilUtil::makeDir($qpl_dir);
757 if (!@is_dir($qpl_dir)) {
758 $ilias->raiseError("Creation of Questionpool Directory failed.", $ilias->error_obj->FATAL);
759 }
760 return $qpl_dir;
761 }
762
766 public static function _setImportDirectory($a_import_dir = null)
767 {
768 if (strlen($a_import_dir)) {
769 $_SESSION["qpl_import_dir"] = $a_import_dir;
770 } else {
771 unset($_SESSION["qpl_import_dir"]);
772 }
773 }
774
778 public static function _getImportDirectory()
779 {
780 if (strlen($_SESSION["qpl_import_dir"])) {
781 return $_SESSION["qpl_import_dir"];
782 }
783 return null;
784 }
785
786 public function getImportDirectory()
787 {
789 }
790
796 public function &getAllQuestions()
797 {
798 global $DIC;
799 $ilDB = $DIC['ilDB'];
800
801 $result = $ilDB->queryF(
802 "SELECT question_id FROM qpl_questions WHERE obj_fi = %s AND qpl_questions.tstamp > 0 AND original_id IS NULL",
803 array('integer'),
804 array($this->getId())
805 );
806 $questions = array();
807 while ($row = $ilDB->fetchAssoc($result)) {
808 array_push($questions, $row["question_id"]);
809 }
810 return $questions;
811 }
812
813 public function &getAllQuestionIds()
814 {
815 global $DIC;
816 $ilDB = $DIC['ilDB'];
817
818 $query_result = $ilDB->queryF(
819 "SELECT question_id, qpl_qst_type.type_tag, qpl_qst_type.plugin FROM qpl_questions, qpl_qst_type WHERE original_id IS NULL AND qpl_questions.tstamp > 0 AND obj_fi = %s AND complete = %s AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
820 array('integer','text'),
821 array($this->getId(), 1)
822 );
823 $questions = array();
824 if ($query_result->numRows()) {
825 while ($row = $ilDB->fetchAssoc($query_result)) {
826 if ($row["plugin"]) {
827 if ($this->isPluginActive($row["type_tag"])) {
828 array_push($questions, $row["question_id"]);
829 }
830 } else {
831 array_push($questions, $row["question_id"]);
832 }
833 }
834 }
835 return $questions;
836 }
837
838 public function checkQuestionParent($questionId)
839 {
840 global $DIC; /* @var ILIAS\DI\Container $DIC */
841
842 $row = $DIC->database()->fetchAssoc($DIC->database()->queryF(
843 "SELECT COUNT(question_id) cnt FROM qpl_questions WHERE question_id = %s AND obj_fi = %s",
844 array('integer', 'integer'),
845 array($questionId, $this->getId())
846 ));
847
848 return (bool) $row['cnt'];
849 }
850
855 public function getImportMapping()
856 {
857 if (!is_array($this->import_mapping)) {
858 return array();
859 } else {
860 return $this->import_mapping;
861 }
862 }
863
871 public function questionsToXML($questions)
872 {
873 $xml = "";
874 // export button was pressed
875 if (count($questions) > 0) {
876 foreach ($questions as $key => $value) {
877 $question = &$this->createQuestion("", $value);
878 $xml .= $question->object->toXML();
879 }
880 if (count($questions) > 1) {
881 $xml = preg_replace("/<\/questestinterop>\s*<.xml.*?>\s*<questestinterop>/", "", $xml);
882 }
883 }
884 $xml = preg_replace("/(<\?xml[^>]*?>)/", "\\1" . "<!DOCTYPE questestinterop SYSTEM \"ims_qtiasiv1p2p1.dtd\">", $xml);
885 return $xml;
886 }
887
896 public static function _getQuestionCount($questionpool_id, $complete_questions_only = false)
897 {
898 global $DIC;
899 $ilDB = $DIC['ilDB'];
900 if ($complete_questions_only) {
901 $result = $ilDB->queryF(
902 "SELECT COUNT(question_id) question_count FROM qpl_questions WHERE obj_fi = %s AND qpl_questions.tstamp > 0 AND original_id IS NULL AND complete = %s",
903 array('integer', 'text'),
904 array($questionpool_id, 1)
905 );
906 } else {
907 $result = $ilDB->queryF(
908 "SELECT COUNT(question_id) question_count FROM qpl_questions WHERE obj_fi = %s AND qpl_questions.tstamp > 0 AND original_id IS NULL",
909 array('integer'),
910 array($questionpool_id)
911 );
912 }
913 $row = $ilDB->fetchAssoc($result);
914 return $row["question_count"];
915 }
916
924 public function setOnline($a_online_status)
925 {
926 switch ($a_online_status) {
927 case 0:
928 case 1:
929 $this->online = $a_online_status;
930 break;
931 default:
932 $this->online = 0;
933 break;
934 }
935 }
936
937 public function getOnline()
938 {
939 if (strcmp($this->online, "") == 0) {
940 $this->online = "0";
941 }
942 return $this->online;
943 }
944
946 {
947 $this->showTaxonomies = $showTaxonomies;
948 }
949
950 public function getShowTaxonomies()
951 {
953 }
954
956 {
957 $this->navTaxonomyId = $navTaxonomyId;
958 }
959
960 public function getNavTaxonomyId()
961 {
963 }
964
965 public function isNavTaxonomyActive()
966 {
967 return $this->getShowTaxonomies() && (int) $this->getNavTaxonomyId();
968 }
969
970 public static function _lookupOnline($a_obj_id, $is_reference = false)
971 {
972 global $DIC;
973 $ilDB = $DIC['ilDB'];
974
975 if ($is_reference) {
976 $result = $ilDB->queryF(
977 "SELECT qpl_questionpool.isonline FROM qpl_questionpool,object_reference WHERE object_reference.ref_id = %s AND object_reference.obj_id = qpl_questionpool.obj_fi",
978 array('integer'),
979 array($a_obj_id)
980 );
981 } else {
982 $result = $ilDB->queryF(
983 "SELECT isonline FROM qpl_questionpool WHERE obj_fi = %s",
984 array('integer'),
985 array($a_obj_id)
986 );
987 }
988 if ($result->numRows() == 1) {
989 $row = $ilDB->fetchAssoc($result);
990 return $row["isonline"];
991 }
992 return 0;
993 }
994
1001 public static function _hasEqualPoints($a_obj_id, $is_reference = false)
1002 {
1003 global $DIC;
1004 $ilDB = $DIC['ilDB'];
1005
1006 if ($is_reference) {
1007 $result = $ilDB->queryF(
1008 "SELECT count(DISTINCT qpl_questions.points) equal_points FROM qpl_questions, object_reference WHERE object_reference.ref_id = %s AND qpl_questions.tstamp > 0 AND object_reference.obj_id = qpl_questions.obj_fi AND qpl_questions.original_id IS NULL",
1009 array('integer'),
1010 array($a_obj_id)
1011 );
1012 } else {
1013 $result = $ilDB->queryF(
1014 "SELECT count(DISTINCT points) equal_points FROM qpl_questions WHERE obj_fi = %s AND qpl_questions.tstamp > 0 AND qpl_questions.original_id IS NULL",
1015 array('integer'),
1016 array($a_obj_id)
1017 );
1018 }
1019 if ($result->numRows() == 1) {
1020 $row = $ilDB->fetchAssoc($result);
1021 if ($row["equal_points"] == 1) {
1022 return 1;
1023 } else {
1024 return 0;
1025 }
1026 }
1027 return 0;
1028 }
1029
1035 public function pasteFromClipboard()
1036 {
1037 global $DIC;
1038 $ilDB = $DIC['ilDB'];
1039
1040 $success = false;
1041 if (array_key_exists("qpl_clipboard", $_SESSION)) {
1042 $success = true;
1043 foreach ($_SESSION["qpl_clipboard"] as $question_object) {
1044 if (strcmp($question_object["action"], "move") == 0) {
1045 $result = $ilDB->queryF(
1046 "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
1047 array('integer'),
1048 array($question_object["question_id"])
1049 );
1050 if ($result->numRows() == 1) {
1051 $row = $ilDB->fetchAssoc($result);
1052 $source_questionpool = $row["obj_fi"];
1053 // change the questionpool id in the qpl_questions table
1054 $affectedRows = $ilDB->manipulateF(
1055 "UPDATE qpl_questions SET obj_fi = %s WHERE question_id = %s",
1056 array('integer','integer'),
1057 array($this->getId(), $question_object["question_id"])
1058 );
1059 if (!$affectedRows) {
1060 $success = false;
1061 }
1062
1063 // move question data to the new target directory
1064 $source_path = CLIENT_WEB_DIR . "/assessment/" . $source_questionpool . "/" . $question_object["question_id"] . "/";
1065 if (@is_dir($source_path)) {
1066 $target_path = CLIENT_WEB_DIR . "/assessment/" . $this->getId() . "/";
1067 if (!@is_dir($target_path)) {
1068 include_once "./Services/Utilities/classes/class.ilUtil.php";
1069 ilUtil::makeDirParents($target_path);
1070 }
1071 rename($source_path, $target_path . $question_object["question_id"]);
1072 }
1073 // update question count of source question pool
1074 ilObjQuestionPool::_updateQuestionCount($source_questionpool);
1075 }
1076 } else {
1077 $new_question_id = $this->copyQuestion($question_object["question_id"], $this->getId());
1078 if (!$new_question_id) {
1079 $success = false;
1080 }
1081 }
1082 }
1083 }
1084 // update question count of question pool
1086 unset($_SESSION["qpl_clipboard"]);
1087
1088 return (bool) $success;
1089 }
1090
1097 public function copyToClipboard($question_id)
1098 {
1099 if (!array_key_exists("qpl_clipboard", $_SESSION)) {
1100 $_SESSION["qpl_clipboard"] = array();
1101 }
1102 $_SESSION["qpl_clipboard"][$question_id] = array("question_id" => $question_id, "action" => "copy");
1103 }
1104
1111 public function moveToClipboard($question_id)
1112 {
1113 if (!array_key_exists("qpl_clipboard", $_SESSION)) {
1114 $_SESSION["qpl_clipboard"] = array();
1115 }
1116 $_SESSION["qpl_clipboard"][$question_id] = array("question_id" => $question_id, "action" => "move");
1117 }
1118
1119 public function cleanupClipboard($deletedQuestionId)
1120 {
1121 if (!isset($_SESSION['qpl_clipboard'])) {
1122 return;
1123 }
1124
1125 if (!isset($_SESSION['qpl_clipboard'][$deletedQuestionId])) {
1126 return;
1127 }
1128
1129 unset($_SESSION['qpl_clipboard'][$deletedQuestionId]);
1130
1131 if (!count($_SESSION['qpl_clipboard'])) {
1132 unset($_SESSION['qpl_clipboard']);
1133 }
1134 }
1135
1143 public static function _isWriteable($object_id, $user_id)
1144 {
1145 global $DIC;
1146 $rbacsystem = $DIC['rbacsystem'];
1147
1148 include_once "./Services/Object/classes/class.ilObject.php";
1149 $refs = ilObject::_getAllReferences($object_id);
1150 if (count($refs)) {
1151 foreach ($refs as $ref_id) {
1152 if ($rbacsystem->checkAccess("write", $ref_id) && (ilObject::_hasUntrashedReference($object_id))) {
1153 return true;
1154 }
1155 }
1156 }
1157 return false;
1158 }
1159
1167 public function &getQuestionDetails($question_ids)
1168 {
1169 global $DIC;
1170 $ilDB = $DIC['ilDB'];
1171
1172 $result = array();
1173 $query_result = $ilDB->query("SELECT qpl_questions.*, qpl_qst_type.type_tag FROM qpl_questions, qpl_qst_type WHERE qpl_questions.question_type_fi = qpl_qst_type.question_type_id AND " . $ilDB->in('qpl_questions.question_id', $question_ids, false, 'integer') . " ORDER BY qpl_questions.title");
1174 if ($query_result->numRows()) {
1175 while ($row = $ilDB->fetchAssoc($query_result)) {
1176 array_push($result, $row);
1177 }
1178 }
1179 return $result;
1180 }
1181
1190 public function &getDeleteableQuestionDetails($question_ids)
1191 {
1192 global $DIC;
1193 $ilDB = $DIC['ilDB'];
1194 $ilLog = $DIC['ilLog'];
1195
1196 $result = array();
1197 $query_result = $ilDB->query("SELECT qpl_questions.*, qpl_qst_type.type_tag FROM qpl_questions, qpl_qst_type WHERE qpl_questions.question_type_fi = qpl_qst_type.question_type_id AND " . $ilDB->in('qpl_questions.question_id', $question_ids, false, 'integer') . " ORDER BY qpl_questions.title");
1198 if ($query_result->numRows()) {
1199 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1200 while ($row = $ilDB->fetchAssoc($query_result)) {
1201 if (!assQuestion::_isUsedInRandomTest($row["question_id"])) {
1202 array_push($result, $row);
1203 } else {
1204 // the question was used in a random test prior to ILIAS 3.7 so it was inserted
1205 // as a reference to the original question pool object and not as a copy. To allow
1206 // the deletion of the question pool object, a copy must be created and all database references
1207 // of the original question must changed with the reference of the copy
1208
1209 // 1. Create a copy of the original question
1210 $question = &$this->createQuestion("", $row["question_id"]);
1211 $duplicate_id = $question->object->duplicate(true);
1212 if ($duplicate_id > 0) {
1213 // 2. replace the question id in the solutions
1214 $affectedRows = $ilDB->manipulateF(
1215 "UPDATE tst_solutions SET question_fi = %s WHERE question_fi = %s",
1216 array('integer','integer'),
1217 array($duplicate_id, $row["question_id"])
1218 );
1219
1220 // 3. replace the question id in the question list of random tests
1221 $affectedRows = $ilDB->manipulateF(
1222 "UPDATE tst_test_rnd_qst SET question_fi = %s WHERE question_fi = %s",
1223 array('integer','integer'),
1224 array($duplicate_id, $row["question_id"])
1225 );
1226
1227 // 4. replace the question id in the test results
1228 $affectedRows = $ilDB->manipulateF(
1229 "UPDATE tst_test_result SET question_fi = %s WHERE question_fi = %s",
1230 array('integer','integer'),
1231 array($duplicate_id, $row["question_id"])
1232 );
1233
1234 // 5. replace the question id in the test&assessment log
1235 $affectedRows = $ilDB->manipulateF(
1236 "UPDATE ass_log SET question_fi = %s WHERE question_fi = %s",
1237 array('integer','integer'),
1238 array($duplicate_id, $row["question_id"])
1239 );
1240
1241 // 6. The original question can be deleted, so add it to the list of questions
1242 array_push($result, $row);
1243 }
1244 }
1245 }
1246 }
1247 return $result;
1248 }
1249
1257 {
1258 global $DIC;
1259 $tree = $DIC['tree'];
1260 $path = $tree->getPathFull($ref_id);
1261 $items = array();
1262 $counter = 0;
1263 foreach ($path as $item) {
1264 if (($counter > 0) && ($counter < count($path) - 1)) {
1265 array_push($items, $item["title"]);
1266 }
1267 $counter++;
1268 }
1269 $fullpath = join(" > ", $items);
1270 include_once "./Services/Utilities/classes/class.ilStr.php";
1271 if (strlen($fullpath) > 60) {
1272 $fullpath = ilStr::subStr($fullpath, 0, 30) . "..." . ilStr::subStr($fullpath, ilStr::strLen($fullpath) - 30, 30);
1273 }
1274 return $fullpath;
1275 }
1276
1283 public static function _getAvailableQuestionpools($use_object_id = false, $equal_points = false, $could_be_offline = false, $showPath = false, $with_questioncount = false, $permission = "read", $usr_id = "")
1284 {
1285 global $DIC;
1286 $ilUser = $DIC['ilUser'];
1287 $ilDB = $DIC['ilDB'];
1288 $lng = $DIC['lng'];
1289
1290 $result_array = array();
1291 $permission = (strlen($permission) == 0) ? "read" : $permission;
1292 $qpls = ilUtil::_getObjectsByOperations("qpl", $permission, (strlen($usr_id)) ? $usr_id : $ilUser->getId(), -1);
1293 $obj_ids = array();
1294 foreach ($qpls as $ref_id) {
1296 $obj_ids[$ref_id] = $obj_id;
1297 }
1298 $titles = ilObject::_prepareCloneSelection($qpls, "qpl");
1299 if (count($obj_ids)) {
1300 $in = $ilDB->in('object_data.obj_id', $obj_ids, false, 'integer');
1301 if ($could_be_offline) {
1302 $result = $ilDB->query("SELECT qpl_questionpool.*, object_data.title FROM qpl_questionpool, object_data WHERE " .
1303 "qpl_questionpool.obj_fi = object_data.obj_id AND $in ORDER BY object_data.title");
1304 } else {
1305 $result = $ilDB->queryF(
1306 "SELECT qpl_questionpool.*, object_data.title FROM qpl_questionpool, object_data WHERE " .
1307 "qpl_questionpool.obj_fi = object_data.obj_id AND $in AND qpl_questionpool.isonline = %s " .
1308 "ORDER BY object_data.title",
1309 array('text'),
1310 array(1)
1311 );
1312 }
1313 while ($row = $ilDB->fetchAssoc($result)) {
1314 $add = true;
1315 if ($equal_points) {
1316 if (!ilObjQuestionPool::_hasEqualPoints($row["obj_fi"])) {
1317 $add = false;
1318 }
1319 }
1320 if ($add) {
1321 $ref_id = array_search($row["obj_fi"], $obj_ids);
1322 $title = (($showPath) ? $titles[$ref_id] : $row["title"]);
1323 if ($with_questioncount) {
1324 $title .= " [" . $row["questioncount"] . " " . ($row["questioncount"] == 1 ? $lng->txt("ass_question") : $lng->txt("assQuestions")) . "]";
1325 }
1326
1327 if ($use_object_id) {
1328 $result_array[$row["obj_fi"]] = array(
1329 'qpl_id' => $row['obj_fi'],
1330 'qpl_title' => $row['title'],
1331 "title" => $title,
1332 "count" => $row["questioncount"]
1333 );
1334 } else {
1335 $result_array[$ref_id] = array(
1336 'qpl_id' => $row['obj_fi'],
1337 'qpl_title' => $row['title'],
1338 "title" => $title,
1339 "count" => $row["questioncount"]
1340 );
1341 }
1342 }
1343 }
1344 }
1345 return $result_array;
1346 }
1347
1348 public function &getQplQuestions()
1349 {
1350 global $DIC;
1351 $ilDB = $DIC['ilDB'];
1352
1353 $questions = array();
1354 $result = $ilDB->queryF(
1355 "SELECT qpl_questions.question_id FROM qpl_questions WHERE qpl_questions.original_id IS NULL AND qpl_questions.tstamp > 0 AND qpl_questions.obj_fi = %s",
1356 array('integer'),
1357 array($this->getId())
1358 );
1359 while ($row = $ilDB->fetchAssoc($result)) {
1360 array_push($questions, $row["question_id"]);
1361 }
1362 return $questions;
1363 }
1364
1370 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
1371 {
1372 $newObj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
1373
1374 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
1375 $newObj->setOnline($this->getOnline());
1376 if ($cp_options->isRootNode($this->getRefId())) {
1377 $newObj->setOnline(0);
1378 }
1379
1380 $newObj->setSkillServiceEnabled($this->isSkillServiceEnabled());
1381 $newObj->setShowTaxonomies($this->getShowTaxonomies());
1382 $newObj->saveToDb();
1383
1384 // clone the questions in the question pool
1385 $questions = &$this->getQplQuestions();
1386 $questionIdsMap = array();
1387 foreach ($questions as $question_id) {
1388 $newQuestionId = $newObj->copyQuestion($question_id, $newObj->getId());
1389 $questionIdsMap[$question_id] = $newQuestionId;
1390 }
1391
1392 // clone meta data
1393 include_once "./Services/MetaData/classes/class.ilMD.php";
1394 $md = new ilMD($this->getId(), 0, $this->getType());
1395 $md->cloneMD($newObj->getId(), 0, $newObj->getType());
1396
1397 // update the metadata with the new title of the question pool
1398 $newObj->updateMetaData();
1399
1400 require_once 'Modules/TestQuestionPool/classes/class.ilQuestionPoolTaxonomiesDuplicator.php';
1401 $duplicator = new ilQuestionPoolTaxonomiesDuplicator();
1402 $duplicator->setSourceObjId($this->getId());
1403 $duplicator->setSourceObjType($this->getType());
1404 $duplicator->setTargetObjId($newObj->getId());
1405 $duplicator->setTargetObjType($newObj->getType());
1406 $duplicator->setQuestionIdMapping($questionIdsMap);
1407 $duplicator->duplicate($duplicator->getAllTaxonomiesForSourceObject());
1408
1409 $duplicatedTaxKeyMap = $duplicator->getDuplicatedTaxonomiesKeysMap();
1410 $newObj->setNavTaxonomyId($duplicatedTaxKeyMap->getMappedTaxonomyId($this->getNavTaxonomyId()));
1411 $newObj->saveToDb();
1412
1413 return $newObj;
1414 }
1415
1416 public function getQuestionTypes($all_tags = false, $fixOrder = false, $withDeprecatedTypes = true)
1417 {
1418 return self::_getQuestionTypes($all_tags, $fixOrder, $withDeprecatedTypes);
1419 }
1420
1421 public static function _getQuestionTypes($all_tags = false, $fixOrder = false, $withDeprecatedTypes = true)
1422 {
1423 global $DIC;
1424 $ilDB = $DIC['ilDB'];
1425 $lng = $DIC['lng'];
1426
1427 include_once "./Modules/Test/classes/class.ilObjAssessmentFolder.php";
1429 $lng->loadLanguageModule("assessment");
1430 $result = $ilDB->query("SELECT * FROM qpl_qst_type");
1431 $types = array();
1432 while ($row = $ilDB->fetchAssoc($result)) {
1433 if ($all_tags || (!in_array($row["question_type_id"], $forbidden_types))) {
1434 global $DIC;
1435 $ilLog = $DIC['ilLog'];
1436
1437 if ($row["plugin"] == 0) {
1438 $types[$lng->txt($row["type_tag"])] = $row;
1439 } else {
1440 global $DIC;
1441 $ilPluginAdmin = $DIC['ilPluginAdmin'];
1442 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_MODULE, "TestQuestionPool", "qst");
1443 foreach ($pl_names as $pl_name) {
1444 $pl = ilPlugin::getPluginObject(IL_COMP_MODULE, "TestQuestionPool", "qst", $pl_name);
1445 if (strcmp($pl->getQuestionType(), $row["type_tag"]) == 0) {
1446 $types[$pl->getQuestionTypeTranslation()] = $row;
1447 }
1448 }
1449 }
1450 }
1451 }
1452
1453 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionTypeOrderer.php';
1455 $orderer = new ilAssQuestionTypeOrderer($types, $orderMode);
1456 $types = $orderer->getOrderedTypes($withDeprecatedTypes);
1457
1458 return $types;
1459 }
1460
1461 public static function getQuestionTypeByTypeId($type_id)
1462 {
1463 global $DIC;
1464 $ilDB = $DIC['ilDB'];
1465
1466 $query = "SELECT type_tag FROM qpl_qst_type WHERE question_type_id = %s";
1467 $types = array('integer');
1468 $values = array($type_id);
1469 $result = $ilDB->queryF($query, $types, $values);
1470
1471 if ($row = $ilDB->fetchAssoc($result)) {
1472 return $row['type_tag'];
1473 }
1474 }
1475
1476 public static function getQuestionTypeTranslations()
1477 {
1478 global $DIC;
1479 $ilDB = $DIC['ilDB'];
1480 $lng = $DIC['lng'];
1481 $ilLog = $DIC['ilLog'];
1482 $ilPluginAdmin = $DIC['ilPluginAdmin'];
1483
1484 $lng->loadLanguageModule("assessment");
1485 $result = $ilDB->query("SELECT * FROM qpl_qst_type");
1486 $types = array();
1487 while ($row = $ilDB->fetchAssoc($result)) {
1488 if ($row["plugin"] == 0) {
1489 $types[$row['type_tag']] = $lng->txt($row["type_tag"]);
1490 } else {
1491 $pl_names = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_MODULE, "TestQuestionPool", "qst");
1492 foreach ($pl_names as $pl_name) {
1493 $pl = ilPlugin::getPluginObject(IL_COMP_MODULE, "TestQuestionPool", "qst", $pl_name);
1494 if (strcmp($pl->getQuestionType(), $row["type_tag"]) == 0) {
1495 $types[$row['type_tag']] = $pl->getQuestionTypeTranslation();
1496 }
1497 }
1498 }
1499 }
1500 ksort($types);
1501 return $types;
1502 }
1503
1509 public static function &_getSelfAssessmentQuestionTypes($all_tags = false)
1510 {
1511 /* $allowed_types = array(
1512 "assSingleChoice" => 1,
1513 "assMultipleChoice" => 2,
1514 "assClozeTest" => 3,
1515 "assMatchingQuestion" => 4,
1516 "assOrderingQuestion" => 5,
1517 "assOrderingHorizontal" => 6,
1518 "assImagemapQuestion" => 7,
1519 "assTextQuestion" => 8,
1520 "assTextSubset" => 9,
1521 "assErrorText" => 10
1522 );*/
1523 $allowed_types = array(
1524 "assSingleChoice" => 1,
1525 "assMultipleChoice" => 2,
1526 "assKprimChoice" => 3,
1527 "assClozeTest" => 4,
1528 "assMatchingQuestion" => 5,
1529 "assOrderingQuestion" => 6,
1530 "assOrderingHorizontal" => 7,
1531 "assImagemapQuestion" => 8,
1532 "assTextSubset" => 9,
1533 "assErrorText" => 10,
1534 "assLongMenu" => 11
1535 );
1536 $satypes = array();
1537 $qtypes = ilObjQuestionPool::_getQuestionTypes($all_tags);
1538 foreach ($qtypes as $k => $t) {
1539 //if (in_array($t["type_tag"], $allowed_types))
1540 if (isset($allowed_types[$t["type_tag"]])) {
1541 $t["order"] = $allowed_types[$t["type_tag"]];
1542 $satypes[$k] = $t;
1543 }
1544 }
1545 return $satypes;
1546 }
1547
1548
1549 public function &getQuestionList()
1550 {
1551 global $DIC;
1552 $ilDB = $DIC['ilDB'];
1553
1554 $questions = array();
1555 $result = $ilDB->queryF(
1556 "SELECT qpl_questions.*, qpl_qst_type.* FROM qpl_questions, qpl_qst_type WHERE qpl_questions.original_id IS NULL AND qpl_questions.obj_fi = %s AND qpl_questions.tstamp > 0 AND qpl_questions.question_type_fi = qpl_qst_type.question_type_id",
1557 array('integer'),
1558 array($this->getId())
1559 );
1560 while ($row = $ilDB->fetchAssoc($result)) {
1561 array_push($questions, $row);
1562 }
1563 return $questions;
1564 }
1565
1572 public static function _updateQuestionCount($object_id)
1573 {
1574 global $DIC;
1575 $ilDB = $DIC['ilDB'];
1576 $result = $ilDB->manipulateF(
1577 "UPDATE qpl_questionpool SET questioncount = %s, tstamp = %s WHERE obj_fi = %s",
1578 array('integer','integer','integer'),
1579 array(ilObjQuestionPool::_getQuestionCount($object_id, true), time(), $object_id)
1580 );
1581 }
1582
1589 public function isPluginActive($questionType)
1590 {
1591 /* @var ilPluginAdmin $ilPluginAdmin */
1592 global $DIC;
1593 $ilPluginAdmin = $DIC['ilPluginAdmin'];
1594
1595 $plugins = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_MODULE, "TestQuestionPool", "qst");
1596 foreach ($plugins as $pluginName) {
1597 if ($pluginName == $questionType) { // plugins having pname == qtype
1598 return true;
1599 }
1600
1601 /* @var ilQuestionsPlugin $plugin */
1602 $plugin = ilPlugin::getPluginObject(IL_COMP_MODULE, "TestQuestionPool", "qst", $pluginName);
1603
1604 if ($plugin->getQuestionType() == $questionType) { // plugins havin an independent name
1605 return true;
1606 }
1607 }
1608
1609 return false;
1610 }
1611
1612 /*
1613 * Remove all questions with owner = 0
1614 */
1615 public function purgeQuestions()
1616 {
1617 global $DIC;
1618 $ilDB = $DIC['ilDB'];
1619 $ilUser = $DIC['ilUser'];
1620
1621 require_once 'Modules/TestQuestionPool/classes/class.ilAssIncompleteQuestionPurger.php';
1622 $incompleteQuestionPurger = new ilAssIncompleteQuestionPurger($ilDB);
1623 $incompleteQuestionPurger->setOwnerId($ilUser->getId());
1624 $incompleteQuestionPurger->purge();
1625 }
1626
1632 public function getTaxonomyIds()
1633 {
1634 require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
1635 return ilObjTaxonomy::getUsageOfObject($this->getId());
1636 }
1637
1641 public function isSkillServiceEnabled()
1642 {
1644 }
1645
1650 {
1651 $this->skillServiceEnabled = $skillServiceEnabled;
1652 }
1653
1655
1656 public static function isSkillManagementGloballyActivated()
1657 {
1658 if (self::$isSkillManagementGloballyActivated === null) {
1659 $skmgSet = new ilSkillManagementSettings();
1660
1661 self::$isSkillManagementGloballyActivated = $skmgSet->isActivated();
1662 }
1663
1665 }
1666
1667 public function fromXML($xmlFile)
1668 {
1669 require_once 'Modules/TestQuestionPool/classes/class.ilObjQuestionPoolXMLParser.php';
1670 $parser = new ilObjQuestionPoolXMLParser($this, $xmlFile);
1671 $parser->startParsing();
1672 }
1673} // END class.ilObjQuestionPool
$result
$success
Definition: Utf8Test.php:86
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
const IL_COMP_MODULE
Abstract basic class which is to be extended by the concrete assessment question type classes.
static _isUsedInRandomTest($question_id="")
Checks whether the question is used in a random test or not.
addQuestionChangeListener(ilQuestionChangeListener $listener)
static & _instanciateQuestionGUI($question_id)
Creates an instance of a question gui with a given question id.
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
Question page object.
const ORDER_MODE_FIX
order mode with fixed priority for ordering
const ORDER_MODE_ALPHA
order mode that orders by alphanumerical priority
static _getInstance($a_copy_id)
Get instance of copy wizard options.
static _getExportDirectory($a_obj_id, $a_type="xml", $a_obj_type="", $a_entity="")
Get export directory for an repository object.
static _getForbiddenQuestionTypes()
Returns the forbidden questiontypes for ILIAS.
Class ilObjFile.
Class ilObjMediaObject.
static _exists($a_id, $a_reference=false, $a_type=null)
checks wether a lm content object with specified id exists or not
static _getQuestionCount($questionpool_id, $complete_questions_only=false)
Returns the number of questions in a question pool.
static _lookupOnline($a_obj_id, $is_reference=false)
static _getQuestionTypes($all_tags=false, $fixOrder=false, $withDeprecatedTypes=true)
getExportDirectory($type="")
get export directory of questionpool
getImportMapping()
get array of (two) new created questions for import id
setDescription($a_description)
set description of content object
getTitle()
get title of glossary object
deleteQuestion($question_id)
Deletes a question from the question pool.
getQuestiontype($question_id)
Returns the question type of a question with a given id.
cleanupClipboard($deletedQuestionId)
cloneObject($a_target_id, $a_copy_id=0, $a_omit_tree=false)
Creates a 1:1 copy of the object and places the copy in a given repository.
static _isWriteable($object_id, $user_id)
Returns true, if the question pool is writeable by a given user.
getDescription()
get description of content object
& getQuestionDetails($question_ids)
Returns an array containing the qpl_question and qpl_qst_type fields for an array of question ids.
addQuestionChangeListeners(assQuestion $question)
& getDeleteableQuestionDetails($question_ids)
Returns an array containing the qpl_question and qpl_qst_type fields of deleteable questions for an a...
moveToClipboard($question_id)
Moves a question to the clipboard.
getTaxonomyIds()
get ids of all taxonomies corresponding to current pool
setOnline($a_online_status)
Sets the questionpool online status.
exportFileItems($target_dir, &$expLog)
export files of file itmes
modifyExportIdentifier($a_tag, $a_param, $a_value)
getPrintviewQuestions()
Calculates the data for the print view of the questionpool.
setTitle($a_title)
set title of glossary object
setShowTaxonomies($showTaxonomies)
read($a_force_db=false)
read object data from db into object
static _createImportDirectory()
creates data directory for import files (data_dir/qpl_data/qpl_<id>/import, depending on data directo...
static _getImportDirectory()
get import directory of lm
createReference()
Creates a database reference id for the object (saves the object to the database and creates a refere...
loadFromDb()
Loads a ilObjQuestionpool object from a database.
questionsToXML($questions)
Returns a QTI xml representation of a list of questions.
_getFullPathToQpl($ref_id)
Retrieves the full path to a question pool with a given reference id.
static & _getSelfAssessmentQuestionTypes($all_tags=false)
Get all self assessment question types.
copyQuestion($question_id, $questionpool_to)
Copies a question into another question pool.
create($a_upload=false)
create questionpool object
objectToXmlWriter(ilXmlWriter &$a_xml_writer, $a_inst, $a_target_dir, &$expLog, $questions)
export pages of test to xml (see ilias_co.dtd)
exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
export media objects to xml (see ilias_co.dtd)
createExportDirectory()
creates data directory for export files (data_dir/qpl_data/qpl_<id>/export, depending on data directo...
setNavTaxonomyId($navTaxonomyId)
isPluginActive($questionType)
Checks wheather or not a question plugin with a given name is active.
duplicateQuestion($question_id)
Duplicates a question for a questionpool.
static _setImportDirectory($a_import_dir=null)
set import directory
exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog, $questions)
export page objects to xml (see ilias_co.dtd)
static _hasEqualPoints($a_obj_id, $is_reference=false)
Checks a question pool for questions with the same maximum points.
setSkillServiceEnabled($skillServiceEnabled)
static getQuestionTypeByTypeId($type_id)
exportXMLMetaData(&$a_xml_writer)
export content objects meta data to xml (see ilias_co.dtd)
isInUse($question_id)
Checks whether the question is in use or not.
__construct($a_id=0, $a_call_by_reference=true)
Constructor @access public.
update()
update object data
saveToDb()
Saves a ilObjQuestionpool object to a database.
copyToClipboard($question_id)
Copies a question to the clipboard.
static _getAvailableQuestionpools($use_object_id=false, $equal_points=false, $could_be_offline=false, $showPath=false, $with_questioncount=false, $permission="read", $usr_id="")
Returns the available question pools for the active user.
static _updateQuestionCount($object_id)
Updates the number of available questions for a question pool in the database.
& createQuestion($question_type, $question_id=-1)
pasteFromClipboard()
Copies/Moves a question from the clipboard.
& getAllQuestions()
Retrieve an array containing all question ids of the questionpool.
updateMetaData()
update meta data entry
populateQuestionSkillAssignmentsXml(ilXmlWriter &$a_xml_writer, $questions)
getQuestionTypes($all_tags=false, $fixOrder=false, $withDeprecatedTypes=true)
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
static getPoolQuestionChangeListeners(ilDBInterface $db, $poolObjId)
Class ilObject Basic functions for all objects.
getType()
get object type @access public
static _lookupObjId($a_id)
deleteMetaData()
delete meta data entry
createMetaData()
create meta data entry
static _getAllReferences($a_id)
get all reference ids of object
getId()
get object id @access public
static _hasUntrashedReference($a_obj_id)
checks wether an object has at least one reference that is not in trash
static _prepareCloneSelection($a_ref_ids, $new_type, $show_path=true)
Prepare copy wizard object selection.
static collectFileItems($a_page, $a_domdoc)
Get all file items that are used within the page.
static getPluginObject(string $a_ctype, string $a_cname, string $a_slot_id, string $a_pname)
static subStr($a_str, $a_start, $a_length=null)
Definition: class.ilStr.php:15
static strLen($a_string)
Definition: class.ilStr.php:78
static getDataDir()
get data directory (outside webspace)
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static insertInstIntoID($a_value)
inserts installation id into ILIAS id
static _getObjectsByOperations($a_obj_type, $a_operation, $a_usr_id=0, $limit=0)
Get all objects of a specific type and check access This function is not recursive,...
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
XML writer class.
xmlEndTag($tag)
Writes an endtag.
xmlStartTag($tag, $attrs=null, $empty=false, $encode=true, $escape=true)
Writes a starttag.
const CLIENT_WEB_DIR
Definition: constants.php:45
const IL_INST_ID
Definition: constants.php:38
global $DIC
Definition: goto.php:24
global $ilBench
Definition: ilias.php:21
$ilUser
Definition: imgupload.php:18
$xml
Definition: metadata.php:332
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
redirection script todo: (a better solution should control the processing via a xml file)
$query
global $ilDB
$data
Definition: storeScorm.php:23
$rows
Definition: xhr_table.php:10