ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 $ilUser;
113  include_once "./Services/MetaData/classes/class.ilMD.php";
114  $md = new ilMD($this->getId(), 0, $this->getType());
115  $md_gen =&$md->getGeneral();
116  if ($md_gen == false) {
117  include_once "./Services/MetaData/classes/class.ilMDCreator.php";
118  $md_creator = new ilMDCreator($this->getId(), 0, $this->getType());
119  $md_creator->setTitle($this->getTitle());
120  $md_creator->setTitleLanguage($ilUser->getPref('language'));
121  $md_creator->create();
122  }
123  parent::updateMetaData();
124  }
125 
131  public function read($a_force_db = false)
132  {
133  parent::read($a_force_db);
134  $this->loadFromDb();
135  }
136 
137 
144  public function delete()
145  {
146  // always call parent delete function first!!
147  if (!parent::delete()) {
148  return false;
149  }
150 
151  // delete meta data
152  $this->deleteMetaData();
153 
154  //put here your module specific stuff
155  $this->deleteQuestionpool();
156 
157  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionSkillAssignmentImportFails.php';
158  $qsaImportFails = new ilAssQuestionSkillAssignmentImportFails($this->getId());
159  $qsaImportFails->deleteRegisteredImportFails();
160 
161  return true;
162  }
163 
164  public function deleteQuestionpool()
165  {
166  $questions =&$this->getAllQuestions();
167 
168  if (count($questions)) {
169  foreach ($questions as $question_id) {
170  $this->deleteQuestion($question_id);
171  }
172  }
173 
174  // delete export files
175  include_once "./Services/Utilities/classes/class.ilUtil.php";
176  $qpl_data_dir = ilUtil::getDataDir() . "/qpl_data";
177  $directory = $qpl_data_dir . "/qpl_" . $this->getId();
178  if (is_dir($directory)) {
179  include_once "./Services/Utilities/classes/class.ilUtil.php";
180  ilUtil::delDir($directory);
181  }
182  }
183 
190  public function deleteQuestion($question_id)
191  {
192  include_once "./Modules/Test/classes/class.ilObjTest.php";
193  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
194 
195  $question = assQuestion::_instanciateQuestion($question_id);
196  $this->addQuestionChangeListeners($question);
197  $question->delete($question_id);
198  }
199 
203  public function addQuestionChangeListeners(assQuestion $question)
204  {
205  global $ilDB;
206 
207  foreach (ilObjTest::getPoolQuestionChangeListeners($ilDB, $this->getId()) as $listener) {
208  $question->addQuestionChangeListener($listener);
209  }
210  }
211 
217  public function loadFromDb()
218  {
219  global $ilDB;
220 
221  $result = $ilDB->queryF(
222  "SELECT * FROM qpl_questionpool WHERE obj_fi = %s",
223  array('integer'),
224  array($this->getId())
225  );
226  if ($result->numRows() == 1) {
227  $row = $ilDB->fetchAssoc($result);
228  $this->setOnline($row['isonline']);
229  $this->setShowTaxonomies($row['show_taxonomies']);
230  $this->setNavTaxonomyId($row['nav_taxonomy']);
231  $this->setSkillServiceEnabled($row['skill_service']);
232  }
233  }
234 
240  public function saveToDb()
241  {
242  global $ilDB;
243 
244  $result = $ilDB->queryF(
245  "SELECT id_questionpool FROM qpl_questionpool WHERE obj_fi = %s",
246  array('integer'),
247  array($this->getId())
248  );
249 
250  if ($result->numRows() == 1) {
251  $result = $ilDB->update(
252  'qpl_questionpool',
253  array(
254  'isonline' => array('text', $this->getOnline()),
255  'show_taxonomies' => array('integer', (int) $this->getShowTaxonomies()),
256  'nav_taxonomy' => array('integer', (int) $this->getNavTaxonomyId()),
257  'skill_service' => array('integer', (int) $this->isSkillServiceEnabled()),
258  'tstamp' => array('integer', time())
259  ),
260  array(
261  'obj_fi' => array('integer', $this->getId())
262  )
263  );
264  } else {
265  $next_id = $ilDB->nextId('qpl_questionpool');
266 
267  $result = $ilDB->insert('qpl_questionpool', array(
268  'id_questionpool' => array('integer', $next_id),
269  'isonline' => array('text', $this->getOnline()),
270  'show_taxonomies' => array('integer', (int) $this->getShowTaxonomies()),
271  'nav_taxonomy' => array('integer', (int) $this->getNavTaxonomyId()),
272  'skill_service' => array('integer', (int) $this->isSkillServiceEnabled()),
273  'tstamp' => array('integer', time()),
274  'obj_fi' => array('integer', $this->getId())
275  ));
276  }
277  }
278 
286  public function getQuestiontype($question_id)
287  {
288  global $ilDB;
289 
290  if ($question_id < 1) {
291  return;
292  }
293 
294  $result = $ilDB->queryF(
295  "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",
296  array('integer'),
297  array($question_id)
298  );
299  if ($result->numRows() == 1) {
300  $data = $ilDB->fetchAssoc($result);
301  return $data["type_tag"];
302  } else {
303  return;
304  }
305  }
306 
312  public function getDescription()
313  {
314  return parent::getDescription();
315  }
316 
320  public function setDescription($a_description)
321  {
322  parent::setDescription($a_description);
323  }
324 
330  public function getTitle()
331  {
332  return parent::getTitle();
333  }
334 
338  public function setTitle($a_title)
339  {
340  parent::setTitle($a_title);
341  }
342 
350  public function isInUse($question_id)
351  {
352  global $ilDB;
353 
354  $result = $ilDB->queryF(
355  "SELECT COUNT(solution_id) solution_count FROM tst_solutions WHERE question_fi = %s",
356  array('integer'),
357  array($question_id)
358  );
359  $row = $ilDB->fetchAssoc($result);
360  return $row["solution_count"];
361  }
362 
363  public function &createQuestion($question_type, $question_id = -1)
364  {
365  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
366  if ($question_id > 0) {
367  return assQuestion::_instanciateQuestionGUI($question_id);
368  }
369  assQuestion::_includeClass($question_type, 1);
370  $question_type_gui = $question_type . "GUI";
371  $question_gui = new $question_type_gui();
372  return $question_gui;
373  }
374 
381  public function duplicateQuestion($question_id)
382  {
383  $question =&$this->createQuestion("", $question_id);
384  $newtitle = $question->object->getTitle();
385  if ($question->object->questionTitleExists($this->getId(), $question->object->getTitle())) {
386  $counter = 2;
387  while ($question->object->questionTitleExists($this->getId(), $question->object->getTitle() . " ($counter)")) {
388  $counter++;
389  }
390  $newtitle = $question->object->getTitle() . " ($counter)";
391  }
392  $new_id = $question->object->duplicate(false, $newtitle);
393  // update question count of question pool
395  return $new_id;
396  }
397 
405  public function copyQuestion($question_id, $questionpool_to)
406  {
407  $question_gui =&$this->createQuestion("", $question_id);
408  if ($question_gui->object->getObjId() == $questionpool_to) {
409  // the question is copied into the same question pool
410  return $this->duplicateQuestion($question_id);
411  } else {
412  // the question is copied into another question pool
413  $newtitle = $question_gui->object->getTitle();
414  if ($question_gui->object->questionTitleExists($this->getId(), $question_gui->object->getTitle())) {
415  $counter = 2;
416  while ($question_gui->object->questionTitleExists($this->getId(), $question_gui->object->getTitle() . " ($counter)")) {
417  $counter++;
418  }
419  $newtitle = $question_gui->object->getTitle() . " ($counter)";
420  }
421  return $question_gui->object->copyObject($this->getId(), $newtitle);
422  }
423  }
424 
430  public function getPrintviewQuestions()
431  {
432  global $ilDB;
433 
434  $query_result = $ilDB->queryF(
435  "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",
436  array('integer'),
437  array($this->getId())
438  );
439  $rows = array();
440  $types = $this->getQuestionTypeTranslations();
441  if ($query_result->numRows()) {
442  while ($row = $ilDB->fetchAssoc($query_result)) {
443  $row['ttype'] = $types[$row['type_tag']];
444  if ($row["plugin"]) {
445  if ($this->isPluginActive($row["type_tag"])) {
446  array_push($rows, $row);
447  }
448  } else {
449  array_push($rows, $row);
450  }
451  }
452  }
453  return $rows;
454  }
455 
459  private function exportXMLSettings($xmlWriter)
460  {
461  $xmlWriter->xmlStartTag('Settings');
462 
463  $xmlWriter->xmlElement('ShowTaxonomies', null, (int) $this->getShowTaxonomies());
464  $xmlWriter->xmlElement('NavTaxonomy', null, (int) $this->getNavTaxonomyId());
465  $xmlWriter->xmlElement('SkillService', null, (int) $this->isSkillServiceEnabled());
466 
467  $xmlWriter->xmlEndTag('Settings');
468  }
469 
476  public function objectToXmlWriter(ilXmlWriter &$a_xml_writer, $a_inst, $a_target_dir, &$expLog, $questions)
477  {
478  global $ilBench;
479 
480  $this->mob_ids = array();
481  $this->file_ids = array();
482 
483  $attrs = array();
484  $attrs["Type"] = "Questionpool_Test";
485  $a_xml_writer->xmlStartTag("ContentObject", $attrs);
486 
487  // MetaData
488  $this->exportXMLMetaData($a_xml_writer);
489 
490  // Settings
491  $this->exportXMLSettings($a_xml_writer);
492 
493  // PageObjects
494  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Page Objects");
495  $ilBench->start("ContentObjectExport", "exportPageObjects");
496  $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog, $questions);
497  $ilBench->stop("ContentObjectExport", "exportPageObjects");
498  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Page Objects");
499 
500  // MediaObjects
501  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Media Objects");
502  $ilBench->start("ContentObjectExport", "exportMediaObjects");
503  $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
504  $ilBench->stop("ContentObjectExport", "exportMediaObjects");
505  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Media Objects");
506 
507  // FileItems
508  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export File Items");
509  $ilBench->start("ContentObjectExport", "exportFileItems");
510  $this->exportFileItems($a_target_dir, $expLog);
511  $ilBench->stop("ContentObjectExport", "exportFileItems");
512  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export File Items");
513 
514  // skill assignments
515  $this->populateQuestionSkillAssignmentsXml($a_xml_writer, $questions);
516 
517  $a_xml_writer->xmlEndTag("ContentObject");
518  }
519 
524  protected function populateQuestionSkillAssignmentsXml(ilXmlWriter &$a_xml_writer, $questions)
525  {
526  global $ilDB;
527 
528  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionSkillAssignmentList.php';
529  $assignmentList = new ilAssQuestionSkillAssignmentList($ilDB);
530  $assignmentList->setParentObjId($this->getId());
531  $assignmentList->loadFromDb();
532  $assignmentList->loadAdditionalSkillData();
533 
534  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssQuestionSkillAssignmentExporter.php';
535  $skillQuestionAssignmentExporter = new ilAssQuestionSkillAssignmentExporter();
536  $skillQuestionAssignmentExporter->setXmlWriter($a_xml_writer);
537  $skillQuestionAssignmentExporter->setQuestionIds($questions);
538  $skillQuestionAssignmentExporter->setAssignmentList($assignmentList);
539  $skillQuestionAssignmentExporter->export();
540  }
541 
548  public function exportXMLMetaData(&$a_xml_writer)
549  {
550  include_once("Services/MetaData/classes/class.ilMD2XML.php");
551  $md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
552  $md2xml->setExportMode(true);
553  $md2xml->startExport();
554  $a_xml_writer->appendXML($md2xml->getXML());
555  }
556 
557  public function modifyExportIdentifier($a_tag, $a_param, $a_value)
558  {
559  if ($a_tag == "Identifier" && $a_param == "Entry") {
560  include_once "./Services/Utilities/classes/class.ilUtil.php";
561  $a_value = ilUtil::insertInstIntoID($a_value);
562  }
563 
564  return $a_value;
565  }
566 
567 
574  public function exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog, $questions)
575  {
576  global $ilBench;
577 
578  include_once "./Modules/LearningModule/classes/class.ilLMPageObject.php";
579 
580  foreach ($questions as $question_id) {
581  $ilBench->start("ContentObjectExport", "exportPageObject");
582  $expLog->write(date("[y-m-d H:i:s] ") . "Page Object " . $question_id);
583 
584  $attrs = array();
585  $a_xml_writer->xmlStartTag("PageObject", $attrs);
586 
587 
588  // export xml to writer object
589  $ilBench->start("ContentObjectExport", "exportPageObject_XML");
590  include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPage.php");
591  $page_object = new ilAssQuestionPage($question_id);
592  $page_object->buildDom();
593  $page_object->insertInstIntoIDs($a_inst);
594  $mob_ids = $page_object->collectMediaObjects(false);
595  require_once 'Services/COPage/classes/class.ilPCFileList.php';
596  $file_ids = ilPCFileList::collectFileItems($page_object, $page_object->getDomDoc());
597  $xml = $page_object->getXMLFromDom(false, false, false, "", true);
598  $xml = str_replace("&", "&amp;", $xml);
599  $a_xml_writer->appendXML($xml);
600  $page_object->freeDom();
601  unset($page_object);
602 
603  $ilBench->stop("ContentObjectExport", "exportPageObject_XML");
604 
605  // collect media objects
606  $ilBench->start("ContentObjectExport", "exportPageObject_CollectMedia");
607  //$mob_ids = $page_obj->getMediaObjectIDs();
608  foreach ($mob_ids as $mob_id) {
609  $this->mob_ids[$mob_id] = $mob_id;
610  }
611  $ilBench->stop("ContentObjectExport", "exportPageObject_CollectMedia");
612 
613  // collect all file items
614  $ilBench->start("ContentObjectExport", "exportPageObject_CollectFileItems");
615  //$file_ids = $page_obj->getFileItemIds();
616  foreach ($file_ids as $file_id) {
617  $this->file_ids[$file_id] = $file_id;
618  }
619  $ilBench->stop("ContentObjectExport", "exportPageObject_CollectFileItems");
620 
621  $a_xml_writer->xmlEndTag("PageObject");
622  //unset($page_obj);
623 
624  $ilBench->stop("ContentObjectExport", "exportPageObject");
625  }
626  }
627 
634  public function exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
635  {
636  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
637 
638  foreach ($this->mob_ids as $mob_id) {
639  $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
640  if (ilObjMediaObject::_exists($mob_id)) {
641  $media_obj = new ilObjMediaObject($mob_id);
642  $media_obj->exportXML($a_xml_writer, $a_inst);
643  $media_obj->exportFiles($a_target_dir);
644  unset($media_obj);
645  }
646  }
647  }
648 
653  public function exportFileItems($a_target_dir, &$expLog)
654  {
655  include_once("./Modules/File/classes/class.ilObjFile.php");
656 
657  foreach ($this->file_ids as $file_id) {
658  $expLog->write(date("[y-m-d H:i:s] ") . "File Item " . $file_id);
659  $file_obj = new ilObjFile($file_id, false);
660  $file_obj->export($a_target_dir);
661  unset($file_obj);
662  }
663  }
664 
670  public function createExportDirectory()
671  {
672  include_once "./Services/Utilities/classes/class.ilUtil.php";
673  $qpl_data_dir = ilUtil::getDataDir() . "/qpl_data";
674  ilUtil::makeDir($qpl_data_dir);
675  if (!is_writable($qpl_data_dir)) {
676  $this->ilias->raiseError("Questionpool Data Directory (" . $qpl_data_dir
677  . ") not writeable.", $this->ilias->error_obj->FATAL);
678  }
679 
680  // create learning module directory (data_dir/lm_data/lm_<id>)
681  $qpl_dir = $qpl_data_dir . "/qpl_" . $this->getId();
682  ilUtil::makeDir($qpl_dir);
683  if (!@is_dir($qpl_dir)) {
684  $this->ilias->raiseError("Creation of Questionpool Directory failed.", $this->ilias->error_obj->FATAL);
685  }
686  // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
687  ilUtil::makeDir($this->getExportDirectory('xls'));
688  if (!@is_dir($this->getExportDirectory('xls'))) {
689  $this->ilias->raiseError("Creation of Export Directory failed.", $this->ilias->error_obj->FATAL);
690  }
691  ilUtil::makeDir($this->getExportDirectory('zip'));
692  if (!@is_dir($this->getExportDirectory('zip'))) {
693  $this->ilias->raiseError("Creation of Export Directory failed.", $this->ilias->error_obj->FATAL);
694  }
695  }
696 
700  public function getExportDirectory($type = "")
701  {
702  include_once "./Services/Utilities/classes/class.ilUtil.php";
703  switch ($type) {
704  case 'xml':
705  include_once("./Services/Export/classes/class.ilExport.php");
706  $export_dir = ilExport::_getExportDirectory($this->getId(), $type, $this->getType());
707  break;
708  case 'xls':
709  case 'zip':
710  $export_dir = ilUtil::getDataDir() . "/qpl_data" . "/qpl_" . $this->getId() . "/export_$type";
711  break;
712  default:
713  $export_dir = ilUtil::getDataDir() . "/qpl_data" . "/qpl_" . $this->getId() . "/export";
714  break;
715  }
716  return $export_dir;
717  }
718 
724  public static function _createImportDirectory()
725  {
726  global $ilias;
727 
728  include_once "./Services/Utilities/classes/class.ilUtil.php";
729  $qpl_data_dir = ilUtil::getDataDir() . "/qpl_data";
730  ilUtil::makeDir($qpl_data_dir);
731 
732  if (!is_writable($qpl_data_dir)) {
733  $ilias->raiseError("Questionpool Data Directory (" . $qpl_data_dir
734  . ") not writeable.", $ilias->error_obj->FATAL);
735  }
736 
737  // create questionpool directory (data_dir/qpl_data/qpl_import)
738  $qpl_dir = $qpl_data_dir . "/qpl_import";
739  ilUtil::makeDir($qpl_dir);
740  if (!@is_dir($qpl_dir)) {
741  $ilias->raiseError("Creation of Questionpool Directory failed.", $ilias->error_obj->FATAL);
742  }
743  return $qpl_dir;
744  }
745 
749  public static function _setImportDirectory($a_import_dir = null)
750  {
751  if (strlen($a_import_dir)) {
752  $_SESSION["qpl_import_dir"] = $a_import_dir;
753  } else {
754  unset($_SESSION["qpl_import_dir"]);
755  }
756  }
757 
761  public static function _getImportDirectory()
762  {
763  if (strlen($_SESSION["qpl_import_dir"])) {
764  return $_SESSION["qpl_import_dir"];
765  }
766  return null;
767  }
768 
769  public function getImportDirectory()
770  {
772  }
773 
779  public function &getAllQuestions()
780  {
781  global $ilDB;
782 
783  $result = $ilDB->queryF(
784  "SELECT question_id FROM qpl_questions WHERE obj_fi = %s AND qpl_questions.tstamp > 0 AND original_id IS NULL",
785  array('integer'),
786  array($this->getId())
787  );
788  $questions = array();
789  while ($row = $ilDB->fetchAssoc($result)) {
790  array_push($questions, $row["question_id"]);
791  }
792  return $questions;
793  }
794 
795  public function &getAllQuestionIds()
796  {
797  global $ilDB;
798 
799  $query_result = $ilDB->queryF(
800  "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",
801  array('integer','text'),
802  array($this->getId(), 1)
803  );
804  $questions = array();
805  if ($query_result->numRows()) {
806  while ($row = $ilDB->fetchAssoc($query_result)) {
807  if ($row["plugin"]) {
808  if ($this->isPluginActive($row["type_tag"])) {
809  array_push($questions, $row["question_id"]);
810  }
811  } else {
812  array_push($questions, $row["question_id"]);
813  }
814  }
815  }
816  return $questions;
817  }
818 
819  public function checkQuestionParent($questionId)
820  {
821  global $DIC; /* @var ILIAS\DI\Container $DIC */
822 
823  $row = $DIC->database()->fetchAssoc($DIC->database()->queryF(
824  "SELECT COUNT(question_id) cnt FROM qpl_questions WHERE question_id = %s AND obj_fi = %s",
825  array('integer', 'integer'),
826  array($questionId, $this->getId())
827  ));
828 
829  return (bool) $row['cnt'];
830  }
831 
836  public function getImportMapping()
837  {
838  if (!is_array($this->import_mapping)) {
839  return array();
840  } else {
841  return $this->import_mapping;
842  }
843  }
844 
852  public function questionsToXML($questions)
853  {
854  $xml = "";
855  // export button was pressed
856  if (count($questions) > 0) {
857  foreach ($questions as $key => $value) {
858  $question =&$this->createQuestion("", $value);
859  $xml .= $question->object->toXML();
860  }
861  if (count($questions) > 1) {
862  $xml = preg_replace("/<\/questestinterop>\s*<.xml.*?>\s*<questestinterop>/", "", $xml);
863  }
864  }
865  $xml = preg_replace("/(<\?xml[^>]*?>)/", "\\1" . "<!DOCTYPE questestinterop SYSTEM \"ims_qtiasiv1p2p1.dtd\">", $xml);
866  return $xml;
867  }
868 
877  public static function _getQuestionCount($questionpool_id, $complete_questions_only = false)
878  {
879  global $ilDB;
880  if ($complete_questions_only) {
881  $result = $ilDB->queryF(
882  "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",
883  array('integer', 'text'),
884  array($questionpool_id, 1)
885  );
886  } else {
887  $result = $ilDB->queryF(
888  "SELECT COUNT(question_id) question_count FROM qpl_questions WHERE obj_fi = %s AND qpl_questions.tstamp > 0 AND original_id IS NULL",
889  array('integer'),
890  array($questionpool_id)
891  );
892  }
893  $row = $ilDB->fetchAssoc($result);
894  return $row["question_count"];
895  }
896 
904  public function setOnline($a_online_status)
905  {
906  switch ($a_online_status) {
907  case 0:
908  case 1:
909  $this->online = $a_online_status;
910  break;
911  default:
912  $this->online = 0;
913  break;
914  }
915  }
916 
917  public function getOnline()
918  {
919  if (strcmp($this->online, "") == 0) {
920  $this->online = "0";
921  }
922  return $this->online;
923  }
924 
926  {
927  $this->showTaxonomies = $showTaxonomies;
928  }
929 
930  public function getShowTaxonomies()
931  {
932  return $this->showTaxonomies;
933  }
934 
936  {
937  $this->navTaxonomyId = $navTaxonomyId;
938  }
939 
940  public function getNavTaxonomyId()
941  {
942  return $this->navTaxonomyId;
943  }
944 
945  public function isNavTaxonomyActive()
946  {
947  return $this->getShowTaxonomies() && (int) $this->getNavTaxonomyId();
948  }
949 
950  public static function _lookupOnline($a_obj_id, $is_reference = false)
951  {
952  global $ilDB;
953 
954  if ($is_reference) {
955  $result = $ilDB->queryF(
956  "SELECT qpl_questionpool.isonline FROM qpl_questionpool,object_reference WHERE object_reference.ref_id = %s AND object_reference.obj_id = qpl_questionpool.obj_fi",
957  array('integer'),
958  array($a_obj_id)
959  );
960  } else {
961  $result = $ilDB->queryF(
962  "SELECT isonline FROM qpl_questionpool WHERE obj_fi = %s",
963  array('integer'),
964  array($a_obj_id)
965  );
966  }
967  if ($result->numRows() == 1) {
968  $row = $ilDB->fetchAssoc($result);
969  return $row["isonline"];
970  }
971  return 0;
972  }
973 
980  public static function _hasEqualPoints($a_obj_id, $is_reference = false)
981  {
982  global $ilDB;
983 
984  if ($is_reference) {
985  $result = $ilDB->queryF(
986  "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",
987  array('integer'),
988  array($a_obj_id)
989  );
990  } else {
991  $result = $ilDB->queryF(
992  "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",
993  array('integer'),
994  array($a_obj_id)
995  );
996  }
997  if ($result->numRows() == 1) {
998  $row = $ilDB->fetchAssoc($result);
999  if ($row["equal_points"] == 1) {
1000  return 1;
1001  } else {
1002  return 0;
1003  }
1004  }
1005  return 0;
1006  }
1007 
1013  public function pasteFromClipboard()
1014  {
1015  global $ilDB;
1016 
1017  $success = false;
1018  if (array_key_exists("qpl_clipboard", $_SESSION)) {
1019  $success = true;
1020  foreach ($_SESSION["qpl_clipboard"] as $question_object) {
1021  if (strcmp($question_object["action"], "move") == 0) {
1022  $result = $ilDB->queryF(
1023  "SELECT obj_fi FROM qpl_questions WHERE question_id = %s",
1024  array('integer'),
1025  array($question_object["question_id"])
1026  );
1027  if ($result->numRows() == 1) {
1028  $row = $ilDB->fetchAssoc($result);
1029  $source_questionpool = $row["obj_fi"];
1030  // change the questionpool id in the qpl_questions table
1031  $affectedRows = $ilDB->manipulateF(
1032  "UPDATE qpl_questions SET obj_fi = %s WHERE question_id = %s",
1033  array('integer','integer'),
1034  array($this->getId(), $question_object["question_id"])
1035  );
1036  if (!$affectedRows) {
1037  $success = false;
1038  }
1039 
1040  // move question data to the new target directory
1041  $source_path = CLIENT_WEB_DIR . "/assessment/" . $source_questionpool . "/" . $question_object["question_id"] . "/";
1042  if (@is_dir($source_path)) {
1043  $target_path = CLIENT_WEB_DIR . "/assessment/" . $this->getId() . "/";
1044  if (!@is_dir($target_path)) {
1045  include_once "./Services/Utilities/classes/class.ilUtil.php";
1046  ilUtil::makeDirParents($target_path);
1047  }
1048  rename($source_path, $target_path . $question_object["question_id"]);
1049  }
1050  // update question count of source question pool
1051  ilObjQuestionPool::_updateQuestionCount($source_questionpool);
1052  }
1053  } else {
1054  $new_question_id = $this->copyQuestion($question_object["question_id"], $this->getId());
1055  if (!$new_question_id) {
1056  $success = false;
1057  }
1058  }
1059  }
1060  }
1061  // update question count of question pool
1063  unset($_SESSION["qpl_clipboard"]);
1064 
1065  return (bool) $success;
1066  }
1067 
1074  public function copyToClipboard($question_id)
1075  {
1076  if (!array_key_exists("qpl_clipboard", $_SESSION)) {
1077  $_SESSION["qpl_clipboard"] = array();
1078  }
1079  $_SESSION["qpl_clipboard"][$question_id] = array("question_id" => $question_id, "action" => "copy");
1080  }
1081 
1088  public function moveToClipboard($question_id)
1089  {
1090  if (!array_key_exists("qpl_clipboard", $_SESSION)) {
1091  $_SESSION["qpl_clipboard"] = array();
1092  }
1093  $_SESSION["qpl_clipboard"][$question_id] = array("question_id" => $question_id, "action" => "move");
1094  }
1095 
1096  public function cleanupClipboard($deletedQuestionId)
1097  {
1098  if (!isset($_SESSION['qpl_clipboard'])) {
1099  return;
1100  }
1101 
1102  if (!isset($_SESSION['qpl_clipboard'][$deletedQuestionId])) {
1103  return;
1104  }
1105 
1106  unset($_SESSION['qpl_clipboard'][$deletedQuestionId]);
1107 
1108  if (!count($_SESSION['qpl_clipboard'])) {
1109  unset($_SESSION['qpl_clipboard']);
1110  }
1111  }
1112 
1120  public static function _isWriteable($object_id, $user_id)
1121  {
1122  global $rbacsystem;
1123 
1124  include_once "./Services/Object/classes/class.ilObject.php";
1125  $refs = ilObject::_getAllReferences($object_id);
1126  if (count($refs)) {
1127  foreach ($refs as $ref_id) {
1128  if ($rbacsystem->checkAccess("write", $ref_id) && (ilObject::_hasUntrashedReference($object_id))) {
1129  return true;
1130  }
1131  }
1132  }
1133  return false;
1134  }
1135 
1143  public function &getQuestionDetails($question_ids)
1144  {
1145  global $ilDB;
1146 
1147  $result = array();
1148  $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");
1149  if ($query_result->numRows()) {
1150  while ($row = $ilDB->fetchAssoc($query_result)) {
1151  array_push($result, $row);
1152  }
1153  }
1154  return $result;
1155  }
1156 
1165  public function &getDeleteableQuestionDetails($question_ids)
1166  {
1167  global $ilDB, $ilLog;
1168 
1169  $result = array();
1170  $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");
1171  if ($query_result->numRows()) {
1172  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1173  while ($row = $ilDB->fetchAssoc($query_result)) {
1174  if (!assQuestion::_isUsedInRandomTest($row["question_id"])) {
1175  array_push($result, $row);
1176  } else {
1177  // the question was used in a random test prior to ILIAS 3.7 so it was inserted
1178  // as a reference to the original question pool object and not as a copy. To allow
1179  // the deletion of the question pool object, a copy must be created and all database references
1180  // of the original question must changed with the reference of the copy
1181 
1182  // 1. Create a copy of the original question
1183  $question =&$this->createQuestion("", $row["question_id"]);
1184  $duplicate_id = $question->object->duplicate(true);
1185  if ($duplicate_id > 0) {
1186  // 2. replace the question id in the solutions
1187  $affectedRows = $ilDB->manipulateF(
1188  "UPDATE tst_solutions SET question_fi = %s WHERE question_fi = %s",
1189  array('integer','integer'),
1190  array($duplicate_id, $row["question_id"])
1191  );
1192 
1193  // 3. replace the question id in the question list of random tests
1194  $affectedRows = $ilDB->manipulateF(
1195  "UPDATE tst_test_rnd_qst SET question_fi = %s WHERE question_fi = %s",
1196  array('integer','integer'),
1197  array($duplicate_id, $row["question_id"])
1198  );
1199 
1200  // 4. replace the question id in the test results
1201  $affectedRows = $ilDB->manipulateF(
1202  "UPDATE tst_test_result SET question_fi = %s WHERE question_fi = %s",
1203  array('integer','integer'),
1204  array($duplicate_id, $row["question_id"])
1205  );
1206 
1207  // 5. replace the question id in the test&assessment log
1208  $affectedRows = $ilDB->manipulateF(
1209  "UPDATE ass_log SET question_fi = %s WHERE question_fi = %s",
1210  array('integer','integer'),
1211  array($duplicate_id, $row["question_id"])
1212  );
1213 
1214  // 6. The original question can be deleted, so add it to the list of questions
1215  array_push($result, $row);
1216  }
1217  }
1218  }
1219  }
1220  return $result;
1221  }
1222 
1229  public function _getFullPathToQpl($ref_id)
1230  {
1231  global $tree;
1232  $path = $tree->getPathFull($ref_id);
1233  $items = array();
1234  $counter = 0;
1235  foreach ($path as $item) {
1236  if (($counter > 0) && ($counter < count($path)-1)) {
1237  array_push($items, $item["title"]);
1238  }
1239  $counter++;
1240  }
1241  $fullpath = join(" > ", $items);
1242  include_once "./Services/Utilities/classes/class.ilStr.php";
1243  if (strlen($fullpath) > 60) {
1244  $fullpath = ilStr::subStr($fullpath, 0, 30) . "..." . ilStr::subStr($fullpath, ilStr::strLen($fullpath)-30, 30);
1245  }
1246  return $fullpath;
1247  }
1248 
1255  public static function _getAvailableQuestionpools($use_object_id = false, $equal_points = false, $could_be_offline = false, $showPath = false, $with_questioncount = false, $permission = "read", $usr_id = "")
1256  {
1257  global $ilUser, $ilDB, $lng;
1258 
1259  $result_array = array();
1260  $permission = (strlen($permission) == 0) ? "read" : $permission;
1261  $qpls = ilUtil::_getObjectsByOperations("qpl", $permission, (strlen($usr_id)) ? $usr_id : $ilUser->getId(), -1);
1262  $obj_ids = array();
1263  foreach ($qpls as $ref_id) {
1264  $obj_id = ilObject::_lookupObjId($ref_id);
1265  $obj_ids[$ref_id] = $obj_id;
1266  }
1267  $titles = ilObject::_prepareCloneSelection($qpls, "qpl");
1268  if (count($obj_ids)) {
1269  $in = $ilDB->in('object_data.obj_id', $obj_ids, false, 'integer');
1270  if ($could_be_offline) {
1271  $result = $ilDB->query("SELECT qpl_questionpool.*, object_data.title FROM qpl_questionpool, object_data WHERE " .
1272  "qpl_questionpool.obj_fi = object_data.obj_id AND $in ORDER BY object_data.title");
1273  } else {
1274  $result = $ilDB->queryF(
1275  "SELECT qpl_questionpool.*, object_data.title FROM qpl_questionpool, object_data WHERE " .
1276  "qpl_questionpool.obj_fi = object_data.obj_id AND $in AND qpl_questionpool.isonline = %s " .
1277  "ORDER BY object_data.title",
1278  array('text'),
1279  array(1)
1280  );
1281  }
1282  while ($row = $ilDB->fetchAssoc($result)) {
1283  $add = true;
1284  if ($equal_points) {
1285  if (!ilObjQuestionPool::_hasEqualPoints($row["obj_fi"])) {
1286  $add = false;
1287  }
1288  }
1289  if ($add) {
1290  $ref_id = array_search($row["obj_fi"], $obj_ids);
1291  $title = (($showPath) ? $titles[$ref_id] : $row["title"]);
1292  if ($with_questioncount) {
1293  $title .= " [" . $row["questioncount"] . " " . ($row["questioncount"] == 1 ? $lng->txt("ass_question") : $lng->txt("assQuestions")) . "]";
1294  }
1295 
1296  if ($use_object_id) {
1297  $result_array[$row["obj_fi"]] = array(
1298  'qpl_id' => $row['obj_fi'],
1299  'qpl_title' => $row['title'],
1300  "title" => $title,
1301  "count" => $row["questioncount"]
1302  );
1303  } else {
1304  $result_array[$ref_id] = array(
1305  'qpl_id' => $row['obj_fi'],
1306  'qpl_title' => $row['title'],
1307  "title" => $title,
1308  "count" => $row["questioncount"]
1309  );
1310  }
1311  }
1312  }
1313  }
1314  return $result_array;
1315  }
1316 
1317  public function &getQplQuestions()
1318  {
1319  global $ilDB;
1320 
1321  $questions = array();
1322  $result = $ilDB->queryF(
1323  "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",
1324  array('integer'),
1325  array($this->getId())
1326  );
1327  while ($row = $ilDB->fetchAssoc($result)) {
1328  array_push($questions, $row["question_id"]);
1329  }
1330  return $questions;
1331  }
1332 
1338  public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
1339  {
1340  global $ilLog;
1341 
1342  $newObj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
1343 
1344  //copy online status if object is not the root copy object
1345  $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
1346 
1347  if (!$cp_options->isRootNode($this->getRefId())) {
1348  $newObj->setOnline($this->getOnline());
1349  }
1350 
1351  $newObj->setSkillServiceEnabled($this->isSkillServiceEnabled());
1352  $newObj->setShowTaxonomies($this->getShowTaxonomies());
1353  $newObj->saveToDb();
1354 
1355  // clone the questions in the question pool
1356  $questions =&$this->getQplQuestions();
1357  $questionIdsMap = array();
1358  foreach ($questions as $question_id) {
1359  $newQuestionId = $newObj->copyQuestion($question_id, $newObj->getId());
1360  $questionIdsMap[$question_id] = $newQuestionId;
1361  }
1362 
1363  // clone meta data
1364  include_once "./Services/MetaData/classes/class.ilMD.php";
1365  $md = new ilMD($this->getId(), 0, $this->getType());
1366  $new_md =&$md->cloneMD($newObj->getId(), 0, $newObj->getType());
1367 
1368  // update the metadata with the new title of the question pool
1369  $newObj->updateMetaData();
1370 
1371  require_once 'Modules/TestQuestionPool/classes/class.ilQuestionPoolTaxonomiesDuplicator.php';
1372  $duplicator = new ilQuestionPoolTaxonomiesDuplicator();
1373  $duplicator->setSourceObjId($this->getId());
1374  $duplicator->setSourceObjType($this->getType());
1375  $duplicator->setTargetObjId($newObj->getId());
1376  $duplicator->setTargetObjType($newObj->getType());
1377  $duplicator->setQuestionIdMapping($questionIdsMap);
1378  $duplicator->duplicate($duplicator->getAllTaxonomiesForSourceObject());
1379 
1380  $duplicatedTaxKeyMap = $duplicator->getDuplicatedTaxonomiesKeysMap();
1381  $newObj->setNavTaxonomyId($duplicatedTaxKeyMap->getMappedTaxonomyId($this->getNavTaxonomyId()));
1382  $newObj->saveToDb();
1383 
1384  return $newObj;
1385  }
1386 
1387  public function getQuestionTypes($all_tags = false, $fixOrder = false)
1388  {
1389  return self::_getQuestionTypes($all_tags, $fixOrder);
1390  }
1391 
1392  public static function _getQuestionTypes($all_tags = false, $fixOrder = false)
1393  {
1394  global $ilDB;
1395  global $lng;
1396 
1397  include_once "./Modules/Test/classes/class.ilObjAssessmentFolder.php";
1399  $lng->loadLanguageModule("assessment");
1400  $result = $ilDB->query("SELECT * FROM qpl_qst_type");
1401  $types = array();
1402  while ($row = $ilDB->fetchAssoc($result)) {
1403  if ($all_tags || (!in_array($row["question_type_id"], $forbidden_types))) {
1404  global $ilLog;
1405 
1406  if ($row["plugin"] == 0) {
1407  $types[$lng->txt($row["type_tag"])] = $row;
1408  } else {
1409  global $ilPluginAdmin;
1410  $pl_names = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_MODULE, "TestQuestionPool", "qst");
1411  foreach ($pl_names as $pl_name) {
1412  $pl = ilPlugin::getPluginObject(IL_COMP_MODULE, "TestQuestionPool", "qst", $pl_name);
1413  if (strcmp($pl->getQuestionType(), $row["type_tag"]) == 0) {
1414  $types[$pl->getQuestionTypeTranslation()] = $row;
1415  }
1416  }
1417  }
1418  }
1419  }
1420 
1421  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionTypeOrderer.php';
1423  $orderer = new ilAssQuestionTypeOrderer($types, $orderMode);
1424  $types = $orderer->getOrderedTypes();
1425 
1426  return $types;
1427  }
1428 
1429  public static function getQuestionTypeByTypeId($type_id)
1430  {
1431  global $ilDB;
1432 
1433  $query = "SELECT type_tag FROM qpl_qst_type WHERE question_type_id = %s";
1434  $types = array('integer');
1435  $values = array($type_id);
1436  $result = $ilDB->queryF($query, $types, $values);
1437 
1438  if ($row = $ilDB->fetchAssoc($result)) {
1439  return $row['type_tag'];
1440  }
1441  }
1442 
1443  public static function getQuestionTypeTranslations()
1444  {
1445  global $ilDB;
1446  global $lng;
1447  global $ilLog;
1448  global $ilPluginAdmin;
1449 
1450  $lng->loadLanguageModule("assessment");
1451  $result = $ilDB->query("SELECT * FROM qpl_qst_type");
1452  $types = array();
1453  while ($row = $ilDB->fetchAssoc($result)) {
1454  if ($row["plugin"] == 0) {
1455  $types[$row['type_tag']] = $lng->txt($row["type_tag"]);
1456  } else {
1457  $pl_names = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_MODULE, "TestQuestionPool", "qst");
1458  foreach ($pl_names as $pl_name) {
1459  $pl = ilPlugin::getPluginObject(IL_COMP_MODULE, "TestQuestionPool", "qst", $pl_name);
1460  if (strcmp($pl->getQuestionType(), $row["type_tag"]) == 0) {
1461  $types[$row['type_tag']] = $pl->getQuestionTypeTranslation();
1462  }
1463  }
1464  }
1465  }
1466  ksort($types);
1467  return $types;
1468  }
1469 
1475  public static function &_getSelfAssessmentQuestionTypes($all_tags = false)
1476  {
1477  /* $allowed_types = array(
1478  "assSingleChoice" => 1,
1479  "assMultipleChoice" => 2,
1480  "assClozeTest" => 3,
1481  "assMatchingQuestion" => 4,
1482  "assOrderingQuestion" => 5,
1483  "assOrderingHorizontal" => 6,
1484  "assImagemapQuestion" => 7,
1485  "assTextQuestion" => 8,
1486  "assTextSubset" => 9,
1487  "assErrorText" => 10
1488  );*/
1489  $allowed_types = array(
1490  "assSingleChoice" => 1,
1491  "assMultipleChoice" => 2,
1492  "assKprimChoice" => 3,
1493  "assClozeTest" => 4,
1494  "assMatchingQuestion" => 5,
1495  "assOrderingQuestion" => 6,
1496  "assOrderingHorizontal" => 7,
1497  "assImagemapQuestion" => 8,
1498  "assTextSubset" => 9,
1499  "assErrorText" => 10,
1500  "assLongMenu" => 11
1501  );
1502  $satypes = array();
1503  $qtypes = ilObjQuestionPool::_getQuestionTypes($all_tags);
1504  foreach ($qtypes as $k => $t) {
1505  //if (in_array($t["type_tag"], $allowed_types))
1506  if (isset($allowed_types[$t["type_tag"]])) {
1507  $t["order"] = $allowed_types[$t["type_tag"]];
1508  $satypes[$k] = $t;
1509  }
1510  }
1511  return $satypes;
1512  }
1513 
1514 
1515  public function &getQuestionList()
1516  {
1517  global $ilDB;
1518 
1519  $questions = array();
1520  $result = $ilDB->queryF(
1521  "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",
1522  array('integer'),
1523  array($this->getId())
1524  );
1525  while ($row = $ilDB->fetchAssoc($result)) {
1526  array_push($questions, $row);
1527  }
1528  return $questions;
1529  }
1530 
1537  public static function _updateQuestionCount($object_id)
1538  {
1539  global $ilDB;
1540  $result = $ilDB->manipulateF(
1541  "UPDATE qpl_questionpool SET questioncount = %s, tstamp = %s WHERE obj_fi = %s",
1542  array('integer','integer','integer'),
1543  array(ilObjQuestionPool::_getQuestionCount($object_id, true), time(), $object_id)
1544  );
1545  }
1546 
1553  public function isPluginActive($questionType)
1554  {
1555  /* @var ilPluginAdmin $ilPluginAdmin */
1556  global $ilPluginAdmin;
1557 
1558  $plugins = $ilPluginAdmin->getActivePluginsForSlot(IL_COMP_MODULE, "TestQuestionPool", "qst");
1559  foreach ($plugins as $pluginName) {
1560  if ($pluginName == $questionType) { // plugins having pname == qtype
1561  return true;
1562  }
1563 
1564  /* @var ilQuestionsPlugin $plugin */
1565  $plugin = ilPlugin::getPluginObject(IL_COMP_MODULE, "TestQuestionPool", "qst", $pluginName);
1566 
1567  if ($plugin->getQuestionType() == $questionType) { // plugins havin an independent name
1568  return true;
1569  }
1570  }
1571 
1572  return false;
1573  }
1574 
1575  /*
1576  * Remove all questions with owner = 0
1577  */
1578  public function purgeQuestions()
1579  {
1580  global $ilDB, $ilUser;
1581 
1582  require_once 'Modules/TestQuestionPool/classes/class.ilAssIncompleteQuestionPurger.php';
1583  $incompleteQuestionPurger = new ilAssIncompleteQuestionPurger($ilDB);
1584  $incompleteQuestionPurger->setOwnerId($ilUser->getId());
1585  $incompleteQuestionPurger->purge();
1586  }
1587 
1593  public function getTaxonomyIds()
1594  {
1595  require_once 'Services/Taxonomy/classes/class.ilObjTaxonomy.php';
1596  return ilObjTaxonomy::getUsageOfObject($this->getId());
1597  }
1598 
1602  public function isSkillServiceEnabled()
1603  {
1605  }
1606 
1611  {
1612  $this->skillServiceEnabled = $skillServiceEnabled;
1613  }
1614 
1616 
1617  public static function isSkillManagementGloballyActivated()
1618  {
1619  if (self::$isSkillManagementGloballyActivated === null) {
1620  include_once 'Services/Skill/classes/class.ilSkillManagementSettings.php';
1621  $skmgSet = new ilSkillManagementSettings();
1622 
1623  self::$isSkillManagementGloballyActivated = $skmgSet->isActivated();
1624  }
1625 
1626  return self::$isSkillManagementGloballyActivated;
1627  }
1628 
1629  public function fromXML($xmlFile)
1630  {
1631  require_once 'Modules/TestQuestionPool/classes/class.ilObjQuestionPoolXMLParser.php';
1632  $parser = new ilObjQuestionPoolXMLParser($this, $xmlFile);
1633  $parser->startParsing();
1634  }
1635 } // END class.ilObjQuestionPool
static getPluginObject($a_ctype, $a_cname, $a_slot_id, $a_pname)
Get plugin object.
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.
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
exportFileItems($a_target_dir, &$expLog)
export files of file itmes
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.
addQuestionChangeListeners(assQuestion $question)
static _isUsedInRandomTest($question_id="")
Checks whether the question is used in a random test or not.
global $DIC
Definition: saml.php:7
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.
static _getQuestionTypes($all_tags=false, $fixOrder=false)
& 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.
$counter
$xml
Definition: metadata.php:240
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
getQuestionTypes($all_tags=false, $fixOrder=false)
static _lookupObjId($a_id)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
__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.
cleanupClipboard($deletedQuestionId)
static _setImportDirectory($a_import_dir=null)
set import directory
const IL_COMP_MODULE
$ilUser
Definition: imgupload.php:18
redirection script todo: (a better solution should control the processing via a xml file) ...
update()
update object data
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
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
Create styles array
The data for the language used.
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
update($pash, $contents, Config $config)
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.
$parser
Definition: BPMN2Parser.php:23
static getDataDir()
get data directory (outside webspace)
static _getQuestionCount($questionpool_id, $complete_questions_only=false)
Returns the number of questions in a question pool.
global $ilBench
Definition: ilias.php:18
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
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
addQuestionChangeListener(ilQuestionChangeListener $listener)
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
$key
Definition: croninfo.php:18
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...