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 
4 include_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  {
952  return $this->showTaxonomies;
953  }
954 
956  {
957  $this->navTaxonomyId = $navTaxonomyId;
958  }
959 
960  public function getNavTaxonomyId()
961  {
962  return $this->navTaxonomyId;
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 
1256  public function _getFullPathToQpl($ref_id)
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) {
1295  $obj_id = ilObject::_lookupObjId($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 
1664  return self::$isSkillManagementGloballyActivated;
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
static makeDirParents($a_dir)
Create a new directory and all parent directories.
const ORDER_MODE_FIX
order mode with fixed priority for ordering
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 getPoolQuestionChangeListeners(ilDBInterface $db, $poolObjId)
exportXMLMetaData(&$a_xml_writer)
export content objects meta data to xml (see ilias_co.dtd)
setTitle($a_title)
set title of glossary object
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
static getPluginObject(string $a_ctype, string $a_cname, string $a_slot_id, string $a_pname)
xmlStartTag($tag, $attrs=null, $empty=false, $encode=true, $escape=true)
Writes a starttag.
exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog, $questions)
export page objects to xml (see ilias_co.dtd)
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
static _hasUntrashedReference($a_obj_id)
checks wether an object has at least one reference that is not in trash
static strLen($a_string)
Definition: class.ilStr.php:78
static _isWriteable($object_id, $user_id)
Returns true, if the question pool is writeable by a given user.
populateQuestionSkillAssignmentsXml(ilXmlWriter &$a_xml_writer, $questions)
const ORDER_MODE_ALPHA
order mode that orders by alphanumerical priority
$data
Definition: storeScorm.php:23
const IL_INST_ID
Definition: constants.php:38
moveToClipboard($question_id)
Moves a question to the clipboard.
exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
export media objects to xml (see ilias_co.dtd)
static _prepareCloneSelection($a_ref_ids, $new_type, $show_path=true)
Prepare copy wizard object selection.
$_SESSION["AccountId"]
$result
static getUsageOfObject($a_obj_id, $a_include_titles=false)
Get usage of object.
exportFileItems($target_dir, &$expLog)
export files of file itmes
addQuestionChangeListeners(assQuestion $question)
static _isUsedInRandomTest($question_id="")
Checks whether the question is used in a random test or not.
getQuestiontype($question_id)
Returns the question type of a question with a given id.
setNavTaxonomyId($navTaxonomyId)
static _lookupOnline($a_obj_id, $is_reference=false)
pasteFromClipboard()
Copies/Moves a question from the clipboard.
Abstract basic class which is to be extended by the concrete assessment question type classes...
objectToXmlWriter(ilXmlWriter &$a_xml_writer, $a_inst, $a_target_dir, &$expLog, $questions)
export pages of test to xml (see ilias_co.dtd)
static getQuestionTypeByTypeId($type_id)
static & _instanciateQuestionGUI($question_id)
Creates an instance of a question gui with a given question 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, instead it parses the serialized rbac_pa entries.
getExportDirectory($type="")
get export directory of questionpool
getDescription()
get description of content object
deleteQuestion($question_id)
Deletes a question from the question pool.
createReference()
Creates a database reference id for the object (saves the object to the database and creates a refere...
createMetaData()
create meta data entry
_getFullPathToQpl($ref_id)
Retrieves the full path to a question pool with a given reference id.
XML writer class.
Question page object.
getPrintviewQuestions()
Calculates the data for the print view of the questionpool.
& getQuestionDetails($question_ids)
Returns an array containing the qpl_question and qpl_qst_type fields for an array of question ids...
copyQuestion($question_id, $questionpool_to)
Copies a question into another question pool.
getImportMapping()
get array of (two) new created questions for import id
static subStr($a_str, $a_start, $a_length=null)
Definition: class.ilStr.php:15
saveToDb()
Saves a ilObjQuestionpool object to a database.
static _getAllReferences($a_id)
get all reference ids of object
xmlEndTag($tag)
Writes an endtag.
setOnline($a_online_status)
Sets the questionpool online status.
setSkillServiceEnabled($skillServiceEnabled)
modifyExportIdentifier($a_tag, $a_param, $a_value)
static _hasEqualPoints($a_obj_id, $is_reference=false)
Checks a question pool for questions with the same maximum points.
getQuestionTypes($all_tags=false, $fixOrder=false, $withDeprecatedTypes=true)
static & _getSelfAssessmentQuestionTypes($all_tags=false)
Get all self assessment question types.
duplicateQuestion($question_id)
Duplicates a question for a questionpool.
setShowTaxonomies($showTaxonomies)
questionsToXML($questions)
Returns a QTI xml representation of a list of questions.
static _getInstance($a_copy_id)
Get instance of copy wizard options.
static _updateQuestionCount($object_id)
Updates the number of available questions for a question pool in the database.
$success
Definition: Utf8Test.php:86
getId()
get object id public
static _lookupObjId($a_id)
__construct($a_id=0, $a_call_by_reference=true)
Constructor public.
static collectFileItems($a_page, $a_domdoc)
Get all file items that are used within the page.
static _getForbiddenQuestionTypes()
Returns the forbidden questiontypes for ILIAS.
global $DIC
Definition: goto.php:24
cleanupClipboard($deletedQuestionId)
static _setImportDirectory($a_import_dir=null)
set import directory
const IL_COMP_MODULE
redirection script todo: (a better solution should control the processing via a xml file) ...
update()
update object data
$xml
Definition: metadata.php:332
createExportDirectory()
creates data directory for export files (data_dir/qpl_data/qpl_<id>/export, depending on data directo...
& createQuestion($question_type, $question_id=-1)
Class ilObjMediaObject.
$query
const CLIENT_WEB_DIR
Definition: constants.php:45
copyToClipboard($question_id)
Copies a question to the clipboard.
read($a_force_db=false)
read object data from db into object
getType()
get object type public
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
$rows
Definition: xhr_table.php:10
getTitle()
get title of glossary object
isPluginActive($questionType)
Checks wheather or not a question plugin with a given name is active.
& getAllQuestions()
Retrieve an array containing all question ids of the questionpool.
static getDataDir()
get data directory (outside webspace)
static _getQuestionCount($questionpool_id, $complete_questions_only=false)
Returns the number of questions in a question pool.
__construct(Container $dic, ilPlugin $plugin)
global $ilBench
Definition: ilias.php:21
global $ilDB
getTaxonomyIds()
get ids of all taxonomies corresponding to current pool
loadFromDb()
Loads a ilObjQuestionpool object from a database.
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 _getExportDirectory($a_obj_id, $a_type="xml", $a_obj_type="", $a_entity="")
Get export directory for an repository object.
static insertInstIntoID($a_value)
inserts installation id into ILIAS id
deleteMetaData()
delete meta data entry
static _getImportDirectory()
get import directory of lm
addQuestionChangeListener(ilQuestionChangeListener $listener)
$ilUser
Definition: imgupload.php:18
static _exists($a_id, $a_reference=false, $a_type=null)
checks wether a lm content object with specified id exists or not
static _createImportDirectory()
creates data directory for import files (data_dir/qpl_data/qpl_<id>/import, depending on data directo...
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
setDescription($a_description)
set description of content object
create($a_upload=false)
create questionpool object
isInUse($question_id)
Checks whether the question is in use or not.
& getDeleteableQuestionDetails($question_ids)
Returns an array containing the qpl_question and qpl_qst_type fields of deleteable questions for an a...
static _getQuestionTypes($all_tags=false, $fixOrder=false, $withDeprecatedTypes=true)