ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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
40 public $tpl;
41 public $lng;
42 public $error;
44
53
54 private $taxonomyIds = array();
55
56 private $targetGuiClass = null;
57
58 private $questionActionCmd = 'handleQuestionAction';
59
64
69
70 const PRESENTATION_CONTEXT_TEST = 'pContextTest';
71 const PRESENTATION_CONTEXT_RESULTS = 'pContextResults';
72
76 private $presentationContext = null;
77
78 const RENDER_PURPOSE_PLAYBACK = 'renderPurposePlayback';
79 const RENDER_PURPOSE_DEMOPLAY = 'renderPurposeDemoplay';
80 const RENDER_PURPOSE_PREVIEW = 'renderPurposePreview';
81 const RENDER_PURPOSE_PRINT_PDF = 'renderPurposePrintPdf';
82 const RENDER_PURPOSE_INPUT_VALUE = 'renderPurposeInputValue';
83
88
89 const EDIT_CONTEXT_AUTHORING = 'authoring';
90 const EDIT_CONTEXT_ADJUSTMENT = 'adjustment';
91
96
97 // hey: prevPassSolutions - flag to indicate that a previous answer is shown
102 // hey.
103
107 protected $editForm;
108
113 protected $use_intermediate_solution = false;
114
118 public function __construct()
119 {
120 global $DIC;
121 $lng = $DIC['lng'];
122 $tpl = $DIC['tpl'];
123 $ilCtrl = $DIC['ilCtrl'];
124
125 $this->lng = &$lng;
126 $this->tpl = &$tpl;
127 $this->ctrl = &$ilCtrl;
128 $this->ctrl->saveParameter($this, "q_id");
129 $this->ctrl->saveParameter($this, "prev_qid");
130 $this->ctrl->saveParameter($this, "calling_test");
131 $this->ctrl->saveParameter($this, "calling_consumer");
132 $this->ctrl->saveParameter($this, "consumer_context");
133 $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'test_express_mode');
134 $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'calling_consumer');
135 $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'consumer_context');
136 $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'test_express_mode');
137 $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'calling_consumer');
138 $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'consumer_context');
139
140 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
141 $this->errormessage = $this->lng->txt("fill_out_all_required_fields");
142
143 $this->selfassessmenteditingmode = false;
144 $this->new_id_listeners = array();
145 $this->new_id_listener_cnt = 0;
146
147 $this->navigationGUI = null;
148 }
149
155 public function hasInlineFeedback()
156 {
157 return false;
158 }
159
160 public function addHeaderAction()
161 {
162 global $DIC; /* @var ILIAS\DI\Container $DIC */
163
164 $DIC->ui()->mainTemplate()->setVariable(
165 "HEAD_ACTION",
166 $this->getHeaderAction()
167 );
168
169 $notesUrl = $this->ctrl->getLinkTargetByClass(
170 array("ilcommonactiondispatchergui", "ilnotegui"),
171 "",
172 "",
173 true,
174 false
175 );
176
177 ilNoteGUI::initJavascript($notesUrl, IL_NOTE_PUBLIC, $DIC->ui()->mainTemplate());
178
179 $redrawActionsUrl = $DIC->ctrl()->getLinkTarget($this, 'redrawHeaderAction', '', true);
180 $DIC->ui()->mainTemplate()->addOnLoadCode("il.Object.setRedrawAHUrl('$redrawActionsUrl');");
181 }
182
183 public function redrawHeaderAction()
184 {
185 global $DIC; /* @var ILIAS\DI\Container $DIC */
186 echo $this->getHeaderAction() . $DIC->ui()->mainTemplate()->getOnLoadCodeForAsynch();
187 exit;
188 }
189
190 public function getHeaderAction()
191 {
192 global $DIC; /* @var ILIAS\DI\Container $DIC */
193 /* @var ilObjectDataCache $ilObjDataCache */
194 $ilObjDataCache = $DIC['ilObjDataCache'];
195
196 $parentObjType = $ilObjDataCache->lookupType($this->object->getObjId());
197
198 $dispatcher = new ilCommonActionDispatcherGUI(
200 $DIC->access(),
201 $parentObjType,
202 $_GET["ref_id"],
203 $this->object->getObjId()
204 );
205
206 $dispatcher->setSubObject("quest", $this->object->getId());
207
208 $ha = $dispatcher->initHeaderAction();
209 $ha->enableComments(true, false);
210
211 return $ha->getHeaderAction($DIC->ui()->mainTemplate());
212 }
213
214 public function getNotesHTML()
215 {
216 $notesGUI = new ilNoteGUI($this->object->getObjId(), $this->object->getId(), 'quest');
217 $notesGUI->enablePublicNotes(true);
218 $notesGUI->enablePublicNotesDeletion(true);
219
220 return $notesGUI->getNotesHTML();
221 }
222
226 public function executeCommand()
227 {
228 global $DIC; /* @var \ILIAS\DI\Container $DIC */
229 $ilHelp = $DIC['ilHelp']; /* @var ilHelpGUI $ilHelp */
230 $ilHelp->setScreenIdComponent('qpl');
231
232 $cmd = $this->ctrl->getCmd("editQuestion");
233 $next_class = $this->ctrl->getNextClass($this);
234
235 $cmd = $this->getCommand($cmd);
236
237 switch ($next_class) {
238 case 'ilformpropertydispatchgui':
239 $form = $this->buildEditForm();
240
241 require_once 'Services/Form/classes/class.ilFormPropertyDispatchGUI.php';
242 $form_prop_dispatch = new ilFormPropertyDispatchGUI();
243 $form_prop_dispatch->setItem($form->getItemByPostVar(ilUtil::stripSlashes($_GET['postvar'])));
244 return $this->ctrl->forwardCommand($form_prop_dispatch);
245 break;
246
247 default:
248 $ret = $this->$cmd();
249 break;
250 }
251 return $ret;
252 }
253
254 public function getCommand($cmd)
255 {
256 return $cmd;
257 }
258
262 public function getType()
263 {
264 return $this->getQuestionType();
265 }
266
270 public function getPresentationContext()
271 {
273 }
274
279 {
280 $this->presentationContext = $presentationContext;
281 }
282
284 {
286 }
287
288 // hey: previousPassSolutions - setter/getter for Previous Solution Prefilled flag
293 {
295 }
296
301 {
302 $this->previousSolutionPrefilled = $previousSolutionPrefilled;
303 }
304 // hey.
305
309 public function getRenderPurpose()
310 {
312 }
313
318 {
319 $this->renderPurpose = $renderPurpose;
320 }
321
322 public function isRenderPurposePrintPdf()
323 {
325 }
326
327 public function isRenderPurposePreview()
328 {
330 }
331
333 {
335 }
336
337 public function isRenderPurposePlayback()
338 {
340 }
341
342 public function isRenderPurposeDemoplay()
343 {
345 }
346
348 {
349 if ($this->isRenderPurposePrintPdf()) {
350 return false;
351 }
352
353 if ($this->isRenderPurposeInputValue()) {
354 return false;
355 }
356
357 return true;
358 }
359
363 public function getEditContext()
364 {
365 return $this->editContext;
366 }
367
372 {
373 $this->editContext = $editContext;
374 }
375
379 public function isAuthoringEditContext()
380 {
382 }
383
387 public function isAdjustmentEditContext()
388 {
390 }
391
392 public function setAdjustmentEditContext()
393 {
394 return $this->setEditContext(self::EDIT_CONTEXT_ADJUSTMENT);
395 }
396
400 public function getNavigationGUI()
401 {
403 }
404
409 {
410 $this->navigationGUI = $navigationGUI;
411 }
412
414 {
415 $this->taxonomyIds = $taxonomyIds;
416 }
417
418 public function getTaxonomyIds()
419 {
420 return $this->taxonomyIds;
421 }
422
423 public function setTargetGui($linkTargetGui)
424 {
425 $this->setTargetGuiClass(get_class($linkTargetGui));
426 }
427
429 {
430 $this->targetGuiClass = $targetGuiClass;
431 }
432
433 public function getTargetGuiClass()
434 {
436 }
437
442 {
443 $this->questionHeaderBlockBuilder = $questionHeaderBlockBuilder;
444 }
445
446 // fau: testNav - get the question header block bulder (for tweaking)
451 {
453 }
454 // fau.
455
457 {
458 $this->questionActionCmd = $questionActionCmd;
459
460 if (is_object($this->object)) {
461 $this->object->questionActionCmd = $questionActionCmd;
462 }
463 }
464
465 public function getQuestionActionCmd()
466 {
468 }
469
474 protected function writePostData($always = false)
475 {
476 }
477
481 public function assessment()
482 {
486 global $DIC;
487 $tpl = $DIC['tpl'];
488
489 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionCumulatedStatisticsTableGUI.php';
490 $stats_table = new ilQuestionCumulatedStatisticsTableGUI($this, 'assessment', '', $this->object);
491
492 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionUsagesTableGUI.php';
493 $usage_table = new ilQuestionUsagesTableGUI($this, 'assessment', '', $this->object);
494
495 $tpl->setContent(implode('<br />', array(
496 $stats_table->getHTML(),
497 $usage_table->getHTML()
498 )));
499 }
500
510 public static function _getQuestionGUI($question_type, $question_id = -1)
511 {
512 global $DIC;
513 $ilCtrl = $DIC['ilCtrl'];
514 $ilDB = $DIC['ilDB'];
515 $lng = $DIC['lng'];
516
517 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
518
519 if ((!$question_type) and ($question_id > 0)) {
520 $question_type = assQuestion::getQuestionTypeFromDb($question_id);
521 }
522
523 if (strlen($question_type) == 0) {
524 return null;
525 }
526
527 assQuestion::_includeClass($question_type, 1);
528
529 $question_type_gui = assQuestion::getGuiClassNameByQuestionType($question_type);
530 $question = new $question_type_gui();
531
532 $feedbackObjectClassname = assQuestion::getFeedbackClassNameByQuestionType($question_type);
533 $question->object->feedbackOBJ = new $feedbackObjectClassname($question->object, $ilCtrl, $ilDB, $lng);
534
535 if ($question_id > 0) {
536 $question->object->loadFromDb($question_id);
537 }
538
539 return $question;
540 }
541
545 public static function _getGUIClassNameForId($a_q_id)
546 {
547 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
548 include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
549 $q_type = assQuestion::getQuestionTypeFromDb($a_q_id);
550 $class_name = assQuestionGUI::_getClassNameForQType($q_type);
551 return $class_name;
552 }
553
557 public static function _getClassNameForQType($q_type)
558 {
559 return $q_type . "GUI";
560 }
561
574 public function &createQuestionGUI($question_type, $question_id = -1)
575 {
576 include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
577 $this->question = &assQuestionGUI::_getQuestionGUI($question_type, $question_id);
578 }
579
581 {
582 foreach ($this->getPresentationJavascripts() as $jsFile) {
583 $tpl->addJavaScript($jsFile);
584 }
585 }
586
588 {
589 return array();
590 }
591
595 public function getQuestionTemplate()
596 {
597 // @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)
598 if (!$this->tpl->blockExists('content')) {
599 $this->tpl->addBlockFile("CONTENT", "content", "tpl.il_as_qpl_content.html", "Modules/TestQuestionPool");
600 }
601 // @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)
602 if (!$this->tpl->blockExists('statusline')) {
603 $this->tpl->addBlockFile("STATUSLINE", "statusline", "tpl.statusline.html");
604 }
605 // @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
606 if (!$this->tpl->blockExists('adm_content')) {
607 $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_as_question.html", "Modules/TestQuestionPool");
608 }
609 }
610
614 protected function renderEditForm($form)
615 {
616 $this->getQuestionTemplate();
617 $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
618 }
619
626 public function getILIASPage($html = "")
627 {
628 include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
629 $page_gui = new ilAssQuestionPageGUI($this->object->getId());
630 $page_gui->setQuestionHTML(array($this->object->getId() => $html));
631 $presentation = $page_gui->presentation();
632 $presentation = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $presentation);
633 return $presentation;
634 }
635
639 public function outQuestionPage($a_temp_var, $a_postponed = false, $active_id = "", $html = "", $inlineFeedbackEnabled = false)
640 {
641 // hey: prevPassSolutions - add the "use previous answer"
642 // hey: prevPassSolutions - refactored identifiers
643 if ($this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled()) {
644 // hey
647 } elseif // (!) --> if ($this->object->getTestQuestionConfig()->isUnchangedAnswerPossible())
648 // hey.
649// fau: testNav - add the "use unchanged answer checkbox"
650 // hey: prevPassSolutions - refactored identifiers
651 ($this->object->getTestPresentationConfig()->isUnchangedAnswerPossible()) {
652 // hey.
653 $html .= $this->getUseUnchangedAnswerCheckboxHtml();
654 }
655 // fau.
656
657 $this->lng->loadLanguageModule("content");
658
659 // fau: testNav - add question buttons below question, add actions menu
660 include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
661 $page_gui = new ilAssQuestionPageGUI($this->object->getId());
662 $page_gui->setOutputMode("presentation");
663 $page_gui->setTemplateTargetVar($a_temp_var);
664
665 if ($this->getNavigationGUI()) {
666 $html .= $this->getNavigationGUI()->getHTML();
667 $page_gui->setQuestionActionsHTML($this->getNavigationGUI()->getActionsHTML());
668 }
669 // fau.
670
671 if (strlen($html)) {
672 if ($inlineFeedbackEnabled && $this->hasInlineFeedback()) {
673 $html = $this->buildFocusAnchorHtml() . $html;
674 }
675
676 $page_gui->setQuestionHTML(array($this->object->getId() => $html));
677 }
678
679 // fau: testNav - fill the header with subtitle blocks for question info an actions
680 $page_gui->setPresentationTitle($this->questionHeaderBlockBuilder->getPresentationTitle());
681 $page_gui->setQuestionInfoHTML($this->questionHeaderBlockBuilder->getQuestionInfoHTML());
682 // fau.
683
684 return $page_gui->presentation();
685 }
686
687 // fau: testNav - get the html of the "use unchanged answer checkbox"
689 {
690 // hey: prevPassSolutions - use abstracted template to share with other purposes of this kind
691 $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
692 $tpl->setVariable('TXT_FORCE_FORM_DIFF_LABEL', $this->object->getTestPresentationConfig()->getUseUnchangedAnswerLabel());
693 // hey.
694 return $tpl->get();
695 }
696 // fau.
697
698 // hey: prevPassSolutions - build prev solution message / build "use previous answer checkbox" html
700 {
701 return $this->lng->txt('use_previous_solution_advice');
702 }
703
705 {
706 $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
707 // hey: prevPassSolutions - use abtract template
708 $tpl->setVariable('TXT_FORCE_FORM_DIFF_LABEL', $this->lng->txt('use_previous_solution'));
709 // hey.
710 return $tpl->get();
711 }
712 // hey.
713
717 public function cancel()
718 {
719 if ($_GET["calling_test"]) {
720 $_GET["ref_id"] = $_GET["calling_test"];
721 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
722 } elseif ($_GET["test_ref_id"]) {
723 $_GET["ref_id"] = $_GET["test_ref_id"];
724 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["test_ref_id"]);
725 } else {
726 if ($_GET["q_id"] > 0) {
727 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
728 $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
729 } else {
730 $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
731 }
732 }
733 }
734
739 public function originalSyncForm($return_to = "", $return_to_feedback = '')
740 {
741 if (strlen($return_to)) {
742 $this->ctrl->setParameter($this, "return_to", $return_to);
743 } elseif ($_REQUEST['return_to']) {
744 $this->ctrl->setParameter($this, "return_to", $_REQUEST['return_to']);
745 }
746 if (strlen($return_to_feedback)) {
747 $this->ctrl->setParameter($this, 'return_to_fb', 'true');
748 }
749
750 $this->ctrl->saveParameter($this, 'test_express_mode');
751
752 $template = new ilTemplate("tpl.il_as_qpl_sync_original.html", true, true, "Modules/TestQuestionPool");
753 $template->setVariable("BUTTON_YES", $this->lng->txt("yes"));
754 $template->setVariable("BUTTON_NO", $this->lng->txt("no"));
755 $template->setVariable("FORM_ACTION", $this->ctrl->getFormAction($this));
756 $template->setVariable("TEXT_SYNC", $this->lng->txt("confirm_sync_questions"));
757 $this->tpl->setVariable("ADM_CONTENT", $template->get());
758 }
759
760 public function sync()
761 {
762 $original_id = $this->object->original_id;
763 if ($original_id) {
764 $this->object->syncWithOriginal();
765 }
766 if (strlen($_GET["return_to"])) {
767 $this->ctrl->redirect($this, $_GET["return_to"]);
768 }
769 if (strlen($_REQUEST["return_to_fb"])) {
770 $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
771 } else {
772 if (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer']) {
773 $ref_id = (int) $_GET['calling_consumer'];
774 $consumer = ilObjectFactory::getInstanceByRefId($ref_id);
775 if ($consumer instanceof ilQuestionEditingFormConsumer) {
776 ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
777 }
778 require_once 'Services/Link/classes/class.ilLink.php';
780 }
781 $_GET["ref_id"] = $_GET["calling_test"];
782
783 if ($_REQUEST['test_express_mode']) {
785 } else {
786 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
787 }
788 }
789 }
790
791 public function cancelSync()
792 {
793 if (strlen($_GET["return_to"])) {
794 $this->ctrl->redirect($this, $_GET["return_to"]);
795 }
796 if (strlen($_REQUEST['return_to_fb'])) {
797 $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
798 } else {
799 if (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer']) {
800 $ref_id = (int) $_GET['calling_consumer'];
801 $consumer = ilObjectFactory::getInstanceByRefId($ref_id);
802 if ($consumer instanceof ilQuestionEditingFormConsumer) {
803 ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
804 }
805 require_once 'Services/Link/classes/class.ilLink.php';
807 }
808 $_GET["ref_id"] = $_GET["calling_test"];
809
810 if ($_REQUEST['test_express_mode']) {
812 } else {
813 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
814 }
815 }
816 }
817
821 public function saveEdit()
822 {
823 global $DIC;
824 $ilUser = $DIC['ilUser'];
825
826 $result = $this->writePostData();
827 if ($result == 0) {
828 $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
829 $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
830 $this->object->saveToDb();
831 $originalexists = $this->object->_questionExists($this->object->original_id);
832 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
833 if ($_GET["calling_test"] && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
834 $this->ctrl->redirect($this, "originalSyncForm");
835 } elseif ($_GET["calling_test"]) {
836 $_GET["ref_id"] = $_GET["calling_test"];
837 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
838 return;
839 } elseif ($_GET["test_ref_id"]) {
840 global $DIC;
841 $tree = $DIC['tree'];
842 $ilDB = $DIC['ilDB'];
843 $ilPluginAdmin = $DIC['ilPluginAdmin'];
844
845 include_once("./Modules/Test/classes/class.ilObjTest.php");
846 $_GET["ref_id"] = $_GET["test_ref_id"];
847 $test = new ilObjTest($_GET["test_ref_id"], true);
848
849 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
850 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
851
852 $test->insertQuestion($testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId());
853
854 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["test_ref_id"]);
855 } else {
856 $this->ctrl->setParameter($this, "q_id", $this->object->getId());
857 $this->editQuestion();
858 if (strcmp($_SESSION["info"], "") != 0) {
859 ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), false);
860 } else {
861 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), false);
862 }
863 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $this->object->getId());
864 $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
865 }
866 }
867 }
868
872 public function save()
873 {
874 global $DIC;
875 $ilUser = $DIC['ilUser'];
876 $old_id = $_GET["q_id"];
877 $result = $this->writePostData();
878
879 if ($result == 0) {
880 $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
881 $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
882 $this->object->saveToDb();
883 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
884
885
886 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
887 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
888 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
889 $this->ctrl->setParameter($this, 'return_to', 'editQuestion');
890 $this->ctrl->redirect($this, "originalSyncForm");
891 return;
892 } elseif ($_GET["calling_test"]) {
893 require_once 'Modules/Test/classes/class.ilObjTest.php';
894 $test = new ilObjTest($_GET["calling_test"]);
895 if (!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId())) {
896 global $DIC;
897 $tree = $DIC['tree'];
898 $ilDB = $DIC['ilDB'];
899 $ilPluginAdmin = $DIC['ilPluginAdmin'];
900
901 include_once("./Modules/Test/classes/class.ilObjTest.php");
902 $_GET["ref_id"] = $_GET["calling_test"];
903 $test = new ilObjTest($_GET["calling_test"], true);
904
905 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
906 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
907
908 $new_id = $test->insertQuestion(
909 $testQuestionSetConfigFactory->getQuestionSetConfig(),
910 $this->object->getId()
911 );
912
913 if (isset($_REQUEST['prev_qid'])) {
914 $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
915 }
916
917 $this->ctrl->setParameter($this, 'q_id', $new_id);
918 $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
919 #$this->ctrl->setParameter($this, 'test_ref_id', false);
920 }
921 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
922 $this->ctrl->redirect($this, 'editQuestion');
923 } else {
924 $this->callNewIdListeners($this->object->getId());
925
926 if ($this->object->getId() != $old_id) {
927 // first save
928 $this->ctrl->setParameterByClass($_GET["cmdClass"], "q_id", $this->object->getId());
929 $this->ctrl->setParameterByClass($_GET["cmdClass"], "sel_question_types", $_GET["sel_question_types"]);
930 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
931
932 //global $___test_express_mode;
936 if ($_REQUEST['prev_qid']) {
937 // @todo: bheyser/mbecker wtf? ..... thx@jposselt ....
938 // mbecker: Possible fix: Just instantiate the obj?
939 include_once("./Modules/Test/classes/class.ilObjTest.php");
940 $test = new ilObjTest($_GET["ref_id"], true);
941 $test->moveQuestionAfter($_REQUEST['prev_qid'], $this->object->getId());
942 }
943 if ( /*$___test_express_mode || */ $_REQUEST['express_mode']) {
944 global $DIC;
945 $tree = $DIC['tree'];
946 $ilDB = $DIC['ilDB'];
947 $ilPluginAdmin = $DIC['ilPluginAdmin'];
948
949 include_once("./Modules/Test/classes/class.ilObjTest.php");
950 $test = new ilObjTest($_GET["ref_id"], true);
951
952 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
953 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
954
955 $test->insertQuestion(
956 $testQuestionSetConfigFactory->getQuestionSetConfig(),
957 $this->object->getId()
958 );
959
960 require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
961 $_REQUEST['q_id'] = $this->object->getId();
963 }
964
965 $this->ctrl->redirectByClass($_GET["cmdClass"], "editQuestion");
966 }
967 if (strcmp($_SESSION["info"], "") != 0) {
968 ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
969 } else {
970 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
971 }
972 $this->ctrl->redirect($this, 'editQuestion');
973 }
974 }
975 }
976
980 public function saveReturn()
981 {
982 global $DIC;
983 $ilUser = $DIC['ilUser'];
984 $old_id = $_GET["q_id"];
985 $result = $this->writePostData();
986 if ($result == 0) {
987 $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
988 $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
989 $this->object->saveToDb();
990 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
991 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
992 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
993 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
994 $this->ctrl->setParameter($this, 'test_express_mode', $_REQUEST['test_express_mode']);
995 $this->ctrl->redirect($this, "originalSyncForm");
996 return;
997 } elseif ($_GET["calling_test"]) {
998 require_once 'Modules/Test/classes/class.ilObjTest.php';
999 $test = new ilObjTest($_GET["calling_test"]);
1000 #var_dump(assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()));
1001 $q_id = $this->object->getId();
1002 if (!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId())) {
1003 global $DIC;
1004 $tree = $DIC['tree'];
1005 $ilDB = $DIC['ilDB'];
1006 $ilPluginAdmin = $DIC['ilPluginAdmin'];
1007
1008 include_once("./Modules/Test/classes/class.ilObjTest.php");
1009 $_GET["ref_id"] = $_GET["calling_test"];
1010 $test = new ilObjTest($_GET["calling_test"], true);
1011
1012 require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
1013 $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
1014
1015 $new_id = $test->insertQuestion(
1016 $testQuestionSetConfigFactory->getQuestionSetConfig(),
1017 $this->object->getId()
1018 );
1019
1020 $q_id = $new_id;
1021 if (isset($_REQUEST['prev_qid'])) {
1022 $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
1023 }
1024
1025 $this->ctrl->setParameter($this, 'q_id', $new_id);
1026 $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
1027 #$this->ctrl->setParameter($this, 'test_ref_id', false);
1028 }
1029 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1030 if ( /*$___test_express_mode || */
1031 $_REQUEST['test_express_mode']
1032 ) {
1034 } else {
1035 ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
1036 }
1037 } else {
1038 if ($this->object->getId() != $old_id) {
1039 $this->callNewIdListeners($this->object->getId());
1040 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1041 $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
1042 }
1043 if (strcmp($_SESSION["info"], "") != 0) {
1044 ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
1045 } else {
1046 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1047 }
1048 $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
1049 }
1050 }
1051 }
1052
1056 public function apply()
1057 {
1058 $this->writePostData();
1059 $this->object->saveToDb();
1060 $this->ctrl->setParameter($this, "q_id", $this->object->getId());
1061 $this->editQuestion();
1062 }
1063
1070 public function getContextPath($cont_obj, $a_endnode_id, $a_startnode_id = 1)
1071 {
1072 $path = "";
1073
1074 $tmpPath = $cont_obj->getLMTree()->getPathFull($a_endnode_id, $a_startnode_id);
1075
1076 // count -1, to exclude the learning module itself
1077 for ($i = 1; $i < (count($tmpPath) - 1); $i++) {
1078 if ($path != "") {
1079 $path .= " > ";
1080 }
1081
1082 $path .= $tmpPath[$i]["title"];
1083 }
1084
1085 return $path;
1086 }
1087
1088 public function setSequenceNumber($nr)
1089 {
1090 $this->sequence_no = $nr;
1091 }
1092
1093 public function getSequenceNumber()
1094 {
1095 return $this->sequence_no;
1096 }
1097
1098 public function setQuestionCount($a_question_count)
1099 {
1100 $this->question_count = $a_question_count;
1101 }
1102
1103 public function getQuestionCount()
1104 {
1105 return $this->question_count;
1106 }
1107
1108 public function getErrorMessage()
1109 {
1110 return $this->errormessage;
1111 }
1112
1114 {
1115 $this->errormessage = $errormessage;
1116 }
1117
1119 {
1120 $this->errormessage .= ((strlen($this->errormessage)) ? "<br />" : "") . $errormessage;
1121 }
1122
1123 public function outAdditionalOutput()
1124 {
1125 }
1126
1135 public function getQuestionType()
1136 {
1137 return $this->object->getQuestionType();
1138 }
1139
1147 public function getAsValueAttribute($a_value)
1148 {
1149 $result = "";
1150 if (strlen($a_value)) {
1151 $result = " value=\"$a_value\" ";
1152 }
1153 return $result;
1154 }
1155
1156 // scorm2004-start
1161 public function addNewIdListener(&$a_object, $a_method, $a_parameters = "")
1162 {
1163 $cnt = $this->new_id_listener_cnt;
1164 $this->new_id_listeners[$cnt]["object"] = &$a_object;
1165 $this->new_id_listeners[$cnt]["method"] = $a_method;
1166 $this->new_id_listeners[$cnt]["parameters"] = $a_parameters;
1167 $this->new_id_listener_cnt++;
1168 }
1169
1173 public function callNewIdListeners($a_new_id)
1174 {
1175 for ($i = 0; $i < $this->new_id_listener_cnt; $i++) {
1176 $this->new_id_listeners[$i]["parameters"]["new_id"] = $a_new_id;
1177 $object = &$this->new_id_listeners[$i]["object"];
1178 $method = $this->new_id_listeners[$i]["method"];
1179 $parameters = $this->new_id_listeners[$i]["parameters"];
1180 //var_dump($object);
1181 //var_dump($method);
1182 //var_dump($parameters);
1183
1184 $object->$method($parameters);
1185 }
1186 }
1187
1191 public function addQuestionFormCommandButtons($form)
1192 {
1193 //if (!$this->object->getSelfAssessmentEditingMode() && !$_GET["calling_test"]) $form->addCommandButton("saveEdit", $this->lng->txt("save_edit"));
1194 if (!$this->object->getSelfAssessmentEditingMode()) {
1195 $form->addCommandButton("saveReturn", $this->lng->txt("save_return"));
1196 }
1197 $form->addCommandButton("save", $this->lng->txt("save"));
1198 }
1199
1206 public function addBasicQuestionFormProperties($form)
1207 {
1208 // title
1209 $title = new ilTextInputGUI($this->lng->txt("title"), "title");
1210 $title->setMaxLength(100);
1211 $title->setValue($this->object->getTitle());
1212 $title->setRequired(true);
1213 $form->addItem($title);
1214
1215 if (!$this->object->getSelfAssessmentEditingMode()) {
1216 // author
1217 $author = new ilTextInputGUI($this->lng->txt("author"), "author");
1218 $author->setValue($this->object->getAuthor());
1219 $author->setRequired(true);
1220 $form->addItem($author);
1221
1222 // description
1223 $description = new ilTextInputGUI($this->lng->txt("description"), "comment");
1224 $description->setValue($this->object->getComment());
1225 $description->setRequired(false);
1226 $form->addItem($description);
1227 } else {
1228 // author as hidden field
1229 $hi = new ilHiddenInputGUI("author");
1230 $author = ilUtil::prepareFormOutput($this->object->getAuthor());
1231 if (trim($author) == "") {
1232 $author = "-";
1233 }
1234 $hi->setValue($author);
1235 $form->addItem($hi);
1236 }
1237
1238 // lifecycle
1239 $lifecycle = new ilSelectInputGUI($this->lng->txt('qst_lifecycle'), 'lifecycle');
1240 $lifecycle->setOptions($this->object->getLifecycle()->getSelectOptions($this->lng));
1241 $lifecycle->setValue($this->object->getLifecycle()->getIdentifier());
1242 $form->addItem($lifecycle);
1243
1244 // questiontext
1245 $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
1246 $question->setValue($this->object->getQuestion());
1247 $question->setRequired(true);
1248 $question->setRows(10);
1249 $question->setCols(80);
1250
1251 if (!$this->object->getSelfAssessmentEditingMode()) {
1252 if ($this->object->getAdditionalContentEditingMode() != assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT) {
1253 $question->setUseRte(true);
1254 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
1255 $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
1256 $question->addPlugin("latex");
1257 $question->addButton("latex");
1258 $question->addButton("pastelatex");
1259 $question->setRTESupport($this->object->getId(), "qpl", "assessment");
1260 }
1261 } else {
1262 require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
1264 $question->setUseTagsForRteOnly(false);
1265 }
1266 $form->addItem($question);
1267
1268 if (!$this->object->getSelfAssessmentEditingMode()) {
1269 // duration
1270 $duration = new ilDurationInputGUI($this->lng->txt("working_time"), "Estimated");
1271 $duration->setShowHours(true);
1272 $duration->setShowMinutes(true);
1273 $duration->setShowSeconds(true);
1274 $ewt = $this->object->getEstimatedWorkingTime();
1275 $duration->setHours($ewt["h"]);
1276 $duration->setMinutes($ewt["m"]);
1277 $duration->setSeconds($ewt["s"]);
1278 $duration->setRequired(false);
1279 $form->addItem($duration);
1280 } else {
1281 // number of tries
1282 if (strlen($this->object->getNrOfTries())) {
1283 $nr_tries = $this->object->getNrOfTries();
1284 } else {
1285 $nr_tries = $this->object->getDefaultNrOfTries();
1286 }
1287 if ($nr_tries < 1) {
1288 $nr_tries = "";
1289 }
1290
1291 $ni = new ilNumberInputGUI($this->lng->txt("qst_nr_of_tries"), "nr_of_tries");
1292 $ni->setValue($nr_tries);
1293 $ni->setMinValue(0);
1294 $ni->setSize(5);
1295 $ni->setMaxLength(5);
1296 $form->addItem($ni);
1297 }
1298 }
1299
1300 protected function saveTaxonomyAssignments()
1301 {
1302 if (count($this->getTaxonomyIds())) {
1303 require_once 'Services/Taxonomy/classes/class.ilTaxAssignInputGUI.php';
1304
1305 foreach ($this->getTaxonomyIds() as $taxonomyId) {
1306 $postvar = "tax_node_assign_$taxonomyId";
1307
1308 $tax_node_assign = new ilTaxAssignInputGUI($taxonomyId, true, '', $postvar);
1309 // TODO: determine tst/qpl when tax assigns become maintainable within tests
1310 $tax_node_assign->saveInput("qpl", $this->object->getObjId(), "quest", $this->object->getId());
1311 }
1312 }
1313 }
1314
1316 {
1317 if (count($this->getTaxonomyIds())) {
1318 // this is needed by ilTaxSelectInputGUI in some cases
1319 require_once 'Services/UIComponent/Overlay/classes/class.ilOverlayGUI.php';
1320 ilOverlayGUI::initJavaScript();
1321
1322 $sectHeader = new ilFormSectionHeaderGUI();
1323 $sectHeader->setTitle($this->lng->txt('qpl_qst_edit_form_taxonomy_section'));
1324 $form->addItem($sectHeader);
1325
1326 require_once 'Services/Taxonomy/classes/class.ilTaxSelectInputGUI.php';
1327
1328 foreach ($this->getTaxonomyIds() as $taxonomyId) {
1329 $taxonomy = new ilObjTaxonomy($taxonomyId);
1330 $label = sprintf($this->lng->txt('qpl_qst_edit_form_taxonomy'), $taxonomy->getTitle());
1331 $postvar = "tax_node_assign_$taxonomyId";
1332
1333 $taxSelect = new ilTaxSelectInputGUI($taxonomy->getId(), $postvar, true);
1334 $taxSelect->setTitle($label);
1335
1336 require_once 'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
1337 $taxNodeAssignments = new ilTaxNodeAssignment(ilObject::_lookupType($this->object->getObjId()), $this->object->getObjId(), 'quest', $taxonomyId);
1338 $assignedNodes = $taxNodeAssignments->getAssignmentsOfItem($this->object->getId());
1339
1340 $taxSelect->setValue(array_map(function ($assignedNode) {
1341 return $assignedNode['node_id'];
1342 }, $assignedNodes));
1343 $form->addItem($taxSelect);
1344 }
1345 }
1346 }
1347
1357 public function getAnswerFeedbackOutput($active_id, $pass)
1358 {
1359 return $this->getGenericFeedbackOutput($active_id, $pass);
1360 }
1361
1371 public function getGenericFeedbackOutput($active_id, $pass)
1372 {
1373 $output = "";
1374 include_once "./Modules/Test/classes/class.ilObjTest.php";
1375 $manual_feedback = ilObjTest::getManualFeedback($active_id, $this->object->getId(), $pass);
1376 if (strlen($manual_feedback)) {
1377 return $manual_feedback;
1378 }
1379 $correct_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true);
1380 $incorrect_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false);
1381 if (strlen($correct_feedback . $incorrect_feedback)) {
1382 $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
1383 $max_points = $this->object->getMaximumPoints();
1384 if ($reached_points == $max_points) {
1385 $output = $correct_feedback;
1386 } else {
1387 $output = $incorrect_feedback;
1388 }
1389 }
1390 return $this->object->prepareTextareaOutput($output, true);
1391 }
1392
1394 {
1395 return $this->object->prepareTextareaOutput(
1396 $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true),
1397 true
1398 );
1399 }
1400
1402 {
1403 return $this->object->prepareTextareaOutput(
1404 $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false),
1405 true
1406 );
1407 }
1408
1419 abstract public function getSpecificFeedbackOutput($userSolution);
1420
1421 public function outQuestionType()
1422 {
1423 $count = $this->object->isInUse();
1424
1425 if ($this->object->_questionExistsInPool($this->object->getId()) && $count) {
1426 global $DIC;
1427 $rbacsystem = $DIC['rbacsystem'];
1428 if ($rbacsystem->checkAccess("write", $_GET["ref_id"])) {
1429 ilUtil::sendInfo(sprintf($this->lng->txt("qpl_question_is_in_use"), $count));
1430 }
1431 }
1432
1433 return assQuestion::_getQuestionTypeName($this->object->getQuestionType());
1434 }
1435
1436 public function showSuggestedSolution()
1437 {
1438 $this->suggestedsolution();
1439 }
1440
1446 public function suggestedsolution()
1447 {
1448 global $DIC;
1449 $ilUser = $DIC['ilUser'];
1450 global $DIC;
1451 $ilAccess = $DIC['ilAccess'];
1452
1453 $save = (is_array($_POST["cmd"]) && array_key_exists("suggestedsolution", $_POST["cmd"])) ? true : false;
1454
1455 if ($save && $_POST["deleteSuggestedSolution"] == 1) {
1456 $this->object->deleteSuggestedSolutions();
1457 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1458 $this->ctrl->redirect($this, "suggestedsolution");
1459 }
1460
1461 $output = "";
1462 $solution_array = $this->object->getSuggestedSolution(0);
1463 $options = array(
1464 "lm" => $this->lng->txt("obj_lm"),
1465 "st" => $this->lng->txt("obj_st"),
1466 "pg" => $this->lng->txt("obj_pg"),
1467 "git" => $this->lng->txt("glossary_term"),
1468 "file" => $this->lng->txt("fileDownload"),
1469 "text" => $this->lng->txt("solutionText")
1470 );
1471
1472 if ((strcmp($_POST["solutiontype"], "file") == 0) && (strcmp($solution_array["type"], "file") != 0)) {
1473 $solution_array = array(
1474 "type" => "file"
1475 );
1476 } elseif ((strcmp($_POST["solutiontype"], "text") == 0) && (strcmp($solution_array["type"], "text") != 0)) {
1477 $oldOutputMode = $this->getRenderPurpose();
1478 $this->setRenderPurpose(self::RENDER_PURPOSE_INPUT_VALUE);
1479
1480 $solution_array = array(
1481 "type" => "text",
1482 "value" => $this->getSolutionOutput(0, null, false, false, true, false, true)
1483 );
1484 $this->setRenderPurpose($oldsaveSuggestedSolutionOutputMode);
1485 }
1486 if ($save && strlen($_POST["filename"])) {
1487 $solution_array["value"]["filename"] = $_POST["filename"];
1488 }
1489 if ($save && strlen($_POST["solutiontext"])) {
1490 $solution_array["value"] = $_POST["solutiontext"];
1491 }
1492 include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
1493 if (count($solution_array)) {
1494 $form = new ilPropertyFormGUI();
1495 $form->setFormAction($this->ctrl->getFormAction($this));
1496 $form->setTitle($this->lng->txt("solution_hint"));
1497 $form->setMultipart(true);
1498 $form->setTableWidth("100%");
1499 $form->setId("suggestedsolutiondisplay");
1500
1501 // suggested solution output
1502 include_once "./Modules/TestQuestionPool/classes/class.ilSolutionTitleInputGUI.php";
1503 $title = new ilSolutionTitleInputGUI($this->lng->txt("showSuggestedSolution"), "solutiontype");
1504 $template = new ilTemplate("tpl.il_as_qpl_suggested_solution_input_presentation.html", true, true, "Modules/TestQuestionPool");
1505 if (strlen($solution_array["internal_link"])) {
1506 $href = assQuestion::_getInternalLinkHref($solution_array["internal_link"]);
1507 $template->setCurrentBlock("preview");
1508 $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1509 $template->setVariable("VALUE_SOLUTION", " <a href=\"$href\" target=\"content\">" . $this->lng->txt("view") . "</a> ");
1510 $template->parseCurrentBlock();
1511 } elseif ((strcmp($solution_array["type"], "file") == 0) && (is_array($solution_array["value"]))) {
1512 $href = $this->object->getSuggestedSolutionPathWeb() . $solution_array["value"]["name"];
1513 $template->setCurrentBlock("preview");
1514 $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1515 $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> ");
1516 $template->parseCurrentBlock();
1517 }
1518 $template->setVariable("TEXT_TYPE", $this->lng->txt("type"));
1519 $template->setVariable("VALUE_TYPE", $options[$solution_array["type"]]);
1520 $title->setHtml($template->get());
1521 $deletesolution = new ilCheckboxInputGUI("", "deleteSuggestedSolution");
1522 $deletesolution->setOptionTitle($this->lng->txt("deleteSuggestedSolution"));
1523 $title->addSubItem($deletesolution);
1524 $form->addItem($title);
1525
1526 if (strcmp($solution_array["type"], "file") == 0) {
1527 // file
1528 $file = new ilFileInputGUI($this->lng->txt("fileDownload"), "file");
1529 $file->setRequired(true);
1530 $file->enableFileNameSelection("filename");
1531 //$file->setSuffixes(array("doc","xls","png","jpg","gif","pdf"));
1532 if ($_FILES["file"]["tmp_name"] && $file->checkInput()) {
1533 if (!file_exists($this->object->getSuggestedSolutionPath())) {
1534 ilUtil::makeDirParents($this->object->getSuggestedSolutionPath());
1535 }
1536
1537 $res = ilUtil::moveUploadedFile($_FILES["file"]["tmp_name"], $_FILES["file"]["name"], $this->object->getSuggestedSolutionPath() . $_FILES["file"]["name"]);
1538 if ($res) {
1539 ilUtil::renameExecutables($this->object->getSuggestedSolutionPath());
1540
1541 // remove an old file download
1542 if (is_array($solution_array["value"])) {
1543 @unlink($this->object->getSuggestedSolutionPath() . $solution_array["value"]["name"]);
1544 }
1545 $file->setValue($_FILES["file"]["name"]);
1546 $this->object->saveSuggestedSolution("file", "", 0, array("name" => $_FILES["file"]["name"], "type" => $_FILES["file"]["type"], "size" => $_FILES["file"]["size"], "filename" => $_POST["filename"]));
1547 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
1548 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
1549 return $this->originalSyncForm("suggestedsolution");
1550 } else {
1551 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1552 $this->ctrl->redirect($this, "suggestedsolution");
1553 }
1554 } else {
1555 // BH: $res as info string? wtf? it holds a bool or something else!!?
1557 }
1558 } else {
1559 if (is_array($solution_array["value"])) {
1560 $file->setValue($solution_array["value"]["name"]);
1561 $file->setFilename((strlen($solution_array["value"]["filename"])) ? $solution_array["value"]["filename"] : $solution_array["value"]["name"]);
1562 }
1563 }
1564 $form->addItem($file);
1565 $hidden = new ilHiddenInputGUI("solutiontype");
1566 $hidden->setValue("file");
1567 $form->addItem($hidden);
1568 } elseif (strcmp($solution_array["type"], "text") == 0) {
1569 $solutionContent = $solution_array['value'];
1570 $solutionContent = $this->object->fixSvgToPng($solutionContent);
1571 $solutionContent = $this->object->fixUnavailableSkinImageSources($solutionContent);
1572 $question = new ilTextAreaInputGUI($this->lng->txt("solutionText"), "solutiontext");
1573 $question->setValue($this->object->prepareTextareaOutput($solutionContent));
1574 $question->setRequired(true);
1575 $question->setRows(10);
1576 $question->setCols(80);
1577 $question->setUseRte(true);
1578 $question->addPlugin("latex");
1579 $question->addButton("latex");
1580 $question->setRTESupport($this->object->getId(), "qpl", "assessment");
1581 $hidden = new ilHiddenInputGUI("solutiontype");
1582 $hidden->setValue("text");
1583 $form->addItem($hidden);
1584 $form->addItem($question);
1585 }
1586 if ($ilAccess->checkAccess("write", "", $_GET['ref_id'])) {
1587 $form->addCommandButton('showSuggestedSolution', $this->lng->txt('cancel'));
1588 $form->addCommandButton('suggestedsolution', $this->lng->txt('save'));
1589 }
1590
1591 if ($save) {
1592 if ($form->checkInput()) {
1593 switch ($solution_array["type"]) {
1594 case "file":
1595 $this->object->saveSuggestedSolution("file", "", 0, array(
1596 "name" => $solution_array["value"]["name"],
1597 "type" => $solution_array["value"]["type"],
1598 "size" => $solution_array["value"]["size"],
1599 "filename" => $_POST["filename"]
1600 ));
1601 break;
1602 case "text":
1603 $this->object->saveSuggestedSolution("text", "", 0, $solution_array["value"]);
1604 break;
1605 }
1606 $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
1607 if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId())) {
1608 return $this->originalSyncForm("suggestedsolution");
1609 } else {
1610 ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1611 $this->ctrl->redirect($this, "suggestedsolution");
1612 }
1613 }
1614 }
1615
1616 $output = $form->getHTML();
1617 }
1618
1619 $savechange = (strcmp($this->ctrl->getCmd(), "saveSuggestedSolution") == 0) ? true : false;
1620
1621 $changeoutput = "";
1622 if ($ilAccess->checkAccess("write", "", $_GET['ref_id'])) {
1623 $formchange = new ilPropertyFormGUI();
1624 $formchange->setFormAction($this->ctrl->getFormAction($this));
1625 $formchange->setTitle((count($solution_array)) ? $this->lng->txt("changeSuggestedSolution") : $this->lng->txt("addSuggestedSolution"));
1626 $formchange->setMultipart(false);
1627 $formchange->setTableWidth("100%");
1628 $formchange->setId("suggestedsolution");
1629
1630 $solutiontype = new ilRadioGroupInputGUI($this->lng->txt("suggestedSolutionType"), "solutiontype");
1631 foreach ($options as $opt_value => $opt_caption) {
1632 $solutiontype->addOption(new ilRadioOption($opt_caption, $opt_value));
1633 }
1634 if (count($solution_array)) {
1635 $solutiontype->setValue($solution_array["type"]);
1636 }
1637 $solutiontype->setRequired(true);
1638 $formchange->addItem($solutiontype);
1639
1640 $formchange->addCommandButton("saveSuggestedSolution", $this->lng->txt("select"));
1641
1642 if ($savechange) {
1643 $formchange->checkInput();
1644 }
1645 $changeoutput = $formchange->getHTML();
1646 }
1647
1648 $this->tpl->setVariable("ADM_CONTENT", $changeoutput . $output);
1649 }
1650
1651 public function outSolutionExplorer()
1652 {
1653 global $DIC;
1654 $tree = $DIC['tree'];
1655
1656 include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1657 $type = $_GET["link_new_type"];
1658 $search = $_GET["search_link_type"];
1659 $this->ctrl->setParameter($this, "link_new_type", $type);
1660 $this->ctrl->setParameter($this, "search_link_type", $search);
1661 $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1662
1663 ilUtil::sendInfo($this->lng->txt("select_object_to_link"));
1664
1665 $parent_ref_id = $tree->getParentId($_GET["ref_id"]);
1666 $exp = new ilSolutionExplorer($this->ctrl->getLinkTarget($this, 'suggestedsolution'), get_class($this));
1667 $exp->setExpand($_GET['expand_sol'] ? $_GET['expand_sol'] : $parent_ref_id);
1668 $exp->setExpandTarget($this->ctrl->getLinkTarget($this, 'outSolutionExplorer'));
1669 $exp->setTargetGet("ref_id");
1670 $exp->setRefId($_GET["ref_id"]);
1671 $exp->addFilter($type);
1672 $exp->setSelectableType($type);
1673 if (isset($_GET['expandCurrentPath']) && $_GET['expandCurrentPath']) {
1674 $exp->expandPathByRefId($parent_ref_id);
1675 }
1676
1677 // build html-output
1678 $exp->setOutput(0);
1679
1680 $template = new ilTemplate("tpl.il_as_qpl_explorer.html", true, true, "Modules/TestQuestionPool");
1681 $template->setVariable("EXPLORER_TREE", $exp->getOutput());
1682 $template->setVariable("BUTTON_CANCEL", $this->lng->txt("cancel"));
1683 $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this, "suggestedsolution"));
1684 $this->tpl->setVariable("ADM_CONTENT", $template->get());
1685 }
1686
1687 public function saveSuggestedSolution()
1688 {
1689 global $DIC;
1690 $tree = $DIC['tree'];
1691
1692 include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1693 switch ($_POST["solutiontype"]) {
1694 case "lm":
1695 $type = "lm";
1696 $search = "lm";
1697 break;
1698 case "git":
1699 $type = "glo";
1700 $search = "glo";
1701 break;
1702 case "st":
1703 $type = "lm";
1704 $search = "st";
1705 break;
1706 case "pg":
1707 $type = "lm";
1708 $search = "pg";
1709 break;
1710 case "file":
1711 case "text":
1712 return $this->suggestedsolution();
1713 break;
1714 default:
1715 return $this->suggestedsolution();
1716 break;
1717 }
1718 if (isset($_POST['solutiontype'])) {
1719 $this->ctrl->setParameter($this, 'expandCurrentPath', 1);
1720 }
1721 $this->ctrl->setParameter($this, "link_new_type", $type);
1722 $this->ctrl->setParameter($this, "search_link_type", $search);
1723 $this->ctrl->redirect($this, "outSolutionExplorer");
1724 }
1725
1726 public function cancelExplorer()
1727 {
1728 $this->ctrl->redirect($this, "suggestedsolution");
1729 }
1730
1731 public function outPageSelector()
1732 {
1733 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1734 require_once 'Modules/LearningModule/classes/class.ilLMPageObject.php';
1735 require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1736
1737 $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1738
1739 $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1740 $cont_obj = $cont_obj_gui->object;
1741 $pages = ilLMPageObject::getPageList($cont_obj->getId());
1742 $shownpages = array();
1743 $tree = $cont_obj->getLMTree();
1744 $chapters = $tree->getSubtree($tree->getNodeData($tree->getRootId()));
1745
1746 $rows = array();
1747
1748 foreach ($chapters as $chapter) {
1749 $chapterpages = $tree->getChildsByType($chapter['obj_id'], 'pg');
1750 foreach ($chapterpages as $page) {
1751 if ($page['type'] == $_GET['search_link_type']) {
1752 array_push($shownpages, $page['obj_id']);
1753
1754 if ($tree->isInTree($page['obj_id'])) {
1755 $path_str = $this->getContextPath($cont_obj, $page['obj_id']);
1756 } else {
1757 $path_str = '---';
1758 }
1759
1760 $this->ctrl->setParameter($this, $page['type'], $page['obj_id']);
1761 $rows[] = array(
1762 'title' => $page['title'],
1763 'description' => ilUtil::prepareFormOutput($path_str),
1764 'text_add' => $this->lng->txt('add'),
1765 'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($page['type']))
1766 );
1767 }
1768 }
1769 }
1770 foreach ($pages as $page) {
1771 if (!in_array($page['obj_id'], $shownpages)) {
1772 $this->ctrl->setParameter($this, $page['type'], $page['obj_id']);
1773 $rows[] = array(
1774 'title' => $page['title'],
1775 'description' => '---',
1776 'text_add' => $this->lng->txt('add'),
1777 'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($page['type']))
1778 );
1779 }
1780 }
1781
1782 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1783 $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1784 $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1785 $table->setData($rows);
1786
1787 $this->tpl->setContent($table->getHTML());
1788 }
1789
1790 public function outChapterSelector()
1791 {
1792 require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1793 require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1794
1795 $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1796
1797 $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1798 $cont_obj = $cont_obj_gui->object;
1799 $ctree = $cont_obj->getLMTree();
1800 $nodes = $ctree->getSubtree($ctree->getNodeData($ctree->getRootId()));
1801
1802 $rows = array();
1803
1804 foreach ($nodes as $node) {
1805 if ($node['type'] == $_GET['search_link_type']) {
1806 $this->ctrl->setParameter($this, $node['type'], $node['obj_id']);
1807 $rows[] = array(
1808 'title' => $node['title'],
1809 'description' => '',
1810 'text_add' => $this->lng->txt('add'),
1811 'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($node['type']))
1812 );
1813 }
1814 }
1815
1816 $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1817 $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1818 $table->setData($rows);
1819
1820 $this->tpl->setContent($table->getHTML());
1821 }
1822
1823 public function outGlossarySelector()
1824 {
1825 $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1826
1827 $glossary = new ilObjGlossary($_GET['source_id'], true);
1828 $terms = $glossary->getTermList();
1829
1830 $rows = array();
1831
1832 foreach ($terms as $term) {
1833 $this->ctrl->setParameter($this, 'git', $term['id']);
1834 $rows[] = array(
1835 'title' => $term['term'],
1836 'description' => '',
1837 'text_add' => $this->lng->txt('add'),
1838 'href_add' => $this->ctrl->getLinkTarget($this, 'addGIT')
1839 );
1840 }
1841
1842 $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1843 $table->setTitle($this->lng->txt('glossary_term'));
1844 $table->setData($rows);
1845
1846 $this->tpl->setContent($table->getHTML());
1847 }
1848
1849 public function linkChilds()
1850 {
1851 $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1852 switch ($_GET["search_link_type"]) {
1853 case "pg":
1854 return $this->outPageSelector();
1855 break;
1856 case "st":
1857 return $this->outChapterSelector();
1858 break;
1859 case "glo":
1860 return $this->outGlossarySelector();
1861 break;
1862 case "lm":
1863 $subquestion_index = ($_GET["subquestion_index"] > 0) ? $_GET["subquestion_index"] : 0;
1864 $this->object->saveSuggestedSolution("lm", "il__lm_" . $_GET["source_id"], $subquestion_index);
1865 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1866 $this->ctrl->redirect($this, "suggestedsolution");
1867 break;
1868 }
1869 }
1870
1871 public function addPG()
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("pg", "il__pg_" . $_GET["pg"], $subquestion_index);
1878 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1879 $this->ctrl->redirect($this, "suggestedsolution");
1880 }
1881
1882 public function addST()
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("st", "il__st_" . $_GET["st"], $subquestion_index);
1889 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1890 $this->ctrl->redirect($this, "suggestedsolution");
1891 }
1892
1893 public function addGIT()
1894 {
1895 $subquestion_index = 0;
1896 if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0) {
1897 $subquestion_index = $_GET["subquestion_index"];
1898 }
1899 $this->object->saveSuggestedSolution("git", "il__git_" . $_GET["git"], $subquestion_index);
1900 ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), true);
1901 $this->ctrl->redirect($this, "suggestedsolution");
1902 }
1903
1904 public function isSaveCommand()
1905 {
1906 return in_array($this->ctrl->getCmd(), array('save', 'saveEdit', 'saveReturn'));
1907 }
1908
1917 public static function getCommandsFromClassConstants($guiClassName, $cmdConstantNameBegin = 'CMD_')
1918 {
1919 $reflectionClass = new ReflectionClass($guiClassName);
1920
1921 $commands = null;
1922
1923 if ($reflectionClass instanceof ReflectionClass) {
1924 $commands = array();
1925
1926 foreach ($reflectionClass->getConstants() as $constName => $constValue) {
1927 if (substr($constName, 0, strlen($cmdConstantNameBegin)) == $cmdConstantNameBegin) {
1928 $commands[] = $constValue;
1929 }
1930 }
1931 }
1932
1933 return $commands;
1934 }
1935
1936 public function setQuestionTabs()
1937 {
1938 global $DIC;
1939 $rbacsystem = $DIC['rbacsystem'];
1940 $ilTabs = $DIC['ilTabs'];
1941
1942 $ilTabs->clearTargets();
1943
1944 $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1945 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1946 $q_type = $this->object->getQuestionType();
1947
1948 if (strlen($q_type)) {
1949 $classname = $q_type . "GUI";
1950 $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1951 $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1952 }
1953
1954 if ($_GET["q_id"]) {
1955 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
1956 // edit page
1957 $ilTabs->addTarget(
1958 "edit_page",
1959 $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1960 array("edit", "insert", "exec_pg"),
1961 "",
1962 "",
1963 $force_active
1964 );
1965 }
1966
1967 $this->addTab_QuestionPreview($ilTabs);
1968 }
1969 $force_active = false;
1970 if ($rbacsystem->checkAccess('write', $_GET["ref_id"])) {
1971 $url = "";
1972 if ($classname) {
1973 $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1974 }
1975 $force_active = false;
1976 // edit question properties
1977 $ilTabs->addTarget(
1978 "edit_question",
1979 $url,
1981 $classname,
1982 "",
1983 $force_active
1984 );
1985 }
1986
1987 // add tab for question feedback within common class assQuestionGUI
1988 $this->addTab_QuestionFeedback($ilTabs);
1989
1990 // add tab for question hint within common class assQuestionGUI
1991 $this->addTab_QuestionHints($ilTabs);
1992
1993 // add tab for question's suggested solution within common class assQuestionGUI
1994 $this->addTab_SuggestedSolution($ilTabs, $classname);
1995
1996 // Assessment of questions sub menu entry
1997 if ($_GET["q_id"]) {
1998 $ilTabs->addTarget(
1999 "statistics",
2000 $this->ctrl->getLinkTargetByClass($classname, "assessment"),
2001 array("assessment"),
2002 $classname,
2003 ""
2004 );
2005 }
2006
2007 $this->addBackTab($ilTabs);
2008 }
2009
2010 public function addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
2011 {
2012 if ($_GET["q_id"]) {
2013 $tabs->addTarget(
2014 "suggested_solution",
2015 $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
2016 array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
2017 "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
2018 ),
2019 $classname,
2020 ""
2021 );
2022 }
2023 }
2024
2025 final public function getEditQuestionTabCommands()
2026 {
2027 return array_merge($this->getBasicEditQuestionTabCommands(), $this->getAdditionalEditQuestionCommands());
2028 }
2029
2031 {
2032 return array('editQuestion', 'save', 'saveEdit', 'originalSyncForm');
2033 }
2034
2036 {
2037 return array();
2038 }
2039
2046 protected function addTab_QuestionFeedback(ilTabsGUI $tabs)
2047 {
2048 global $DIC;
2049 $ilCtrl = $DIC['ilCtrl'];
2050
2051 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionFeedbackEditingGUI.php';
2052 $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionFeedbackEditingGUI');
2053
2054 $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionFeedbackEditingGUI', ilAssQuestionFeedbackEditingGUI::CMD_SHOW);
2055
2056 $tabs->addTarget('tst_feedback', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
2057 }
2058
2062 protected function addTab_Units(ilTabsGUI $tabs)
2063 {
2067 global $DIC;
2068 $ilCtrl = $DIC['ilCtrl'];
2069
2070 $tabs->addTarget('units', $ilCtrl->getLinkTargetByClass('ilLocalUnitConfigurationGUI', ''), '', 'illocalunitconfigurationgui');
2071 }
2072
2079 protected function addTab_QuestionHints(ilTabsGUI $tabs)
2080 {
2081 global $DIC;
2082 $ilCtrl = $DIC['ilCtrl'];
2083
2084 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsGUI.php';
2085
2086 switch ($ilCtrl->getCmdClass()) {
2087 case 'ilassquestionhintsgui':
2088
2089 $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintsGUI');
2090 break;
2091
2092 case 'ilassquestionhintgui':
2093
2094 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintGUI.php';
2095 $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintGUI');
2096 break;
2097
2098 default:
2099
2100 $tabCommands = array();
2101 }
2102
2103 $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
2104
2105 $tabs->addTarget('tst_question_hints_tab', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
2106 }
2107
2108 protected function addTab_QuestionPreview(ilTabsGUI $tabsGUI)
2109 {
2110 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionPreviewGUI.php';
2111
2112 $tabsGUI->addTarget(
2114 $this->ctrl->getLinkTargetByClass('ilAssQuestionPreviewGUI', ilAssQuestionPreviewGUI::CMD_SHOW),
2115 array(),
2116 array('ilAssQuestionPreviewGUI')
2117 );
2118 }
2119
2120 abstract public function getSolutionOutput(
2121 $active_id,
2122 $pass = null,
2123 $graphicalOutput = false,
2124 $result_output = false,
2125 $show_question_only = true,
2126 $show_feedback = false,
2127 $show_correct_solution = false,
2128 $show_manual_scoring = false,
2129 $show_question_text = true
2130 );
2131
2138 {
2139 return false;
2140 }
2141
2148 public function hasIntermediateSolution($activeId, $passIndex)
2149 {
2150 $result = $this->object->lookupForExistingSolutions($activeId, $passIndex);
2151 return ($result['intermediate']);
2152 }
2153
2158 public function setUseIntermediateSolution($use)
2159 {
2160 $this->use_intermediate_solution = (bool) $use;
2161 }
2162
2168 {
2170 }
2171
2172 protected function hasCorrectSolution($activeId, $passIndex)
2173 {
2174 $reachedPoints = $this->object->getAdjustedReachedPoints($activeId, $passIndex, true);
2175 $maximumPoints = $this->object->getMaximumPoints();
2176
2177 return $reachedPoints == $maximumPoints;
2178 }
2179
2180 public function isAutosaveable()
2181 {
2182 return $this->object->isAutosaveable();
2183 }
2184
2185 protected function writeQuestionGenericPostData()
2186 {
2187 $this->object->setTitle($_POST["title"]);
2188 $this->object->setAuthor($_POST["author"]);
2189 $this->object->setComment($_POST["comment"]);
2190 if ($this->object->getSelfAssessmentEditingMode()) {
2191 $this->object->setNrOfTries($_POST['nr_of_tries']);
2192 }
2193
2194 try {
2195 $lifecycle = ilAssQuestionLifecycle::getInstance($_POST['lifecycle']);
2196 $this->object->setLifecycle($lifecycle);
2198 }
2199
2200 $this->object->setQuestion(ilUtil::stripOnlySlashes($_POST['question'])); // ?
2201 $this->object->setEstimatedWorkingTime(
2202 $_POST["Estimated"]["hh"],
2203 $_POST["Estimated"]["mm"],
2204 $_POST["Estimated"]["ss"]
2205 );
2206 }
2207
2208 abstract public function getPreview($show_question_only = false, $showInlineFeedback = false);
2209
2218 final public function outQuestionForTest(
2219 $formaction,
2220 $active_id,
2221 // hey: prevPassSolutions - pass will be always available from now on
2222 $pass,
2223 // hey.
2224 $is_question_postponed = false,
2225 $user_post_solutions = false,
2226 $show_specific_inline_feedback = false
2227 ) {
2228 $formaction = $this->completeTestOutputFormAction($formaction, $active_id, $pass);
2229
2230 $test_output = $this->getTestOutput(
2231 $active_id,
2232 $pass,
2233 $is_question_postponed,
2234 $user_post_solutions,
2235 $show_specific_inline_feedback
2236 );
2237
2238 $this->magicAfterTestOutput();
2239
2240 $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
2241 $this->tpl->setVariable("FORMACTION", $formaction);
2242 $this->tpl->setVariable("ENCTYPE", 'enctype="' . $this->getFormEncodingType() . '"');
2243 $this->tpl->setVariable("FORM_TIMESTAMP", time());
2244 }
2245
2246 // hey: prevPassSolutions - $pass will be passed always from now on
2247 protected function completeTestOutputFormAction($formAction, $active_id, $pass)
2248 // hey.
2249 {
2250 return $formAction;
2251 }
2252
2253 public function magicAfterTestOutput()
2254 {
2255 return;
2256 }
2257
2258 abstract public function getTestOutput(
2259 $active_id,
2260 $pass,
2261 $is_question_postponed,
2262 $user_post_solutions,
2263 $show_specific_inline_feedback
2264 );
2265
2266 public function getFormEncodingType()
2267 {
2269 }
2270
2274 protected function addBackTab(ilTabsGUI $ilTabs)
2275 {
2276 if (($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0)) {
2277 $ref_id = $_GET["calling_test"];
2278 if (strlen($ref_id) == 0) {
2279 $ref_id = $_GET["test_ref_id"];
2280 }
2281
2282 if (!$_GET['test_express_mode'] && !$GLOBALS['___test_express_mode']) {
2283 $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
2284 } else {
2286 $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
2287 }
2288 } elseif (isset($_GET['calling_consumer']) && (int) $_GET['calling_consumer']) {
2289 $ref_id = (int) $_GET['calling_consumer'];
2290 $consumer = ilObjectFactory::getInstanceByRefId($ref_id);
2291 if ($consumer instanceof ilQuestionEditingFormConsumer) {
2292 $ilTabs->setBackTarget($consumer->getQuestionEditingFormBackTargetLabel(), $consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
2293 } else {
2294 require_once 'Services/Link/classes/class.ilLink.php';
2295 $ilTabs->setBackTarget($this->lng->txt("qpl"), ilLink::_getLink($ref_id));
2296 }
2297 } else {
2298 $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
2299 }
2300 }
2301
2306
2311 {
2312 $this->previewSession = $previewSession;
2313 }
2314
2318 public function getPreviewSession()
2319 {
2320 return $this->previewSession;
2321 }
2322
2326 protected function buildBasicEditFormObject()
2327 {
2328 require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
2329 $form = new ilPropertyFormGUI();
2330
2331 $form->setFormAction($this->ctrl->getFormAction($this));
2332
2333 $form->setId($this->getType());
2334 $form->setTitle($this->outQuestionType());
2335
2336 $form->setTableWidth('100%');
2337
2338 $form->setMultipart(true);
2339
2340 return $form;
2341 }
2342
2343 public function showHints()
2344 {
2345 global $DIC;
2346 $ilCtrl = $DIC['ilCtrl'];
2347 $ilCtrl->redirectByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
2348 }
2349
2353 protected function buildEditForm()
2354 {
2355 $errors = $this->editQuestion(true); // TODO bheyser: editQuestion should be added to the abstract base class with a unified signature
2356 return $this->editForm;
2357 }
2358
2362 public function buildFocusAnchorHtml()
2363 {
2364 return '<div id="focus"></div>';
2365 }
2366
2368 {
2369 return true;
2370 }
2371
2372 public function getSubQuestionsIndex()
2373 {
2374 return array(0);
2375 }
2376
2377 public function getAnswersFrequency($relevantAnswers, $questionIndex)
2378 {
2379 return array();
2380 }
2381
2389 public function getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
2390 {
2391 require_once 'Modules/TestQuestionPool/classes/tables/class.ilAnswerFrequencyStatisticTableGUI.php';
2392
2393 $table = new ilAnswerFrequencyStatisticTableGUI($parentGui, $parentCmd, $this->object);
2394 $table->setQuestionIndex($questionIndex);
2395 $table->setData($this->getAnswersFrequency($relevantAnswers, $questionIndex));
2396 $table->initColumns();
2397
2398 return $table;
2399 }
2400
2405 {
2406 }
2407
2412 {
2413 }
2414
2419 {
2420 }
2421}
$result
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$test
Definition: Utf8Test.php:84
$_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)
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)
populateJavascriptFilesRequiredForWorkForm(ilGlobalTemplateInterface $tpl)
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, ilGlobalTemplateInterface $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 feedback comment for a question in a test if it is finalized.
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.
addItem($a_item)
Add Item (Property, SectionHeader).
Class ilQuestionUsagesTableGUI.
This class represents a property in a property form.
This class represents an option in a radio group.
This class represents a selection list property in a property form.
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 moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
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.
global $ilCtrl
Definition: ilias.php:18
exit
Definition: login.php:29
$i
Definition: metadata.php:24
QTI assessment class.
$ret
Definition: parser.php:6
$type
$url
foreach($_POST as $key=> $value) $res
global $ilDB
$errors
$ilUser
Definition: imgupload.php:18
$DIC
Definition: xapitoken.php:46
$rows
Definition: xhr_table.php:10