ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilSurveyEditorGUI.php
Go to the documentation of this file.
1 <?php
2 
21 
31 {
32  protected \ILIAS\Survey\Sequence\SequenceManager $sequence_manager;
33  protected \ILIAS\Survey\InternalGUIService $gui;
34  protected \ILIAS\Survey\PrintView\GUIService $print;
35  protected \ILIAS\HTTP\Services $http;
36  protected \ILIAS\DI\UIServices $ui;
37  protected string $requested_pgov;
40  protected ilCtrl $ctrl;
41  protected ilLanguage $lng;
43  protected ilTabsGUI $tabs;
44  protected ilHelpGUI $help;
46  protected ilObjUser $user;
47  protected ilTree $tree;
49  protected ilObjSurvey $object;
50  protected array $print_options;
51 
52  public function __construct(ilObjSurveyGUI $a_parent_gui)
53  {
54  global $DIC;
55 
56  $this->tabs = $DIC->tabs();
57  $this->help = $DIC["ilHelp"];
58  $this->toolbar = $DIC->toolbar();
59  $this->user = $DIC->user();
60  $this->tree = $DIC->repositoryTree();
61  $ilCtrl = $DIC->ctrl();
62  $lng = $DIC->language();
63  $tpl = $DIC["tpl"];
64 
65  $this->parent_gui = $a_parent_gui;
67  $survey = $this->parent_gui->getObject();
68  $this->object = $survey;
69 
70  $this->ctrl = $ilCtrl;
71  $this->lng = $lng;
72  $this->tpl = $tpl;
73 
74  $this->ctrl->saveParameter($this, array("pgov", "pgov_pos"));
75 
76  $this->print_options = array(
77  //0 => $this->lng->txt('none'),
78  ilObjSurvey::PRINT_HIDE_LABELS => $this->lng->txt('svy_print_hide_labels'),
79  //2 => $this->lng->txt('svy_print_label_only'),
80  ilObjSurvey::PRINT_SHOW_LABELS => $this->lng->txt('svy_print_show_labels')
81  );
82  $this->edit_manager = $DIC->survey()
83  ->internal()
84  ->domain()
85  ->edit();
86  $this->request = $DIC->survey()
87  ->internal()
88  ->gui()
89  ->editing()
90  ->request();
91  $this->requested_pgov = $this->request->getTargetPosition();
92  $this->ui = $DIC->ui();
93  $this->http = $DIC->http();
94  $this->print = $DIC->survey()
95  ->internal()
96  ->gui()
97  ->print();
98  $this->gui = $DIC->survey()
99  ->internal()
100  ->gui();
101  $this->sequence_manager = $DIC->survey()->internal()->domain()->sequence(
102  $this->object->getSurveyId(),
104  );
105  }
106 
107  public function setRequestedPgov(string $pgov): void
108  {
109  $this->requested_pgov = $pgov;
110  }
111 
112  public function executeCommand(): void
113  {
114  $ilTabs = $this->tabs;
115 
116  $cmd = $this->ctrl->getCmd("questions");
117 
118  $next_class = $this->ctrl->getNextClass($this);
119  switch ($next_class) {
120 
121  default:
122  // question gui
123  if (stripos($next_class, "questiongui") !== false) {
124  $ilTabs->clearTargets();
125  $this->ctrl->saveParameter($this, array("new_for_survey"));
127  null,
128  $this->request->getQuestionId()
129  );
130  if (is_object($q_gui->object)) {
131  $ilHelp = $this->help;
132  $ilHelp->setScreenIdComponent("spl_qt" . $q_gui->object->getQuestionTypeId());
133  }
134  // $q_gui->object->setObjId($this->object->getId());
135  $q_gui->setBackUrl($this->ctrl->getLinkTarget($this, "questions"));
136  $q_gui->setQuestionTabs();
137  $this->ctrl->forwardCommand($q_gui);
138 
139  if (!$this->request->getNewForSurvey()) {
140  // not on create
141  $this->tpl->setTitle($this->lng->txt("question") . ": " . $q_gui->object->getTitle());
142  }
143  } else {
144  $cmd .= "Object";
145  $this->$cmd();
146  }
147  break;
148  }
149  }
150 
151  protected function questionsSubtabs(
152  string $a_cmd
153  ): void {
154  $ilTabs = $this->tabs;
155 
156  if ($a_cmd === "questions" && $this->requested_pgov !== "") {
157  $a_cmd = "page";
158  }
159 
160  $this->ctrl->setParameter($this, "pgov", "");
161  $ilTabs->addSubTab(
162  "questions",
163  $this->lng->txt("survey_question_editor"),
164  $this->ctrl->getLinkTarget($this, "questions")
165  );
166  $this->ctrl->setParameter($this, "pgov", $this->requested_pgov);
167 
168  if ($this->object->getSurveyPages()) {
169  if ($a_cmd === "page") {
170  $this->ctrl->setParameterByClass("ilsurveyexecutiongui", "pgov", max(1, $this->request->getPage()));
171  }
172  $this->ctrl->setParameterByClass("ilsurveyexecutiongui", "prvw", 1);
173  $ilTabs->addSubTab(
174  "preview",
175  $this->lng->txt("preview"),
176  $this->ctrl->getLinkTargetByClass(array("ilobjsurveygui", "ilsurveyexecutiongui"), "preview")
177  );
178  }
179 
180  $ilTabs->activateSubTab($a_cmd);
181  }
182 
183 
184  //
185  // QUESTIONS BROWSER INCL. MULTI-ACTIONS
186  //
187 
188  public function questionsObject(): void
189  {
190  $ilToolbar = $this->toolbar;
191  $ilUser = $this->user;
192 
193  // insert new questions?
194  if ($this->request->getNewId() > 0) {
195  // add a question to the survey previous created in a questionpool
196  $existing = $this->object->getExistingQuestions();
197  if (!in_array($this->request->getNewId(), $existing)) {
198  $inserted = $this->object->insertQuestion($this->request->getNewId());
199  if (!$inserted) {
200  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("survey_error_insert_incomplete_question"));
201  } else {
202  // this ensures the status update of the survey, see #36162
203  $this->ctrl->redirect($this, "questions");
204  }
205  }
206  }
207  $this->questionsSubtabs("questions");
208 
209  $hasDatasets = ilObjSurvey::_hasDatasets($this->object->getSurveyId());
210  $read_only = $hasDatasets;
211 
212  // toolbar
213  if (!$read_only) {
214  $qtypes = array();
215  foreach (ilObjSurveyQuestionPool::_getQuestiontypes() as $translation => $data) {
216  $qtypes[$data["type_tag"]] = $translation;
217  }
218 
219  $ilToolbar->setFormAction($this->ctrl->getFormAction($this));
220  $types = new ilSelectInputGUI($this->lng->txt("create_new"), "sel_question_types");
221  $types->setOptions($qtypes);
222  $ilToolbar->addStickyItem($types, "");
223 
224  $this->gui->button(
225  $this->lng->txt("svy_create_question"),
226  "createQuestion"
227  )->submit()->toToolbar(true);
228 
229  if ($this->object->getPoolUsage()) {
230  $cmd = ((int) $ilUser->getPref('svy_insert_type') === 1 ||
231  ($ilUser->getPref('svy_insert_type') ?? '') === '')
232  ? 'browseForQuestions'
233  : 'browseForQuestionblocks';
234 
235  $this->gui->button(
236  $this->lng->txt("browse_for_questions"),
237  $this->ctrl->getLinkTarget($this, $cmd)
238  )->toToolbar(true);
239  }
240 
241  if ($this->object->hasQuestions()) {
242  $ilToolbar->addSeparator();
243  $this->gui->button(
244  $this->lng->txt("add_heading"),
245  $this->ctrl->getLinkTarget($this, "addHeading")
246  )->toToolbar();
247  }
248 
249  $ilToolbar->addSeparator();
250  $print_view = $this->print->list($this->object->getRefId());
251  $modal_elements = $print_view->getModalElements(
252  $this->ctrl->getLinkTarget(
253  $this,
254  "printListViewSelection"
255  )
256  );
257  $ilToolbar->addComponent($modal_elements->button);
258  $ilToolbar->addComponent($modal_elements->modal);
259  }
260  $mess = "";
261  if ($hasDatasets) {
262  $mbox = new ilSurveyContainsDataMessageBoxGUI();
263  $mess = $mbox->getHTML();
264  }
265 
266  // table gui
267  $table = new ilSurveyQuestionTableGUI(
268  $this,
269  "questions",
270  $this->object,
271  $read_only
272  );
273  $this->tpl->setContent($mess . $table->getHTML());
274  }
275 
280  protected function gatherSelectedTableItems(
281  bool $allow_blocks = true,
282  bool $allow_questions = true,
283  bool $allow_headings = false,
284  bool $allow_questions_in_blocks = false
285  ): array {
286  $block_map = array();
287  foreach ($this->object->getSurveyQuestions() as $item) {
288  $block_map[$item["question_id"]] = $item["questionblock_id"];
289  }
290 
291  $questions = $blocks = $headings = array();
292  $ids = $this->request->getIds();
293  if (count($ids) > 0) {
294  foreach ($ids as $key) {
295  // questions
296  if ($allow_questions && preg_match("/cb_(\d+)/", $key, $matches)) {
297  if (($allow_questions_in_blocks || !$block_map[$matches[1]]) &&
298  !in_array($block_map[$matches[1]], $blocks)) {
299  $questions[] = $matches[1];
300  }
301  }
302  // blocks
303  if ($allow_blocks && preg_match("/cb_qb_(\d+)/", $key, $matches)) {
304  $blocks[] = $matches[1];
305  }
306  // headings
307  if ($allow_headings && preg_match("/cb_tb_(\d+)/", $key, $matches)) {
308  $headings[] = $matches[1];
309  }
310  }
311  }
312 
313  return array("questions" => $questions,
314  "blocks" => $blocks,
315  "headings" => $headings);
316  }
317 
318  public function saveObligatoryObject(): void
319  {
320  $req_order = $this->request->getOrder();
321  $req_block_order = $this->request->getBlockOrder();
322  if (count($req_order) > 0) {
323  $position = -1;
324  $order = array();
325  asort($req_order);
326  foreach (array_keys($req_order) as $id) {
327  // block items
328  if (strpos($id, "qb_") === 0) {
329  $block_id = substr($id, 3);
330  $block = $req_block_order[$block_id];
331  asort($block);
332  foreach (array_keys($block) as $question_id) {
333  $position++;
334  $order[$question_id] = $position;
335  }
336  } else {
337  $question_id = substr($id, 2);
338  $position++;
339  $order[$question_id] = $position;
340  }
341  }
342  $this->object->updateOrder($order);
343  }
344 
345  $obligatory = $this->request->getObligatory();
346  $this->object->setObligatoryStates($obligatory);
347  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
348  $this->ctrl->redirect($this, "questions");
349  }
350 
351  public function unfoldQuestionblockObject(): void
352  {
353  $items = $this->gatherSelectedTableItems(true, false, false, false);
354  if (count($items["blocks"])) {
355  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
356  $this->object->unfoldQuestionblocks($items["blocks"]);
357  } else {
358  $this->tpl->setOnScreenMessage('info', $this->lng->txt("qpl_unfold_select_none"), true);
359  }
360  $this->ctrl->redirect($this, "questions");
361  }
362 
363  public function moveQuestionsObject(): void
364  {
365  $items = $this->gatherSelectedTableItems(true, true, false, false);
366 
367  $move_questions = $items["questions"];
368  foreach ($items["blocks"] as $block_id) {
369  foreach ($this->object->getQuestionblockQuestionIds($block_id) as $qid) {
370  $move_questions[] = $qid;
371  }
372  }
373  if (count($move_questions) === 0) {
374  $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_question_selected_for_move"), true);
375  $this->ctrl->redirect($this, "questions");
376  } else {
377  $this->edit_manager->setMoveSurveyQuestions($this->object->getId(), $move_questions);
378  $this->tpl->setOnScreenMessage('info', $this->lng->txt("select_target_position_for_move_question"));
379  $this->questionsObject();
380  }
381  }
382 
383  public function insertQuestionsBeforeObject(): void
384  {
385  $this->insertQuestions(0);
386  }
387 
388  public function insertQuestionsAfterObject(): void
389  {
390  $this->insertQuestions(1);
391  }
392 
393  protected function insertQuestions(
394  int $insert_mode
395  ): void {
396  $copy = ($this->edit_manager->getQuestionClipboardMode($this->object->getRefId()) === "copy");
397  if ($copy) {
398  $this->copyPasteObject($insert_mode);
399  return;
400  }
401 
402  $insert_id = null;
403  $ids = $this->request->getIds();
404  if (count($ids) > 0) {
405  $items = $this->gatherSelectedTableItems(true, true, false, false);
406 
407  // we are using POST id for original order
408  while (!$insert_id && count($ids) > 0) {
409  $target = array_shift($ids);
410  if (preg_match("/^cb_(\d+)$/", $target, $matches)) {
411  // questions in blocks are not allowed
412  if (in_array($matches[1], $items["questions"])) {
413  $insert_id = $matches[1];
414  }
415  }
416  if (!$insert_id && preg_match("/^cb_qb_(\d+)$/", $target, $matches)) {
417  $ids = $this->object->getQuestionblockQuestionIds($matches[1]);
418  if (count($ids)) {
419  if ($insert_mode === 0) {
420  $insert_id = $ids[0];
421  } elseif ($insert_mode === 1) {
422  $insert_id = $ids[count($ids) - 1];
423  }
424  }
425  }
426  }
427  }
428  if (!$insert_id) {
429  $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_target_selected_for_move"), true);
430  } else {
431  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
432  if ($this->edit_manager->getMoveSurveyId() === $this->object->getId()) {
433  $this->object->moveQuestions(
434  $this->edit_manager->getMoveSurveyQuestions(),
435  $insert_id,
436  $insert_mode
437  );
438  $this->edit_manager->clearMoveSurveyQuestions();
439  }
440  }
441 
442  $this->ctrl->redirect($this, "questions");
443  }
444 
445  public function removeQuestionsObject(): void
446  {
447  $items = $this->gatherSelectedTableItems(true, true, true, true);
448  if (count($items["blocks"]) + count($items["questions"]) + count($items["headings"]) > 0) {
449  $this->tpl->setOnScreenMessage('question', $this->lng->txt("remove_questions"));
450  $this->removeQuestionsForm($items["blocks"], $items["questions"], $items["headings"]);
451  } else {
452  $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_question_selected_for_removal"), true);
453  $this->ctrl->redirect($this, "questions");
454  }
455  }
456 
457  public function removeQuestionsForm(
458  array $checked_questionblocks,
459  array $checked_questions,
460  array $checked_headings
461  ): void {
462  $cgui = new ilConfirmationGUI();
463  $cgui->setHeaderText($this->lng->txt("survey_sure_delete_questions"));
464  $cgui->setFormAction($this->ctrl->getFormAction($this, "confirmRemoveQuestions"));
465  $cgui->setCancel($this->lng->txt("cancel"), "questions");
466  $cgui->setConfirm($this->lng->txt("confirm"), "confirmRemoveQuestions");
467  $surveyquestions = $this->object->getSurveyQuestions();
468  foreach ($surveyquestions as $question_id => $data) {
469  if (in_array($data["question_id"], $checked_questions)) {
470  $type = SurveyQuestion::_getQuestionTypeName($data["type_tag"]);
471 
472  $cgui->addItem(
473  "q_id[]",
474  $data["question_id"],
475  $type . ": " . $data["title"]
476  );
477  } elseif ((in_array($data["questionblock_id"], $checked_questionblocks))) {
478  $type = SurveyQuestion::_getQuestionTypeName($data["type_tag"]);
479 
480  $cgui->addItem(
481  "cb[" . $data["questionblock_id"] . "]",
482  $data["questionblock_id"],
483  $data["questionblock_title"] . " - " . $type . ": " . $data["title"]
484  );
485  } elseif (in_array($data["question_id"], $checked_headings)) {
486  $cgui->addItem(
487  "heading[" . $data["question_id"] . "]",
488  $data["question_id"],
489  $data["heading"]
490  );
491  }
492  }
493 
494  $this->tpl->setContent($cgui->getHTML());
495  }
496 
497  public function confirmRemoveQuestionsObject(): void
498  {
499  $checked_questions = $this->request->getQuestionIds();
500  $checked_questionblocks = $this->request->getBlockIds();
501  $checked_headings = $this->request->getHeadings();
502 
503  if (count($checked_questions) || count($checked_questionblocks)) {
504  $this->object->removeQuestions($checked_questions, $checked_questionblocks);
505  }
506  if ($checked_headings) {
507  foreach ($checked_headings as $q_id) {
508  $this->object->saveHeading("", $q_id);
509  }
510  }
511  $this->object->saveCompletionStatus();
512  $this->tpl->setOnScreenMessage('success', $this->lng->txt("questions_removed"), true);
513  $this->ctrl->redirect($this, "questions");
514  }
515 
516  public function copyQuestionsToPoolObject(): void
517  {
518  $items = $this->gatherSelectedTableItems(true, true, false, true);
519 
520  // gather questions from blocks
521  $copy_questions = $items["questions"];
522  foreach ($items["blocks"] as $block_id) {
523  foreach ($this->object->getQuestionblockQuestionIds($block_id) as $qid) {
524  $copy_questions[] = $qid;
525  }
526  }
527  $copy_questions = array_unique($copy_questions);
528 
529  // only if not already in pool
530  if (count($copy_questions)) {
531  foreach ($copy_questions as $idx => $question_id) {
532  $question = ilObjSurvey::_instanciateQuestion($question_id);
533  if ($question->getOriginalId()) {
534  unset($copy_questions[$idx]);
535  }
536  }
537  }
538  if (count($copy_questions) === 0) {
539  $this->tpl->setOnScreenMessage('info', $this->lng->txt("no_question_selected_for_copy_to_pool"), true);
540  $this->ctrl->redirect($this, "questions");
541  } else {
542  $this->questionsSubtabs("questions");
543 
544  $form = new ilPropertyFormGUI();
545 
546  $form->setFormAction($this->ctrl->getFormAction($this, "executeCreateQuestion"));
547 
548  $ids = new ilHiddenInputGUI("question_ids");
549  $ids->setValue(implode(";", $copy_questions));
550  $form->addItem($ids);
551 
552  $questionpools = $this->object->getAvailableQuestionpools(false, false, true, "write");
553  $pools = new ilSelectInputGUI($this->lng->txt("survey_copy_select_questionpool"), "sel_spl");
554  $pools->setOptions($questionpools);
555  $form->addItem($pools);
556 
557  $form->addCommandButton("executeCopyQuestionsToPool", $this->lng->txt("submit"));
558  $form->addCommandButton("questions", $this->lng->txt("cancel"));
559 
560  $this->tpl->setContent($form->getHTML());
561  }
562  }
563 
564  public function executeCopyQuestionsToPoolObject(): void
565  {
566  $question_ids = $this->request->getQuestionIdsFromString();
567  $pool_id = ilObject::_lookupObjId($this->request->getSelectedPool());
568 
569  foreach ($question_ids as $qid) {
570  // create copy (== pool "original")
571  $new_question = ilObjSurvey::_instanciateQuestion($qid);
572  $new_question->setId();
573  $new_question->setObjId($pool_id);
574  $new_question->saveToDb();
575 
576  // link "source" (survey) to copy (pool)
577  SurveyQuestion::_changeOriginalId($qid, $new_question->getId(), $pool_id);
578  }
579 
580  $this->tpl->setOnScreenMessage('success', $this->lng->txt("survey_copy_to_questionpool_success"), true);
581  $this->ctrl->redirect($this, "questions");
582  }
583 
584 
585  //
586  // QUESTION CREATION
587  //
588 
589  public function createQuestionObject(
590  ilPropertyFormGUI $a_form = null,
591  $sel_question_types = null,
592  string $pgov_pos = null
593  ): ?ilPropertyFormGUI {
594  if (!$this->object->getPoolUsage()) {
595  $this->executeCreateQuestionObject(null, 1, $pgov_pos);
596  return null;
597  }
598 
599  if (!$a_form) {
600  $this->questionsSubtabs("questions");
601  $form = new ilPropertyFormGUI();
602 
603  if (is_null($sel_question_types)) {
604  $sel_question_types = $this->request->getSelectedQuestionTypes();
605  }
606  $this->ctrl->setParameter($this, "sel_question_types", $sel_question_types);
607  $form->setFormAction($this->ctrl->getFormAction($this, "executeCreateQuestion"));
608  } else {
609  $form = $a_form;
610  }
611 
612  $usage = new ilRadioGroupInputGUI($this->lng->txt("survey_pool_selection"), "usage");
613  $usage->setRequired(true);
614  $no_pool = new ilRadioOption($this->lng->txt("survey_no_pool"), 1);
615  $usage->addOption($no_pool);
616  $existing_pool = new ilRadioOption($this->lng->txt("survey_existing_pool"), 3);
617  $usage->addOption($existing_pool);
618  $new_pool = new ilRadioOption($this->lng->txt("survey_new_pool"), 2);
619  $usage->addOption($new_pool);
620  $form->addItem($usage);
621 
622  if ($this->edit_manager->getPoolChoice() > 0) {
623  $usage->setValue($this->edit_manager->getPoolChoice());
624  } else {
625  // default: no pool
626  $usage->setValue(1);
627  }
628 
629  $questionpools = $this->object->getAvailableQuestionpools(false, true, true, "write");
630  $pools = new ilSelectInputGUI($this->lng->txt("select_questionpool"), "sel_spl");
631  $pools->setOptions($questionpools);
632  $existing_pool->addSubItem($pools);
633 
634  $name = new ilTextInputGUI($this->lng->txt("spl_new"), "name_spl"); // #11740
635  $name->setSize(50);
636  $name->setMaxLength(50);
637  $new_pool->addSubItem($name);
638 
639  if ($a_form) {
640  return $a_form;
641  }
642 
643  $form->addCommandButton("executeCreateQuestion", $this->lng->txt("submit"));
644  $form->addCommandButton("questions", $this->lng->txt("cancel"));
645 
646  $this->tpl->setContent($form->getHTML());
647  return null;
648  }
649 
651  ?string $q_type = null,
652  ?int $pool_usage = null,
653  ?string $pgov_pos = null
654  ): void {
655  $this->edit_manager->setPoolChoice($this->request->getPoolUsage());
656 
657  if (is_null($q_type)) {
658  $q_type = $this->request->getSelectedQuestionTypes();
659  }
660 
661  $pgov = $this->requested_pgov;
662  if (is_null($pgov_pos)) {
663  $pgov_pos = $this->request->getTargetQuestionPosition();
664  }
665 
666  if (is_null($pool_usage)) {
667  $pool_usage = $this->request->getPoolUsage();
668  }
669 
670  $obj_id = 0;
671 
672  // no pool
673  if ($pool_usage == 1) {
674  $obj_id = $this->object->getId();
675  }
676  // existing pool
677  elseif ($pool_usage == 3 && $this->request->getSelectedPool() > 0) {
678  $obj_id = ilObject::_lookupObjId($this->request->getSelectedPool());
679  }
680  // new pool
681  elseif ($pool_usage == 2 && $this->request->getPoolName() !== "") {
682  $obj_id = $this->createQuestionPool($this->request->getPoolName());
683  } else {
684  if (!$pool_usage) {
685  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("select_one"), true);
686  } else {
687  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("err_no_pool_name"), true);
688  }
689  $this->ctrl->setParameter($this, "sel_question_types", $q_type);
690  $this->ctrl->redirect($this, "createQuestion");
691  }
692 
693 
694  // create question and redirect to question form
695 
696  $q_gui = SurveyQuestionGUI::_getQuestionGUI($q_type);
697  $q_gui->object->setObjId($obj_id); // survey/pool!
698  $q_gui->object->createNewQuestion();
699  $q_gui_class = get_class($q_gui);
700 
701  if ($pgov !== "") {
702  $this->ctrl->setParameterByClass($q_gui_class, "pgov", $pgov);
703  $this->ctrl->setParameterByClass($q_gui_class, "pgov_pos", $pgov_pos);
704  }
705 
706  $this->ctrl->setParameterByClass($q_gui_class, "ref_id", $this->object->getRefId());
707  $this->ctrl->setParameterByClass($q_gui_class, "new_for_survey", $this->object->getRefId());
708  $this->ctrl->setParameterByClass($q_gui_class, "q_id", $q_gui->object->getId());
709  $this->ctrl->setParameterByClass($q_gui_class, "sel_question_types", $q_gui->getQuestionType());
710  $this->ctrl->redirectByClass($q_gui_class, "editQuestion");
711  }
712 
713  protected function createQuestionPool($name = "dummy"): int
714  {
715  $tree = $this->tree;
716 
717  $parent_ref = $tree->getParentId($this->object->getRefId());
718 
719  $qpl = new ilObjSurveyQuestionPool();
720  $qpl->setType("spl");
721  $qpl->setTitle($name);
722  $qpl->setDescription("");
723  $qpl->create();
724  $qpl->createReference();
725  $qpl->putInTree($parent_ref);
726  $qpl->setPermissions($parent_ref);
727  $qpl->setOnline(1); // must be online to be available
728  $qpl->saveToDb();
729 
730  return $qpl->getId();
731  }
732 
733 
734  //
735  // ADD FROM POOL
736  //
737 
738  protected function setBrowseForQuestionsSubtabs(): void
739  {
740  $ilTabs = $this->tabs;
741  $ilToolbar = $this->toolbar;
742  $ilUser = $this->user;
743 
744  $link = $this->ctrl->getLinkTarget($this, "questions");
745  $ilTabs->setBackTarget($this->lng->txt("menubacktosurvey"), $link);
746 
747  // type selector
748  $types = new ilSelectInputGUI($this->lng->txt("display_all_available"), "datatype");
749  $types->setOptions(array(
750  1 => $this->lng->txt("questions"),
751  2 => $this->lng->txt("questionblocks")
752  ));
753  $types->setValue($ilUser->getPref('svy_insert_type'));
754  $ilToolbar->addInputItem($types, true);
755  $ilToolbar->addFormButton($this->lng->txt("change"), "changeDatatype");
756  $ilToolbar->setFormAction($this->ctrl->getFormAction($this, "changeDatatype"));
757  }
758 
759  public function changeDatatypeObject(): void
760  {
761  $ilUser = $this->user;
762 
763  $ilUser->writePref('svy_insert_type', $this->request->getDataType());
764 
765  switch ($this->request->getDataType()) {
766  case 2:
767  $this->ctrl->redirect($this, 'browseForQuestionblocks');
768  break;
769 
770  case 1:
771  default:
772  $this->ctrl->redirect($this, 'browseForQuestions');
773  break;
774  }
775  }
776 
777  public function browseForQuestionsObject(): void
778  {
780 
781  $table_gui = new ilSurveyQuestionbrowserTableGUI($this, 'browseForQuestions', $this->object, true);
782  $table_gui->setEditable(true);
783  $this->tpl->setContent($table_gui->getHTML());
784  }
785 
786  public function filterQuestionBrowserObject(): void
787  {
788  $table_gui = new ilSurveyQuestionbrowserTableGUI($this, 'browseForQuestions', $this->object);
789  $table_gui->writeFilterToSession();
790  $this->ctrl->redirect($this, 'browseForQuestions');
791  }
792 
793  public function resetfilterQuestionBrowserObject(): void
794  {
795  $table_gui = new ilSurveyQuestionbrowserTableGUI($this, 'browseForQuestions', $this->object);
796  $table_gui->resetFilter();
797  $this->ctrl->redirect($this, 'browseForQuestions');
798  }
799 
800  public function insertQuestionsObject(): void
801  {
802  $inserted_objects = 0;
803  $page_gui = null;
804  $qids = $this->request->getQuestionIds();
805  if (count($qids) > 0) {
806  foreach ($qids as $question_id) {
807  if ($this->requested_pgov === "") {
808  $this->object->insertQuestion($question_id);
809  } else {
810  // "pgov" must be set to 1 to land here
811  // target position in page (pgov_pos) is processed there
812  $page_gui->insertNewQuestion($question_id);
813  }
814  $inserted_objects++;
815  }
816  }
817  if ($inserted_objects) {
818  $this->object->saveCompletionStatus();
819  $this->tpl->setOnScreenMessage('success', $this->lng->txt("questions_inserted"), true);
820  $this->ctrl->redirect($this, "questions");
821  } else {
822  $this->tpl->setOnScreenMessage('info', $this->lng->txt("insert_missing_question"), true);
823  $this->ctrl->redirect($this, 'browseForQuestions');
824  }
825  }
826 
827  public function browseForQuestionblocksObject(): void
828  {
830 
831  $table_gui = new ilSurveyQuestionblockbrowserTableGUI($this, 'browseForQuestionblocks', $this->object, true);
832  $table_gui->setEditable(true);
833  $this->tpl->setContent($table_gui->getHTML());
834  }
835 
836  public function filterQuestionblockBrowserObject(): void
837  {
838  $table_gui = new ilSurveyQuestionblockbrowserTableGUI($this, 'browseForQuestionblocks', $this->object);
839  $table_gui->writeFilterToSession();
840  $this->ctrl->redirect($this, 'browseForQuestionblocks');
841  }
842 
844  {
845  $table_gui = new ilSurveyQuestionblockbrowserTableGUI($this, 'browseForQuestionblocks', $this->object);
846  $table_gui->resetFilter();
847  $this->ctrl->redirect($this, 'browseForQuestionblocks');
848  }
849 
850  public function insertQuestionblocksObject(): void
851  {
852  $inserted_objects = 0;
853  $page_gui = null;
854  $block_ids = $this->request->getBlockIds();
855  if (count($block_ids) > 0) {
856  foreach ($block_ids as $questionblock_id) {
857  if ($this->requested_pgov === "") {
858  $this->object->insertQuestionblock($questionblock_id);
859  } else {
860  $page_gui->insertQuestionBlock($questionblock_id);
861  }
862  $inserted_objects++;
863  }
864  }
865  if ($inserted_objects) {
866  $this->object->saveCompletionStatus();
867  $this->tpl->setOnScreenMessage('success', ($inserted_objects === 1) ? $this->lng->txt("questionblock_inserted") : $this->lng->txt("questionblocks_inserted"), true);
868  $this->ctrl->redirect($this, "questions");
869  } else {
870  $this->tpl->setOnScreenMessage('info', $this->lng->txt("insert_missing_questionblock"), true);
871  $this->ctrl->redirect($this, 'browseForQuestionblocks');
872  }
873  }
874 
875 
876  //
877  // BLOCKS
878  //
879 
880  public function editQuestionblockObject(
881  ilPropertyFormGUI $a_form = null
882  ): void {
883  $block_id = $this->request->getBlockId();
884  $this->ctrl->setParameter($this, "bl_id", $block_id);
885 
886  if (!$a_form) {
887  $a_form = $this->initQuestionblockForm($block_id);
888  }
889 
890  $this->questionsSubtabs("questions");
891  $this->tpl->setContent($a_form->getHTML());
892  }
893 
894  public function createQuestionblockObject(
895  ilPropertyFormGUI $a_form = null
896  ): void {
897  if (!$a_form) {
898  // gather questions from table selected
899  $items = $this->gatherSelectedTableItems(false, true, false, false);
900 
901  $qids = $this->request->getQuestionIds();
902  if (count($qids) > 0) {
903  $items["questions"] = $qids;
904  }
905  if (count($items["questions"]) < 2) {
906  $this->tpl->setOnScreenMessage('info', $this->lng->txt("qpl_define_questionblock_select_missing"), true);
907  $this->ctrl->redirect($this, "questions");
908  }
909 
910  $a_form = $this->initQuestionblockForm(null, $items["questions"]);
911  }
912 
913  $this->questionsSubtabs("questions");
914  $this->tpl->setContent($a_form->getHTML());
915  }
916 
917  protected function initQuestionblockForm(
918  ?int $a_block_id = null,
919  ?array $a_question_ids = null
920  ): ilPropertyFormGUI {
921  $questionblock = null;
922  $form = new ilPropertyFormGUI();
923  $form->setFormAction($this->ctrl->getFormAction($this, "saveDefineQuestionblock"));
924  $form->setTitle($this->lng->txt("define_questionblock"));
925 
926  $title = new ilTextInputGUI($this->lng->txt("title"), "title");
927  $title->setRequired(true);
928  $form->addItem($title);
929 
930  $toggle_blocktitle = new ilCheckboxInputGUI($this->lng->txt("survey_show_blocktitle"), "show_blocktitle");
931  $toggle_blocktitle->setInfo($this->lng->txt("survey_show_blocktitle_description"));
932  $form->addItem($toggle_blocktitle);
933 
934  $toggle_questiontitle = new ilCheckboxInputGUI($this->lng->txt("show_questiontext"), "show_questiontext");
935  $toggle_questiontitle->setInfo($this->lng->txt("show_questiontext_description"));
936  $form->addItem($toggle_questiontitle);
937 
938  if ($a_block_id) {
939  $questionblock = ilObjSurvey::_getQuestionblock($a_block_id);
940  $title->setValue($questionblock["title"]);
941  $toggle_blocktitle->setChecked((bool) $questionblock["show_blocktitle"]);
942  $toggle_questiontitle->setChecked((bool) $questionblock["show_questiontext"]);
943  } else {
944  $toggle_blocktitle->setChecked(true);
945  $toggle_questiontitle->setChecked(true);
946  }
947 
948  $compress_view = new ilCheckboxInputGUI($this->lng->txt("svy_compress_view"), "compress_view");
949  $compress_view->setInfo($this->lng->txt("svy_compress_view_info"));
950  $compress_view->setChecked((bool) ($questionblock["compress_view"] ?? false));
951  $form->addItem($compress_view);
952 
953  $form->addCommandButton("saveDefineQuestionblock", $this->lng->txt("save"));
954  $form->addCommandButton("questions", $this->lng->txt("cancel"));
955 
956  // reload?
957  $qids = $this->request->getQuestionIds();
958  if (!$a_question_ids && count($qids) > 0) {
959  $a_question_ids = $qids;
960  }
961 
962  if ($a_question_ids) {
963  foreach ($a_question_ids as $q_id) {
964  $hidden = new ilHiddenInputGUI("qids[]");
965  $hidden->setValue($q_id);
966  $form->addItem($hidden);
967  }
968  }
969 
970  return $form;
971  }
972 
973  public function saveDefineQuestionblockObject(): void
974  {
975  $block_id = $this->request->getBlockId();
976  $q_ids = $this->request->getQuestionIds();
977 
978  $this->ctrl->setParameter($this, "bl_id", $block_id);
979 
980  if (!$block_id && count($q_ids) === 0) {
981  $this->ctrl->redirect($this, "questions");
982  }
983 
984  $form = $this->initQuestionblockForm($block_id);
985  if ($form->checkInput()) {
986  $title = $form->getInput("title");
987  $show_questiontext = $form->getInput("show_questiontext");
988  $show_blocktitle = $form->getInput("show_blocktitle") ;
989  $compress_view = $form->getInput("compress_view") ;
990  if ($block_id) {
991  $this->object->modifyQuestionblock(
992  $block_id,
993  $title,
994  $show_questiontext,
995  $show_blocktitle,
996  $compress_view
997  );
998  } elseif ($q_ids) {
999  $this->object->createQuestionblock(
1000  $title,
1001  $show_questiontext,
1002  $show_blocktitle,
1003  $q_ids,
1004  $compress_view
1005  );
1006  }
1007 
1008  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
1009  $this->ctrl->redirect($this, "questions");
1010  }
1011 
1012  $form->setValuesByPost();
1013  $this->editQuestionblockObject($form);
1014  }
1015 
1016 
1017  //
1018  // HEADING
1019  //
1020 
1021  protected function initHeadingForm(
1022  ?int $a_question_id = null
1023  ): ilPropertyFormGUI {
1024  $survey_questions = $this->object->getSurveyQuestions();
1025 
1026  $form = new ilPropertyFormGUI();
1027  $form->setFormAction($this->ctrl->getFormAction($this, ""));
1028 
1029  // heading
1030  $heading = new ilTextAreaInputGUI($this->lng->txt("heading"), "heading");
1031  $heading->setRows(10);
1032  $heading->setCols(80);
1033  if (ilObjAdvancedEditing::_getRichTextEditor() === "tinymce") {
1034  $heading->setUseRte(true);
1035  $heading->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("survey"));
1036  $heading->removePlugin(ilRTE::ILIAS_IMG_MANAGER_PLUGIN);
1037  $heading->setRTESupport($this->object->getId(), "svy", "survey");
1038  }
1039  $heading->setRequired(true);
1040  $form->addItem($heading);
1041 
1042  $insertbefore = new ilSelectInputGUI($this->lng->txt("insert"), "insertbefore");
1043  $options = array();
1044  foreach ($survey_questions as $key => $value) {
1045  $options[$key] = $this->lng->txt("before") . ": \"" . $value["title"] . "\"";
1046  }
1047  $insertbefore->setOptions($options);
1048  $insertbefore->setRequired(true);
1049  $form->addItem($insertbefore);
1050 
1051  $form->addCommandButton("saveHeading", $this->lng->txt("save"));
1052  $form->addCommandButton("questions", $this->lng->txt("cancel"));
1053 
1054  if ($a_question_id) {
1055  $form->setTitle($this->lng->txt("edit_heading"));
1056 
1057  $heading->setValue($this->object->prepareTextareaOutput($survey_questions[$a_question_id]["heading"] ?? ""));
1058  $insertbefore->setValue($a_question_id);
1059  $insertbefore->setDisabled(true);
1060  } else {
1061  $form->setTitle($this->lng->txt("add_heading"));
1062  }
1063 
1064  return $form;
1065  }
1066 
1067  public function addHeadingObject(
1068  ilPropertyFormGUI $a_form = null
1069  ): void {
1070  $q_id = $this->request->getQuestionId();
1071  $this->ctrl->setParameter($this, "q_id", $q_id);
1072 
1073  $this->questionsSubtabs("questions");
1074 
1075  if (!$a_form) {
1076  $a_form = $this->initHeadingForm($q_id);
1077  }
1078 
1079  $this->tpl->setContent($a_form->getHTML());
1080  }
1081 
1082  public function editHeadingObject(
1083  ilPropertyFormGUI $a_form = null
1084  ): void {
1085  $q_id = $this->request->getQuestionId();
1086  $this->ctrl->setParameter($this, "q_id", $q_id);
1087 
1088  $this->questionsSubtabs("questions");
1089 
1090  if (!$a_form) {
1091  $a_form = $this->initHeadingForm($q_id);
1092  }
1093 
1094  $this->tpl->setContent($a_form->getHTML());
1095  }
1096 
1097  public function saveHeadingObject(): void
1098  {
1099  // #15474
1100  $q_id = $this->request->getQuestionId();
1101  $this->ctrl->setParameter($this, "q_id", $q_id);
1102 
1103  $form = $this->initHeadingForm($q_id);
1104  if ($form->checkInput()) {
1105  $this->object->saveHeading(
1107  $form->getInput("heading"),
1108  true,
1110  ),
1111  $form->getInput("insertbefore")
1112  );
1113  $this->ctrl->redirect($this, "questions");
1114  }
1115 
1116  $form->setValuesByPost();
1117  $this->addHeadingObject($form);
1118  }
1119 
1120  public function removeHeadingObject(): void
1121  {
1122  $q_id = $this->request->getQuestionId();
1123  $this->ctrl->setParameter($this, "q_id", $q_id);
1124 
1125  if (!$q_id) {
1126  $this->ctrl->redirect($this, "questions");
1127  }
1128 
1129  $this->questionsSubtabs("questions");
1130 
1131  $cgui = new ilConfirmationGUI();
1132  $cgui->setHeaderText($this->lng->txt("confirm_remove_heading"));
1133 
1134  $cgui->setFormAction($this->ctrl->getFormAction($this, "confirmedRemoveHeading"));
1135  $cgui->setCancel($this->lng->txt("cancel"), "questions");
1136  $cgui->setConfirm($this->lng->txt("confirm"), "confirmedRemoveHeading");
1137 
1138  $this->tpl->setContent($cgui->getHTML());
1139  }
1140 
1141  public function confirmedRemoveHeadingObject(): void
1142  {
1143  $q_id = $this->request->getQuestionId();
1144  if (!$q_id) {
1145  $this->ctrl->redirect($this, "questions");
1146  }
1147 
1148  $this->object->saveHeading("", $q_id);
1149  $this->ctrl->redirect($this, "questions");
1150  }
1151 
1152  public function printViewObject(): void
1153  {
1154  $print_view = $this->print->page($this->object->getRefId());
1155  $print_view->sendPrintView();
1156  }
1157 
1158  public function printListViewSelectionObject(): void
1159  {
1160  $view = $this->print->list($this->object->getRefId());
1161  $view->sendForm();
1162  }
1163 
1164  public function printListViewObject(): void
1165  {
1166  $print_view = $this->print->list($this->object->getRefId());
1167  $print_view->sendPrintView();
1168  }
1169 
1170  protected function copyQuestionObject(): void
1171  {
1172  $id = $this->request->getQuestionId();
1173  $lng = $this->lng;
1174  $this->tpl->setOnScreenMessage('success', $lng->txt("survey_questions_to_clipboard_copy"), true);
1175  //$this->suppress_clipboard_msg = true;
1176 
1177  $this->edit_manager->setQuestionClipboard(
1178  $this->object->getRefId(),
1179  0,
1180  "copy",
1181  [$id]
1182  );
1183  $this->ctrl->redirect($this, "questions");
1184  }
1185 
1190  protected function copyPasteObject($pos = 0): void
1191  {
1192  $a_id = null;
1193  $ids = $this->request->getIds();
1194  if (count($ids) > 0) {
1195  if (substr($ids[0], 0, 3) == "cb_") {
1196  $a_id = (int) substr($ids[0], 3);
1197  }
1198  }
1199  if (is_null($a_id)) {
1200  return;
1201  }
1202 
1203  $qids = $this->edit_manager->getQuestionClipboardQuestions($this->object->getRefId());
1204  $mode = $this->edit_manager->getQuestionClipboardMode($this->object->getRefId());
1205  $pages = $this->object->getSurveyPages();
1206  $target = null;
1207  foreach ($pages as $page) {
1208  foreach ($page as $question) {
1209  if ($question["question_id"] === $a_id) {
1210  $target = $page;
1211  }
1212  }
1213  }
1214  if (is_null($target)) {
1215  return;
1216  }
1217 
1218  if ($mode !== "copy") {
1219  return;
1220  }
1221 
1222  $titles = array();
1223  foreach ($this->object->getSurveyPages() as $page) {
1224  foreach ($page as $question) {
1225  $titles[] = $question["title"];
1226  }
1227  }
1228 
1229  // copy questions
1230  $question_pointer = array();
1231  foreach ($qids as $qid) {
1232  // create new questions
1233  $question = ilObjSurvey::_instanciateQuestion($qid);
1234 
1235  // handle exisiting copies
1236  $title = $question->getTitle();
1237  $max = 0;
1238  foreach ($titles as $existing_title) {
1239  #21278 preg_quote with delimiter
1240  if (preg_match("/" . preg_quote($title, "/") . " \(([0-9]+)\)$/", $existing_title, $match)) {
1241  $max = max($match[1], $max);
1242  }
1243  }
1244  if ($max) {
1245  $title .= " (" . ($max + 1) . ")";
1246  } else {
1247  $title .= " (2)";
1248  }
1249  $titles[] = $title;
1250  $question->setTitle($title);
1251 
1252  $question->id = -1;
1253  $question->saveToDb(); // this creates the copy
1254 
1255  $question_pointer[$qid] = $question->getId();
1256  $this->sequence_manager->appendQuestion($question->getId(), false);
1257  }
1258 
1259  // copy textblocks
1260  $this->object->cloneTextblocks($question_pointer);
1261 
1262  $this->object->loadQuestionsFromDb();
1263 
1264  $nodes = array_values($question_pointer);
1265 
1266 
1267  // paste
1268 
1269  // create new block
1270  if (count($target) === 1) {
1271  $this->object->moveQuestions($nodes, $a_id, $pos);
1272  }
1273  // add to existing block
1274  else {
1275  $target_block_id = $target;
1276  $target_block_id = array_shift($target_block_id);
1277  $target_block_id = $target_block_id["questionblock_id"];
1278 
1279  foreach ($nodes as $qid) {
1280  $this->object->addQuestionToBlock($qid, $target_block_id);
1281  }
1282 
1283  // move to new position
1284  $this->object->moveQuestions($nodes, $a_id, $pos);
1285  }
1286 
1287  $this->clearClipboard();
1288  $this->ctrl->redirect($this, "questions");
1289  }
1290 
1291  protected function clearClipboard(): void
1292  {
1293  $this->edit_manager->clearQuestionClipboard($this->object->getRefId());
1294  }
1295 
1296  public function getAutoBlockTitle(): string
1297  {
1298  $lng = $this->lng;
1299  return $lng->txt("survey_auto_block_title");
1300  }
1301 
1302 }
initHeadingForm(?int $a_question_id=null)
createQuestionObject(ilPropertyFormGUI $a_form=null, $sel_question_types=null, string $pgov_pos=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
editHeadingObject(ilPropertyFormGUI $a_form=null)
ILIAS HTTP Services $http
ILIAS DI UIServices $ui
copyPasteObject($pos=0)
Paste from clipboard.
Class ilSurveyEditorGUI.
static _hasDatasets(int $survey_id)
writePref(string $a_keyword, string $a_value)
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
Class ilObjSurveyQuestionPool.
static _getRichTextEditor()
Returns the identifier for the Rich Text Editor.
ILIAS Survey PrintView GUIService $print
insertQuestions(int $insert_mode)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
Help GUI class.
static _getQuestionblock(int $questionblock_id)
get question block properties
removeQuestionsForm(array $checked_questionblocks, array $checked_questions, array $checked_headings)
addHeadingObject(ilPropertyFormGUI $a_form=null)
initQuestionblockForm(?int $a_block_id=null, ?array $a_question_ids=null)
executeCreateQuestionObject(?string $q_type=null, ?int $pool_usage=null, ?string $pgov_pos=null)
static _changeOriginalId(int $a_question_id, int $a_original_id, int $a_object_id)
Change original id of existing question in db.
ilGlobalTemplateInterface $tpl
EditingGUIRequest $request
static _getQuestionTypeName(string $type_tag)
Return the translation for a given question type.
setOptions(array $a_options)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
editQuestionblockObject(ilPropertyFormGUI $a_form=null)
createQuestionblockObject(ilPropertyFormGUI $a_form=null)
gatherSelectedTableItems(bool $allow_blocks=true, bool $allow_questions=true, bool $allow_headings=false, bool $allow_questions_in_blocks=false)
Gather (and filter) selected items from table gui.
static _lookupObjId(int $ref_id)
global $DIC
Definition: feed.php:28
Class ilObjSurveyGUI.
createQuestionPool($name="dummy")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getQuestionGUI(?string $questiontype, int $question_id=-1)
Creates a question gui representation.
static http()
Fetches the global http state from ILIAS.
This class represents a property in a property form.
__construct(VocabulariesInterface $vocabularies)
static _instanciateQuestion(int $question_id)
Creates an instance of a question with a given question id.
const ILIAS_IMG_MANAGER_PLUGIN
Definition: class.ilRTE.php:31
setScreenIdComponent(string $a_comp)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setValue(string $a_value)
string $key
Consumer key/client ID value.
Definition: System.php:193
static _getUsedHTMLTagsAsString(string $a_module="")
Returns a string of all allowed HTML tags for text editing.
getParentId(int $a_node_id)
get parent id of given node
setRequired(bool $a_required)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ILIAS Survey InternalGUIService $gui
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This class represents a text area property in a property form.
static _getQuestiontypes()
Get all available question types.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
ILIAS Survey Sequence SequenceManager $sequence_manager
static _getUsedHTMLTags(string $a_module="")
Returns an array of all allowed HTML tags for text editing.