ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assQuestionGUI.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once './Modules/Test/classes/inc.AssessmentConstants.php';
5require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
6require_once 'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
7require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
8require_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
9
20abstract class assQuestionGUI
21{
22 const FORM_MODE_EDIT = 'edit';
23 const FORM_MODE_ADJUST = 'adjust';
24
25 const FORM_ENCODING_URLENCODE = 'application/x-www-form-urlencoded';
26 const FORM_ENCODING_MULTIPART = 'multipart/form-data';
27
28 const SESSION_PREVIEW_DATA_BASE_INDEX = 'ilAssQuestionPreviewAnswers';
29
37 public $object;
38
39 public $tpl;
40 public $lng;
41 public $error;
43
52
53 private $taxonomyIds = array();
54
55 private $targetGuiClass = null;
56
57 private $questionActionCmd = 'handleQuestionAction';
58
63
68
69 const PRESENTATION_CONTEXT_TEST = 'pContextTest';
70 const PRESENTATION_CONTEXT_RESULTS = 'pContextResults';
71
75 private $presentationContext = null;
76
77 const RENDER_PURPOSE_PLAYBACK = 'renderPurposePlayback';
78 const RENDER_PURPOSE_DEMOPLAY = 'renderPurposeDemoplay';
79 const RENDER_PURPOSE_PREVIEW = 'renderPurposePreview';
80 const RENDER_PURPOSE_PRINT_PDF = 'renderPurposePrintPdf';
81 const RENDER_PURPOSE_INPUT_VALUE = 'renderPurposeInputValue';
82
87
88 const EDIT_CONTEXT_AUTHORING = 'authoring';
89 const EDIT_CONTEXT_ADJUSTMENT = 'adjustment';
90
95
96 // hey: prevPassSolutions - flag to indicate that a previous answer is shown
101 // hey.
102
106 protected $editForm;
107
112 protected $use_intermediate_solution = false;
113
117 public function __construct()
118 {
119 global $DIC;
120 $lng = $DIC['lng'];
121 $tpl = $DIC['tpl'];
122 $ilCtrl = $DIC['ilCtrl'];
123
124 $this->lng = &$lng;
125 $this->tpl = &$tpl;
126 $this->ctrl = &$ilCtrl;
127 $this->ctrl->saveParameter($this, "q_id");
128 $this->ctrl->saveParameter($this, "prev_qid");
129 $this->ctrl->saveParameter($this, "calling_test");
130 $this->ctrl->saveParameter($this, "calling_consumer");
131 $this->ctrl->saveParameter($this, "consumer_context");
132 $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'test_express_mode');
133 $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'calling_consumer');
134 $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'consumer_context');
135 $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'test_express_mode');
136 $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'calling_consumer');
137 $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'consumer_context');
138
139 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
140 $this->errormessage = $this->lng->txt("fill_out_all_required_fields");
141
142 $this->selfassessmenteditingmode = false;
143 $this->new_id_listeners = array();
144 $this->new_id_listener_cnt = 0;
145
146 $this->navigationGUI = null;
147 }
148
154 public function hasInlineFeedback()
155 {
156 return false;
157 }
158
159 public function addHeaderAction()
160 {
161 global $DIC; /* @var ILIAS\DI\Container $DIC */
162
163 $DIC->ui()->mainTemplate()->setVariable(
164 "HEAD_ACTION",
165 $this->getHeaderAction()
166 );
167
168 $notesUrl = $this->ctrl->getLinkTargetByClass(
169 array("ilcommonactiondispatchergui", "ilnotegui"),
170 "",
171 "",
172 true,
173 false
174 );
175
176 ilNoteGUI::initJavascript($notesUrl, IL_NOTE_PUBLIC, $DIC->ui()->mainTemplate());
177
178 $redrawActionsUrl = $DIC->ctrl()->getLinkTarget($this, 'redrawHeaderAction', '', true);
179 $DIC->ui()->mainTemplate()->addOnLoadCode("il.Object.setRedrawAHUrl('$redrawActionsUrl');");
180 }
181
182 public function redrawHeaderAction()
183 {
184 global $DIC; /* @var ILIAS\DI\Container $DIC */
185 echo $this->getHeaderAction() . $DIC->ui()->mainTemplate()->getOnLoadCodeForAsynch();
186 exit;
187 }
188
189 public function getHeaderAction()
190 {
191 global $DIC; /* @var ILIAS\DI\Container $DIC */
192 /* @var ilObjectDataCache $ilObjDataCache */
193 $ilObjDataCache = $DIC['ilObjDataCache'];
194
195 $parentObjType = $ilObjDataCache->lookupType($this->object->getObjId());
196
197 $dispatcher = new ilCommonActionDispatcherGUI(
199 $DIC->access(),
200 $parentObjType,
201 $_GET["ref_id"],
202 $this->object->getObjId()
203 );
204
205 $dispatcher->setSubObject("quest", $this->object->getId());
206
207 $ha = $dispatcher->initHeaderAction();
208 $ha->enableComments(true, false);
209
210 return $ha->getHeaderAction($DIC->ui()->mainTemplate());
211 }
212
213 public function getNotesHTML()
214 {
215 $notesGUI = new ilNoteGUI($this->object->getObjId(), $this->object->getId(), 'quest');
216 $notesGUI->enablePublicNotes(true);
217 $notesGUI->enablePublicNotesDeletion(true);
218
219 return $notesGUI->getNotesHTML();
220 }
221
225 public function executeCommand()
226 {
227 global $DIC; /* @var \ILIAS\DI\Container $DIC */
228 $ilHelp = $DIC['ilHelp']; /* @var ilHelpGUI $ilHelp */
229 $ilHelp->setScreenIdComponent('qpl');
230
231 $cmd = $this->ctrl->getCmd("editQuestion");
232 $next_class = $this->ctrl->getNextClass($this);
233
234 $cmd = $this->getCommand($cmd);
235
236 switch ($next_class) {
237 case 'ilformpropertydispatchgui':
238 $form = $this->buildEditForm();
239
240 require_once 'Services/Form/classes/class.ilFormPropertyDispatchGUI.php';
241 $form_prop_dispatch = new ilFormPropertyDispatchGUI();
242 $form_prop_dispatch->setItem($form->getItemByPostVar(ilUtil::stripSlashes($_GET['postvar'])));
243 return $this->ctrl->forwardCommand($form_prop_dispatch);
244 break;
245
246 default:
247 $ret = $this->$cmd();
248 break;
249 }
250 return $ret;
251 }
252
253 public function getCommand($cmd)
254 {
255 return $cmd;
256 }
257
261 public function getType()
262 {
263 return $this->getQuestionType();
264 }
265
269 public function getPresentationContext()
270 {
272 }
273
278 {
279 $this->presentationContext = $presentationContext;
280 }
281
283 {
285 }
286
287 // hey: previousPassSolutions - setter/getter for Previous Solution Prefilled flag
292 {
294 }
295
300 {
301 $this->previousSolutionPrefilled = $previousSolutionPrefilled;
302 }
303 // hey.
304
308 public function getRenderPurpose()
309 {
311 }
312
317 {
318 $this->renderPurpose = $renderPurpose;
319 }
320
321 public function isRenderPurposePrintPdf()
322 {
324 }
325
326 public function isRenderPurposePreview()
327 {
329 }
330
332 {
334 }
335
336 public function isRenderPurposePlayback()
337 {
339 }
340
341 public function isRenderPurposeDemoplay()
342 {
344 }
345
347 {
348 if ($this->isRenderPurposePrintPdf()) {
349 return false;
350 }
351
352 if ($this->isRenderPurposeInputValue()) {
353 return false;
354 }
355
356 return true;
357 }
358
362 public function getEditContext()
363 {
364 return $this->editContext;
365 }
366
371 {
372 $this->editContext = $editContext;
373 }
374
378 public function isAuthoringEditContext()
379 {
381 }
382
386 public function isAdjustmentEditContext()
387 {
389 }
390
391 public function setAdjustmentEditContext()
392 {
393 return $this->setEditContext(self::EDIT_CONTEXT_ADJUSTMENT);
394 }
395
399 public function getNavigationGUI()
400 {
402 }
403
408 {
409 $this->navigationGUI = $navigationGUI;
410 }
411
413 {
414 $this->taxonomyIds = $taxonomyIds;
415 }
416
417 public function getTaxonomyIds()
418 {
419 return $this->taxonomyIds;
420 }
421
422 public function setTargetGui($linkTargetGui)
423 {
424 $this->setTargetGuiClass(get_class($linkTargetGui));
425 }
426
428 {
429 $this->targetGuiClass = $targetGuiClass;
430 }
431
432 public function getTargetGuiClass()
433 {
435 }
436
441 {
442 $this->questionHeaderBlockBuilder = $questionHeaderBlockBuilder;
443 }
444
445 // fau: testNav - get the question header block bulder (for tweaking)
450 {
452 }
453 // fau.
454
456 {
457 $this->questionActionCmd = $questionActionCmd;
458
459 if (is_object($this->object)) {
460 $this->object->questionActionCmd = $questionActionCmd;
461 }
462 }
463
464 public function getQuestionActionCmd()
465 {
467 }
468
473 protected function writePostData($always = false)
474 {
475 }
476
480 public function assessment()
481 {
485 global $DIC;
486 $tpl = $DIC['tpl'];
487
488 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionCumulatedStatisticsTableGUI.php';
489 $stats_table = new ilQuestionCumulatedStatisticsTableGUI($this, 'assessment', '', $this->object);
490
491 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionUsagesTableGUI.php';
492 $usage_table = new ilQuestionUsagesTableGUI($this, 'assessment', '', $this->object);
493
494 $tpl->setContent(implode('<br />', array(
495 $stats_table->getHTML(),
496 $usage_table->getHTML()
497 )));
498 }
499
509 public static function _getQuestionGUI($question_type, $question_id = -1)
510 {
511 global $DIC;
512 $ilCtrl = $DIC['ilCtrl'];
513 $ilDB = $DIC['ilDB'];
514 $lng = $DIC['lng'];
515
516 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
517
518 if ((!$question_type) and ($question_id > 0)) {
519 $question_type = assQuestion::getQuestionTypeFromDb($question_id);
520 }
521
522 if (strlen($question_type) == 0) {
523 return null;
524 }
525
526 assQuestion::_includeClass($question_type, 1);
527
528 $question_type_gui = assQuestion::getGuiClassNameByQuestionType($question_type);
529 $question = new $question_type_gui();
530
531 $feedbackObjectClassname = assQuestion::getFeedbackClassNameByQuestionType($question_type);
532 $question->object->feedbackOBJ = new $feedbackObjectClassname($question->object, $ilCtrl, $ilDB, $lng);
533
534 if ($question_id > 0) {
535 $question->object->loadFromDb($question_id);
536 }
537
538 return $question;
539 }
540
544 public static function _getGUIClassNameForId($a_q_id)
545 {
546 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
547 include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
548 $q_type = assQuestion::getQuestionTypeFromDb($a_q_id);
549 $class_name = assQuestionGUI::_getClassNameForQType($q_type);
550 return $class_name;
551 }
552
556 public static function _getClassNameForQType($q_type)
557 {
558 return $q_type . "GUI";
559 }
560
573 public function &createQuestionGUI($question_type, $question_id = -1)
574 {
575 include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
576 $this->question = &assQuestionGUI::_getQuestionGUI($question_type, $question_id);
577 }
578
580 {
581 $tpl->addJavaScript('Modules/TestQuestionPool/js/ilAssMultipleChoice.js');
582 }
583
587 public function getQuestionTemplate()
588 {
589 // @todo Björn: Maybe this has to be changed for PHP 7/ILIAS 5.2.x (ilObjTestGUI::executeCommand, switch -> default case -> $this->prepareOutput(); already added a template to the CONTENT variable wrapped in a block named content)
590 if (!$this->tpl->blockExists('content')) {
591 $this->tpl->addBlockFile("CONTENT", "content", "tpl.il_as_qpl_content.html", "Modules/TestQuestionPool");
592 }
593 // @todo Björn: Maybe this has to be changed for PHP 7/ILIAS 5.2.x (ilObjTestGUI::executeCommand, switch -> default case -> $this->prepareOutput(); already added a template to the STATUSLINE variable wrapped in a block named statusline)
594 if (!$this->tpl->blockExists('statusline')) {
595 $this->tpl->addBlockFile("STATUSLINE", "statusline", "tpl.statusline.html");
596 }
597 // @todo Björn: Maybe this has to be changed for PHP 7/ILIAS 5.2.x because ass[XYZ]QuestionGUI::editQuestion is called multiple times
598 if (!$this->tpl->blockExists('adm_content')) {
599 $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_as_question.html", "Modules/TestQuestionPool");
600 }
601 }
602
606 protected function renderEditForm($form)
607 {
608 $this->getQuestionTemplate();
609 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
610 }
611
618 public function getILIASPage($html = "")
619 {
620 include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
621 $page_gui = new ilAssQuestionPageGUI($this->object->getId());
622 $page_gui->setQuestionHTML(array($this->object->getId() => $html));
623 $presentation = $page_gui->presentation();
624 $presentation = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $presentation);
625 return $presentation;
626 }
627
631 public function outQuestionPage($a_temp_var, $a_postponed = false, $active_id = "", $html = "", $inlineFeedbackEnabled = false)
632 {
633 // hey: prevPassSolutions - add the "use previous answer"
634 // hey: prevPassSolutions - refactored identifiers
635 if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
636 // hey
639 } elseif // (!) --> if ($this->object->getTestQuestionConfig()->isUnchangedAnswerPossible())
640 // hey.
641// fau: testNav - add the "use unchanged answer checkbox"
642 // hey: prevPassSolutions - refactored identifiers
643 ($this->object->getTestPresentationConfig()->isUnchangedAnswerPossible()) {
644 // hey.
646 }
647 // fau.
648
649 $this->lng->loadLanguageModule("content");
650
651 // fau: testNav - add question buttons below question, add actions menu
652 include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
653 $page_gui = new ilAssQuestionPageGUI($this->object->getId());
654 $page_gui->setOutputMode("presentation");
655 $page_gui->setTemplateTargetVar($a_temp_var);
656
657 if ($this->getNavigationGUI()) {
658 $html .= $this->getNavigationGUI()->getHTML();
659 $page_gui->setQuestionActionsHTML($this->getNavigationGUI()->getActionsHTML());
660 }
661 // fau.
662
663 if (strlen($html)) {
664 if ($inlineFeedbackEnabled && $this->hasInlineFeedback()) {
665 $html = $this->buildFocusAnchorHtml() . $html;
666 }
667
668 $page_gui->setQuestionHTML(array($this->object->getId() => $html));
669 }
670
671 // fau: testNav - fill the header with subtitle blocks for question info an actions
672 $page_gui->setPresentationTitle($this->questionHeaderBlockBuilder->getPresentationTitle());
673 $page_gui->setQuestionInfoHTML($this->questionHeaderBlockBuilder->getQuestionInfoHTML());
674 // fau.
675
676 return $page_gui->presentation();
677 }
678
679 // fau: testNav - get the html of the "use unchanged answer checkbox"
681 {
682 // hey: prevPassSolutions - use abstracted template to share with other purposes of this kind
683 $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
684 $tpl->setVariable('TXT_FORCE_FORM_DIFF_LABEL', $this->object->getTestPresentationConfig()->getUseUnchangedAnswerLabel());
685 // hey.
686 return $tpl->get();
687 }
688 // fau.
689
690 // hey: prevPassSolutions - build prev solution message / build "use previous answer checkbox" html
692 {
693 return $this->lng->txt('use_previous_solution_advice');
694 }
695
697 {
698 $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
699 // hey: prevPassSolutions - use abtract template
700 $tpl->setVariable('TXT_FORCE_FORM_DIFF_LABEL', $this->lng->txt('use_previous_solution'));
701 // hey.
702 return $tpl->get();
703 }
704 // hey.
705
709 public function cancel()
710 {
711 if ($_GET["calling_test"]) {
712 $_GET["ref_id"] = $_GET["calling_test"];
713 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
714 } elseif ($_GET["test_ref_id"]) {
715 $_GET["ref_id"] = $_GET["test_ref_id"];
716 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["test_ref_id"]);
717 } else {
718 if ($_GET["q_id"] > 0) {
719 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
720 $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
721 } else {
722 $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
723 }
724 }
725 }
726
731 public function originalSyncForm($return_to = "", $return_to_feedback = '')
732 {
733 if (strlen($return_to)) {
734 $this->ctrl->setParameter($this, "return_to", $return_to);
735 } elseif ($_REQUEST['return_to']) {
736 $this->ctrl->setParameter($this, "return_to", $_REQUEST['return_to']);
737 }
738 if (strlen($return_to_feedback)) {
739 $this->ctrl->setParameter($this, 'return_to_fb', 'true');
740 }
741
742 $this->ctrl->saveParameter($this, 'test_express_mode');
743
744 $template = new ilTemplate("tpl.il_as_qpl_sync_original.html", true, true, "Modules/TestQuestionPool");
745 $template->setVariable("BUTTON_YES", $this->lng->txt("yes"));
746 $template->setVariable("BUTTON_NO", $this->lng->txt("no"));
747 $template->setVariable("FORM_ACTION", $this->ctrl->getFormAction($this));
748 $template->setVariable("TEXT_SYNC", $this->lng->txt("confirm_sync_questions"));
749 $this->tpl->setVariable("ADM_CONTENT", $template->get());
750 }
751
752 public function sync()
753 {
754 $original_id = $this->object->original_id;
755 if ($original_id) {
756 $this->object->syncWithOriginal();
757 }
758 if (strlen($_GET["return_to"])) {
759 $this->ctrl->redirect($this, $_GET["return_to"]);
760 }
761 if (strlen($_REQUEST["return_to_fb"])) {
762 $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
763 } else {
764 if (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer']) {
765 $ref_id = (int) $_GET['calling_consumer'];
766 $consumer = ilObjectFactory::getInstanceByRefId($ref_id);
767 if ($consumer instanceof ilQuestionEditingFormConsumer) {
768 ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
769 }
770 require_once 'Services/Link/classes/class.ilLink.php';
772 }
773 $_GET["ref_id"] = $_GET["calling_test"];
774
775 if ($_REQUEST['test_express_mode']) {
777 } else {
778 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
779 }
780 }
781 }
782
783 public function cancelSync()
784 {
785 if (strlen($_GET["return_to"])) {
786 $this->ctrl->redirect($this, $_GET["return_to"]);
787 }
788 if (strlen($_REQUEST['return_to_fb'])) {
789 $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
790 } else {
791 if (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer']) {
792 $ref_id = (int) $_GET['calling_consumer'];
793 $consumer = ilObjectFactory::getInstanceByRefId($ref_id);
794 if ($consumer instanceof ilQuestionEditingFormConsumer) {
795 ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
796 }
797 require_once 'Services/Link/classes/class.ilLink.php';
799 }
800 $_GET["ref_id"] = $_GET["calling_test"];
801
802 if ($_REQUEST['test_express_mode']) {
804 } else {
805 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
806 }
807 }
808 }
809
813 public function saveEdit()
814 {
815 global $DIC;
816 $ilUser = $DIC['ilUser'];
817
818 $result = $this->writePostData();
819 if ($result == 0) {
820 $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
821 $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
822 $this->object->saveToDb();
823 $originalexists = $this->object->_questionExists($this->object->original_id);
824 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
825 if ($_GET["calling_test"] && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
826 $this->ctrl->redirect($this, "originalSyncForm");
827 } elseif ($_GET["calling_test"]) {
828 $_GET["ref_id"] = $_GET["calling_test"];
829 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
830 return;
831 } elseif ($_GET["test_ref_id"]) {
832 global $DIC;
833 $tree = $DIC['tree'];
834 $ilDB = $DIC['ilDB'];
835 $ilPluginAdmin = $DIC['ilPluginAdmin'];
836
837 include_once("./Modules/Test/classes/class.ilObjTest.php");
838 $_GET["ref_id"] = $_GET["test_ref_id"];
839 $test = new ilObjTest($_GET["test_ref_id"], true);
840
841 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
842 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
843
844 $test->insertQuestion($testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId());
845
846 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["test_ref_id"]);
847 } else {
848 $this->ctrl->setParameter($this, "q_id", $this->object->getId());
849 $this->editQuestion();
850 if (strcmp($_SESSION["info"], "") != 0) {
851 ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), false);
852 } else {
853 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), false);
854 }
855 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $this->object->getId());
856 $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
857 }
858 }
859 }
860
864 public function save()
865 {
866 global $DIC;
867 $ilUser = $DIC['ilUser'];
868 $old_id = $_GET["q_id"];
869 $result = $this->writePostData();
870
871 if ($result == 0) {
872 $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
873 $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
874 $this->object->saveToDb();
875 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
876
877
878 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
879 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
880 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
881 $this->ctrl->setParameter($this, 'return_to', 'editQuestion');
882 $this->ctrl->redirect($this, "originalSyncForm");
883 return;
884 } elseif ($_GET["calling_test"]) {
885 require_once 'Modules/Test/classes/class.ilObjTest.php';
886 $test = new ilObjTest($_GET["calling_test"]);
887 if (!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId())) {
888 global $DIC;
889 $tree = $DIC['tree'];
890 $ilDB = $DIC['ilDB'];
891 $ilPluginAdmin = $DIC['ilPluginAdmin'];
892
893 include_once("./Modules/Test/classes/class.ilObjTest.php");
894 $_GET["ref_id"] = $_GET["calling_test"];
895 $test = new ilObjTest($_GET["calling_test"], true);
896
897 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
898 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
899
900 $new_id = $test->insertQuestion(
901 $testQuestionSetConfigFactory->getQuestionSetConfig(),
902 $this->object->getId()
903 );
904
905 if (isset($_REQUEST['prev_qid'])) {
906 $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
907 }
908
909 $this->ctrl->setParameter($this, 'q_id', $new_id);
910 $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
911 #$this->ctrl->setParameter($this, 'test_ref_id', false);
912 }
913 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
914 $this->ctrl->redirect($this, 'editQuestion');
915 } else {
916 $this->callNewIdListeners($this->object->getId());
917
918 if ($this->object->getId() != $old_id) {
919 // first save
920 $this->ctrl->setParameterByClass($_GET["cmdClass"], "q_id", $this->object->getId());
921 $this->ctrl->setParameterByClass($_GET["cmdClass"], "sel_question_types", $_GET["sel_question_types"]);
922 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
923
924 //global $___test_express_mode;
928 if ($_REQUEST['prev_qid']) {
929 // @todo: bheyser/mbecker wtf? ..... thx@jposselt ....
930 // mbecker: Possible fix: Just instantiate the obj?
931 include_once("./Modules/Test/classes/class.ilObjTest.php");
932 $test = new ilObjTest($_GET["ref_id"], true);
933 $test->moveQuestionAfter($_REQUEST['prev_qid'], $this->object->getId());
934 }
935 if ( /*$___test_express_mode || */ $_REQUEST['express_mode']) {
936 global $DIC;
937 $tree = $DIC['tree'];
938 $ilDB = $DIC['ilDB'];
939 $ilPluginAdmin = $DIC['ilPluginAdmin'];
940
941 include_once("./Modules/Test/classes/class.ilObjTest.php");
942 $test = new ilObjTest($_GET["ref_id"], true);
943
944 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
945 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
946
947 $test->insertQuestion(
948 $testQuestionSetConfigFactory->getQuestionSetConfig(),
949 $this->object->getId()
950 );
951
952 require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
953 $_REQUEST['q_id'] = $this->object->getId();
955 }
956
957 $this->ctrl->redirectByClass($_GET["cmdClass"], "editQuestion");
958 }
959 if (strcmp($_SESSION["info"], "") != 0) {
960 ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
961 } else {
962 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
963 }
964 $this->ctrl->redirect($this, 'editQuestion');
965 }
966 }
967 }
968
972 public function saveReturn()
973 {
974 global $DIC;
975 $ilUser = $DIC['ilUser'];
976 $old_id = $_GET["q_id"];
977 $result = $this->writePostData();
978 if ($result == 0) {
979 $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
980 $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
981 $this->object->saveToDb();
982 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
983 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
984 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
985 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
986 $this->ctrl->setParameter($this, 'test_express_mode', $_REQUEST['test_express_mode']);
987 $this->ctrl->redirect($this, "originalSyncForm");
988 return;
989 } elseif ($_GET["calling_test"]) {
990 require_once 'Modules/Test/classes/class.ilObjTest.php';
991 $test = new ilObjTest($_GET["calling_test"]);
992 #var_dump(assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()));
993 $q_id = $this->object->getId();
994 if (!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId())) {
995 global $DIC;
996 $tree = $DIC['tree'];
997 $ilDB = $DIC['ilDB'];
998 $ilPluginAdmin = $DIC['ilPluginAdmin'];
999
1000 include_once("./Modules/Test/classes/class.ilObjTest.php");
1001 $_GET["ref_id"] = $_GET["calling_test"];
1002 $test = new ilObjTest($_GET["calling_test"], true);
1003
1004 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
1005 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
1006
1007 $new_id = $test->insertQuestion(
1008 $testQuestionSetConfigFactory->getQuestionSetConfig(),
1009 $this->object->getId()
1010 );
1011
1012 $q_id = $new_id;
1013 if (isset($_REQUEST['prev_qid'])) {
1014 $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
1015 }
1016
1017 $this->ctrl->setParameter($this, 'q_id', $new_id);
1018 $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
1019 #$this->ctrl->setParameter($this, 'test_ref_id', false);
1020 }
1021 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1022 if ( /*$___test_express_mode || */
1023 $_REQUEST['test_express_mode']
1024 ) {
1026 } else {
1027 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
1028 }
1029 } else {
1030 if ($this->object->getId() != $old_id) {
1031 $this->callNewIdListeners($this->object->getId());
1032 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1033 $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
1034 }
1035 if (strcmp($_SESSION["info"], "") != 0) {
1036 ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
1037 } else {
1038 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1039 }
1040 $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
1041 }
1042 }
1043 }
1044
1048 public function apply()
1049 {
1050 $this->writePostData();
1051 $this->object->saveToDb();
1052 $this->ctrl->setParameter($this, "q_id", $this->object->getId());
1053 $this->editQuestion();
1054 }
1055
1062 public function getContextPath($cont_obj, $a_endnode_id, $a_startnode_id = 1)
1063 {
1064 $path = "";
1065
1066 $tmpPath = $cont_obj->getLMTree()->getPathFull($a_endnode_id, $a_startnode_id);
1067
1068 // count -1, to exclude the learning module itself
1069 for ($i = 1; $i < (count($tmpPath) - 1); $i++) {
1070 if ($path != "") {
1071 $path .= " > ";
1072 }
1073
1074 $path .= $tmpPath[$i]["title"];
1075 }
1076
1077 return $path;
1078 }
1079
1080 public function setSequenceNumber($nr)
1081 {
1082 $this->sequence_no = $nr;
1083 }
1084
1085 public function getSequenceNumber()
1086 {
1087 return $this->sequence_no;
1088 }
1089
1090 public function setQuestionCount($a_question_count)
1091 {
1092 $this->question_count = $a_question_count;
1093 }
1094
1095 public function getQuestionCount()
1096 {
1097 return $this->question_count;
1098 }
1099
1100 public function getErrorMessage()
1101 {
1102 return $this->errormessage;
1103 }
1104
1106 {
1107 $this->errormessage = $errormessage;
1108 }
1109
1111 {
1112 $this->errormessage .= ((strlen($this->errormessage)) ? "<br />" : "") . $errormessage;
1113 }
1114
1115 public function outAdditionalOutput()
1116 {
1117 }
1118
1127 public function getQuestionType()
1128 {
1129 return $this->object->getQuestionType();
1130 }
1131
1139 public function getAsValueAttribute($a_value)
1140 {
1141 $result = "";
1142 if (strlen($a_value)) {
1143 $result = " value=\"$a_value\" ";
1144 }
1145 return $result;
1146 }
1147
1148 // scorm2004-start
1153 public function addNewIdListener(&$a_object, $a_method, $a_parameters = "")
1154 {
1155 $cnt = $this->new_id_listener_cnt;
1156 $this->new_id_listeners[$cnt]["object"] = &$a_object;
1157 $this->new_id_listeners[$cnt]["method"] = $a_method;
1158 $this->new_id_listeners[$cnt]["parameters"] = $a_parameters;
1159 $this->new_id_listener_cnt++;
1160 }
1161
1165 public function callNewIdListeners($a_new_id)
1166 {
1167 for ($i = 0; $i < $this->new_id_listener_cnt; $i++) {
1168 $this->new_id_listeners[$i]["parameters"]["new_id"] = $a_new_id;
1169 $object = &$this->new_id_listeners[$i]["object"];
1170 $method = $this->new_id_listeners[$i]["method"];
1171 $parameters = $this->new_id_listeners[$i]["parameters"];
1172 //var_dump($object);
1173 //var_dump($method);
1174 //var_dump($parameters);
1175
1176 $object->$method($parameters);
1177 }
1178 }
1179
1184 {
1185 //if (!$this->object->getSelfAssessmentEditingMode() && !$_GET["calling_test"]) $form->addCommandButton("saveEdit", $this->lng->txt("save_edit"));
1186 if (!$this->object->getSelfAssessmentEditingMode()) {
1187 $form->addCommandButton("saveReturn", $this->lng->txt("save_return"));
1188 }
1189 $form->addCommandButton("save", $this->lng->txt("save"));
1190 }
1191
1199 {
1200 // title
1201 $title = new ilTextInputGUI($this->lng->txt("title"), "title");
1202 $title->setMaxLength(100);
1203 $title->setValue($this->object->getTitle());
1204 $title->setRequired(true);
1205 $form->addItem($title);
1206
1207 if (!$this->object->getSelfAssessmentEditingMode()) {
1208 // author
1209 $author = new ilTextInputGUI($this->lng->txt("author"), "author");
1210 $author->setValue($this->object->getAuthor());
1211 $author->setRequired(true);
1212 $form->addItem($author);
1213
1214 // description
1215 $description = new ilTextInputGUI($this->lng->txt("description"), "comment");
1216 $description->setValue($this->object->getComment());
1217 $description->setRequired(false);
1218 $form->addItem($description);
1219 } else {
1220 // author as hidden field
1221 $hi = new ilHiddenInputGUI("author");
1222 $author = ilUtil::prepareFormOutput($this->object->getAuthor());
1223 if (trim($author) == "") {
1224 $author = "-";
1225 }
1226 $hi->setValue($author);
1227 $form->addItem($hi);
1228 }
1229
1230 // questiontext
1231 $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
1232 $question->setValue($this->object->getQuestion());
1233 $question->setRequired(true);
1234 $question->setRows(10);
1235 $question->setCols(80);
1236
1237 if (!$this->object->getSelfAssessmentEditingMode()) {
1238 if ($this->object->getAdditionalContentEditingMode() != assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT) {
1239 $question->setUseRte(true);
1240 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
1241 $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
1242 $question->addPlugin("latex");
1243 $question->addButton("latex");
1244 $question->addButton("pastelatex");
1245 $question->setRTESupport($this->object->getId(), "qpl", "assessment");
1246 }
1247 } else {
1248 require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
1250 $question->setUseTagsForRteOnly(false);
1251 }
1252 $form->addItem($question);
1253
1254 if (!$this->object->getSelfAssessmentEditingMode()) {
1255 // duration
1256 $duration = new ilDurationInputGUI($this->lng->txt("working_time"), "Estimated");
1257 $duration->setShowHours(true);
1258 $duration->setShowMinutes(true);
1259 $duration->setShowSeconds(true);
1260 $ewt = $this->object->getEstimatedWorkingTime();
1261 $duration->setHours($ewt["h"]);
1262 $duration->setMinutes($ewt["m"]);
1263 $duration->setSeconds($ewt["s"]);
1264 $duration->setRequired(false);
1265 $form->addItem($duration);
1266 } else {
1267 // number of tries
1268 if (strlen($this->object->getNrOfTries())) {
1269 $nr_tries = $this->object->getNrOfTries();
1270 } else {
1271 $nr_tries = $this->object->getDefaultNrOfTries();
1272 }
1273 if ($nr_tries < 1) {
1274 $nr_tries = "";
1275 }
1276
1277 $ni = new ilNumberInputGUI($this->lng->txt("qst_nr_of_tries"), "nr_of_tries");
1278 $ni->setValue($nr_tries);
1279 $ni->setMinValue(0);
1280 $ni->setSize(5);
1281 $ni->setMaxLength(5);
1282 $form->addItem($ni);
1283 }
1284 }
1285
1286 protected function saveTaxonomyAssignments()
1287 {
1288 if (count($this->getTaxonomyIds())) {
1289 require_once 'Services/Taxonomy/classes/class.ilTaxAssignInputGUI.php';
1290
1291 foreach ($this->getTaxonomyIds() as $taxonomyId) {
1292 $postvar = "tax_node_assign_$taxonomyId";
1293
1294 $tax_node_assign = new ilTaxAssignInputGUI($taxonomyId, true, '', $postvar);
1295 // TODO: determine tst/qpl when tax assigns become maintainable within tests
1296 $tax_node_assign->saveInput("qpl", $this->object->getObjId(), "quest", $this->object->getId());
1297 }
1298 }
1299 }
1300
1302 {
1303 if (count($this->getTaxonomyIds())) {
1304 // this is needed by ilTaxSelectInputGUI in some cases
1305 require_once 'Services/UIComponent/Overlay/classes/class.ilOverlayGUI.php';
1306 ilOverlayGUI::initJavaScript();
1307
1308 $sectHeader = new ilFormSectionHeaderGUI();
1309 $sectHeader->setTitle($this->lng->txt('qpl_qst_edit_form_taxonomy_section'));
1310 $form->addItem($sectHeader);
1311
1312 require_once 'Services/Taxonomy/classes/class.ilTaxSelectInputGUI.php';
1313
1314 foreach ($this->getTaxonomyIds() as $taxonomyId) {
1315 $taxonomy = new ilObjTaxonomy($taxonomyId);
1316 $label = sprintf($this->lng->txt('qpl_qst_edit_form_taxonomy'), $taxonomy->getTitle());
1317 $postvar = "tax_node_assign_$taxonomyId";
1318
1319 $taxSelect = new ilTaxSelectInputGUI($taxonomy->getId(), $postvar, true);
1320 $taxSelect->setTitle($label);
1321
1322 require_once 'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
1323 $taxNodeAssignments = new ilTaxNodeAssignment(ilObject::_lookupType($this->object->getObjId()), $this->object->getObjId(), 'quest', $taxonomyId);
1324 $assignedNodes = $taxNodeAssignments->getAssignmentsOfItem($this->object->getId());
1325
1326 $taxSelect->setValue(array_map(function ($assignedNode) {
1327 return $assignedNode['node_id'];
1328 }, $assignedNodes));
1329 $form->addItem($taxSelect);
1330 }
1331 }
1332 }
1333
1343 public function getAnswerFeedbackOutput($active_id, $pass)
1344 {
1345 return $this->getGenericFeedbackOutput($active_id, $pass);
1346 }
1347
1357 public function getGenericFeedbackOutput($active_id, $pass)
1358 {
1359 $output = "";
1360 include_once "./Modules/Test/classes/class.ilObjTest.php";
1361 $manual_feedback = ilObjTest::getManualFeedback($active_id, $this->object->getId(), $pass);
1362 if (strlen($manual_feedback)) {
1363 return $manual_feedback;
1364 }
1365 $correct_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true);
1366 $incorrect_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false);
1367 if (strlen($correct_feedback . $incorrect_feedback)) {
1368 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
1369 $max_points = $this->object->getMaximumPoints();
1370 if ($reached_points == $max_points) {
1371 $output = $correct_feedback;
1372 } else {
1373 $output = $incorrect_feedback;
1374 }
1375 }
1376 return $this->object->prepareTextareaOutput($output, true);
1377 }
1378
1380 {
1381 return $this->object->prepareTextareaOutput(
1382 $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true),
1383 true
1384 );
1385 }
1386
1388 {
1389 return $this->object->prepareTextareaOutput(
1390 $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false),
1391 true
1392 );
1393 }
1394
1405 abstract public function getSpecificFeedbackOutput($userSolution);
1406
1407 public function outQuestionType()
1408 {
1409 $count = $this->object->isInUse();
1410
1411 if ($this->object->_questionExistsInPool($this->object->getId()) && $count) {
1412 global $DIC;
1413 $rbacsystem = $DIC['rbacsystem'];
1414 if ($rbacsystem->checkAccess("write", $_GET["ref_id"])) {
1415 ilUtil::sendInfo(sprintf($this->lng->txt("qpl_question_is_in_use"), $count));
1416 }
1417 }
1418
1419 return assQuestion::_getQuestionTypeName($this->object->getQuestionType());
1420 }
1421
1422 public function showSuggestedSolution()
1423 {
1424 $this->suggestedsolution();
1425 }
1426
1432 public function suggestedsolution()
1433 {
1434 global $DIC;
1435 $ilUser = $DIC['ilUser'];
1436 global $DIC;
1437 $ilAccess = $DIC['ilAccess'];
1438
1439 $save = (is_array($_POST["cmd"]) && array_key_exists("suggestedsolution", $_POST["cmd"])) ? true : false;
1440
1441 if ($save && $_POST["deleteSuggestedSolution"] == 1) {
1442 $this->object->deleteSuggestedSolutions();
1443 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1444 $this->ctrl->redirect($this, "suggestedsolution");
1445 }
1446
1447 $output = "";
1448 $solution_array = $this->object->getSuggestedSolution(0);
1449 $options = array(
1450 "lm" => $this->lng->txt("obj_lm"),
1451 "st" => $this->lng->txt("obj_st"),
1452 "pg" => $this->lng->txt("obj_pg"),
1453 "git" => $this->lng->txt("glossary_term"),
1454 "file" => $this->lng->txt("fileDownload"),
1455 "text" => $this->lng->txt("solutionText")
1456 );
1457
1458 if ((strcmp($_POST["solutiontype"], "file") == 0) && (strcmp($solution_array["type"], "file") != 0)) {
1459 $solution_array = array(
1460 "type" => "file"
1461 );
1462 } elseif ((strcmp($_POST["solutiontype"], "text") == 0) && (strcmp($solution_array["type"], "text") != 0)) {
1463 $oldOutputMode = $this->getRenderPurpose();
1464 $this->setRenderPurpose(self::RENDER_PURPOSE_INPUT_VALUE);
1465
1466 $solution_array = array(
1467 "type" => "text",
1468 "value" => $this->getSolutionOutput(0, null, false, false, true, false, true)
1469 );
1470 $this->setRenderPurpose($oldsaveSuggestedSolutionOutputMode);
1471 }
1472 if ($save && strlen($_POST["filename"])) {
1473 $solution_array["value"]["filename"] = $_POST["filename"];
1474 }
1475 if ($save && strlen($_POST["solutiontext"])) {
1476 $solution_array["value"] = $_POST["solutiontext"];
1477 }
1478 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
1479 if (count($solution_array)) {
1480 $form = new ilPropertyFormGUI();
1481 $form->setFormAction($this->ctrl->getFormAction($this));
1482 $form->setTitle($this->lng->txt("solution_hint"));
1483 $form->setMultipart(true);
1484 $form->setTableWidth("100%");
1485 $form->setId("suggestedsolutiondisplay");
1486
1487 // suggested solution output
1488 include_once "./Modules/TestQuestionPool/classes/class.ilSolutionTitleInputGUI.php";
1489 $title = new ilSolutionTitleInputGUI($this->lng->txt("showSuggestedSolution"), "solutiontype");
1490 $template = new ilTemplate("tpl.il_as_qpl_suggested_solution_input_presentation.html", true, true, "Modules/TestQuestionPool");
1491 if (strlen($solution_array["internal_link"])) {
1492 $href = assQuestion::_getInternalLinkHref($solution_array["internal_link"]);
1493 $template->setCurrentBlock("preview");
1494 $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1495 $template->setVariable("VALUE_SOLUTION", " <a href=\"$href\" target=\"content\">" . $this->lng->txt("view") . "</a> ");
1496 $template->parseCurrentBlock();
1497 } elseif ((strcmp($solution_array["type"], "file") == 0) && (is_array($solution_array["value"]))) {
1498 $href = $this->object->getSuggestedSolutionPathWeb() . $solution_array["value"]["name"];
1499 $template->setCurrentBlock("preview");
1500 $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1501 $template->setVariable("VALUE_SOLUTION", " <a href=\"$href\" target=\"content\">" . ilUtil::prepareFormOutput((strlen($solution_array["value"]["filename"])) ? $solution_array["value"]["filename"] : $solution_array["value"]["name"]) . "</a> ");
1502 $template->parseCurrentBlock();
1503 }
1504 $template->setVariable("TEXT_TYPE", $this->lng->txt("type"));
1505 $template->setVariable("VALUE_TYPE", $options[$solution_array["type"]]);
1506 $title->setHtml($template->get());
1507 $deletesolution = new ilCheckboxInputGUI("", "deleteSuggestedSolution");
1508 $deletesolution->setOptionTitle($this->lng->txt("deleteSuggestedSolution"));
1509 $title->addSubItem($deletesolution);
1510 $form->addItem($title);
1511
1512 if (strcmp($solution_array["type"], "file") == 0) {
1513 // file
1514 $file = new ilFileInputGUI($this->lng->txt("fileDownload"), "file");
1515 $file->setRequired(true);
1516 $file->enableFileNameSelection("filename");
1517 //$file->setSuffixes(array("doc","xls","png","jpg","gif","pdf"));
1518 if ($_FILES["file"]["tmp_name"] && $file->checkInput()) {
1519 if (!file_exists($this->object->getSuggestedSolutionPath())) {
1520 ilUtil::makeDirParents($this->object->getSuggestedSolutionPath());
1521 }
1522
1523 $res = ilUtil::moveUploadedFile($_FILES["file"]["tmp_name"], $_FILES["file"]["name"], $this->object->getSuggestedSolutionPath() . $_FILES["file"]["name"]);
1524 if ($res) {
1525 ilUtil::renameExecutables($this->object->getSuggestedSolutionPath());
1526
1527 // remove an old file download
1528 if (is_array($solution_array["value"])) {
1529 @unlink($this->object->getSuggestedSolutionPath() . $solution_array["value"]["name"]);
1530 }
1531 $file->setValue($_FILES["file"]["name"]);
1532 $this->object->saveSuggestedSolution("file", "", 0, array("name" => $_FILES["file"]["name"], "type" => $_FILES["file"]["type"], "size" => $_FILES["file"]["size"], "filename" => $_POST["filename"]));
1533 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
1534 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
1535 return $this->originalSyncForm("suggestedsolution");
1536 } else {
1537 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1538 $this->ctrl->redirect($this, "suggestedsolution");
1539 }
1540 } else {
1541 // BH: $res as info string? wtf? it holds a bool or something else!!?
1543 }
1544 } else {
1545 if (is_array($solution_array["value"])) {
1546 $file->setValue($solution_array["value"]["name"]);
1547 $file->setFilename((strlen($solution_array["value"]["filename"])) ? $solution_array["value"]["filename"] : $solution_array["value"]["name"]);
1548 }
1549 }
1550 $form->addItem($file);
1551 $hidden = new ilHiddenInputGUI("solutiontype");
1552 $hidden->setValue("file");
1553 $form->addItem($hidden);
1554 } elseif (strcmp($solution_array["type"], "text") == 0) {
1555 $solutionContent = $solution_array['value'];
1556 $solutionContent = $this->object->fixSvgToPng($solutionContent);
1557 $solutionContent = $this->object->fixUnavailableSkinImageSources($solutionContent);
1558 $question = new ilTextAreaInputGUI($this->lng->txt("solutionText"), "solutiontext");
1559 $question->setValue($this->object->prepareTextareaOutput($solutionContent));
1560 $question->setRequired(true);
1561 $question->setRows(10);
1562 $question->setCols(80);
1563 $question->setUseRte(true);
1564 $question->addPlugin("latex");
1565 $question->addButton("latex");
1566 $question->setRTESupport($this->object->getId(), "qpl", "assessment");
1567 $hidden = new ilHiddenInputGUI("solutiontype");
1568 $hidden->setValue("text");
1569 $form->addItem($hidden);
1570 $form->addItem($question);
1571 }
1572 if ($ilAccess->checkAccess("write", "", $_GET['ref_id'])) {
1573 $form->addCommandButton('showSuggestedSolution', $this->lng->txt('cancel'));
1574 $form->addCommandButton('suggestedsolution', $this->lng->txt('save'));
1575 }
1576
1577 if ($save) {
1578 if ($form->checkInput()) {
1579 switch ($solution_array["type"]) {
1580 case "file":
1581 $this->object->saveSuggestedSolution("file", "", 0, array(
1582 "name" => $solution_array["value"]["name"],
1583 "type" => $solution_array["value"]["type"],
1584 "size" => $solution_array["value"]["size"],
1585 "filename" => $_POST["filename"]
1586 ));
1587 break;
1588 case "text":
1589 $this->object->saveSuggestedSolution("text", "", 0, $solution_array["value"]);
1590 break;
1591 }
1592 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
1593 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
1594 return $this->originalSyncForm("suggestedsolution");
1595 } else {
1596 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1597 $this->ctrl->redirect($this, "suggestedsolution");
1598 }
1599 }
1600 }
1601
1602 $output = $form->getHTML();
1603 }
1604
1605 $savechange = (strcmp($this->ctrl->getCmd(), "saveSuggestedSolution") == 0) ? true : false;
1606
1607 $changeoutput = "";
1608 if ($ilAccess->checkAccess("write", "", $_GET['ref_id'])) {
1609 $formchange = new ilPropertyFormGUI();
1610 $formchange->setFormAction($this->ctrl->getFormAction($this));
1611 $formchange->setTitle((count($solution_array)) ? $this->lng->txt("changeSuggestedSolution") : $this->lng->txt("addSuggestedSolution"));
1612 $formchange->setMultipart(false);
1613 $formchange->setTableWidth("100%");
1614 $formchange->setId("suggestedsolution");
1615
1616 $solutiontype = new ilRadioGroupInputGUI($this->lng->txt("suggestedSolutionType"), "solutiontype");
1617 foreach ($options as $opt_value => $opt_caption) {
1618 $solutiontype->addOption(new ilRadioOption($opt_caption, $opt_value));
1619 }
1620 if (count($solution_array)) {
1621 $solutiontype->setValue($solution_array["type"]);
1622 }
1623 $solutiontype->setRequired(true);
1624 $formchange->addItem($solutiontype);
1625
1626 $formchange->addCommandButton("saveSuggestedSolution", $this->lng->txt("select"));
1627
1628 if ($savechange) {
1629 $formchange->checkInput();
1630 }
1631 $changeoutput = $formchange->getHTML();
1632 }
1633
1634 $this->tpl->setVariable("ADM_CONTENT", $changeoutput . $output);
1635 }
1636
1637 public function outSolutionExplorer()
1638 {
1639 global $DIC;
1640 $tree = $DIC['tree'];
1641
1642 include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1643 $type = $_GET["link_new_type"];
1644 $search = $_GET["search_link_type"];
1645 $this->ctrl->setParameter($this, "link_new_type", $type);
1646 $this->ctrl->setParameter($this, "search_link_type", $search);
1647 $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1648
1649 ilUtil::sendInfo($this->lng->txt("select_object_to_link"));
1650
1651 $parent_ref_id = $tree->getParentId($_GET["ref_id"]);
1652 $exp = new ilSolutionExplorer($this->ctrl->getLinkTarget($this, 'suggestedsolution'), get_class($this));
1653 $exp->setExpand($_GET['expand_sol'] ? $_GET['expand_sol'] : $parent_ref_id);
1654 $exp->setExpandTarget($this->ctrl->getLinkTarget($this, 'outSolutionExplorer'));
1655 $exp->setTargetGet("ref_id");
1656 $exp->setRefId($_GET["ref_id"]);
1657 $exp->addFilter($type);
1658 $exp->setSelectableType($type);
1659 if (isset($_GET['expandCurrentPath']) && $_GET['expandCurrentPath']) {
1660 $exp->expandPathByRefId($parent_ref_id);
1661 }
1662
1663 // build html-output
1664 $exp->setOutput(0);
1665
1666 $template = new ilTemplate("tpl.il_as_qpl_explorer.html", true, true, "Modules/TestQuestionPool");
1667 $template->setVariable("EXPLORER_TREE", $exp->getOutput());
1668 $template->setVariable("BUTTON_CANCEL", $this->lng->txt("cancel"));
1669 $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "suggestedsolution"));
1670 $this->tpl->setVariable("ADM_CONTENT", $template->get());
1671 }
1672
1673 public function saveSuggestedSolution()
1674 {
1675 global $DIC;
1676 $tree = $DIC['tree'];
1677
1678 include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1679 switch ($_POST["solutiontype"]) {
1680 case "lm":
1681 $type = "lm";
1682 $search = "lm";
1683 break;
1684 case "git":
1685 $type = "glo";
1686 $search = "glo";
1687 break;
1688 case "st":
1689 $type = "lm";
1690 $search = "st";
1691 break;
1692 case "pg":
1693 $type = "lm";
1694 $search = "pg";
1695 break;
1696 case "file":
1697 case "text":
1698 return $this->suggestedsolution();
1699 break;
1700 default:
1701 return $this->suggestedsolution();
1702 break;
1703 }
1704 if (isset($_POST['solutiontype'])) {
1705 $this->ctrl->setParameter($this, 'expandCurrentPath', 1);
1706 }
1707 $this->ctrl->setParameter($this, "link_new_type", $type);
1708 $this->ctrl->setParameter($this, "search_link_type", $search);
1709 $this->ctrl->redirect($this, "outSolutionExplorer");
1710 }
1711
1712 public function cancelExplorer()
1713 {
1714 $this->ctrl->redirect($this, "suggestedsolution");
1715 }
1716
1717 public function outPageSelector()
1718 {
1719 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1720 require_once 'Modules/LearningModule/classes/class.ilLMPageObject.php';
1721 require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1722
1723 $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1724
1725 $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1726 $cont_obj = $cont_obj_gui->object;
1727 $pages = ilLMPageObject::getPageList($cont_obj->getId());
1728 $shownpages = array();
1729 $tree = $cont_obj->getLMTree();
1730 $chapters = $tree->getSubtree($tree->getNodeData($tree->getRootId()));
1731
1732 $rows = array();
1733
1734 foreach ($chapters as $chapter) {
1735 $chapterpages = $tree->getChildsByType($chapter['obj_id'], 'pg');
1736 foreach ($chapterpages as $page) {
1737 if ($page['type'] == $_GET['search_link_type']) {
1738 array_push($shownpages, $page['obj_id']);
1739
1740 if ($tree->isInTree($page['obj_id'])) {
1741 $path_str = $this->getContextPath($cont_obj, $page['obj_id']);
1742 } else {
1743 $path_str = '---';
1744 }
1745
1746 $this->ctrl->setParameter($this, $page['type'], $page['obj_id']);
1747 $rows[] = array(
1748 'title' => $page['title'],
1749 'description' => ilUtil::prepareFormOutput($path_str),
1750 'text_add' => $this->lng->txt('add'),
1751 'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($page['type']))
1752 );
1753 }
1754 }
1755 }
1756 foreach ($pages as $page) {
1757 if (!in_array($page['obj_id'], $shownpages)) {
1758 $this->ctrl->setParameter($this, $page['type'], $page['obj_id']);
1759 $rows[] = array(
1760 'title' => $page['title'],
1761 'description' => '---',
1762 'text_add' => $this->lng->txt('add'),
1763 'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($page['type']))
1764 );
1765 }
1766 }
1767
1768 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1769 $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1770 $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1771 $table->setData($rows);
1772
1773 $this->tpl->setContent($table->getHTML());
1774 }
1775
1776 public function outChapterSelector()
1777 {
1778 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1779 require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1780
1781 $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1782
1783 $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1784 $cont_obj = $cont_obj_gui->object;
1785 $ctree = $cont_obj->getLMTree();
1786 $nodes = $ctree->getSubtree($ctree->getNodeData($ctree->getRootId()));
1787
1788 $rows = array();
1789
1790 foreach ($nodes as $node) {
1791 if ($node['type'] == $_GET['search_link_type']) {
1792 $this->ctrl->setParameter($this, $node['type'], $node['obj_id']);
1793 $rows[] = array(
1794 'title' => $node['title'],
1795 'description' => '',
1796 'text_add' => $this->lng->txt('add'),
1797 'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($node['type']))
1798 );
1799 }
1800 }
1801
1802 $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1803 $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1804 $table->setData($rows);
1805
1806 $this->tpl->setContent($table->getHTML());
1807 }
1808
1809 public function outGlossarySelector()
1810 {
1811 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1812 require_once 'Modules/Glossary/classes/class.ilObjGlossary.php';
1813
1814 $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1815
1816 $glossary = new ilObjGlossary($_GET['source_id'], true);
1817 $terms = $glossary->getTermList();
1818
1819 $rows = array();
1820
1821 foreach ($terms as $term) {
1822 $this->ctrl->setParameter($this, 'git', $term['id']);
1823 $rows[] = array(
1824 'title' => $term['term'],
1825 'description' => '',
1826 'text_add' => $this->lng->txt('add'),
1827 'href_add' => $this->ctrl->getLinkTarget($this, 'addGIT')
1828 );
1829 }
1830
1831 $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1832 $table->setTitle($this->lng->txt('glossary_term'));
1833 $table->setData($rows);
1834
1835 $this->tpl->setContent($table->getHTML());
1836 }
1837
1838 public function linkChilds()
1839 {
1840 $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1841 switch ($_GET["search_link_type"]) {
1842 case "pg":
1843 return $this->outPageSelector();
1844 break;
1845 case "st":
1846 return $this->outChapterSelector();
1847 break;
1848 case "glo":
1849 return $this->outGlossarySelector();
1850 break;
1851 case "lm":
1852 $subquestion_index = ($_GET["subquestion_index"] > 0) ? $_GET["subquestion_index"] : 0;
1853 $this->object->saveSuggestedSolution("lm", "il__lm_" . $_GET["source_id"], $subquestion_index);
1854 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1855 $this->ctrl->redirect($this, "suggestedsolution");
1856 break;
1857 }
1858 }
1859
1860 public function addPG()
1861 {
1862 $subquestion_index = 0;
1863 if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0) {
1864 $subquestion_index = $_GET["subquestion_index"];
1865 }
1866 $this->object->saveSuggestedSolution("pg", "il__pg_" . $_GET["pg"], $subquestion_index);
1867 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1868 $this->ctrl->redirect($this, "suggestedsolution");
1869 }
1870
1871 public function addST()
1872 {
1873 $subquestion_index = 0;
1874 if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0) {
1875 $subquestion_index = $_GET["subquestion_index"];
1876 }
1877 $this->object->saveSuggestedSolution("st", "il__st_" . $_GET["st"], $subquestion_index);
1878 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1879 $this->ctrl->redirect($this, "suggestedsolution");
1880 }
1881
1882 public function addGIT()
1883 {
1884 $subquestion_index = 0;
1885 if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0) {
1886 $subquestion_index = $_GET["subquestion_index"];
1887 }
1888 $this->object->saveSuggestedSolution("git", "il__git_" . $_GET["git"], $subquestion_index);
1889 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1890 $this->ctrl->redirect($this, "suggestedsolution");
1891 }
1892
1893 public function isSaveCommand()
1894 {
1895 return in_array($this->ctrl->getCmd(), array('save', 'saveEdit', 'saveReturn'));
1896 }
1897
1906 public static function getCommandsFromClassConstants($guiClassName, $cmdConstantNameBegin = 'CMD_')
1907 {
1908 $reflectionClass = new ReflectionClass($guiClassName);
1909
1910 $commands = null;
1911
1912 if ($reflectionClass instanceof ReflectionClass) {
1913 $commands = array();
1914
1915 foreach ($reflectionClass->getConstants() as $constName => $constValue) {
1916 if (substr($constName, 0, strlen($cmdConstantNameBegin)) == $cmdConstantNameBegin) {
1917 $commands[] = $constValue;
1918 }
1919 }
1920 }
1921
1922 return $commands;
1923 }
1924
1925 public function setQuestionTabs()
1926 {
1927 global $DIC;
1928 $rbacsystem = $DIC['rbacsystem'];
1929 $ilTabs = $DIC['ilTabs'];
1930
1931 $ilTabs->clearTargets();
1932
1933 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1934 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1935 $q_type = $this->object->getQuestionType();
1936
1937 if (strlen($q_type)) {
1938 $classname = $q_type . "GUI";
1939 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1940 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1941 }
1942
1943 if ($_GET["q_id"]) {
1944 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
1945 // edit page
1946 $ilTabs->addTarget(
1947 "edit_page",
1948 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1949 array("edit", "insert", "exec_pg"),
1950 "",
1951 "",
1952 $force_active
1953 );
1954 }
1955
1956 $this->addTab_QuestionPreview($ilTabs);
1957 }
1958 $force_active = false;
1959 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
1960 $url = "";
1961 if ($classname) {
1962 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1963 }
1964 $force_active = false;
1965 // edit question properties
1966 $ilTabs->addTarget(
1967 "edit_question",
1968 $url,
1970 $classname,
1971 "",
1972 $force_active
1973 );
1974 }
1975
1976 // add tab for question feedback within common class assQuestionGUI
1977 $this->addTab_QuestionFeedback($ilTabs);
1978
1979 // add tab for question hint within common class assQuestionGUI
1980 $this->addTab_QuestionHints($ilTabs);
1981
1982 // add tab for question's suggested solution within common class assQuestionGUI
1983 $this->addTab_SuggestedSolution($ilTabs, $classname);
1984
1985 // Assessment of questions sub menu entry
1986 if ($_GET["q_id"]) {
1987 $ilTabs->addTarget(
1988 "statistics",
1989 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1990 array("assessment"),
1991 $classname,
1992 ""
1993 );
1994 }
1995
1996 $this->addBackTab($ilTabs);
1997 }
1998
1999 public function addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
2000 {
2001 if ($_GET["q_id"]) {
2002 $tabs->addTarget(
2003 "suggested_solution",
2004 $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
2005 array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
2006 "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
2007 ),
2008 $classname,
2009 ""
2010 );
2011 }
2012 }
2013
2014 final public function getEditQuestionTabCommands()
2015 {
2016 return array_merge($this->getBasicEditQuestionTabCommands(), $this->getAdditionalEditQuestionCommands());
2017 }
2018
2020 {
2021 return array('editQuestion', 'save', 'saveEdit', 'originalSyncForm');
2022 }
2023
2025 {
2026 return array();
2027 }
2028
2036 {
2037 global $DIC;
2038 $ilCtrl = $DIC['ilCtrl'];
2039
2040 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionFeedbackEditingGUI.php';
2041 $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionFeedbackEditingGUI');
2042
2043 $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionFeedbackEditingGUI', ilAssQuestionFeedbackEditingGUI::CMD_SHOW);
2044
2045 $tabs->addTarget('tst_feedback', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
2046 }
2047
2051 protected function addTab_Units(ilTabsGUI $tabs)
2052 {
2056 global $DIC;
2057 $ilCtrl = $DIC['ilCtrl'];
2058
2059 $tabs->addTarget('units', $ilCtrl->getLinkTargetByClass('ilLocalUnitConfigurationGUI', ''), '', 'illocalunitconfigurationgui');
2060 }
2061
2069 {
2070 global $DIC;
2071 $ilCtrl = $DIC['ilCtrl'];
2072
2073 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsGUI.php';
2074
2075 switch ($ilCtrl->getCmdClass()) {
2076 case 'ilassquestionhintsgui':
2077
2078 $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintsGUI');
2079 break;
2080
2081 case 'ilassquestionhintgui':
2082
2083 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintGUI.php';
2084 $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintGUI');
2085 break;
2086
2087 default:
2088
2089 $tabCommands = array();
2090 }
2091
2092 $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
2093
2094 $tabs->addTarget('tst_question_hints_tab', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
2095 }
2096
2097 protected function addTab_QuestionPreview(ilTabsGUI $tabsGUI)
2098 {
2099 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionPreviewGUI.php';
2100
2101 $tabsGUI->addTarget(
2103 $this->ctrl->getLinkTargetByClass('ilAssQuestionPreviewGUI', ilAssQuestionPreviewGUI::CMD_SHOW),
2104 array(),
2105 array('ilAssQuestionPreviewGUI')
2106 );
2107 }
2108
2109 abstract public function getSolutionOutput(
2110 $active_id,
2111 $pass = null,
2112 $graphicalOutput = false,
2113 $result_output = false,
2114 $show_question_only = true,
2115 $show_feedback = false,
2116 $show_correct_solution = false,
2117 $show_manual_scoring = false,
2118 $show_question_text = true
2119 );
2120
2127 {
2128 return false;
2129 }
2130
2137 public function hasIntermediateSolution($activeId, $passIndex)
2138 {
2139 $result = $this->object->lookupForExistingSolutions($activeId, $passIndex);
2140 return ($result['intermediate']);
2141 }
2142
2147 public function setUseIntermediateSolution($use)
2148 {
2149 $this->use_intermediate_solution = (bool) $use;
2150 }
2151
2157 {
2159 }
2160
2161 protected function hasCorrectSolution($activeId, $passIndex)
2162 {
2163 $reachedPoints = $this->object->getAdjustedReachedPoints($activeId, $passIndex, true);
2164 $maximumPoints = $this->object->getMaximumPoints();
2165
2166 return $reachedPoints == $maximumPoints;
2167 }
2168
2169 public function isAutosaveable()
2170 {
2171 return $this->object->isAutosaveable();
2172 }
2173
2174 protected function writeQuestionGenericPostData()
2175 {
2176 $this->object->setTitle($_POST["title"]);
2177 $this->object->setAuthor($_POST["author"]);
2178 $this->object->setComment($_POST["comment"]);
2179 if ($this->object->getSelfAssessmentEditingMode()) {
2180 $this->object->setNrOfTries($_POST['nr_of_tries']);
2181 }
2182 $this->object->setQuestion(ilUtil::stripOnlySlashes($_POST['question'])); // ?
2183 $this->object->setEstimatedWorkingTime(
2184 $_POST["Estimated"]["hh"],
2185 $_POST["Estimated"]["mm"],
2186 $_POST["Estimated"]["ss"]
2187 );
2188 }
2189
2190 abstract public function getPreview($show_question_only = false, $showInlineFeedback = false);
2191
2200 final public function outQuestionForTest(
2201 $formaction,
2202 $active_id,
2203 // hey: prevPassSolutions - pass will be always available from now on
2204 $pass,
2205 // hey.
2206 $is_question_postponed = false,
2207 $user_post_solutions = false,
2208 $show_specific_inline_feedback = false
2209 ) {
2210 $formaction = $this->completeTestOutputFormAction($formaction, $active_id, $pass);
2211
2212 $test_output = $this->getTestOutput(
2213 $active_id,
2214 $pass,
2215 $is_question_postponed,
2216 $user_post_solutions,
2217 $show_specific_inline_feedback
2218 );
2219
2220 $this->magicAfterTestOutput();
2221
2222 $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
2223 $this->tpl->setVariable("FORMACTION", $formaction);
2224 $this->tpl->setVariable("ENCTYPE", 'enctype="' . $this->getFormEncodingType() . '"');
2225 $this->tpl->setVariable("FORM_TIMESTAMP", time());
2226 }
2227
2228 // hey: prevPassSolutions - $pass will be passed always from now on
2229 protected function completeTestOutputFormAction($formAction, $active_id, $pass)
2230 // hey.
2231 {
2232 return $formAction;
2233 }
2234
2235 public function magicAfterTestOutput()
2236 {
2237 return;
2238 }
2239
2240 abstract public function getTestOutput(
2241 $active_id,
2242 $pass,
2243 $is_question_postponed,
2244 $user_post_solutions,
2245 $show_specific_inline_feedback
2246 );
2247
2248 public function getFormEncodingType()
2249 {
2251 }
2252
2256 protected function addBackTab(ilTabsGUI $ilTabs)
2257 {
2258 if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0)) {
2259 $ref_id = $_GET["calling_test"];
2260 if (strlen($ref_id) == 0) {
2261 $ref_id = $_GET["test_ref_id"];
2262 }
2263
2264 if (!$_GET['test_express_mode'] && !$GLOBALS['___test_express_mode']) {
2265 $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
2266 } else {
2268 $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
2269 }
2270 } elseif (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer']) {
2271 $ref_id = (int) $_GET['calling_consumer'];
2272 $consumer = ilObjectFactory::getInstanceByRefId($ref_id);
2273 if ($consumer instanceof ilQuestionEditingFormConsumer) {
2274 $ilTabs->setBackTarget($consumer->getQuestionEditingFormBackTargetLabel(), $consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
2275 } else {
2276 require_once 'Services/Link/classes/class.ilLink.php';
2277 $ilTabs->setBackTarget($this->lng->txt("qpl"), ilLink::_getLink($ref_id));
2278 }
2279 } else {
2280 $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
2281 }
2282 }
2283
2288
2293 {
2294 $this->previewSession = $previewSession;
2295 }
2296
2300 public function getPreviewSession()
2301 {
2302 return $this->previewSession;
2303 }
2304
2308 protected function buildBasicEditFormObject()
2309 {
2310 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
2311 $form = new ilPropertyFormGUI();
2312
2313 $form->setFormAction($this->ctrl->getFormAction($this));
2314
2315 $form->setId($this->getType());
2316 $form->setTitle($this->outQuestionType());
2317
2318 $form->setTableWidth('100%');
2319
2320 $form->setMultipart(true);
2321
2322 return $form;
2323 }
2324
2325 public function showHints()
2326 {
2327 global $DIC;
2328 $ilCtrl = $DIC['ilCtrl'];
2329 $ilCtrl->redirectByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
2330 }
2331
2335 protected function buildEditForm()
2336 {
2337 $errors = $this->editQuestion(true); // TODO bheyser: editQuestion should be added to the abstract base class with a unified signature
2338 return $this->editForm;
2339 }
2340
2344 public function buildFocusAnchorHtml()
2345 {
2346 return '<div id="focus"></div>';
2347 }
2348
2350 {
2351 return true;
2352 }
2353
2354 public function getSubQuestionsIndex()
2355 {
2356 return array(0);
2357 }
2358
2359 public function getAnswersFrequency($relevantAnswers, $questionIndex)
2360 {
2361 return array();
2362 }
2363
2371 public function getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
2372 {
2373 require_once 'Modules/TestQuestionPool/classes/tables/class.ilAnswerFrequencyStatisticTableGUI.php';
2374
2375 $table = new ilAnswerFrequencyStatisticTableGUI($parentGui, $parentCmd, $this->object);
2376 $table->setQuestionIndex($questionIndex);
2377 $table->setData($this->getAnswersFrequency($relevantAnswers, $questionIndex));
2378 $table->initColumns();
2379
2380 return $table;
2381 }
2382
2387 {
2388 }
2389
2394 {
2395 }
2396
2401 {
2402 }
2403}
$result
$test
Definition: Utf8Test.php:84
$path
Definition: aliased.php:25
exit
Definition: backend.php:16
$_GET["client_id"]
$_POST["username"]
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
const IL_NOTE_PUBLIC
Definition: class.ilNote.php:6
Basic GUI class for assessment questions.
static _getQuestionGUI($question_type, $question_id=-1)
Creates a question gui representation and returns the alias to the question gui note: please do not u...
populateTaxonomyFormSection(ilPropertyFormGUI $form)
addNewIdListener(&$a_object, $a_method, $a_parameters="")
Add a listener that is notified with the new question ID, when a new question is saved.
callNewIdListeners($a_new_id)
Call the new id listeners.
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
const SESSION_PREVIEW_DATA_BASE_INDEX
writePostData($always=false)
Evaluates a posted edit form and writes the form data in the question object.
getContextPath($cont_obj, $a_endnode_id, $a_startnode_id=1)
get context path in content object tree
setErrorMessage($errormessage)
getSolutionOutput( $active_id, $pass=null, $graphicalOutput=false, $result_output=false, $show_question_only=true, $show_feedback=false, $show_correct_solution=false, $show_manual_scoring=false, $show_question_text=true)
getQuestionType()
Returns the question type string.
static _getClassNameForQType($q_type)
getType()
needed for page editor compliance
setEditContext($editContext)
cancel()
cancel action
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
setNavigationGUI($navigationGUI)
hasIntermediateSolution($activeId, $passIndex)
Check if the question has an intermediate solution.
setTargetGuiClass($targetGuiClass)
setQuestionCount($a_question_count)
getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
populateJavascriptFilesRequiredForWorkForm(ilTemplate $tpl)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
getILIASPage($html="")
Returns the ILIAS Page around a question.
getQuestionTemplate()
get question template
& createQuestionGUI($question_type, $question_id=-1)
Creates a question gui representation.
setTaxonomyIds($taxonomyIds)
originalSyncForm($return_to="", $return_to_feedback='')
getAsValueAttribute($a_value)
Returns a HTML value attribute.
setPreviewSession($previewSession)
setTargetGui($linkTargetGui)
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
saveReturn()
save question
prepareReprintableCorrectionsForm(ilPropertyFormGUI $form)
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
outQuestionForTest( $formaction, $active_id, $pass, $is_question_postponed=false, $user_post_solutions=false, $show_specific_inline_feedback=false)
getTestOutput( $active_id, $pass, $is_question_postponed, $user_post_solutions, $show_specific_inline_feedback)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
static _getGUIClassNameForId($a_q_id)
setPresentationContext($presentationContext)
getAnswersFrequency($relevantAnswers, $questionIndex)
setQuestionHeaderBlockBuilder($questionHeaderBlockBuilder)
addErrorMessage($errormessage)
suggestedsolution()
Allows to add suggested solutions for questions.
saveEdit()
save question
completeTestOutputFormAction($formAction, $active_id, $pass)
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
addBackTab(ilTabsGUI $ilTabs)
setPreviousSolutionPrefilled($previousSolutionPrefilled)
__construct()
assQuestionGUI constructor
setRenderPurpose($renderPurpose)
hasCorrectSolution($activeId, $passIndex)
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question,...
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
static getCommandsFromClassConstants($guiClassName, $cmdConstantNameBegin='CMD_')
extracts values of all constants of given class with given prefix as array can be used to get all pos...
setQuestionActionCmd($questionActionCmd)
executeCommand()
execute command
getPreview($show_question_only=false, $showInlineFeedback=false)
hasInlineFeedback()
this method can be overwritten per question type
$sequence_no
sequence number in test
$question_count
question count in test
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
static getFeedbackClassNameByQuestionType($questionType)
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
static _questionExistsInTest($question_id, $test_id)
static _getInternalLinkHref($target="")
static getGuiClassNameByQuestionType($questionType)
const ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
constant for additional content editing mode "pageobject"
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
static getQuestionTypeFromDb($question_id)
get question type for question id
static _isWriteable($question_id, $user_id)
Returns true if the question is writeable by a certain user.
const CMD_SHOW_LIST
command constants
Question page GUI class.
static getSelfAssessmentTags()
Get tags allowed in question tags in self assessment mode.
This class represents a checkbox property in a property form.
Class ilCommonActionDispatcherGUI.
This class represents a duration (typical hh:mm:ss) property in a property form.
This class represents a file property in a property form.
This class represents a section header in a property form.
This class represents a hidden form property in a property form.
static getPageList($lm_id)
static
Notes GUI class.
static initJavascript($a_ajax_url, $a_type=IL_NOTE_PRIVATE, ilTemplate $a_main_tpl=null)
Init javascript.
This class represents a number property in a property form.
static _getUsedHTMLTags($a_module="")
Returns an array of all allowed HTML tags for text editing.
Class ilObjContentObjectGUI.
Class ilObjGlossary.
static getManualFeedback($active_id, $question_id, $pass)
Retrieves the manual feedback for a question in a test.
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
static _lookupType($a_id, $a_reference=false)
lookup object type
This class represents a property form user interface.
Class ilQuestionUsagesTableGUI.
This class represents a property in a property form.
This class represents an option in a radio group.
This class represents a custom property in a property form.
Tabs GUI.
addTarget( $a_text, $a_link, $a_cmd="", $a_cmdClass="", $a_frame="", $a_activate=false, $a_dir_text=false)
setBackTarget($a_title, $a_target, $a_frame="")
back target for upper context
Input GUI class for taxonomy assignments.
Taxonomy node <-> item assignment.
Select taxonomy nodes input GUI.
special template class to simplify handling of ITX/PEAR
static getReturnToPageLink($q_id=null)
This class represents a text area property in a property form.
This class represents a text property in a property form.
static stripOnlySlashes($a_str)
strip slashes if magic qoutes is enabled
static redirect($a_script)
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms @access public
static renameExecutables($a_dir)
Rename uploaded executables for security reasons.
$template
if(!empty($this->data['faventry'])) $tabs
Definition: disco.tpl.php:124
$i
Definition: disco.tpl.php:19
$html
Definition: example_001.php:87
global $ilCtrl
Definition: ilias.php:18
$errors
Definition: index.php:6
$GLOBALS['JPEG_Segment_Names']
Global Variable: XMP_tag_captions.
QTI assessment class.
$ret
Definition: parser.php:6
$type
$url
if(empty($password)) $table
Definition: pwgen.php:24
if(isset($_POST['submit'])) $form
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$ilUser
Definition: imgupload.php:18
$rows
Definition: xhr_table.php:10