ILIAS  release_8 Revision v8.24
class.ilSurveyPageEditGUI.php
Go to the documentation of this file.
1<?php
2
26{
27 protected \ILIAS\Survey\PrintView\GUIService $print;
28 protected \ILIAS\HTTP\Services $http;
29 protected \ILIAS\DI\UIServices $ui;
30 protected bool $suppress_clipboard_msg = false;
31 protected string $pgov;
32 protected \ILIAS\Survey\Editing\EditingGUIRequest $svy_request;
33 protected \ILIAS\Survey\Editing\EditManager $edit_manager;
34 protected ilCtrl $ctrl;
36 protected ilDBInterface $db;
37 protected ilTabsGUI $tabs;
40 protected ilObjUser $user;
41 protected int $ref_id;
42 protected ilLanguage $lng;
45 protected ?int $current_page = null;
46 protected bool $has_previous_page;
47 protected bool $has_next_page;
48 protected bool $has_datasets;
49 protected bool $use_pool;
50 protected ilLogger $log;
51
52 public function __construct(
53 ilObjSurvey $a_survey,
54 ilSurveyEditorGUI $a_survey_editor_gui
55 ) {
56 global $DIC;
57
58 $this->lng = $DIC->language();
59 $this->ctrl = $DIC->ctrl();
60 $this->rbacsystem = $DIC->rbac()->system();
61 $this->db = $DIC->database();
62 $this->tabs = $DIC->tabs();
63 $this->tpl = $DIC["tpl"];
64 $this->toolbar = $DIC->toolbar();
65 $this->user = $DIC->user();
66 $this->editor_gui = $a_survey_editor_gui;
67 $this->ref_id = $a_survey->getRefId();
68 $this->object = $a_survey;
69 $this->log = ilLoggerFactory::getLogger("svy");
70 $this->edit_manager = $DIC->survey()
71 ->internal()
72 ->domain()
73 ->edit();
74 $this->svy_request = $DIC->survey()
75 ->internal()
76 ->gui()
77 ->editing()
78 ->request();
79 $this->pgov = $this->svy_request->getTargetPosition();
80 $this->ui = $DIC->ui();
81 $this->http = $DIC->http();
82 $this->print = $DIC->survey()
83 ->internal()
84 ->gui()
85 ->print();
86 }
87
88 public function executeCommand(): void
89 {
91 $ilCtrl = $this->ctrl;
93
94 $cmd = $ilCtrl->getCmd("renderPage");
95 $next_class = $ilCtrl->getNextClass($this);
96
97 switch ($next_class) {
98 default:
99 $this->determineCurrentPage();
100
101 $has_content = false;
102
103 if ($rbacsystem->checkAccess("write", $this->ref_id)) {
104 // add page?
105 if ($this->svy_request->getNewId()) {
106 $this->insertNewQuestion($this->svy_request->getNewId());
107 $ilCtrl->setParameter($this->editor_gui, "pgov", $this->current_page);
108 $ilCtrl->redirect($this, "questions");
109 }
110
111 // subcommands
112 if ($this->svy_request->getHForm("subcmd")) {
113 $subcmd = $this->svy_request->getHForm("subcmd");
114
115 // make sure that it is set for current and next requests
116 $ilCtrl->setParameter($this->editor_gui, "pgov", $this->current_page);
117 $this->pgov = $this->current_page;
118 // this is necessary, since ILIAS 7
119 // wrote the REQUEST parameter
120 $this->editor_gui->setRequestedPgov($this->pgov);
121
122 $id = explode("_", $this->svy_request->getHForm("node"));
123 $id = (int) ($id[1] ?? 0);
124
125 // multi operation
126 if (strpos($this->svy_request->getHForm("subcmd"), "multi") === 0) {
127 if ($this->svy_request->getHForm("multi")) {
128 // removing types as we only allow questions anyway
129 $id = array();
130 foreach (explode(";", $this->svy_request->getHForm("multi")) as $item) {
131 $item_arr = explode("_", $item);
132 $id[] = (int) array_pop($item_arr);
133 }
134
135 if ($subcmd === "multiDelete") {
136 $subcmd = "deleteQuestion";
137 }
138 } elseif ($subcmd === "multiDelete") {
139 // #9525
140 $this->tpl->setOnScreenMessage('failure', $lng->txt("no_checkbox"), true);
141 $ilCtrl->redirect($this, "renderPage");
142 } else {
143 $this->tpl->setOnScreenMessage('failure', $lng->txt("no_checkbox"));
144 }
145 }
146
147 if (strpos($subcmd, "addQuestion") === 0) {
148 $type = explode("_", $subcmd);
149 $type = (int) $type[1];
150 $has_content = $this->addQuestion(
151 $type,
152 $this->object->getPoolUsage(),
153 $id,
154 $this->svy_request->getHForm("node")
155 );
156 } else {
157 switch ($subcmd) {
158 case "deleteQuestion":
159 $has_content = true;
160 $ids = (!is_array($id))
161 ? [$id]
162 : $id;
163 $this->deleteQuestion($ids);
164 break;
165 default:
166 if ($id === 0 && in_array($subcmd, ["multiCut", "multiCopy"])) {
167 $id = [];
168 }
169 $has_content = $this->$subcmd($id, $this->svy_request->getHForm("node"));
170 break;
171
172 }
173 }
174 }
175 }
176
177 if (!$has_content) {
178 $this->$cmd();
179 }
180 break;
181 }
182 }
183
184 public function determineCurrentPage(): void
185 {
186 $current_page = null;
187 $jump = $this->svy_request->getJump();
188 if ($jump != "") {
189 $jump_parts = explode("__", $jump);
190 $current_page = (int) ($jump_parts[0] ?? 1);
191 }
192
193 if (!$current_page) {
195 }
196 if (!$current_page) {
197 $current_page = $this->svy_request->getPage();
198 }
199 if (!$current_page) {
200 $current_page = 1;
201 }
202 $this->current_page = (int) $current_page;
203 }
204
210 protected function appendNewQuestionToSurvey(
211 int $a_new_id,
212 bool $a_duplicate = true,
213 bool $a_force_duplicate = false
214 ): int {
215 $ilDB = $this->db;
216 $this->log->debug("append question, id: " . $a_new_id . ", duplicate: " . $a_duplicate . ", force: " . $a_force_duplicate);
217
218 // get maximum sequence index in test
219 $result = $ilDB->queryF(
220 "SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
221 array('integer'),
222 array($this->object->getSurveyId())
223 );
224 $sequence = $result->numRows();
225
226 // create duplicate if pool question (or forced for question blocks copy)
227 if ($a_duplicate) {
228 // this does nothing if this is not a pool question and $a_force_duplicate is false
229 $survey_question_id = $this->object->duplicateQuestionForSurvey($a_new_id, $a_force_duplicate);
230 }
231 // used by copy & paste
232 else {
233 $survey_question_id = $a_new_id;
234 }
235
236 // check if question is not already in the survey, see #22018
237 if ($this->object->isQuestionInSurvey($survey_question_id)) {
238 return $survey_question_id;
239 }
240 // append to survey
241 $next_id = $ilDB->nextId('svy_svy_qst');
242 $affectedRows = $ilDB->manipulateF(
243 "INSERT INTO svy_svy_qst (survey_question_id, survey_fi," .
244 "question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
245 array('integer', 'integer', 'integer', 'integer', 'integer'),
246 array($next_id, $this->object->getSurveyId(), $survey_question_id, $sequence, time())
247 );
248
249 $this->log->debug("insert svy_svy_qst, id: " . $next_id . ", qfi: " . $survey_question_id . ", seq: " . $sequence);
250
251 return $survey_question_id;
252 }
253
257 public function insertNewQuestion(
258 int $a_new_id
259 ): void {
260 $lng = $this->lng;
261 if (!SurveyQuestion::_isComplete($a_new_id)) {
262 $this->tpl->setOnScreenMessage('failure', $lng->txt("survey_error_insert_incomplete_question"));
263 } else {
264 $a_new_id = $this->appendNewQuestionToSurvey($a_new_id);
265 $this->object->loadQuestionsFromDb();
266 $this->object->saveCompletionStatus();
267
268 $pos = $this->svy_request->getTargetQuestionPosition();
269
270 // a[fter]/b[efore] on same page
271 if (substr($pos, -1) !== "c") {
272 // block handling
273 $current = $this->object->getSurveyPages();
274 $current = $current[$this->current_page - 1];
275 if (count($current) === 1) {
276 // as questions are moved to first block question
277 // always use existing as first
278 // the new question is moved later on (see below)
279 $this->object->createQuestionblock(
280 $this->getAutoBlockTitle(),
281 true,
282 false,
283 array((int) $pos, $a_new_id)
284 );
285 } else {
286 $block_id = array_pop($current);
287 $block_id = $block_id["questionblock_id"];
288
289 $this->object->addQuestionToBlock($a_new_id, $block_id);
290 }
291 }
292 // c: as new page (from toolbar/pool)
293 elseif ((int) $pos) {
294 $pos = (int) $pos . "a";
295 $this->current_page++;
296 }
297 // at the beginning
298 else {
299 $first = $this->object->getSurveyPages();
300 $first = $first[0];
301 $first = array_shift($first);
302 $pos = $first["question_id"] . "b";
303 $this->current_page = 1;
304 }
305
306 // move to target position
307 $this->object->moveQuestions(
308 array($a_new_id),
309 (int) $pos,
310 ((substr($pos, -1) === "a") ? 1 : 0)
311 );
312
313 $this->object->fixSequenceStructure();
314 }
315 }
316
320 public function insertQuestionBlock(
321 int $a_block_id
322 ): void {
323 $new_ids = array();
324 $question_ids = $this->object->getQuestionblockQuestionIds($a_block_id);
325 foreach ($question_ids as $qid) {
326 $new_ids[] = $this->appendNewQuestionToSurvey($qid, true, true);
327 }
328
329 if (count($new_ids)) {
330 $this->object->loadQuestionsFromDb();
331
332 $pos = $this->svy_request->getTargetQuestionPosition();
333
334 // a[fter]/b[efore] on same page
335 if (substr($pos, -1) !== "c") {
336 // block handling
337 $current = $this->object->getSurveyPages();
338 $current = $current[$this->current_page - 1];
339 if (count($current) === 1) {
340 // as questions are moved to first block question
341 // always use existing as first
342 // the new question is moved later on (see below)
343 $this->object->createQuestionblock(
344 $this->getAutoBlockTitle(),
345 true,
346 false,
347 array((int) $pos) + $new_ids
348 );
349 } else {
350 $block_id = array_pop($current);
351 $block_id = $block_id["questionblock_id"];
352
353 foreach ($new_ids as $qid) {
354 $this->object->addQuestionToBlock($qid, $block_id);
355 }
356 }
357 }
358 // c: as new page (from toolbar/pool)
359 else {
360 // re-create block
361 $this->object->createQuestionblock(
362 $this->getAutoBlockTitle(),
363 true,
364 false,
365 $new_ids
366 );
367
368 // after given question
369 if ((int) $pos) {
370 $pos = (int) $pos . "a";
371 }
372 // at the beginning
373 else {
374 $first = $this->object->getSurveyPages();
375 $first = $first[0];
376 $first = array_shift($first);
377 $pos = $first["question_id"] . "b";
378 }
379 }
380
381 // move to target position
382 $this->object->moveQuestions(
383 $new_ids,
384 (int) $pos,
385 ((substr($pos, -1) === "a") ? 1 : 0)
386 );
387 }
388 }
389
398 protected function addQuestion(
399 int $a_type,
400 bool $a_use_pool,
401 string $a_pos,
402 string $a_special_position
403 ): bool {
404 $ilCtrl = $this->ctrl;
405 $ilTabs = $this->tabs;
406
407 // get translated type
408 $type_trans = "";
410 foreach ($questiontypes as $item) {
411 if ($item["questiontype_id"] == $a_type) {
412 $type_trans = $item["type_tag"];
413 }
414 }
415
416 $id = $a_pos;
417
418 // new page behind current (from toolbar)
419 if ($a_special_position === "toolbar") {
420 $id = $this->object->getSurveyPages();
421 if ($a_pos && $a_pos !== "fst") {
422 $id = $id[(int) $a_pos - 1];
423 $id = array_pop($id);
424 $id = $id["question_id"] . "c";
425 } else {
426 $id = "0c";
427 }
428 }
429 // append current page
430 elseif ($a_special_position === "page_end") {
431 $id = $this->object->getSurveyPages();
432 $id = $id[$this->current_page - 1];
433 $id = array_pop($id);
434 $id = $id["question_id"] . "a";
435 } else {
436 $id .= "b";
437 }
438
439 if ($a_use_pool) {
440 $ilCtrl->setParameter($this->editor_gui, "pgov_pos", $id);
441 $ilCtrl->setParameter($this->editor_gui, "sel_question_types", $type_trans);
442 if ($this->svy_request->getPoolUsage() === 0) {
443 $ilTabs->clearSubTabs(); // #17193
444 $this->editor_gui->createQuestionObject(null, $type_trans, $id);
445 } else {
446 $this->editor_gui->executeCreateQuestionObject($type_trans, null, $id);
447 }
448 return true;
449 } else {
450 // create question and redirect to question form
451
452 $q_gui = SurveyQuestionGUI::_getQuestionGUI($type_trans);
453 $q_gui->object->setObjId($this->object->getId());
454 $q_gui->object->createNewQuestion();
455 $q_gui_class = get_class($q_gui);
456
457 // #12531
458 $ilCtrl->setParameterByClass($q_gui_class, "pgov", $this->current_page);
459 $ilCtrl->setParameterByClass($q_gui_class, "pgov_pos", $id);
460 $ilCtrl->setParameterByClass($q_gui_class, "ref_id", $this->ref_id);
461 $ilCtrl->setParameterByClass($q_gui_class, "new_for_survey", $this->ref_id);
462 $ilCtrl->setParameterByClass($q_gui_class, "q_id", $q_gui->object->getId());
463 $ilCtrl->setParameterByClass($q_gui_class, "sel_question_types", $q_gui->getQuestionType());
464 $ilCtrl->redirectByClass($q_gui_class, "editQuestion");
465 }
466 return false;
467 }
468
472 protected function cutQuestion(int $a_id): void
473 {
475
476 $this->tpl->setOnScreenMessage('success', $lng->txt("survey_questions_to_clipboard_cut"));
477 $this->suppress_clipboard_msg = true;
478
479 $this->edit_manager->setQuestionClipboard(
480 $this->ref_id,
481 $this->current_page,
482 "cut",
483 array($a_id)
484 );
485 }
486
490 protected function copyQuestion(int $a_id): void
491 {
493
494 $this->tpl->setOnScreenMessage('success', $lng->txt("survey_questions_to_clipboard_copy"));
495 $this->suppress_clipboard_msg = true;
496
497 $this->edit_manager->setQuestionClipboard(
498 $this->ref_id,
499 $this->current_page,
500 "copy",
501 array($a_id)
502 );
503 }
504
510 protected function multiCut(array $a_id): void
511 {
513
514 if (count($a_id) > 0) {
515 $this->tpl->setOnScreenMessage('success', $lng->txt("survey_questions_to_clipboard_cut"));
516 $this->suppress_clipboard_msg = true;
517
518 $this->edit_manager->setQuestionClipboard(
519 $this->ref_id,
520 $this->current_page,
521 "cut",
522 $a_id
523 );
524 }
525 }
526
531 protected function multiCopy(array $a_id): void
532 {
534
535 if (count($a_id) > 0) {
536 $this->tpl->setOnScreenMessage('success', $lng->txt("survey_questions_to_clipboard_copy"));
537 $this->suppress_clipboard_msg = true;
538
539 $this->edit_manager->setQuestionClipboard(
540 $this->ref_id,
541 $this->current_page,
542 "copy",
543 $a_id
544 );
545 }
546 }
547
551 protected function clearClipboard(): void
552 {
553 $this->edit_manager->clearQuestionClipboard($this->ref_id);
554 }
555
560 protected function paste(int $a_id): void
561 {
562 $source_page = $this->edit_manager->getQuestionClipboardSourcePage($this->ref_id);
563 $qids = $this->edit_manager->getQuestionClipboardQuestions($this->ref_id);
564 $mode = $this->edit_manager->getQuestionClipboardMode($this->ref_id);
565 $pages = $this->object->getSurveyPages();
566 $source = $pages[$source_page - 1];
567 $target = $pages[$this->current_page - 1];
568
569 // #12558 - use order of source page
570 $nodes = array();
571 foreach ($source as $src_qst) {
572 if (in_array($src_qst["question_id"], $qids)) {
573 $nodes[] = $src_qst["question_id"];
574 }
575 }
576
577 // append to last position?
578 $pos = 0;
579 if ($this->svy_request->getHForm("node") === "page_end") {
580 $a_id = $target;
581 $a_id = array_pop($a_id);
582 $a_id = $a_id["question_id"];
583 $pos = 1;
584 }
585
586 // cut
587 if ($mode === "cut") {
588 // special case: paste cut on same page (no block handling needed)
589 if ($source_page == $this->current_page) {
590 // re-order nodes in page
591 if (count($nodes) <= count($source)) {
592 $this->object->moveQuestions($nodes, $a_id, $pos);
593 }
594 $this->clearClipboard();
595 return;
596 } else {
597 // only if source has block
598 $source_block_id = false;
599 if (count($source) > 1) {
600 $source_block_id = $source;
601 $source_block_id = array_shift($source_block_id);
602 $source_block_id = $source_block_id["questionblock_id"];
603
604 // remove from block
605 if (count($source) > count($nodes)) {
606 foreach ($nodes as $qid) {
607 $this->object->removeQuestionFromBlock($qid, $source_block_id);
608 }
609 }
610 // remove complete block
611 else {
612 $this->object->unfoldQuestionblocks(array($source_block_id));
613 }
614 }
615
616 // page will be "deleted" by operation
617 if (count($source) === count($nodes) && $source_page < $this->current_page) {
618 $this->current_page--;
619 }
620 }
621 }
622
623 // copy
624 elseif ($mode === "copy") {
625 $titles = array();
626 foreach ($this->object->getSurveyPages() as $page) {
627 foreach ($page as $question) {
628 $titles[] = $question["title"];
629 }
630 }
631
632 // copy questions
633 $question_pointer = array();
634 foreach ($nodes as $qid) {
635 // create new questions
636 $question = ilObjSurvey::_instanciateQuestion($qid);
637 // handle exisiting copies
638 $title = $question->getTitle();
639 $max = 0;
640 foreach ($titles as $existing_title) {
641 #21278 preg_quote with delimiter
642 if (preg_match("/" . preg_quote($title, "/") . " \‍(([0-9]+)\‍)$/", $existing_title, $match)) {
643 $max = max($match[1], $max);
644 }
645 }
646 if ($max) {
647 $title .= " (" . ($max + 1) . ")";
648 } else {
649 $title .= " (2)";
650 }
651 $titles[] = $title;
652 $question->setTitle($title);
653
654 $question->id = -1;
655 $question->saveToDb();
656
657 $question_pointer[$qid] = $question->getId();
658 $this->appendNewQuestionToSurvey($question->getId(), false);
659 }
660
661 // copy textblocks
662 $this->object->cloneTextblocks($question_pointer);
663
664 $this->object->loadQuestionsFromDb();
665
666 $nodes = array_values($question_pointer);
667 }
668
669
670 // paste
671
672 // create new block
673 if (count($target) === 1) {
674 $nodes = array_merge(array($a_id), $nodes);
675
676 // moveQuestions() is called within
677 $this->object->createQuestionblock(
678 $this->getAutoBlockTitle(),
679 true,
680 false,
681 $nodes
682 );
683 }
684 // add to existing block
685 else {
686 $target_block_id = $target;
687 $target_block_id = array_shift($target_block_id);
688 $target_block_id = $target_block_id["questionblock_id"];
689
690 foreach ($nodes as $qid) {
691 $this->object->addQuestionToBlock($qid, $target_block_id);
692 }
693
694 // move to new position
695 $this->object->moveQuestions($nodes, $a_id, $pos);
696 }
697
698 $this->clearClipboard();
699 }
700
704 protected function dnd(): void
705 {
706 $source_arr = explode("_", $this->svy_request->getHForm("source"));
707 $target_arr = explode("_", $this->svy_request->getHForm("target"));
708 $source_id = (int) array_pop($source_arr);
709 if ($this->svy_request->getHForm("target") !== "droparea_end") {
710 $target_id = (int) array_pop($target_arr);
711 $pos = 0;
712 } else {
713 $page = $this->object->getSurveyPages();
714 $page = $page[$this->current_page - 1];
715 $last = array_pop($page);
716 $target_id = (int) $last["question_id"];
717 $pos = 1;
718 }
719 if ($source_id !== $target_id) {
720 $this->object->moveQuestions(array($source_id), $target_id, $pos);
721 }
722 }
723
727 protected function deleteBlock(): void
728 {
730 $ilCtrl = $this->ctrl;
731
732 $ilCtrl->setParameter($this->editor_gui, "pgov", $this->current_page);
733 $this->tpl->setOnScreenMessage('question', $lng->txt("remove_questions"));
734
735 $page = $this->object->getSurveyPages();
736 $page = $page[$this->current_page - 1];
737
738 // #10567
739 if ($this->svy_request->getCheckSum() !== md5(print_r($page, true))) {
740 $ilCtrl->redirect($this, "renderPage");
741 }
742
743 $page = array_shift($page);
744 $block_id = $page["questionblock_id"];
745 if ($block_id) {
746 $this->editor_gui->removeQuestionsForm(array($block_id), array(), array());
747 } else {
748 $this->editor_gui->removeQuestionsForm(array(), array($page["question_id"]), array());
749 }
750 }
751
758 protected function deleteQuestion(array $a_id): void
759 {
760 $ilCtrl = $this->ctrl;
761 $ilCtrl->setParameter($this->editor_gui, "pgov", $this->current_page);
762 $this->editor_gui->removeQuestionsForm(array(), $a_id, array());
763 }
764
768 protected function confirmRemoveQuestions(): void
769 {
770 $ilCtrl = $this->ctrl;
771 $ids = $this->svy_request->getQuestionIds();
772
773 $pages = $this->object->getSurveyPages();
774 $source = $pages[$this->current_page - 1];
775
776 $block_id = $source;
777 $block_id = array_shift($block_id);
778 $block_id = $block_id["questionblock_id"];
779
780 if (count($ids) && count($source) > count($ids)) {
781 // block is obsolete
782 if (count($source) - count($ids) === 1) {
783 $this->object->unfoldQuestionblocks(array($block_id));
784 }
785 // block will remain, remove question(s) from block
786 else {
787 foreach ($ids as $qid) {
788 $this->object->removeQuestionFromBlock($qid, $block_id);
789 }
790 }
791
792 $this->object->removeQuestions($ids, array());
793 }
794 // all items on page
795 else {
796 // remove complete block
797 if ($block_id) {
798 $this->object->removeQuestions(array(), array($block_id));
799 }
800 // remove single question
801 else {
802 $this->object->removeQuestions($ids, array());
803 }
804
805 // render previous page
806 if ($this->current_page > 1) {
807 $this->current_page--;
808 }
809 }
810
811 $this->object->saveCompletionStatus();
812
813 // #10567
814 $ilCtrl->setParameter($this, "pgov", $this->current_page);
815 $ilCtrl->redirect($this, "renderPage");
816 }
817
821 protected function editBlock(int $a_id): void
822 {
823 $this->callEditor("editQuestionblock", "bl_id", $a_id);
824 }
825
829 protected function addHeading(int $a_id): void
830 {
831 $this->callEditor("addHeading", "q_id", $a_id);
832 }
833
837 protected function editHeading(int $a_id): void
838 {
839 $this->callEditor("editHeadingObject", "q_id", $a_id);
840 }
841
845 protected function deleteHeading(int $a_id): void
846 {
847 $this->callEditor("removeHeading", "q_id", $a_id);
848 }
849
850 protected function callEditor(
851 string $a_cmd,
852 string $a_param,
853 string $a_value
854 ): void {
855 $ilTabs = $this->tabs;
856
857 $ilTabs->clearSubTabs();
858 $ctrl = $this->ctrl;
859
860 $ctrl->setParameter($this->editor_gui, $a_param, $a_value);
861 $ctrl->redirect($this->editor_gui, $a_cmd);
862
863 //$_REQUEST[$a_param] = $a_value;
864 //call_user_func(array($this->editor_gui, $a_cmd));
865 }
866
870 protected function splitPage(
871 int $a_id
872 ): void {
873 $pages = $this->object->getSurveyPages();
874 $source = $pages[$this->current_page - 1];
875
876 $block_questions = array();
877 $add = $block_id = false;
878 foreach ($source as $idx => $item) {
879 if ($item["question_id"] == $a_id) {
880 $block_id = $item["questionblock_id"];
881 $add = $idx;
882 }
883 if ($add) {
884 $block_questions[] = $item["question_id"];
885 }
886 }
887
888 // just 1 question left: block is obsolete
889 if ($add === 1) {
890 $this->object->unfoldQuestionblocks(array($block_id));
891 }
892 // remove questions from block
893 else {
894 foreach ($block_questions as $qid) {
895 $this->object->removeQuestionFromBlock($qid, $block_id);
896 }
897 }
898
899 // more than 1 moved?
900 if (count($block_questions) > 1) {
901 // create new block and move target questions
902 $this->object->createQuestionblock(
903 $this->getAutoBlockTitle(),
904 true,
905 false,
906 $block_questions
907 );
908 }
909
910 $this->current_page++;
911 }
912
916 protected function moveNext(int $a_id): void
917 {
918 $pages = $this->object->getSurveyPages();
919 $source = $pages[$this->current_page - 1];
920 $target = $pages[$this->current_page];
921 if (count($target)) {
922 $target_id = $target;
923 $target_id = array_shift($target_id);
924 $target_block_id = $target_id["questionblock_id"];
925 $target_id = $target_id["question_id"];
926
927 // nothing to do if no block
928 if (count($source) > 1) {
929 $block_id = $source;
930 $block_id = array_shift($block_id);
931 $block_id = $block_id["questionblock_id"];
932
933 // source pages block is obsolete
934 if (count($source) === 2) {
935 // delete block
936 $this->object->unfoldQuestionblocks(array($block_id));
937 } else {
938 // remove question from block
939 $this->object->removeQuestionFromBlock($a_id, $block_id);
940 }
941 }
942
943 // move source question to target
944 $this->object->moveQuestions(array($a_id), $target_id, 0);
945
946 // new page has no block yet
947 if (count($target) < 2) {
948 // create block and move target question and source into block
949 $this->object->createQuestionblock(
950 $this->getAutoBlockTitle(),
951 true,
952 false,
953 array($a_id, $target_id)
954 );
955 } else {
956 // add source question to block
957 $this->object->addQuestionToBlock($a_id, $target_block_id);
958 }
959
960 // only if current page is not "deleted"
961 if (count($source) > 1) {
962 $this->current_page++;
963 }
964 }
965 }
966
970 protected function movePrevious(
971 int $a_id
972 ): void {
973 $pages = $this->object->getSurveyPages();
974 $source = $pages[$this->current_page - 1];
975 $target = $pages[$this->current_page - 2];
976 if (count($target)) {
977 $target_id = $target;
978 $target_id = array_pop($target_id);
979 $target_block_id = $target_id["questionblock_id"];
980 $target_id = $target_id["question_id"];
981
982 // nothing to do if no block
983 if (count($source) > 1) {
984 $block_id = $source;
985 $block_id = array_shift($block_id);
986 $block_id = $block_id["questionblock_id"];
987
988 // source pages block is obsolete
989 if (count($source) === 2) {
990 // delete block
991 $this->object->unfoldQuestionblocks(array($block_id));
992 } else {
993 // remove question from block
994 $this->object->removeQuestionFromBlock($a_id, $block_id);
995 }
996 }
997
998 // move source question to target
999 $this->object->moveQuestions(array($a_id), $target_id, 1);
1000
1001 // new page has no block yet
1002 if (count($target) < 2) {
1003 // create block and move target question and source into block
1004 $this->object->createQuestionblock(
1005 $this->getAutoBlockTitle(),
1006 true,
1007 false,
1008 array($target_id, $a_id)
1009 );
1010 } else {
1011 // add source question to block
1012 $this->object->addQuestionToBlock($a_id, $target_block_id);
1013 }
1014
1015 $this->current_page--;
1016 }
1017 }
1018
1019 protected function editQuestion(int $a_id): void
1020 {
1021 $ilCtrl = $this->ctrl;
1022
1023 $data = $this->object->getSurveyQuestions();
1024 $data = $data[$a_id];
1025
1026 $q_gui = $data["type_tag"] . "GUI";
1027 $ilCtrl->setParameterByClass($q_gui, "pgov", $this->current_page);
1028 $ilCtrl->setParameterByClass($q_gui, "q_id", $a_id);
1029
1030 $ilCtrl->redirectByClass($q_gui, "editQuestion");
1031 }
1032
1036 protected function addQuestionToolbarForm(): void
1037 {
1038 $lng = $this->lng;
1039 $ilCtrl = $this->ctrl;
1040 $tpl = $this->tpl;
1041
1042 $form = new ilPropertyFormGUI();
1043 $form->setFormAction($ilCtrl->getFormAction($this, "addQuestionToolbar"));
1044 $form->setTitle($lng->txt("survey_add_new_question"));
1045
1046 // question types
1048 $type_map = array();
1049 foreach ($questiontypes as $trans => $item) {
1050 $type_map[$item["questiontype_id"]] = $trans;
1051 }
1052 $si = new ilSelectInputGUI($lng->txt("question_type"), "qtype");
1053 $si->setOptions($type_map);
1054 $form->addItem($si);
1055
1056 $pages = $this->object->getSurveyPages();
1057 if ($pages) {
1058 $pages_drop = array("fst" => $lng->txt("survey_at_beginning"));
1059 foreach ($pages as $idx => $questions) {
1060 $question = array_shift($questions);
1061 if ($question["questionblock_id"]) {
1062 $pages_drop[$idx + 1] = $lng->txt("survey_behind_page") . " " . $question["questionblock_title"];
1063 } else {
1064 $pages_drop[$idx + 1] = $lng->txt("survey_behind_page") . " " . strip_tags($question["title"]);
1065 }
1066 }
1067 $pos = new ilSelectInputGUI($lng->txt("position"), "pgov");
1068 $pos->setOptions($pages_drop);
1069 $form->addItem($pos);
1070
1071 $pos->setValue($this->current_page);
1072 } else {
1073 // #9089: 1st page
1074 $pos = new ilHiddenInputGUI("pgov");
1075 $pos->setValue("fst");
1076 $form->addItem($pos);
1077 }
1078
1079 if ($this->object->getPoolUsage()) {
1080 $this->editor_gui->createQuestionObject($form);
1081 }
1082
1083 $form->addCommandButton("addQuestionToolbar", $lng->txt("create"));
1084 $form->addCommandButton("renderPage", $lng->txt("cancel"));
1085
1086 $tpl->setContent($form->getHTML());
1087 }
1088
1092 protected function addQuestionToolbar(): void
1093 {
1094 $ilCtrl = $this->ctrl;
1095 $lng = $this->lng;
1096
1097 $pool_active = $this->object->getPoolUsage();
1098
1099 if ($this->svy_request->getPoolUsage() === 0 && $pool_active) {
1100 $this->tpl->setOnScreenMessage('failure', $lng->txt("select_one"), true);
1101 $this->addQuestionToolbarForm();
1102 return;
1103 }
1104
1105 // make sure that it is set for current and next requests
1106 $ilCtrl->setParameter($this->editor_gui, "pgov", $this->current_page);
1107 if (!$this->addQuestion(
1108 $this->svy_request->getQuestionType(),
1109 $pool_active,
1110 $this->pgov,
1111 "toolbar"
1112 )) {
1113 $this->renderPage();
1114 }
1115 }
1116
1120 protected function movePageForm(): void
1121 {
1122 $lng = $this->lng;
1123 $ilCtrl = $this->ctrl;
1124 $tpl = $this->tpl;
1125
1126 $form = new ilPropertyFormGUI();
1127 $form->setFormAction($ilCtrl->getFormAction($this, "movePage"));
1128 $form->setTitle($lng->txt("survey_move_page"));
1129
1130 $old_pos = new ilHiddenInputGUI("old_pos");
1131 $old_pos->setValue($this->current_page);
1132 $form->addItem($old_pos);
1133
1134 $pages = $this->object->getSurveyPages();
1135 if ($pages) {
1136 $pages_drop = array();
1137 if ((int) $this->current_page !== 1) {
1138 $pages_drop["fst"] = $lng->txt("survey_at_beginning");
1139 }
1140 foreach ($pages as $idx => $questions) {
1141 if (($idx + 1) != $this->current_page && ($idx + 2) != $this->current_page) {
1142 $question = array_shift($questions);
1143 if ($question["questionblock_id"]) {
1144 $pages_drop[$idx + 1] = $lng->txt("survey_behind_page") . " " . $question["questionblock_title"];
1145 } else {
1146 $pages_drop[$idx + 1] = $lng->txt("survey_behind_page") . " " . strip_tags($question["title"]);
1147 }
1148 }
1149 }
1150 $pos = new ilSelectInputGUI($lng->txt("position"), "pgov");
1151 $pos->setOptions($pages_drop);
1152 $form->addItem($pos);
1153 }
1154
1155 $form->addCommandButton("movePage", $lng->txt("submit"));
1156 $form->addCommandButton("renderPage", $lng->txt("cancel"));
1157
1158 $tpl->setContent($form->getHTML());
1159 }
1160
1165 protected function movePage(): void
1166 {
1167 $lng = $this->lng;
1168 $ilCtrl = $this->ctrl;
1169
1170 $questions = [];
1171
1172 // current_page is already set to new position
1173 $target_page = $this->current_page - 1;
1174 $source_page = $this->svy_request->getOldPosition() - 1;
1175
1176 $pages = $this->object->getSurveyPages();
1177 foreach ($pages[$source_page] as $question) {
1178 $questions[] = $question["question_id"];
1179 }
1180
1181 // move to first position
1182 $position = 0;
1183 if ($this->pgov !== "fst") {
1184 $position = 1;
1185 }
1186
1187 $target = $pages[$target_page];
1188 if ($position === 0) { // before
1189 $target = array_shift($target); // ... use always the first question of the page
1190 } else { // after
1191 $target = array_pop($target); // ... use always the last question of the page
1192 }
1193 $this->object->moveQuestions($questions, $target["question_id"], $position);
1194
1195 if ($target_page < $source_page && $position) {
1196 $this->current_page++;
1197 }
1198
1199 $this->tpl->setOnScreenMessage('success', $lng->txt("survey_page_moved"), true);
1200 $ilCtrl->setParameter($this, "pgov", $this->current_page);
1201 $ilCtrl->redirect($this, "renderPage");
1202 }
1203
1207 protected function renderToolbar(?array $a_pages): void
1208 {
1209 $ilToolbar = $this->toolbar;
1210 $ilCtrl = $this->ctrl;
1211 $lng = $this->lng;
1212 $ilUser = $this->user;
1213 $pages_drop = null;
1214
1215 if (!$this->has_datasets) {
1216 $button = ilLinkButton::getInstance();
1217 $button->setCaption("survey_add_new_question");
1218 $button->setUrl($ilCtrl->getLinkTarget($this, "addQuestionToolbarForm"));
1219 $ilToolbar->addStickyItem($button);
1220
1221 if ($this->object->getPoolUsage()) {
1222 //$ilToolbar->addSeparator();
1223
1224 $last_on_page = 0;
1225 if ($a_pages &&
1226 isset($a_pages[$this->current_page - 1])) {
1227 $last_on_page = $a_pages[$this->current_page - 1];
1228 $last_on_page = array_pop($last_on_page);
1229 $last_on_page = $last_on_page["question_id"];
1230 }
1231
1232 $ilCtrl->setParameter($this->editor_gui, "pgov", $this->current_page);
1233 $ilCtrl->setParameter($this->editor_gui, "pgov_pos", $last_on_page . "c");
1234
1235 $cmd = ((int) $ilUser->getPref('svy_insert_type') === 1 ||
1236 ($ilUser->getPref('svy_insert_type') ?? '') === '')
1237 ? 'browseForQuestions'
1238 : 'browseForQuestionblocks';
1239
1240 $button = ilLinkButton::getInstance();
1241 $button->setCaption("browse_for_questions");
1242 $button->setUrl($ilCtrl->getLinkTarget($this->editor_gui, $cmd));
1243 $ilToolbar->addStickyItem($button);
1244
1245 $ilCtrl->setParameter($this->editor_gui, "pgov", "");
1246 $ilCtrl->setParameter($this->editor_gui, "pgov_pos", "");
1247 }
1248
1249 if ($a_pages) {
1250// $ilToolbar->addSeparator();
1251 }
1252 }
1253
1254 // parse data for pages drop-down
1255 if ($a_pages) {
1256 // previous/next
1257
1258 $ilCtrl->setParameter($this, "pg", $this->current_page - 1);
1259 $button = ilLinkButton::getInstance();
1260 $button->setCaption("survey_prev_question");
1261 if ($this->has_previous_page) {
1262 $button->setUrl($ilCtrl->getLinkTarget($this, "renderPage"));
1263 }
1264 $button->setDisabled(!$this->has_previous_page);
1265 $ilToolbar->addStickyItem($button);
1266
1267 $ilCtrl->setParameter($this, "pg", (string) ((int) $this->current_page + 1));
1268 $button = ilLinkButton::getInstance();
1269 $button->setCaption("survey_next_question");
1270 if ($this->has_next_page) {
1271 $button->setUrl($ilCtrl->getLinkTarget($this, "renderPage"));
1272 }
1273 $button->setDisabled(!$this->has_next_page);
1274 $ilToolbar->addStickyItem($button);
1275
1276 $ilCtrl->setParameter($this, "pg", $this->current_page); // #14615
1277
1278 foreach ($a_pages as $idx => $questions) {
1279 $page = $questions;
1280 $page = array_shift($page);
1281 if ($page["questionblock_id"]) {
1282 $pages_drop[$idx + 1] = $page["questionblock_title"];
1283
1284 if (count($questions) > 1) {
1285 foreach ($questions as $question) {
1286 $pages_drop[($idx + 1) . "__" . $question["question_id"]] = "- " . $question["title"];
1287 }
1288 }
1289 } else {
1290 $pages_drop[$idx + 1] = strip_tags($page["title"]);
1291 }
1292 }
1293 }
1294
1295 // jump to page
1296 if (is_array($pages_drop) && count($pages_drop) > 1) {
1297 //$ilToolbar->addSeparator();
1298
1299 $ilToolbar->setFormAction($ilCtrl->getFormAction($this));
1300
1301 $si = new ilSelectInputGUI($lng->txt("survey_jump_to"), "jump");
1302 $si->addCustomAttribute("onChange=\"forms['ilToolbar'].submit();\"");
1303 $si->setOptions($pages_drop);
1304 $si->setValue($this->current_page);
1305 $ilToolbar->addInputItem($si, true);
1306
1307 // we need this to have to right cmd
1308 $cmd = new ilHiddenInputGUI("cmd[renderPage]");
1309 $cmd->setValue("1");
1310 $ilToolbar->addInputItem($cmd);
1311
1312 if (!$this->has_datasets) {
1313 $ilToolbar->addSeparator();
1314
1315 $ilCtrl->setParameter($this, "csum", md5(print_r($a_pages[$this->current_page - 1], true)));
1316 $url = $ilCtrl->getLinkTarget($this, "deleteBlock");
1317 $ilCtrl->setParameter($this, "csum", "");
1318
1319 $button = ilLinkButton::getInstance();
1320 $button->setCaption("survey_delete_page");
1321 $button->setUrl($url);
1322 $ilToolbar->addButtonInstance($button);
1323
1324 $ilToolbar->addSeparator();
1325
1326 $button = ilLinkButton::getInstance();
1327 $button->setCaption("survey_move_page");
1328 $button->setUrl($ilCtrl->getLinkTarget($this, "movePageForm"));
1329 $ilToolbar->addButtonInstance($button);
1330 }
1331 }
1332
1333 // print view
1334 if (is_array($pages_drop)) {
1335 $ilToolbar->addSeparator();
1336 $print_view = $this->print->page($this->ref_id);
1337 $modal_elements = $print_view->getModalElements(
1338 $this->ctrl->getLinkTarget(
1339 $this,
1340 "printViewSelection"
1341 )
1342 );
1343 $ilToolbar->addComponent($modal_elements->button);
1344 $ilToolbar->addComponent($modal_elements->modal);
1345 }
1346 }
1347
1351 protected function renderPage(): void
1352 {
1353 $ilCtrl = $this->ctrl;
1354 $lng = $this->lng;
1355 $tpl = $this->tpl;
1356 $rbacsystem = $this->rbacsystem;
1357
1358 $pages = $this->object->getSurveyPages();
1359 $this->has_next_page = ($this->current_page < count($pages));
1360 $this->has_previous_page = ($this->current_page > 1);
1361 $this->has_datasets = ilObjSurvey::_hasDatasets($this->object->getSurveyId());
1362
1363 $mess = "";
1364 if ($this->has_datasets) {
1366 $mess = $mbox->getHTML();
1367 }
1368
1369 $ilCtrl->setParameter($this, "pg", $this->current_page);
1370 $ilCtrl->setParameter($this, "pgov", "");
1371
1372 $this->renderToolbar($pages);
1373 if ($pages) {
1374 $ttpl = new ilTemplate("tpl.il_svy_svy_page_view.html", true, true, "Modules/Survey");
1375 $tpl->addOnLoadCode("ilSurveyPageView.init();");
1376 $ttpl->setVariable("FORM_ACTION", $ilCtrl->getFormAction($this));
1377 $lng->loadLanguageModule("form");
1378
1379 $read_only = ($this->has_datasets || !$rbacsystem->checkAccess("write", $this->ref_id));
1380
1381 $commands = $multi_commands = array();
1382
1383 if (!$read_only) {
1384 // clipboard is empty
1385 if ($this->edit_manager->isQuestionClipboardEmpty($this->ref_id)) {
1386 $multi_commands[] = array("cmd" => "multiDelete", "text" => $lng->txt("delete"));
1387 $multi_commands[] = array("cmd" => "multiCut", "text" => $lng->txt("cut"));
1388 $multi_commands[] = array("cmd" => "multiCopy", "text" => $lng->txt("copy"));
1389 $multi_commands[] = array("cmd" => "selectAll", "text" => $lng->txt("select_all"));
1390 } else {
1391 if (!$this->suppress_clipboard_msg) {
1392 $this->tpl->setOnScreenMessage('info', $lng->txt("survey_clipboard_notice"));
1393 }
1394 $multi_commands[] = array("cmd" => "clearClipboard", "text" => $lng->txt("survey_dnd_clear_clipboard"));
1395 }
1396
1397 // help - see ilPageObjectGUI::insertHelp()
1398 $lng->loadLanguageModule("content");
1399 $ttpl->setCurrentBlock("help_section");
1400 $ttpl->setVariable("TXT_ADD_EL", $lng->txt("cont_add_elements"));
1401 $ttpl->setVariable("PLUS", ilGlyphGUI::get(ilGlyphGUI::ADD));
1402 $ttpl->setVariable("DRAG_ARROW", ilGlyphGUI::get(ilGlyphGUI::DRAG));
1403 $ttpl->setVariable("TXT_DRAG", $lng->txt("cont_drag_and_drop_elements"));
1404 $ttpl->setVariable("TXT_SEL", $lng->txt("cont_double_click_to_delete"));
1405 $ttpl->parseCurrentBlock();
1406
1407 $ttpl->setVariable("DND_INIT_JS", "initDragElements();");
1408
1409
1410 // tiny mce
1411
1413
1420 $tiny = new ilTinyMCE();
1421 $ttpl->setVariable("WYSIWYG_BLOCKFORMATS", $tiny->_buildAdvancedBlockformatsFromHTMLTags($tags));
1422 $ttpl->setVariable("WYSIWYG_VALID_ELEMENTS", $tiny->_getValidElementsFromHTMLTags($tags));
1423
1424 $buttons_1 = $tiny->_buildAdvancedButtonsFromHTMLTags(1, $tags);
1425 $buttons_2 = $tiny->_buildAdvancedButtonsFromHTMLTags(2, $tags) . ',' .
1426 $tiny->_buildAdvancedTableButtonsFromHTMLTags($tags) .
1427 ($tiny->getStyleSelect() ? ',styleselect' : '');
1428 $buttons_3 = $tiny->_buildAdvancedButtonsFromHTMLTags(3, $tags);
1429 $ttpl->setVariable('WYSIWYG_BUTTONS_1', ilTinyMCE::removeRedundantSeparators($buttons_1));
1430 $ttpl->setVariable('WYSIWYG_BUTTONS_2', ilTinyMCE::removeRedundantSeparators($buttons_2));
1431 $ttpl->setVariable('WYSIWYG_BUTTONS_3', ilTinyMCE::removeRedundantSeparators($buttons_3));
1432 }
1433
1434 // commands
1435 if (count($multi_commands) > 0) {
1436 foreach ($multi_commands as $cmd) {
1437 $ttpl->setCurrentBlock("multi_cmd");
1438 $ttpl->setVariable("ORG_CMD_MULTI", "renderPage");
1439 $ttpl->setVariable("MULTI_CMD", $cmd["cmd"]);
1440 $ttpl->setVariable("MULTI_CMD_TXT", $cmd["text"]);
1441 $ttpl->parseCurrentBlock();
1442 }
1443
1444 $ttpl->setCurrentBlock("multi_cmds");
1445 $ttpl->setVariable("MCMD_ALT", $lng->txt("commands"));
1446 $ttpl->setVariable("MCMD_IMG", ilUtil::getImagePath("arrow_downright.svg"));
1447 $ttpl->parseCurrentBlock();
1448 }
1449
1450 // nodes
1451 $ttpl->setVariable("NODES", $this->getPageNodes(
1452 $pages[$this->current_page - 1] ?? [],
1453 $this->has_previous_page,
1454 $this->has_next_page,
1455 $read_only
1456 ));
1457
1458 $tpl->setContent($mess . $ttpl->get());
1459
1460 // add js to template
1462 $tpl->addJavaScript("./Modules/Survey/js/SurveyPageView.js");
1463 }
1464 }
1465
1470 public function getPageNodes(
1471 array $a_questions,
1472 bool $a_has_previous_page = false,
1473 bool $a_has_next_page = false,
1474 bool $a_readonly = false
1475 ): string {
1476 $ilCtrl = $this->ctrl;
1477 $lng = $this->lng;
1478
1479 $ttpl = new ilTemplate("tpl.il_svy_svy_page_view_nodes.html", true, true, "Modules/Survey");
1480
1481 $has_clipboard = !$this->edit_manager->isQuestionClipboardEmpty($this->ref_id);
1482
1483 // question block ?
1484
1485 $first_question = $a_questions;
1486 $first_question = array_shift($first_question);
1487
1488 $compress_view = false;
1489 if ($first_question["questionblock_id"] ?? false) {
1490 $menu = array();
1491
1492 if (!$a_readonly && !$has_clipboard) {
1493 $menu[] = array("cmd" => "editBlock", "text" => $lng->txt("edit"));
1494 }
1495
1496 if ($first_question["questionblock_show_blocktitle"]) {
1497 $block_status = $lng->txt("survey_block_visible");
1498 } else {
1499 $block_status = $lng->txt("survey_block_hidden");
1500 }
1501
1502 $this->renderPageNode(
1503 $ttpl,
1504 "block",
1505 $first_question["questionblock_id"],
1506 $first_question["questionblock_title"] . " (" . $block_status . ")",
1507 $menu,
1508 false,
1509 false,
1510 $block_status
1511 );
1512
1513 if (count($a_questions) > 1) {
1514 $compress_view = $first_question["questionblock_compress_view"];
1515 }
1516 }
1517
1518
1519 // questions/headings
1520
1522 foreach ($a_questions as $idx => $question) {
1523 // drop area
1524
1525 $menu = array();
1526
1527 if (!$a_readonly) {
1528 if (!$has_clipboard) {
1529 foreach ($questiontypes as $trans => $item) {
1530 $menu[] = array("cmd" => "addQuestion_" . $item["questiontype_id"],
1531 "text" => sprintf($lng->txt("svy_page_add_question"), $trans));
1532 }
1533
1534 if ($this->object->getPoolUsage()) {
1535 $menu[] = array("cmd" => "addPoolQuestion",
1536 "text" => $lng->txt("browse_for_questions"));
1537 }
1538 } else {
1539 $menu[] = array("cmd" => "paste", "text" => $lng->txt("survey_dnd_paste"));
1540 }
1541 }
1542
1543 $this->renderPageNode($ttpl, "droparea", $question["question_id"], null, $menu, true);
1544
1545 // question
1546 $question_gui = $this->object->getQuestionGUI($question["type_tag"], $question["question_id"]);
1547 $question_form = $question_gui->getWorkingForm(
1548 array(),
1549 $this->object->getShowQuestionTitles(),
1550 $question["questionblock_show_questiontext"],
1551 "",
1552 $this->object->getSurveyId(),
1553 $compress_view
1554 );
1555
1556 $menu = array();
1557
1558 if (!$a_readonly && !$has_clipboard) {
1559 $menu[] = array("cmd" => "editQuestion", "text" => $lng->txt("edit"));
1560 $menu[] = array("cmd" => "cutQuestion", "text" => $lng->txt("cut"));
1561 $menu[] = array("cmd" => "copyQuestion", "text" => $lng->txt("copy"));
1562
1563 if (count($a_questions) > 1 && $idx > 0) {
1564 $menu[] = array("cmd" => "splitPage", "text" => $lng->txt("survey_dnd_split_page"));
1565 }
1566 if ($a_has_next_page) {
1567 $menu[] = array("cmd" => "moveNext", "text" => $lng->txt("survey_dnd_move_next"));
1568 }
1569 if ($a_has_previous_page) {
1570 $menu[] = array("cmd" => "movePrevious", "text" => $lng->txt("survey_dnd_move_previous"));
1571 }
1572
1573 $menu[] = array("cmd" => "deleteQuestion", "text" => $lng->txt("delete"));
1574
1575 // heading
1576 if ($question["heading"]) {
1577 $menu[] = array("cmd" => "editHeading", "text" => $lng->txt("survey_edit_heading"));
1578 $menu[] = array("cmd" => "deleteHeading", "text" => $lng->txt("survey_delete_heading"));
1579 } else {
1580 $menu[] = array("cmd" => "addHeading", "text" => $lng->txt("add_heading"));
1581 }
1582 }
1583
1584 if ($first_question["questionblock_show_questiontext"]) {
1585 $question_title_status = $lng->txt("survey_question_text_visible");
1586 } else {
1587 $question_title_status = $lng->txt("survey_question_text_hidden");
1588 }
1589
1590 $this->renderPageNode(
1591 $ttpl,
1592 "question",
1593 $question["question_id"],
1594 $question_form,
1595 $menu,
1596 false,
1597 $question["title"],
1598 $question_title_status,
1599 $question["heading"]
1600 );
1601
1602 $ilCtrl->setParameter($this, "eqid", "");
1603 }
1604
1605
1606 // last position (no question id)
1607
1608 $menu = array();
1609
1610 if (!$a_readonly) {
1611 if (!$has_clipboard) {
1612 foreach ($questiontypes as $trans => $item) {
1613 $menu[] = array("cmd" => "addQuestion_" . $item["questiontype_id"],
1614 "text" => sprintf($lng->txt("svy_page_add_question"), $trans));
1615 }
1616
1617 if ($this->object->getPoolUsage()) {
1618 $menu[] = array("cmd" => "addPoolQuestion",
1619 "text" => $lng->txt("browse_for_questions"));
1620 }
1621 } else {
1622 $menu[] = array("cmd" => "paste", "text" => $lng->txt("survey_dnd_paste"));
1623 }
1624 }
1625
1626 $this->renderPageNode($ttpl, "page", "end", null, $menu, true);
1627
1628 return $ttpl->get();
1629 }
1630
1634 public function renderPageNode(
1635 ilTemplate $a_tpl,
1636 string $a_type,
1637 string $a_id,
1638 ?string $a_content = null,
1639 ?array $a_menu = null,
1640 bool $a_spacer = false,
1641 string $a_subtitle = "",
1642 ?string $a_status = null,
1643 ?string $a_heading = null
1644 ): void {
1645 $ilCtrl = $this->ctrl;
1646 $lng = $this->lng;
1647
1648 $node_id = $a_type . "_" . $a_id;
1649
1650 if ($a_spacer) {
1651 if ($a_menu) {
1652 // drop area menu
1653 foreach ($a_menu as $mcnt => $menu_item) {
1654 $ilCtrl->setParameter($this, "il_hform_node", $node_id);
1655 $ilCtrl->setParameter($this, "il_hform_subcmd", $menu_item["cmd"]);
1656 $url = $ilCtrl->getLinkTarget($this, "renderPage");
1657 $ilCtrl->setParameter($this, "il_hform_subcmd", "");
1658 $ilCtrl->setParameter($this, "il_hform_node", "");
1659
1660 $a_tpl->setCurrentBlock("menu_cmd");
1661 $a_tpl->setVariable("TXT_MENU_CMD", $menu_item["text"]);
1662 $a_tpl->setVariable("URL_MENU_CMD", $url);
1663 $a_tpl->parseCurrentBlock();
1664 }
1665 }
1666
1667 $a_tpl->setCurrentBlock("drop_area");
1668 $a_tpl->setVariable("ICON_ADD", ilGlyphGUI::get(ilGlyphGUI::ADD));
1669 $a_tpl->setVariable("DROP_ID", $a_id);
1670 $a_tpl->parseCurrentBlock();
1671 } elseif ($a_menu) {
1672 // question action menu
1673 foreach ($a_menu as $mcnt => $menu_item) {
1674 $ilCtrl->setParameter($this, "il_hform_node", $node_id);
1675 $ilCtrl->setParameter($this, "il_hform_subcmd", $menu_item["cmd"]);
1676 $url = $ilCtrl->getLinkTarget($this, "renderPage");
1677 $ilCtrl->setParameter($this, "il_hform_subcmd", "");
1678 $ilCtrl->setParameter($this, "il_hform_node", "");
1679
1680 $a_tpl->setCurrentBlock("action_cmd");
1681 $a_tpl->setVariable("TXT_ACTION_CMD", $menu_item["text"]);
1682 $a_tpl->setVariable("URL_ACTION_CMD", $url);
1683 $a_tpl->parseCurrentBlock();
1684 }
1685 }
1686
1687 // add heading to content
1688 if ($a_content !== null &&
1689 $a_type === "question" &&
1690 $a_heading) {
1691 $a_content = "<div class=\"questionheading\">" . $a_heading . "</div>" .
1692 $a_content;
1693 }
1694
1695 if ($a_menu) {
1696 $a_tpl->setVariable("TXT_NODE_CONTENT_ACTIONS", $a_content);
1697 } else {
1698 $a_tpl->setVariable("TXT_NODE_CONTENT_NO_ACTIONS", $a_content);
1699 }
1700
1701 if ($a_content !== null) {
1702 $drag = "";
1703 $selectable = false;
1704 switch ($a_type) {
1705 case "block":
1706 $caption = $lng->txt("questionblock");
1707 break;
1708
1709 case "question":
1710 $caption = $lng->txt("question") . ": " . $a_subtitle;
1711 $drag = "_drag";
1712 $selectable = true;
1713 break;
1714
1715 case "heading":
1716 $caption = $lng->txt("heading");
1717 break;
1718
1719 default:
1720 return;
1721 }
1722
1723 if ($a_status) {
1724 $caption .= " (" . $a_status . ")";
1725 }
1726
1727 $a_tpl->setCurrentBlock("list_item");
1728 $a_tpl->setVariable("NODE_ID", $node_id);
1729 $a_tpl->setVariable("NODE_DRAG", $drag);
1730 $a_tpl->setVariable("TXT_NODE_TYPE", $caption);
1731 if ($selectable) {
1732 $a_tpl->setVariable("SELECTABLE", " selectable");
1733 }
1734 $a_tpl->parseCurrentBlock();
1735 }
1736
1737 $a_tpl->touchBlock("element");
1738 }
1739
1743 public function getAutoBlockTitle(): string
1744 {
1745 $lng = $this->lng;
1746 return $lng->txt("survey_auto_block_title");
1747 }
1748
1749 public function addPoolQuestion(
1750 string $pos,
1751 string $node
1752 ): void {
1753 $ilCtrl = $this->ctrl;
1754 $ilUser = $this->user;
1755
1756 if ($node === "page_end") {
1757 $pages = $this->object->getSurveyPages();
1758 $page = array_pop($pages[$this->current_page - 1]);
1759 $pos = $page["question_id"] . "a";
1760 } else {
1761 $pos .= "b";
1762 }
1763
1764 $ilCtrl->setParameter($this->editor_gui, "pgov", $this->current_page);
1765 $ilCtrl->setParameter($this->editor_gui, "pgov_pos", $pos);
1766
1767 $cmd = ((int) $ilUser->getPref('svy_insert_type') === 1 || ($ilUser->getPref('svy_insert_type') ?? '') === '') ? 'browseForQuestions' : 'browseForQuestionblocks';
1768 $ilCtrl->redirect($this->editor_gui, $cmd);
1769 }
1770
1771 public function printViewSelection(): void
1772 {
1773 $view = $this->print->page($this->ref_id);
1774 $view->sendForm();
1775 }
1776}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
setVariable($variable, $value='')
Sets a variable value.
Definition: IT.php:514
static _getQuestionGUI(?string $questiontype, int $question_id=-1)
Creates a question gui representation.
static _isComplete(int $question_id)
Checks whether the question is complete or not.
Class ilCtrl provides processing control methods.
redirect(object $a_gui_obj, string $a_cmd=null, string $a_anchor=null, bool $is_async=false)
@inheritDoc
setParameter(object $a_gui_obj, string $a_parameter, $a_value)
@inheritDoc
static get(string $a_glyph, string $a_text="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
language handling
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...
static getLogger(string $a_component_id)
Get component logger.
Component logger with individual log levels by component id.
static _getUsedHTMLTags(string $a_module="")
Returns an array of all allowed HTML tags for text editing.
static _getQuestiontypes()
Get all available question types.
static _hasDatasets(int $survey_id)
static _instanciateQuestion(int $question_id)
Creates an instance of a question with a given question id.
User class.
This class represents a property form user interface.
class ilRbacSystem system function like checkAccess, addActiveRole ... Supporting system functions ar...
checkAccess(string $a_operations, int $a_ref_id, string $a_type="")
checkAccess represents the main method of the RBAC-system in ILIAS3 developers want to use With this ...
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...
Class ilSurveyEditorGUI.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
deleteBlock()
Confirm removing question block.
addPoolQuestion(string $pos, string $node)
ilGlobalTemplateInterface $tpl
renderPageNode(ilTemplate $a_tpl, string $a_type, string $a_id, ?string $a_content=null, ?array $a_menu=null, bool $a_spacer=false, string $a_subtitle="", ?string $a_status=null, ?string $a_heading=null)
Render single node of dnd page view.
deleteQuestion(array $a_id)
Confirm removing question(s) from survey.
insertNewQuestion(int $a_new_id)
Add new question to survey.
renderPage()
render questions per page
addQuestionToolbar()
Add question to survey action (used in toolbar)
movePrevious(int $a_id)
Move question to previous page.
insertQuestionBlock(int $a_block_id)
Copy and insert questions from block.
appendNewQuestionToSurvey(int $a_new_id, bool $a_duplicate=true, bool $a_force_duplicate=false)
Add new question to survey (database part)
multiCopy(array $a_id)
Add questions to be copied to clipboard.
copyQuestion(int $a_id)
Add question to be copied to clipboard.
moveNext(int $a_id)
Move question to next page.
ILIAS Survey Editing EditingGUIRequest $svy_request
splitPage(int $a_id)
Split current page in 2 pages.
deleteHeading(int $a_id)
Delete question heading.
callEditor(string $a_cmd, string $a_param, string $a_value)
getPageNodes(array $a_questions, bool $a_has_previous_page=false, bool $a_has_next_page=false, bool $a_readonly=false)
multiCut(array $a_id)
Add questions to be cut to clipboard.
dnd()
Move questions in page.
movePage()
Move current page to new position.
addQuestion(int $a_type, bool $a_use_pool, string $a_pos, string $a_special_position)
Call add question to survey form.
__construct(ilObjSurvey $a_survey, ilSurveyEditorGUI $a_survey_editor_gui)
addQuestionToolbarForm()
Add question to survey form (used in toolbar)
ILIAS Survey Editing EditManager $edit_manager
cutQuestion(int $a_id)
Add question to be cut to clipboard.
confirmRemoveQuestions()
Remove question(s) from survey.
paste(int $a_id)
Paste from clipboard.
getAutoBlockTitle()
Get name for newly created blocks.
editHeading(int $a_id)
Edit question heading.
editBlock(int $a_id)
Edit question block.
renderToolbar(?array $a_pages)
Render toolbar form.
ILIAS Survey PrintView GUIService $print
movePageForm()
Move current page.
addHeading(int $a_id)
Add heading to question.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
special template class to simplify handling of ITX/PEAR
setCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
parseCurrentBlock(string $part=ilGlobalTemplateInterface::DEFAULT_BLOCK)
touchBlock(string $block)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static removeRedundantSeparators(string $a_string)
Removes redundant seperators and removes ,, and , at the first or last position of the string.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static initDragDrop(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI Drag and Drop used in Modules/Survey, Services/Calendar, Services/COPage,...
global $DIC
Definition: feed.php:28
$target_id
Definition: goto.php:52
$target_arr
Definition: goto.php:50
$ilUser
Definition: imgupload.php:34
Interface ilDBInterface.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if($DIC->http() ->request() ->getMethod()=="GET" &&isset($DIC->http() ->request() ->getQueryParams()['tex'])) $tpl
Definition: latex.php:41
$source
Definition: metadata.php:93
static http()
Fetches the global http state from ILIAS.
$type
$url
$lng