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 
4 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
5 require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
6 require_once 'Modules/TestQuestionPool/exceptions/class.ilTestQuestionPoolException.php';
7 require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
8 require_once 'Modules/Test/classes/class.ilObjAssessmentFolder.php';
9 
20 abstract 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;
42  public $errormessage;
43 
47  public $sequence_no;
52 
53  private $taxonomyIds = array();
54 
55  private $targetGuiClass = null;
56 
57  private $questionActionCmd = 'handleQuestionAction';
58 
63 
67  private $navigationGUI;
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 
86  private $renderPurpose = self::RENDER_PURPOSE_PLAYBACK;
87 
88  const EDIT_CONTEXT_AUTHORING = 'authoring';
89  const EDIT_CONTEXT_ADJUSTMENT = 'adjustment';
90 
94  private $editContext = self::EDIT_CONTEXT_AUTHORING;
95 
96  // hey: prevPassSolutions - flag to indicate that a previous answer is shown
100  private $previousSolutionPrefilled = false;
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 
282  public function isTestPresentationContext()
283  {
284  return $this->getPresentationContext() == self::PRESENTATION_CONTEXT_TEST;
285  }
286 
287  // hey: previousPassSolutions - setter/getter for Previous Solution Prefilled flag
291  public function isPreviousSolutionPrefilled()
292  {
294  }
295 
300  {
301  $this->previousSolutionPrefilled = $previousSolutionPrefilled;
302  }
303  // hey.
304 
308  public function getRenderPurpose()
309  {
310  return $this->renderPurpose;
311  }
312 
317  {
318  $this->renderPurpose = $renderPurpose;
319  }
320 
321  public function isRenderPurposePrintPdf()
322  {
323  return $this->getRenderPurpose() == self::RENDER_PURPOSE_PRINT_PDF;
324  }
325 
326  public function isRenderPurposePreview()
327  {
328  return $this->getRenderPurpose() == self::RENDER_PURPOSE_PREVIEW;
329  }
330 
331  public function isRenderPurposeInputValue()
332  {
333  return $this->getRenderPurpose() == self::RENDER_PURPOSE_INPUT_VALUE;
334  }
335 
336  public function isRenderPurposePlayback()
337  {
338  return $this->getRenderPurpose() == self::RENDER_PURPOSE_PLAYBACK;
339  }
340 
341  public function isRenderPurposeDemoplay()
342  {
343  return $this->getRenderPurpose() == self::RENDER_PURPOSE_DEMOPLAY;
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 
370  public function setEditContext($editContext)
371  {
372  $this->editContext = $editContext;
373  }
374 
378  public function isAuthoringEditContext()
379  {
380  return $this->getEditContext() == self::EDIT_CONTEXT_AUTHORING;
381  }
382 
386  public function isAdjustmentEditContext()
387  {
388  return $this->getEditContext() == self::EDIT_CONTEXT_ADJUSTMENT;
389  }
390 
391  public function setAdjustmentEditContext()
392  {
393  return $this->setEditContext(self::EDIT_CONTEXT_ADJUSTMENT);
394  }
395 
399  public function getNavigationGUI()
400  {
401  return $this->navigationGUI;
402  }
403 
408  {
409  $this->navigationGUI = $navigationGUI;
410  }
411 
412  public function setTaxonomyIds($taxonomyIds)
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  {
434  return $this->targetGuiClass;
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!!?
1542  ilUtil::sendInfo($res);
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,
1969  $this->getEditQuestionTabCommands(),
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 
2019  protected function getBasicEditQuestionTabCommands()
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 
2068  protected function addTab_QuestionHints(ilTabsGUI $tabs)
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 
2156  public function getUseIntermediateSolution()
2157  {
2158  return (bool) $this->use_intermediate_solution;
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  {
2250  return self::FORM_ENCODING_URLENCODE;
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 }
QTI assessment class.
hasIntermediateSolution($activeId, $passIndex)
Check if the question has an intermediate solution.
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static getSelfAssessmentTags()
Get tags allowed in question tags in self assessment mode.
setQuestionActionCmd($questionActionCmd)
static prepareFormOutput($a_str, $a_strip=false)
prepares string output for html forms public
This class represents a duration (typical hh:mm:ss) property in a property form.
hasCorrectSolution($activeId, $passIndex)
getAssignmentsOfItem($a_item_id)
Get assignments for item.
addTab_QuestionPreview(ilTabsGUI $tabsGUI)
saveCorrectionsFormProperties(ilPropertyFormGUI $form)
This class represents an option in a radio group.
$path
Definition: aliased.php:25
getTestOutput( $active_id, $pass, $is_question_postponed, $user_post_solutions, $show_specific_inline_feedback)
Taxonomy node <-> item assignment.
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
getAnswersFrequency($relevantAnswers, $questionIndex)
getSpecificFeedbackOutput($userSolution)
Returns the answer specific feedback for the question.
static getQuestionTypeFromDb($question_id)
get question type for question id
getPreview($show_question_only=false, $showInlineFeedback=false)
addBasicQuestionFormProperties($form)
Add basic question form properties: assessment: title, author, description, question, working time.
Select taxonomy nodes input GUI.
setValue($a_value)
Set Value.
$_SESSION["AccountId"]
$result
addTab_QuestionHints(ilTabsGUI $tabs)
adds the hints tab to ilTabsGUI
Tabs GUI.
suggestedsolution()
Allows to add suggested solutions for questions.
$template
This class represents a property form user interface.
static _getGUIClassNameForId($a_q_id)
writePostData($always=false)
Evaluates a posted edit form and writes the form data in the question object.
$type
global $DIC
Definition: saml.php:7
$question_count
question count in test
addErrorMessage($errormessage)
const ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT
constant for additional content editing mode "pageobject"
__construct()
assQuestionGUI constructor
$_GET["client_id"]
setShowHours($a_showhours)
Set Show Hours.
This class represents a section header in a property form.
static initJavascript($a_ajax_url, $a_type=IL_NOTE_PRIVATE, ilTemplate $a_main_tpl=null)
Init javascript.
This class represents a file property in a property form.
Class ilObjGlossary.
const SESSION_PREVIEW_DATA_BASE_INDEX
setPresentationContext($presentationContext)
setPreviousSolutionPrefilled($previousSolutionPrefilled)
static _getUsedHTMLTags($a_module="")
Returns an array of all allowed HTML tags for text editing.
static _getQuestionTypeName($type_tag)
Return the translation for a given question type tag.
setValue($a_value)
Set Value.
setQuestionHeaderBlockBuilder($questionHeaderBlockBuilder)
This class represents a checkbox property in a property form.
addItem($a_item)
Add Item (Property, SectionHeader).
setTaxonomyIds($taxonomyIds)
setRenderPurpose($renderPurpose)
callNewIdListeners($a_new_id)
Call the new id listeners.
addTarget( $a_text, $a_link, $a_cmd="", $a_cmdClass="", $a_frame="", $a_activate=false, $a_dir_text=false)
hasInlineFeedback()
this method can be overwritten per question type
This class represents a custom property in a property form.
getQuestionTemplate()
get question template
Class ilQuestionUsagesTableGUI.
enablePublicNotes($a_enable=true)
enable public notes
setEditContext($editContext)
setBackTarget($a_title, $a_target, $a_frame="")
back target for upper context
Question page GUI class.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
apply()
apply changes
getUseIntermediateSolution()
Get if intermediate solution should be used for solution output.
const CMD_SHOW_LIST
command constants
saveEdit()
save question
static stripOnlySlashes($a_str)
strip slashes if magic qoutes is enabled
Notes GUI class.
global $ilCtrl
Definition: ilias.php:18
prepareReprintableCorrectionsForm(ilPropertyFormGUI $form)
$sequence_no
sequence number in test
static _getInternalLinkHref($target="")
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
populateJavascriptFilesRequiredForWorkForm(ilTemplate $tpl)
cancel()
cancel action
getType()
needed for page editor compliance
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...
This class represents a hidden form property in a property form.
populateCorrectionsFormProperties(ilPropertyFormGUI $form)
& createQuestionGUI($question_type, $question_id=-1)
Creates a question gui representation.
This class represents a property in a property form.
addOption($a_option)
Add Option.
foreach($_POST as $key=> $value) $res
static getReturnToPageLink($q_id=null)
if(isset($_POST['submit'])) $form
addJavaScript($a_js_file, $a_add_version_parameter=true, $a_batch=2)
Add a javascript file that should be included in the header.
const IL_NOTE_PUBLIC
Definition: class.ilNote.php:6
getILIASPage($html="")
Returns the ILIAS Page around a question.
This class represents a number property in a property form.
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...
static getManualFeedback($active_id, $question_id, $pass)
Retrieves the manual feedback for a question in a test.
special template class to simplify handling of ITX/PEAR
setTitle($a_title)
Set Title.
This class represents a text property in a property form.
originalSyncForm($return_to="", $return_to_feedback='')
addNewIdListener(&$a_object, $a_method, $a_parameters="")
Add a listener that is notified with the new question ID, when a new question is saved.
$ilUser
Definition: imgupload.php:18
addTab_QuestionFeedback(ilTabsGUI $tabs)
adds the feedback tab to ilTabsGUI
setTargetGui($linkTargetGui)
getContextPath($cont_obj, $a_endnode_id, $a_startnode_id=1)
get context path in content object tree
getQuestionType()
Returns the question type string.
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
setTargetGuiClass($targetGuiClass)
Basic GUI class for assessment questions.
setErrorMessage($errormessage)
static _lookupType($a_id, $a_reference=false)
lookup object type
static _getClassNameForQType($q_type)
Input GUI class for taxonomy assignments.
completeTestOutputFormAction($formAction, $active_id, $pass)
$rows
Definition: xhr_table.php:10
supportsIntermediateSolutionOutput()
Question type specific support of intermediate solution output The function getSolutionOutput respect...
executeCommand()
execute command
static _questionExistsInTest($question_id, $test_id)
getAnswerFeedbackOutput($active_id, $pass)
Returns the answer generic feedback depending on the results of the question.
if(!empty($this->data['faventry'])) $tabs
Definition: disco.tpl.php:124
exit
Definition: backend.php:16
$errors
Definition: index.php:6
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="", $inlineFeedbackEnabled=false)
output question page
static renameExecutables($a_dir)
Rename uploaded executables for security reasons.
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)
This class represents a text area property in a property form.
addBackTab(ilTabsGUI $ilTabs)
outQuestionForTest( $formaction, $active_id, $pass, $is_question_postponed=false, $user_post_solutions=false, $show_specific_inline_feedback=false)
global $ilDB
$ret
Definition: parser.php:6
setPreviewSession($previewSession)
Class ilObjContentObjectGUI.
$i
Definition: disco.tpl.php:19
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
static getGuiClassNameByQuestionType($questionType)
$url
if(empty($password)) $table
Definition: pwgen.php:24
getGenericFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
static getPageList($lm_id)
static
getAsValueAttribute($a_value)
Returns a HTML value attribute.
setValue($a_value)
Set Value.
static redirect($a_script)
save()
save question
static getFeedbackClassNameByQuestionType($questionType)
$_POST["username"]
$html
Definition: example_001.php:87
Class ilCommonActionDispatcherGUI.
getAnswerFrequencyTableGUI($parentGui, $parentCmd, $relevantAnswers, $questionIndex)
setRequired($a_required)
Set Required.
setSubObject($a_sub_obj_type, $a_sub_obj_id)
Set sub object attributes.
saveReturn()
save question
setExpand($a_node_id)
set the expand option this value is stored in a SESSION variable to save it different view (lo view...
$GLOBALS['JPEG_Segment_Names']
Global Variable: XMP_tag_captions.
addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
setOutputMode($a_mode=IL_PAGE_PRESENTATION)
Set Output Mode.
$test
Definition: Utf8Test.php:84
setQuestionHTML($question_html)
addQuestionFormCommandButtons($form)
Add the command buttons of a question properties form.
setQuestionCount($a_question_count)
static _isWriteable($question_id, $user_id)
Returns true if the question is writeable by a certain user.
setNavigationGUI($navigationGUI)