ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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  var $object;
38 
39  var $tpl;
40  var $lng;
41  var $error;
43 
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 
99  protected $editForm;
100 
104  function __construct()
105  {
106  global $lng, $tpl, $ilCtrl;
107 
108  $this->lng =& $lng;
109  $this->tpl =& $tpl;
110  $this->ctrl =& $ilCtrl;
111  $this->ctrl->saveParameter($this, "q_id");
112  $this->ctrl->saveParameter($this, "prev_qid");
113  $this->ctrl->saveParameter($this, "calling_test");
114  $this->ctrl->saveParameter($this, "calling_consumer");
115  $this->ctrl->saveParameter($this, "consumer_context");
116  $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'test_express_mode');
117  $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'calling_consumer');
118  $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'consumer_context');
119  $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'test_express_mode');
120  $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'calling_consumer');
121  $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'consumer_context');
122 
123  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
124  $this->errormessage = $this->lng->txt("fill_out_all_required_fields");
125 
126  $this->selfassessmenteditingmode = false;
127  $this->new_id_listeners = array();
128  $this->new_id_listener_cnt = 0;
129 
130  $this->navigationGUI = null;
131  }
132 
136  function executeCommand()
137  {
138  global $DIC; /* @var \ILIAS\DI\Container $DIC */
139  $ilHelp = $DIC['ilHelp']; /* @var ilHelpGUI $ilHelp */
140  $ilHelp->setScreenIdComponent('qpl');
141 
142  $cmd = $this->ctrl->getCmd("editQuestion");
143  $next_class = $this->ctrl->getNextClass($this);
144 
145  $cmd = $this->getCommand($cmd);
146 
147  switch($next_class)
148  {
149  case 'ilformpropertydispatchgui':
150  $form = $this->buildEditForm();
151 
152  require_once 'Services/Form/classes/class.ilFormPropertyDispatchGUI.php';
153  $form_prop_dispatch = new ilFormPropertyDispatchGUI();
154  $form_prop_dispatch->setItem($form->getItemByPostVar(ilUtil::stripSlashes($_GET['postvar'])));
155  return $this->ctrl->forwardCommand($form_prop_dispatch);
156  break;
157 
158  default:
159  $ret = $this->$cmd();
160  break;
161  }
162  return $ret;
163  }
164 
165  function getCommand($cmd)
166  {
167  return $cmd;
168  }
169 
173  function getType()
174  {
175  return $this->getQuestionType();
176  }
177 
181  public function getPresentationContext()
182  {
184  }
185 
190  {
191  $this->presentationContext = $presentationContext;
192  }
193 
194  public function isTestPresentationContext()
195  {
196  return $this->getPresentationContext() == self::PRESENTATION_CONTEXT_TEST;
197  }
198 
202  public function getRenderPurpose()
203  {
204  return $this->renderPurpose;
205  }
206 
211  {
212  $this->renderPurpose = $renderPurpose;
213  }
214 
215  public function isRenderPurposePrintPdf()
216  {
217  return $this->getRenderPurpose() == self::RENDER_PURPOSE_PRINT_PDF;
218  }
219 
220  public function isRenderPurposePreview()
221  {
222  return $this->getRenderPurpose() == self::RENDER_PURPOSE_PREVIEW;
223  }
224 
225  public function isRenderPurposeInputValue()
226  {
227  return $this->getRenderPurpose() == self::RENDER_PURPOSE_INPUT_VALUE;
228  }
229 
230  public function isRenderPurposePlayback()
231  {
232  return $this->getRenderPurpose() == self::RENDER_PURPOSE_PLAYBACK;
233  }
234 
235  public function isRenderPurposeDemoplay()
236  {
237  return $this->getRenderPurpose() == self::RENDER_PURPOSE_DEMOPLAY;
238  }
239 
241  {
242  if( $this->isRenderPurposePrintPdf() )
243  {
244  return false;
245  }
246 
247  if( $this->isRenderPurposeInputValue() )
248  {
249  return false;
250  }
251 
252  return true;
253  }
254 
258  public function getEditContext()
259  {
260  return $this->editContext;
261  }
262 
266  public function setEditContext($editContext)
267  {
268  $this->editContext = $editContext;
269  }
270 
274  public function isAuthoringEditContext()
275  {
276  return $this->getEditContext() == self::EDIT_CONTEXT_AUTHORING;
277  }
278 
282  public function isAdjustmentEditContext()
283  {
284  return $this->getEditContext() == self::EDIT_CONTEXT_ADJUSTMENT;
285  }
286 
287  public function setAdjustmentEditContext()
288  {
289  return $this->setEditContext(self::EDIT_CONTEXT_ADJUSTMENT);
290  }
291 
295  public function getNavigationGUI()
296  {
297  return $this->navigationGUI;
298  }
299 
304  {
305  $this->navigationGUI = $navigationGUI;
306  }
307 
308  public function setTaxonomyIds($taxonomyIds)
309  {
310  $this->taxonomyIds = $taxonomyIds;
311  }
312 
313  public function getTaxonomyIds()
314  {
315  return $this->taxonomyIds;
316  }
317 
318  public function setTargetGui($linkTargetGui)
319  {
320  $this->setTargetGuiClass( get_class($linkTargetGui) );
321  }
322 
324  {
325  $this->targetGuiClass = $targetGuiClass;
326  }
327 
328  public function getTargetGuiClass()
329  {
330  return $this->targetGuiClass;
331  }
332 
337  {
338  $this->questionHeaderBlockBuilder = $questionHeaderBlockBuilder;
339  }
340 
341 // fau: testNav - get the question header block bulder (for tweaking)
346  {
348  }
349 // fau.
350 
352  {
353  $this->questionActionCmd = $questionActionCmd;
354 
355  if( is_object($this->object) )
356  {
357  $this->object->questionActionCmd = $questionActionCmd;
358  }
359  }
360 
361  public function getQuestionActionCmd()
362  {
364  }
365 
370  protected function writePostData($always = false)
371  {
372  }
373 
377  public function assessment()
378  {
382  global $tpl;
383 
384  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionCumulatedStatisticsTableGUI.php';
385  $stats_table = new ilQuestionCumulatedStatisticsTableGUI($this, 'assessment', '', $this->object);
386 
387  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionUsagesTableGUI.php';
388  $usage_table = new ilQuestionUsagesTableGUI($this, 'assessment', '', $this->object);
389 
390  $tpl->setContent(implode('<br />', array(
391  $stats_table->getHTML(),
392  $usage_table->getHTML()
393  )));
394  }
395 
405  public static function _getQuestionGUI($question_type, $question_id = -1)
406  {
407  global $ilCtrl, $ilDB, $lng;
408 
409  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
410 
411  if ((!$question_type) and ($question_id > 0))
412  {
413  $question_type = assQuestion::getQuestionTypeFromDb($question_id);
414  }
415 
416  if (strlen($question_type) == 0) return NULL;
417 
418  assQuestion::_includeClass($question_type, 1);
419 
420  $question_type_gui = assQuestion::getGuiClassNameByQuestionType($question_type);
421  $question = new $question_type_gui();
422 
423  $feedbackObjectClassname = assQuestion::getFeedbackClassNameByQuestionType($question_type);
424  $question->object->feedbackOBJ = new $feedbackObjectClassname($question->object, $ilCtrl, $ilDB, $lng);
425 
426  if ($question_id > 0)
427  {
428  $question->object->loadFromDb($question_id);
429  }
430 
431  return $question;
432  }
433 
437  public static function _getGUIClassNameForId($a_q_id)
438  {
439  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
440  include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
441  $q_type = assQuestion::getQuestionTypeFromDb($a_q_id);
442  $class_name = assQuestionGUI::_getClassNameForQType($q_type);
443  return $class_name;
444  }
445 
449  public static function _getClassNameForQType($q_type)
450  {
451  return $q_type . "GUI";
452  }
453 
466  function &createQuestionGUI($question_type, $question_id = -1)
467  {
468  include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
469  $this->question =& assQuestionGUI::_getQuestionGUI($question_type, $question_id);
470  }
471 
473  {
474  $tpl->addJavaScript('Modules/TestQuestionPool/js/ilAssMultipleChoice.js');
475  }
476 
480  public function getQuestionTemplate()
481  {
482  // @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)
483  if(!$this->tpl->blockExists('content'))
484  {
485  $this->tpl->addBlockFile("CONTENT", "content", "tpl.il_as_qpl_content.html", "Modules/TestQuestionPool");
486  }
487  // @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)
488  if(!$this->tpl->blockExists('statusline'))
489  {
490  $this->tpl->addBlockFile("STATUSLINE", "statusline", "tpl.statusline.html");
491  }
492  // @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
493  if(!$this->tpl->blockExists('adm_content'))
494  {
495  $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_as_question.html", "Modules/TestQuestionPool");
496  }
497  }
498 
502  protected function renderEditForm($form)
503  {
504  $this->getQuestionTemplate();
505  $this->tpl->setVariable("QUESTION_DATA", $form->getHTML());
506  }
507 
514  function getILIASPage($html = "")
515  {
516  include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
517  $page_gui = new ilAssQuestionPageGUI($this->object->getId());
518  $page_gui->setQuestionHTML(array($this->object->getId() => $html));
519  $page_gui->setOutputMode("presentation");
520  $presentation = $page_gui->presentation();
521  $presentation = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $presentation);
522  return $presentation;
523  }
524 
528  function outQuestionPage($a_temp_var, $a_postponed = false, $active_id = "", $html = "")
529  {
530  // hey: prevPassSolutions - add the "use previous answer"
531  // hey: prevPassSolutions - refactored identifiers
532  if( $this->object->getTestPresentationConfig()->isSolutionInitiallyPrefilled() )
533  // hey
534  {
537  }
538  else /* if( ...->isUnchangedAnswerPossible() ) --> */
539  // hey.
540 // fau: testNav - add the "use unchanged answer checkbox"
541  // hey: prevPassSolutions - refactored identifiers
542  if ($this->object->getTestPresentationConfig()->isUnchangedAnswerPossible())
543  // hey.
544  {
546  }
547 // fau.
548 
549  $this->lng->loadLanguageModule("content");
550 
551 // fau: testNav - add question buttons below question, add actions menu
552  include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
553  $page_gui = new ilAssQuestionPageGUI($this->object->getId());
554  $page_gui->setOutputMode("presentation");
555  $page_gui->setTemplateTargetVar($a_temp_var);
556 
557  if( $this->getNavigationGUI() )
558  {
559  $html .= $this->getNavigationGUI()->getHTML();
560  $page_gui->setQuestionActionsHTML($this->getNavigationGUI()->getActionsHTML());
561  }
562 // fau.
563 
564  if( strlen($html) )
565  {
566  $page_gui->setQuestionHTML(array($this->object->getId() => $html));
567  }
568 
569 // fau: testNav - fill the header with subtitle blocks for question info an actions
570  $page_gui->setPresentationTitle($this->questionHeaderBlockBuilder->getPresentationTitle());
571  $page_gui->setQuestionInfoHTML($this->questionHeaderBlockBuilder->getQuestionInfoHTML());
572 // fau.
573 
574  return $page_gui->presentation();
575  }
576 
577 // fau: testNav - get the html of the "use unchanged answer checkbox"
579  {
580  // hey: prevPassSolutions - use abstracted template to share with other purposes of this kind
581  $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
582  $tpl->setVariable('TXT_FORCE_FORM_DIFF_LABEL', $this->object->getTestPresentationConfig()->getUseUnchangedAnswerLabel());
583  // hey.
584  return $tpl->get();
585  }
586 // fau.
587 
588  // hey: prevPassSolutions - build prev solution message / build "use previous answer checkbox" html
590  {
591  return $this->lng->txt('use_previous_solution_advice');
592  }
593 
595  {
596  $tpl = new ilTemplate('tpl.tst_question_additional_behaviour_checkbox.html', true, true, 'Modules/TestQuestionPool');
597  // hey: prevPassSolutions - use abtract template
598  $tpl->setVariable('TXT_FORCE_FORM_DIFF_LABEL', $this->lng->txt('use_previous_solution'));
599  // hey.
600  return $tpl->get();
601  }
602  // hey.
603 
607  function cancel()
608  {
609  if ($_GET["calling_test"])
610  {
611  $_GET["ref_id"] = $_GET["calling_test"];
612  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
613  }
614  elseif ($_GET["test_ref_id"])
615  {
616  $_GET["ref_id"] = $_GET["test_ref_id"];
617  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["test_ref_id"]);
618  }
619  else
620  {
621  if ($_GET["q_id"] > 0)
622  {
623  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
624  $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
625  }
626  else
627  {
628  $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
629  }
630  }
631  }
632 
637  function originalSyncForm($return_to = "", $return_to_feedback = '')
638  {
639  if (strlen($return_to))
640  {
641  $this->ctrl->setParameter($this, "return_to", $return_to);
642  }
643  else if ($_REQUEST['return_to']) {
644  $this->ctrl->setParameter($this, "return_to", $_REQUEST['return_to']);
645  }
646  if(strlen($return_to_feedback))
647  {
648  $this->ctrl->setParameter($this, 'return_to_fb', 'true');
649  }
650 
651  $this->ctrl->saveParameter($this, 'test_express_mode');
652 
653  $template = new ilTemplate("tpl.il_as_qpl_sync_original.html",TRUE, TRUE, "Modules/TestQuestionPool");
654  $template->setVariable("BUTTON_YES", $this->lng->txt("yes"));
655  $template->setVariable("BUTTON_NO", $this->lng->txt("no"));
656  $template->setVariable("FORM_ACTION", $this->ctrl->getFormAction($this));
657  $template->setVariable("TEXT_SYNC", $this->lng->txt("confirm_sync_questions"));
658  $this->tpl->setVariable("ADM_CONTENT", $template->get());
659  }
660 
661  function sync()
662  {
663  $original_id = $this->object->original_id;
664  if ($original_id)
665  {
666  $this->object->syncWithOriginal();
667  }
668  if (strlen($_GET["return_to"]))
669  {
670  $this->ctrl->redirect($this, $_GET["return_to"]);
671  }
672  if (strlen($_REQUEST["return_to_fb"]))
673  {
674  $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
675  }
676  else
677  {
678  if(isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])
679  {
680  $ref_id = (int)$_GET['calling_consumer'];
682  if($consumer instanceof ilQuestionEditingFormConsumer)
683  {
684  ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
685  }
686  require_once 'Services/Link/classes/class.ilLink.php';
688  }
689  $_GET["ref_id"] = $_GET["calling_test"];
690 
691  if($_REQUEST['test_express_mode'])
692  {
694  }
695  else
696  {
697  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
698  }
699  }
700  }
701 
702  function cancelSync()
703  {
704  if (strlen($_GET["return_to"]))
705  {
706  $this->ctrl->redirect($this, $_GET["return_to"]);
707  }
708  if(strlen($_REQUEST['return_to_fb']))
709  {
710  $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
711  }
712  else
713  {
714  if(isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])
715  {
716  $ref_id = (int)$_GET['calling_consumer'];
718  if($consumer instanceof ilQuestionEditingFormConsumer)
719  {
720  ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
721  }
722  require_once 'Services/Link/classes/class.ilLink.php';
724  }
725  $_GET["ref_id"] = $_GET["calling_test"];
726 
727  if($_REQUEST['test_express_mode'])
728  {
730  }
731  else
732  {
733  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
734  }
735  }
736  }
737 
741  function saveEdit()
742  {
743  global $ilUser;
744 
745  $result = $this->writePostData();
746  if ($result == 0)
747  {
748  $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
749  $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
750  $this->object->saveToDb();
751  $originalexists = $this->object->_questionExists($this->object->original_id);
752  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
753  if ($_GET["calling_test"] && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
754  {
755  $this->ctrl->redirect($this, "originalSyncForm");
756  }
757  elseif ($_GET["calling_test"])
758  {
759  $_GET["ref_id"] = $_GET["calling_test"];
760  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
761  return;
762  }
763  elseif ($_GET["test_ref_id"])
764  {
765  global $tree, $ilDB, $ilPluginAdmin;
766 
767  include_once ("./Modules/Test/classes/class.ilObjTest.php");
768  $_GET["ref_id"] = $_GET["test_ref_id"];
769  $test = new ilObjTest($_GET["test_ref_id"], true);
770 
771  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
772  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
773 
774  $test->insertQuestion( $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId() );
775 
776  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["test_ref_id"]);
777  }
778  else
779  {
780  $this->ctrl->setParameter($this, "q_id", $this->object->getId());
781  $this->editQuestion();
782  if (strcmp($_SESSION["info"], "") != 0)
783  {
784  ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), false);
785  }
786  else
787  {
788  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), false);
789  }
790  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $this->object->getId());
791  $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
792  }
793  }
794  }
795 
799  function save()
800  {
801  global $ilUser;
802  $old_id = $_GET["q_id"];
803  $result = $this->writePostData();
804 
805  if($result == 0)
806  {
807  $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
808  $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
809  $this->object->saveToDb();
810  $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
811 
812 
813  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
814  if(($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
815  {
816  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
817  $this->ctrl->setParameter($this, 'return_to', 'editQuestion');
818  $this->ctrl->redirect($this, "originalSyncForm");
819  return;
820  }
821  elseif($_GET["calling_test"])
822  {
823  require_once 'Modules/Test/classes/class.ilObjTest.php';
824  $test = new ilObjTest($_GET["calling_test"]);
825  if(!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()))
826  {
827  global $tree, $ilDB, $ilPluginAdmin;
828 
829  include_once("./Modules/Test/classes/class.ilObjTest.php");
830  $_GET["ref_id"] = $_GET["calling_test"];
831  $test = new ilObjTest($_GET["calling_test"], true);
832 
833  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
834  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
835 
836  $new_id = $test->insertQuestion(
837  $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId()
838  );
839 
840  if(isset($_REQUEST['prev_qid']))
841  {
842  $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
843  }
844 
845  $this->ctrl->setParameter($this, 'q_id', $new_id);
846  $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
847  #$this->ctrl->setParameter($this, 'test_ref_id', false);
848  }
849  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
850  $this->ctrl->redirect($this, 'editQuestion');
851 
852  }
853  else
854  {
855  $this->callNewIdListeners($this->object->getId());
856 
857  if($this->object->getId() != $old_id)
858  {
859  // first save
860  $this->ctrl->setParameterByClass($_GET["cmdClass"], "q_id", $this->object->getId());
861  $this->ctrl->setParameterByClass($_GET["cmdClass"], "sel_question_types", $_GET["sel_question_types"]);
862  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
863 
864  //global $___test_express_mode;
868  if($_REQUEST['prev_qid'])
869  {
870  // @todo: bheyser/mbecker wtf? ..... thx@jposselt ....
871  // mbecker: Possible fix: Just instantiate the obj?
872  include_once("./Modules/Test/classes/class.ilObjTest.php");
873  $test = new ilObjTest($_GET["ref_id"], true);
874  $test->moveQuestionAfter($_REQUEST['prev_qid'], $this->object->getId());
875  }
876  if( /*$___test_express_mode || */ $_REQUEST['express_mode'] )
877  {
878  global $tree, $ilDB, $ilPluginAdmin;
879 
880  include_once("./Modules/Test/classes/class.ilObjTest.php");
881  $test = new ilObjTest($_GET["ref_id"], true);
882 
883  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
884  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
885 
886  $test->insertQuestion(
887  $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId()
888  );
889 
890  require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
891  $_REQUEST['q_id'] = $this->object->getId();
893  }
894 
895  $this->ctrl->redirectByClass($_GET["cmdClass"], "editQuestion");
896  }
897  if(strcmp($_SESSION["info"], "") != 0)
898  {
899  ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
900  }
901  else
902  {
903  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
904  }
905  $this->ctrl->redirect($this, 'editQuestion');
906  }
907  }
908  }
909 
913  function saveReturn()
914  {
915  global $ilUser;
916  $old_id = $_GET["q_id"];
917  $result = $this->writePostData();
918  if($result == 0)
919  {
920  $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
921  $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
922  $this->object->saveToDb();
923  $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
924  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
925  if(($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
926  {
927  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
928  $this->ctrl->setParameter($this, 'test_express_mode', $_REQUEST['test_express_mode']);
929  $this->ctrl->redirect($this, "originalSyncForm");
930  return;
931  }
932  elseif($_GET["calling_test"])
933  {
934  require_once 'Modules/Test/classes/class.ilObjTest.php';
935  $test = new ilObjTest($_GET["calling_test"]);
936  #var_dump(assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()));
937  $q_id = $this->object->getId();
938  if(!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()))
939  {
940  global $tree, $ilDB, $ilPluginAdmin;
941 
942  include_once("./Modules/Test/classes/class.ilObjTest.php");
943  $_GET["ref_id"] = $_GET["calling_test"];
944  $test = new ilObjTest($_GET["calling_test"], true);
945 
946  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
947  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
948 
949  $new_id = $test->insertQuestion(
950  $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId()
951  );
952 
953  $q_id = $new_id;
954  if(isset($_REQUEST['prev_qid']))
955  {
956  $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
957  }
958 
959  $this->ctrl->setParameter($this, 'q_id', $new_id);
960  $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
961  #$this->ctrl->setParameter($this, 'test_ref_id', false);
962 
963  }
964  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
965  if( /*$___test_express_mode || */
966  $_REQUEST['test_express_mode']
967  )
968  {
970  }
971  else
972  {
973  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
974  }
975  }
976  else
977  {
978  if($this->object->getId() != $old_id)
979  {
980  $this->callNewIdListeners($this->object->getId());
981  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
982  $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
983  }
984  if(strcmp($_SESSION["info"], "") != 0)
985  {
986  ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
987  }
988  else
989  {
990  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
991  }
992  $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
993  }
994  }
995  }
996 
1000  function apply()
1001  {
1002  $this->writePostData();
1003  $this->object->saveToDb();
1004  $this->ctrl->setParameter($this, "q_id", $this->object->getId());
1005  $this->editQuestion();
1006  }
1007 
1014  function getContextPath($cont_obj, $a_endnode_id, $a_startnode_id = 1)
1015  {
1016  $path = "";
1017 
1018  $tmpPath = $cont_obj->getLMTree()->getPathFull($a_endnode_id, $a_startnode_id);
1019 
1020  // count -1, to exclude the learning module itself
1021  for ($i = 1; $i < (count($tmpPath) - 1); $i++)
1022  {
1023  if ($path != "")
1024  {
1025  $path .= " > ";
1026  }
1027 
1028  $path .= $tmpPath[$i]["title"];
1029  }
1030 
1031  return $path;
1032  }
1033 
1034  function setSequenceNumber($nr)
1035  {
1036  $this->sequence_no = $nr;
1037  }
1038 
1039  function getSequenceNumber()
1040  {
1041  return $this->sequence_no;
1042  }
1043 
1044  function setQuestionCount($a_question_count)
1045  {
1046  $this->question_count = $a_question_count;
1047  }
1048 
1049  function getQuestionCount()
1050  {
1051  return $this->question_count;
1052  }
1053 
1054  function getErrorMessage()
1055  {
1056  return $this->errormessage;
1057  }
1058 
1059  function setErrorMessage($errormessage)
1060  {
1061  $this->errormessage = $errormessage;
1062  }
1063 
1064  function addErrorMessage($errormessage)
1065  {
1066  $this->errormessage .= ((strlen($this->errormessage)) ? "<br />" : "") . $errormessage;
1067  }
1068 
1070  {
1071  }
1072 
1081  function getQuestionType()
1082  {
1083  return $this->object->getQuestionType();
1084  }
1085 
1093  public function getAsValueAttribute($a_value)
1094  {
1095  $result = "";
1096  if (strlen($a_value))
1097  {
1098  $result = " value=\"$a_value\" ";
1099  }
1100  return $result;
1101  }
1102 
1103  // scorm2004-start
1108  function addNewIdListener(&$a_object, $a_method, $a_parameters = "")
1109  {
1110  $cnt = $this->new_id_listener_cnt;
1111  $this->new_id_listeners[$cnt]["object"] =& $a_object;
1112  $this->new_id_listeners[$cnt]["method"] = $a_method;
1113  $this->new_id_listeners[$cnt]["parameters"] = $a_parameters;
1114  $this->new_id_listener_cnt++;
1115  }
1116 
1120  function callNewIdListeners($a_new_id)
1121  {
1122 
1123  for ($i=0; $i<$this->new_id_listener_cnt; $i++)
1124  {
1125  $this->new_id_listeners[$i]["parameters"]["new_id"] = $a_new_id;
1126  $object =& $this->new_id_listeners[$i]["object"];
1127  $method = $this->new_id_listeners[$i]["method"];
1128  $parameters = $this->new_id_listeners[$i]["parameters"];
1129 //var_dump($object);
1130 //var_dump($method);
1131 //var_dump($parameters);
1132 
1133  $object->$method($parameters);
1134  }
1135  }
1136 
1141  {
1142  //if (!$this->object->getSelfAssessmentEditingMode() && !$_GET["calling_test"]) $form->addCommandButton("saveEdit", $this->lng->txt("save_edit"));
1143  if(!$this->object->getSelfAssessmentEditingMode())
1144  {
1145  $form->addCommandButton("saveReturn", $this->lng->txt("save_return"));
1146  }
1147  $form->addCommandButton("save", $this->lng->txt("save"));
1148  }
1149 
1157  {
1158  // title
1159  $title = new ilTextInputGUI($this->lng->txt("title"), "title");
1160  $title->setMaxLength(100);
1161  $title->setValue($this->object->getTitle());
1162  $title->setRequired(TRUE);
1163  $form->addItem($title);
1164 
1165  if (!$this->object->getSelfAssessmentEditingMode())
1166  {
1167  // author
1168  $author = new ilTextInputGUI($this->lng->txt("author"), "author");
1169  $author->setValue($this->object->getAuthor());
1170  $author->setRequired(TRUE);
1171  $form->addItem($author);
1172 
1173  // description
1174  $description = new ilTextInputGUI($this->lng->txt("description"), "comment");
1175  $description->setValue($this->object->getComment());
1176  $description->setRequired(FALSE);
1177  $form->addItem($description);
1178  }
1179  else
1180  {
1181  // author as hidden field
1182  $hi = new ilHiddenInputGUI("author");
1183  $author = ilUtil::prepareFormOutput($this->object->getAuthor());
1184  if (trim($author) == "")
1185  {
1186  $author = "-";
1187  }
1188  $hi->setValue($author);
1189  $form->addItem($hi);
1190 
1191  }
1192 
1193  // questiontext
1194  $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
1195  $question->setValue($this->object->getQuestion());
1196  $question->setRequired(TRUE);
1197  $question->setRows(10);
1198  $question->setCols(80);
1199 
1200  if (!$this->object->getSelfAssessmentEditingMode())
1201  {
1202  if( $this->object->getAdditionalContentEditingMode() != assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT )
1203  {
1204  $question->setUseRte(TRUE);
1205  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
1206  $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
1207  $question->addPlugin("latex");
1208  $question->addButton("latex");
1209  $question->addButton("pastelatex");
1210  $question->setRTESupport($this->object->getId(), "qpl", "assessment");
1211  }
1212  }
1213  else
1214  {
1215  require_once 'Modules/TestQuestionPool/classes/questions/class.ilAssSelfAssessmentQuestionFormatter.php';
1217  $question->setUseTagsForRteOnly(false);
1218  }
1219  $form->addItem($question);
1220 
1221  if (!$this->object->getSelfAssessmentEditingMode())
1222  {
1223  // duration
1224  $duration = new ilDurationInputGUI($this->lng->txt("working_time"), "Estimated");
1225  $duration->setShowHours(TRUE);
1226  $duration->setShowMinutes(TRUE);
1227  $duration->setShowSeconds(TRUE);
1228  $ewt = $this->object->getEstimatedWorkingTime();
1229  $duration->setHours($ewt["h"]);
1230  $duration->setMinutes($ewt["m"]);
1231  $duration->setSeconds($ewt["s"]);
1232  $duration->setRequired(FALSE);
1233  $form->addItem($duration);
1234  }
1235  else
1236  {
1237  // number of tries
1238  if (strlen($this->object->getNrOfTries()))
1239  {
1240  $nr_tries = $this->object->getNrOfTries();
1241  }
1242  else
1243  {
1244  $nr_tries = $this->object->getDefaultNrOfTries();
1245  }
1246  if ($nr_tries < 1)
1247  {
1248  $nr_tries = "";
1249  }
1250 
1251  $ni = new ilNumberInputGUI($this->lng->txt("qst_nr_of_tries"), "nr_of_tries");
1252  $ni->setValue($nr_tries);
1253  $ni->setMinValue(0);
1254  $ni->setSize(5);
1255  $ni->setMaxLength(5);
1256  $form->addItem($ni);
1257  }
1258  }
1259 
1260  protected function saveTaxonomyAssignments()
1261  {
1262  if( count($this->getTaxonomyIds()) )
1263  {
1264  require_once 'Services/Taxonomy/classes/class.ilTaxAssignInputGUI.php';
1265 
1266  foreach($this->getTaxonomyIds() as $taxonomyId)
1267  {
1268  $postvar = "tax_node_assign_$taxonomyId";
1269 
1270  $tax_node_assign = new ilTaxAssignInputGUI($taxonomyId, true, '', $postvar);
1271  // TODO: determine tst/qpl when tax assigns become maintainable within tests
1272  $tax_node_assign->saveInput("qpl", $this->object->getObjId(), "quest", $this->object->getId());
1273  }
1274  }
1275  }
1276 
1278  {
1279  if( count($this->getTaxonomyIds()) )
1280  {
1281  $sectHeader = new ilFormSectionHeaderGUI();
1282  $sectHeader->setTitle($this->lng->txt('qpl_qst_edit_form_taxonomy_section'));
1283  $form->addItem($sectHeader);
1284 
1285  require_once 'Services/Taxonomy/classes/class.ilTaxSelectInputGUI.php';
1286 
1287  foreach($this->getTaxonomyIds() as $taxonomyId)
1288  {
1289  $taxonomy = new ilObjTaxonomy($taxonomyId);
1290  $label = sprintf($this->lng->txt('qpl_qst_edit_form_taxonomy'), $taxonomy->getTitle());
1291  $postvar = "tax_node_assign_$taxonomyId";
1292 
1293  $taxSelect = new ilTaxSelectInputGUI($taxonomy->getId(), $postvar, true);
1294  $taxSelect->setTitle($label);
1295 
1296  require_once 'Services/Taxonomy/classes/class.ilTaxNodeAssignment.php';
1297  $taxNodeAssignments = new ilTaxNodeAssignment(ilObject::_lookupType($this->object->getObjId()), $this->object->getObjId(), 'quest', $taxonomyId);
1298  $assignedNodes = $taxNodeAssignments->getAssignmentsOfItem($this->object->getId());
1299 
1300  $taxSelect->setValue(array_map(function($assignedNode) {
1301  return $assignedNode['node_id'];
1302  }, $assignedNodes));
1303  $form->addItem($taxSelect);
1304  }
1305  }
1306  }
1307 
1317  function getAnswerFeedbackOutput($active_id, $pass)
1318  {
1319  return $this->getGenericFeedbackOutput($active_id, $pass);
1320  }
1321 
1331  function getGenericFeedbackOutput($active_id, $pass)
1332  {
1333  $output = "";
1334  include_once "./Modules/Test/classes/class.ilObjTest.php";
1335  $manual_feedback = ilObjTest::getManualFeedback($active_id, $this->object->getId(), $pass);
1336  if (strlen($manual_feedback))
1337  {
1338  return $manual_feedback;
1339  }
1340  $correct_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true);
1341  $incorrect_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false);
1342  if (strlen($correct_feedback.$incorrect_feedback))
1343  {
1344  $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
1345  $max_points = $this->object->getMaximumPoints();
1346  if ($reached_points == $max_points)
1347  {
1348  $output = $correct_feedback;
1349  }
1350  else
1351  {
1352  $output = $incorrect_feedback;
1353  }
1354  }
1355  return $this->object->prepareTextareaOutput($output, TRUE);
1356  }
1357 
1359  {
1360  return $this->object->prepareTextareaOutput(
1361  $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true), true
1362  );
1363  }
1364 
1366  {
1367  return $this->object->prepareTextareaOutput(
1368  $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false), true
1369  );
1370  }
1371 
1383  abstract function getSpecificFeedbackOutput($active_id, $pass);
1384 
1385  public function outQuestionType()
1386  {
1387  $count = $this->object->isInUse();
1388 
1389  if ($this->object->_questionExistsInPool($this->object->getId()) && $count)
1390  {
1391  global $rbacsystem;
1392  if ($rbacsystem->checkAccess("write", $_GET["ref_id"]))
1393  {
1394  ilUtil::sendInfo(sprintf($this->lng->txt("qpl_question_is_in_use"), $count));
1395  }
1396  }
1397 
1398  return assQuestion::_getQuestionTypeName($this->object->getQuestionType());
1399  }
1400 
1401  public function showSuggestedSolution()
1402  {
1403  $this->suggestedsolution();
1404  }
1405 
1411  public function suggestedsolution()
1412  {
1413  global $ilUser;
1414  global $ilAccess;
1415 
1416  $save = (is_array($_POST["cmd"]) && array_key_exists("suggestedsolution", $_POST["cmd"])) ? TRUE : FALSE;
1417 
1418  if ($save && $_POST["deleteSuggestedSolution"] == 1)
1419  {
1420  $this->object->deleteSuggestedSolutions();
1421  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1422  $this->ctrl->redirect($this, "suggestedsolution");
1423  }
1424 
1425  $output = "";
1426  $solution_array = $this->object->getSuggestedSolution(0);
1427  $options = array(
1428  "lm" => $this->lng->txt("obj_lm"),
1429  "st" => $this->lng->txt("obj_st"),
1430  "pg" => $this->lng->txt("obj_pg"),
1431  "git" => $this->lng->txt("glossary_term"),
1432  "file" => $this->lng->txt("fileDownload"),
1433  "text" => $this->lng->txt("solutionText")
1434  );
1435 
1436  if ((strcmp($_POST["solutiontype"], "file") == 0) && (strcmp($solution_array["type"], "file") != 0))
1437  {
1438  $solution_array = array(
1439  "type" => "file"
1440  );
1441  }
1442  elseif ((strcmp($_POST["solutiontype"], "text") == 0) && (strcmp($solution_array["type"], "text") != 0))
1443  {
1444  $oldOutputMode = $this->getRenderPurpose();
1445  $this->setRenderPurpose(self::RENDER_PURPOSE_INPUT_VALUE);
1446 
1447  $solution_array = array(
1448  "type" => "text",
1449  "value" => $this->getSolutionOutput(0, NULL, FALSE, FALSE, TRUE, FALSE, TRUE)
1450  );
1451  $this->setRenderPurpose($oldsaveSuggestedSolutionOutputMode);
1452  }
1453  if ($save && strlen($_POST["filename"]))
1454  {
1455  $solution_array["value"]["filename"] = $_POST["filename"];
1456  }
1457  if ($save && strlen($_POST["solutiontext"]))
1458  {
1459  $solution_array["value"] = $_POST["solutiontext"];
1460  }
1461  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
1462  if (count($solution_array))
1463  {
1464  $form = new ilPropertyFormGUI();
1465  $form->setFormAction($this->ctrl->getFormAction($this));
1466  $form->setTitle($this->lng->txt("solution_hint"));
1467  $form->setMultipart(TRUE);
1468  $form->setTableWidth("100%");
1469  $form->setId("suggestedsolutiondisplay");
1470 
1471  // suggested solution output
1472  include_once "./Modules/TestQuestionPool/classes/class.ilSolutionTitleInputGUI.php";
1473  $title = new ilSolutionTitleInputGUI($this->lng->txt("showSuggestedSolution"), "solutiontype");
1474  $template = new ilTemplate("tpl.il_as_qpl_suggested_solution_input_presentation.html", TRUE, TRUE, "Modules/TestQuestionPool");
1475  if (strlen($solution_array["internal_link"]))
1476  {
1477  $href = assQuestion::_getInternalLinkHref($solution_array["internal_link"]);
1478  $template->setCurrentBlock("preview");
1479  $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1480  $template->setVariable("VALUE_SOLUTION", " <a href=\"$href\" target=\"content\">" . $this->lng->txt("view"). "</a> ");
1481  $template->parseCurrentBlock();
1482  }
1483  elseif ((strcmp($solution_array["type"], "file") == 0) && (is_array($solution_array["value"])))
1484  {
1485  $href = $this->object->getSuggestedSolutionPathWeb() . $solution_array["value"]["name"];
1486  $template->setCurrentBlock("preview");
1487  $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1488  $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> ");
1489  $template->parseCurrentBlock();
1490  }
1491  $template->setVariable("TEXT_TYPE", $this->lng->txt("type"));
1492  $template->setVariable("VALUE_TYPE", $options[$solution_array["type"]]);
1493  $title->setHtml($template->get());
1494  $deletesolution = new ilCheckboxInputGUI("", "deleteSuggestedSolution");
1495  $deletesolution->setOptionTitle($this->lng->txt("deleteSuggestedSolution"));
1496  $title->addSubItem($deletesolution);
1497  $form->addItem($title);
1498 
1499  if (strcmp($solution_array["type"], "file") == 0)
1500  {
1501  // file
1502  $file = new ilFileInputGUI($this->lng->txt("fileDownload"), "file");
1503  $file->setRequired(TRUE);
1504  $file->enableFileNameSelection("filename");
1505  //$file->setSuffixes(array("doc","xls","png","jpg","gif","pdf"));
1506  if( $_FILES["file"]["tmp_name"] && $file->checkInput() )
1507  {
1508  if (!file_exists($this->object->getSuggestedSolutionPath())) ilUtil::makeDirParents($this->object->getSuggestedSolutionPath());
1509 
1510  $res = ilUtil::moveUploadedFile($_FILES["file"]["tmp_name"], $_FILES["file"]["name"], $this->object->getSuggestedSolutionPath() . $_FILES["file"]["name"]);
1511  if ($res)
1512  {
1513  ilUtil::renameExecutables($this->object->getSuggestedSolutionPath());
1514 
1515  // remove an old file download
1516  if (is_array($solution_array["value"])) @unlink($this->object->getSuggestedSolutionPath() . $solution_array["value"]["name"]);
1517  $file->setValue($_FILES["file"]["name"]);
1518  $this->object->saveSuggestedSolution("file", "", 0, array("name" => $_FILES["file"]["name"], "type" => $_FILES["file"]["type"], "size" => $_FILES["file"]["size"], "filename" => $_POST["filename"]));
1519  $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
1520  if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
1521  {
1522  return $this->originalSyncForm("suggestedsolution");
1523  }
1524  else
1525  {
1526  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1527  $this->ctrl->redirect($this, "suggestedsolution");
1528  }
1529  }
1530  else
1531  {
1532  // BH: $res as info string? wtf? it holds a bool or something else!!?
1533  ilUtil::sendInfo($res);
1534  }
1535  }
1536  else
1537  {
1538  if (is_array($solution_array["value"]))
1539  {
1540  $file->setValue($solution_array["value"]["name"]);
1541  $file->setFilename((strlen($solution_array["value"]["filename"])) ? $solution_array["value"]["filename"] : $solution_array["value"]["name"]);
1542  }
1543  }
1544  $form->addItem($file);
1545  $hidden = new ilHiddenInputGUI("solutiontype");
1546  $hidden->setValue("file");
1547  $form->addItem($hidden);
1548  }
1549  else if (strcmp($solution_array["type"], "text") == 0)
1550  {
1551  $solutionContent = $solution_array['value'];
1552  $solutionContent = $this->object->fixSvgToPng($solutionContent);
1553  $solutionContent = $this->object->fixUnavailableSkinImageSources($solutionContent);
1554  $question = new ilTextAreaInputGUI($this->lng->txt("solutionText"), "solutiontext");
1555  $question->setValue($this->object->prepareTextareaOutput($solutionContent));
1556  $question->setRequired(TRUE);
1557  $question->setRows(10);
1558  $question->setCols(80);
1559  $question->setUseRte(TRUE);
1560  $question->addPlugin("latex");
1561  $question->addButton("latex");
1562  $question->setRTESupport($this->object->getId(), "qpl", "assessment");
1563  $hidden = new ilHiddenInputGUI("solutiontype");
1564  $hidden->setValue("text");
1565  $form->addItem($hidden);
1566  $form->addItem($question);
1567  }
1568  if ($ilAccess->checkAccess("write", "", $_GET['ref_id']))
1569  {
1570  $form->addCommandButton('showSuggestedSolution', $this->lng->txt('cancel'));
1571  $form->addCommandButton('suggestedsolution', $this->lng->txt('save'));
1572  }
1573 
1574  if ($save)
1575  {
1576  if ($form->checkInput())
1577  {
1578  switch ($solution_array["type"])
1579  {
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  {
1595  return $this->originalSyncForm("suggestedsolution");
1596  }
1597  else
1598  {
1599  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1600  $this->ctrl->redirect($this, "suggestedsolution");
1601  }
1602  }
1603  }
1604 
1605  $output = $form->getHTML();
1606  }
1607 
1608  $savechange = (strcmp($this->ctrl->getCmd(), "saveSuggestedSolution") == 0) ? TRUE : FALSE;
1609 
1610  $changeoutput = "";
1611  if ($ilAccess->checkAccess("write", "", $_GET['ref_id']))
1612  {
1613  $formchange = new ilPropertyFormGUI();
1614  $formchange->setFormAction($this->ctrl->getFormAction($this));
1615  $formchange->setTitle((count($solution_array)) ? $this->lng->txt("changeSuggestedSolution") : $this->lng->txt("addSuggestedSolution"));
1616  $formchange->setMultipart(FALSE);
1617  $formchange->setTableWidth("100%");
1618  $formchange->setId("suggestedsolution");
1619 
1620  $solutiontype = new ilRadioGroupInputGUI($this->lng->txt("suggestedSolutionType"), "solutiontype");
1621  foreach($options as $opt_value => $opt_caption)
1622  {
1623  $solutiontype->addOption(new ilRadioOption($opt_caption, $opt_value));
1624  }
1625  if (count($solution_array))
1626  {
1627  $solutiontype->setValue($solution_array["type"]);
1628  }
1629  $solutiontype->setRequired(TRUE);
1630  $formchange->addItem($solutiontype);
1631 
1632  $formchange->addCommandButton("saveSuggestedSolution", $this->lng->txt("select"));
1633 
1634  if ($savechange)
1635  {
1636  $formchange->checkInput();
1637  }
1638  $changeoutput = $formchange->getHTML();
1639  }
1640 
1641  $this->tpl->setVariable("ADM_CONTENT", $changeoutput . $output);
1642  }
1643 
1644  public function outSolutionExplorer()
1645  {
1646  global $tree;
1647 
1648  include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1649  $type = $_GET["link_new_type"];
1650  $search = $_GET["search_link_type"];
1651  $this->ctrl->setParameter($this, "link_new_type", $type);
1652  $this->ctrl->setParameter($this, "search_link_type", $search);
1653  $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1654 
1655  ilUtil::sendInfo($this->lng->txt("select_object_to_link"));
1656 
1657  $parent_ref_id = $tree->getParentId($_GET["ref_id"]);
1658  $exp = new ilSolutionExplorer($this->ctrl->getLinkTarget($this, 'suggestedsolution'), get_class($this));
1659  $exp->setExpand($_GET['expand_sol'] ? $_GET['expand_sol'] : $parent_ref_id);
1660  $exp->setExpandTarget($this->ctrl->getLinkTarget($this, 'outSolutionExplorer'));
1661  $exp->setTargetGet("ref_id");
1662  $exp->setRefId($_GET["ref_id"]);
1663  $exp->addFilter($type);
1664  $exp->setSelectableType($type);
1665  if(isset($_GET['expandCurrentPath']) && $_GET['expandCurrentPath'])
1666  {
1667  $exp->expandPathByRefId($parent_ref_id);
1668  }
1669 
1670  // build html-output
1671  $exp->setOutput(0);
1672 
1673  $template = new ilTemplate("tpl.il_as_qpl_explorer.html", TRUE, TRUE, "Modules/TestQuestionPool");
1674  $template->setVariable("EXPLORER_TREE",$exp->getOutput());
1675  $template->setVariable("BUTTON_CANCEL",$this->lng->txt("cancel"));
1676  $template->setVariable("FORMACTION",$this->ctrl->getFormAction($this, "suggestedsolution"));
1677  $this->tpl->setVariable("ADM_CONTENT", $template->get());
1678  }
1679 
1680  public function saveSuggestedSolution()
1681  {
1682  global $tree;
1683 
1684  include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1685  switch ($_POST["solutiontype"])
1686  {
1687  case "lm":
1688  $type = "lm";
1689  $search = "lm";
1690  break;
1691  case "git":
1692  $type = "glo";
1693  $search = "glo";
1694  break;
1695  case "st":
1696  $type = "lm";
1697  $search = "st";
1698  break;
1699  case "pg":
1700  $type = "lm";
1701  $search = "pg";
1702  break;
1703  case "file":
1704  case "text":
1705  return $this->suggestedsolution();
1706  break;
1707  default:
1708  return $this->suggestedsolution();
1709  break;
1710  }
1711  if(isset($_POST['solutiontype']))
1712  {
1713  $this->ctrl->setParameter($this, 'expandCurrentPath', 1);
1714  }
1715  $this->ctrl->setParameter($this, "link_new_type", $type);
1716  $this->ctrl->setParameter($this, "search_link_type", $search);
1717  $this->ctrl->redirect($this, "outSolutionExplorer");
1718  }
1719 
1720  function cancelExplorer()
1721  {
1722  $this->ctrl->redirect($this, "suggestedsolution");
1723  }
1724 
1725  function outPageSelector()
1726  {
1727  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1728  require_once 'Modules/LearningModule/classes/class.ilLMPageObject.php';
1729  require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1730 
1731  $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1732 
1733  $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1734  $cont_obj = $cont_obj_gui->object;
1735  $pages = ilLMPageObject::getPageList($cont_obj->getId());
1736  $shownpages = array();
1737  $tree = $cont_obj->getLMTree();
1738  $chapters = $tree->getSubtree($tree->getNodeData($tree->getRootId()));
1739 
1740  $rows = array();
1741 
1742  foreach($chapters as $chapter)
1743  {
1744  $chapterpages = $tree->getChildsByType($chapter['obj_id'], 'pg');
1745  foreach($chapterpages as $page)
1746  {
1747  if($page['type'] == $_GET['search_link_type'])
1748  {
1749  array_push($shownpages, $page['obj_id']);
1750 
1751  if($tree->isInTree($page['obj_id']))
1752  {
1753  $path_str = $this->getContextPath($cont_obj, $page['obj_id']);
1754  }
1755  else
1756  {
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  {
1772  if(!in_array($page['obj_id'], $shownpages))
1773  {
1774  $this->ctrl->setParameter($this, $page['type'], $page['obj_id']);
1775  $rows[] = array(
1776  'title' => $page['title'],
1777  'description' => '---',
1778  'text_add' => $this->lng->txt('add'),
1779  'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($page['type']))
1780  );
1781  }
1782  }
1783 
1784  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1785  $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1786  $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1787  $table->setData($rows);
1788 
1789  $this->tpl->setContent($table->getHTML());
1790  }
1791 
1792  public function outChapterSelector()
1793  {
1794  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1795  require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1796 
1797  $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1798 
1799  $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1800  $cont_obj = $cont_obj_gui->object;
1801  $ctree = $cont_obj->getLMTree();
1802  $nodes = $ctree->getSubtree($ctree->getNodeData($ctree->getRootId()));
1803 
1804  $rows = array();
1805 
1806  foreach($nodes as $node)
1807  {
1808  if($node['type'] == $_GET['search_link_type'])
1809  {
1810  $this->ctrl->setParameter($this, $node['type'], $node['obj_id']);
1811  $rows[] = array(
1812  'title' => $node['title'],
1813  'description' => '',
1814  'text_add' => $this->lng->txt('add'),
1815  'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($node['type']))
1816  );
1817  }
1818  }
1819 
1820  $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1821  $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1822  $table->setData($rows);
1823 
1824  $this->tpl->setContent($table->getHTML());
1825  }
1826 
1827  public function outGlossarySelector()
1828  {
1829  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1830  require_once 'Modules/Glossary/classes/class.ilObjGlossary.php';
1831 
1832  $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1833 
1834  $glossary = new ilObjGlossary($_GET['source_id'], true);
1835  $terms = $glossary->getTermList();
1836 
1837  $rows = array();
1838 
1839  foreach($terms as $term)
1840  {
1841  $this->ctrl->setParameter($this, 'git', $term['id']);
1842  $rows[] = array(
1843  'title' => $term['term'],
1844  'description' => '',
1845  'text_add' => $this->lng->txt('add'),
1846  'href_add' => $this->ctrl->getLinkTarget($this, 'addGIT')
1847  );
1848  }
1849 
1850  $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1851  $table->setTitle($this->lng->txt('glossary_term'));
1852  $table->setData($rows);
1853 
1854  $this->tpl->setContent($table->getHTML());
1855  }
1856 
1857  function linkChilds()
1858  {
1859  $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1860  switch ($_GET["search_link_type"])
1861  {
1862  case "pg":
1863  return $this->outPageSelector();
1864  break;
1865  case "st":
1866  return $this->outChapterSelector();
1867  break;
1868  case "glo":
1869  return $this->outGlossarySelector();
1870  break;
1871  case "lm":
1872  $subquestion_index = ($_GET["subquestion_index"] > 0) ? $_GET["subquestion_index"] : 0;
1873  $this->object->saveSuggestedSolution("lm", "il__lm_" . $_GET["source_id"], $subquestion_index);
1874  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1875  $this->ctrl->redirect($this, "suggestedsolution");
1876  break;
1877  }
1878  }
1879 
1880  function addPG()
1881  {
1882  $subquestion_index = 0;
1883  if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0)
1884  {
1885  $subquestion_index = $_GET["subquestion_index"];
1886  }
1887  $this->object->saveSuggestedSolution("pg", "il__pg_" . $_GET["pg"], $subquestion_index);
1888  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1889  $this->ctrl->redirect($this, "suggestedsolution");
1890  }
1891 
1892  function addST()
1893  {
1894  $subquestion_index = 0;
1895  if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0)
1896  {
1897  $subquestion_index = $_GET["subquestion_index"];
1898  }
1899  $this->object->saveSuggestedSolution("st", "il__st_" . $_GET["st"], $subquestion_index);
1900  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1901  $this->ctrl->redirect($this, "suggestedsolution");
1902  }
1903 
1904  function addGIT()
1905  {
1906  $subquestion_index = 0;
1907  if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0)
1908  {
1909  $subquestion_index = $_GET["subquestion_index"];
1910  }
1911  $this->object->saveSuggestedSolution("git", "il__git_" . $_GET["git"], $subquestion_index);
1912  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1913  $this->ctrl->redirect($this, "suggestedsolution");
1914  }
1915 
1916  function isSaveCommand()
1917  {
1918  return in_array($this->ctrl->getCmd(), array('save', 'saveEdit', 'saveReturn'));
1919  }
1920 
1929  public static function getCommandsFromClassConstants($guiClassName, $cmdConstantNameBegin = 'CMD_')
1930  {
1931  $reflectionClass = new ReflectionClass($guiClassName);
1932 
1933  $commands = null;
1934 
1935  if( $reflectionClass instanceof ReflectionClass )
1936  {
1937  $commands = array();
1938 
1939  foreach($reflectionClass->getConstants() as $constName => $constValue)
1940  {
1941  if( substr($constName, 0, strlen($cmdConstantNameBegin)) == $cmdConstantNameBegin )
1942  {
1943  $commands[] = $constValue;
1944  }
1945  }
1946  }
1947 
1948  return $commands;
1949  }
1950 
1951  public function setQuestionTabs()
1952  {
1953  global $rbacsystem, $ilTabs;
1954 
1955  $ilTabs->clearTargets();
1956 
1957  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1958  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1959  $q_type = $this->object->getQuestionType();
1960 
1961  if (strlen($q_type))
1962  {
1963  $classname = $q_type . "GUI";
1964  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1965  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1966  }
1967 
1968  if ($_GET["q_id"])
1969  {
1970  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1971  {
1972  // edit page
1973  $ilTabs->addTarget("edit_page",
1974  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1975  array("edit", "insert", "exec_pg"),
1976  "", "", $force_active);
1977  }
1978 
1979  $this->addTab_QuestionPreview($ilTabs);
1980  }
1981  $force_active = false;
1982  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1983  {
1984  $url = "";
1985  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1986  $force_active = false;
1987  // edit question properties
1988  $ilTabs->addTarget("edit_question",
1989  $url,
1990  $this->getEditQuestionTabCommands(),
1991  $classname, "", $force_active);
1992  }
1993 
1994  // add tab for question feedback within common class assQuestionGUI
1995  $this->addTab_QuestionFeedback($ilTabs);
1996 
1997  // add tab for question hint within common class assQuestionGUI
1998  $this->addTab_QuestionHints($ilTabs);
1999 
2000  // add tab for question's suggested solution within common class assQuestionGUI
2001  $this->addTab_SuggestedSolution($ilTabs, $classname);
2002 
2003  // Assessment of questions sub menu entry
2004  if ($_GET["q_id"])
2005  {
2006  $ilTabs->addTarget("statistics",
2007  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
2008  array("assessment"),
2009  $classname, "");
2010  }
2011 
2012  $this->addBackTab($ilTabs);
2013  }
2014 
2015  public function addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
2016  {
2017  if ($_GET["q_id"])
2018  {
2019  $tabs->addTarget("suggested_solution",
2020  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
2021  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
2022  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
2023  ),
2024  $classname,
2025  ""
2026  );
2027  }
2028  }
2029 
2030  final public function getEditQuestionTabCommands()
2031  {
2032  return array_merge($this->getBasicEditQuestionTabCommands(), $this->getAdditionalEditQuestionCommands());
2033  }
2034 
2035  protected function getBasicEditQuestionTabCommands()
2036  {
2037  return array('editQuestion', 'save', 'saveEdit', 'originalSyncForm');
2038  }
2039 
2041  {
2042  return array();
2043  }
2044 
2051  protected function addTab_QuestionFeedback(ilTabsGUI $tabs)
2052  {
2053  global $ilCtrl;
2054 
2055  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionFeedbackEditingGUI.php';
2056  $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionFeedbackEditingGUI');
2057 
2058  $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionFeedbackEditingGUI', ilAssQuestionFeedbackEditingGUI::CMD_SHOW);
2059 
2060  $tabs->addTarget('tst_feedback', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
2061  }
2062 
2066  protected function addTab_Units(ilTabsGUI $tabs)
2067  {
2071  global $ilCtrl;
2072 
2073  $tabs->addTarget('units', $ilCtrl->getLinkTargetByClass('ilLocalUnitConfigurationGUI', ''), '', 'illocalunitconfigurationgui');
2074  }
2075 
2082  protected function addTab_QuestionHints(ilTabsGUI $tabs)
2083  {
2084  global $ilCtrl;
2085 
2086  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsGUI.php';
2087 
2088  switch( $ilCtrl->getCmdClass() )
2089  {
2090  case 'ilassquestionhintsgui':
2091 
2092  $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintsGUI');
2093  break;
2094 
2095  case 'ilassquestionhintgui':
2096 
2097  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintGUI.php';
2098  $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintGUI');
2099  break;
2100 
2101  default:
2102 
2103  $tabCommands = array();
2104  }
2105 
2106  $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
2107 
2108  $tabs->addTarget('tst_question_hints_tab', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
2109  }
2110 
2111  protected function addTab_QuestionPreview(ilTabsGUI $tabsGUI)
2112  {
2113  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionPreviewGUI.php';
2114 
2115  $tabsGUI->addTarget(
2117  $this->ctrl->getLinkTargetByClass('ilAssQuestionPreviewGUI', ilAssQuestionPreviewGUI::CMD_SHOW),
2118  array(),
2119  array('ilAssQuestionPreviewGUI')
2120  );
2121  }
2122 
2123  abstract public function getSolutionOutput(
2124  $active_id,
2125  $pass = NULL,
2126  $graphicalOutput = FALSE,
2127  $result_output = FALSE,
2128  $show_question_only = TRUE,
2129  $show_feedback = FALSE,
2130  $show_correct_solution = FALSE,
2131  $show_manual_scoring = FALSE,
2132  $show_question_text = TRUE
2133  );
2134 
2135  protected function hasCorrectSolution($activeId, $passIndex)
2136  {
2137  $reachedPoints = $this->object->getAdjustedReachedPoints($activeId, $passIndex, true);
2138  $maximumPoints = $this->object->getMaximumPoints();
2139 
2140  return $reachedPoints == $maximumPoints;
2141  }
2142 
2143  public function isAutosaveable()
2144  {
2145  return $this->object->isAutosaveable();
2146  }
2147 
2148  protected function writeQuestionGenericPostData()
2149  {
2150  $this->object->setTitle( $_POST["title"] );
2151  $this->object->setAuthor( $_POST["author"] );
2152  $this->object->setComment( $_POST["comment"] );
2153  if ($this->object->getSelfAssessmentEditingMode())
2154  {
2155  $this->object->setNrOfTries( $_POST['nr_of_tries'] );
2156  }
2157  $this->object->setQuestion( ilUtil::stripOnlySlashes($_POST['question']) ); // ?
2158  $this->object->setEstimatedWorkingTime(
2159  $_POST["Estimated"]["hh"],
2160  $_POST["Estimated"]["mm"],
2161  $_POST["Estimated"]["ss"]
2162  );
2163  }
2164 
2165  abstract public function getPreview($show_question_only = FALSE, $showInlineFeedback = false);
2166 
2175  final public function outQuestionForTest(
2176  $formaction,
2177  $active_id,
2178  // hey: prevPassSolutions - pass will be always available from now on
2179  $pass,
2180  // hey.
2181  $is_question_postponed = FALSE,
2182  $user_post_solutions = FALSE,
2183  $show_specific_inline_feedback = FALSE
2184  )
2185  {
2186  $formaction = $this->completeTestOutputFormAction($formaction, $active_id, $pass);
2187 
2188  $test_output = $this->getTestOutput(
2189  $active_id,
2190  $pass,
2191  $is_question_postponed,
2192  $user_post_solutions,
2193  $show_specific_inline_feedback
2194  );
2195 
2196  $this->magicAfterTestOutput();
2197 
2198  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
2199  $this->tpl->setVariable("FORMACTION", $formaction);
2200  $this->tpl->setVariable("ENCTYPE", 'enctype="'.$this->getFormEncodingType().'"');
2201  $this->tpl->setVariable("FORM_TIMESTAMP", time());
2202  }
2203 
2204  // hey: prevPassSolutions - $pass will be passed always from now on
2205  protected function completeTestOutputFormAction($formAction, $active_id, $pass)
2206  // hey.
2207  {
2208  return $formAction;
2209  }
2210 
2211  public function magicAfterTestOutput()
2212  {
2213  return;
2214  }
2215 
2216  abstract public function getTestOutput(
2217  $active_id,
2218  $pass,
2219  $is_question_postponed,
2220  $user_post_solutions,
2221  $show_specific_inline_feedback
2222  );
2223 
2224  public function getFormEncodingType()
2225  {
2226  return self::FORM_ENCODING_URLENCODE;
2227  }
2228 
2232  protected function addBackTab(ilTabsGUI $ilTabs)
2233  {
2234  if(($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
2235  {
2236  $ref_id = $_GET["calling_test"];
2237  if(strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
2238 
2239  if(!$_GET['test_express_mode'] && !$GLOBALS['___test_express_mode'])
2240  {
2241  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
2242  }
2243  else
2244  {
2246  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
2247  }
2248  }
2249  else if(isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])
2250  {
2251  $ref_id = (int)$_GET['calling_consumer'];
2253  if($consumer instanceof ilQuestionEditingFormConsumer)
2254  {
2255  $ilTabs->setBackTarget($consumer->getQuestionEditingFormBackTargetLabel(), $consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
2256  }
2257  else
2258  {
2259  require_once 'Services/Link/classes/class.ilLink.php';
2260  $ilTabs->setBackTarget($this->lng->txt("qpl"), ilLink::_getLink($ref_id));
2261  }
2262  }
2263  else
2264  {
2265  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
2266  }
2267  }
2268 
2273 
2278  {
2279  $this->previewSession = $previewSession;
2280  }
2281 
2285  public function getPreviewSession()
2286  {
2287  return $this->previewSession;
2288  }
2289 
2293  protected function buildBasicEditFormObject()
2294  {
2295  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
2296  $form = new ilPropertyFormGUI();
2297 
2298  $form->setFormAction($this->ctrl->getFormAction($this));
2299 
2300  $form->setId($this->getType());
2301  $form->setTitle($this->outQuestionType());
2302 
2303  $form->setTableWidth('100%');
2304 
2305  $form->setMultipart(true);
2306 
2307  return $form;
2308  }
2309 
2310  public function showHints()
2311  {
2312  global $ilCtrl;
2313  $ilCtrl->redirectByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
2314  }
2315 
2319  protected function buildEditForm()
2320  {
2321  $errors = $this->editQuestion(true); // TODO bheyser: editQuestion should be added to the abstract base class with a unified signature
2322  return $this->editForm;
2323  }
2324 }
QTI assessment class.
static sendSuccess($a_info="", $a_keep=false)
Send Success Message to Screen.
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)
This class represents an option in a radio group.
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)
$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.
static getQuestionTypeFromDb($question_id)
get question type for question id
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.
getPreview($show_question_only=FALSE, $showInlineFeedback=false)
suggestedsolution()
Allows to add suggested solutions for questions.
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.
$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"]
This class represents a section header in a property form.
This class represents a file property in a property form.
Class ilObjGlossary.
const SESSION_PREVIEW_DATA_BASE_INDEX
setPresentationContext($presentationContext)
static _getUsedHTMLTags($a_module="")
Returns an array of all allowed HTML tags for text editing.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
$cmd
Definition: sahs_server.php:35
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)
$url
Definition: shib_logout.php:72
setRenderPurpose($renderPurpose)
callNewIdListeners($a_new_id)
Call the new id listeners.
This class represents a custom property in a property form.
getQuestionTemplate()
get question template
addTarget($a_text, $a_link, $a_cmd="", $a_cmdClass="", $a_frame="", $a_activate=false, $a_dir_text=false)
Class ilQuestionUsagesTableGUI.
setEditContext($editContext)
setBackTarget($a_title, $a_target, $a_frame="")
back target for upper context
Question page GUI class.
populateTaxonomyFormSection(ilPropertyFormGUI $form)
apply()
apply changes
const CMD_SHOW_LIST
command constants
saveEdit()
save question
static stripOnlySlashes($a_str)
strip slashes if magic qoutes is enabled
global $ilCtrl
Definition: ilias.php:18
$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...
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
This class represents a hidden form property in a property 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.
static getReturnToPageLink($q_id=null)
if(!is_array($argv)) $options
addJavaScript($a_js_file, $a_add_version_parameter=true, $a_batch=2)
Add a javascript file that should be included in the header.
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 moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
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)
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
static _getClassNameForQType($q_type)
outQuestionForTest( $formaction, $active_id, $pass, $is_question_postponed=FALSE, $user_post_solutions=FALSE, $show_specific_inline_feedback=FALSE)
Input GUI class for taxonomy assignments.
completeTestOutputFormAction($formAction, $active_id, $pass)
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.
$errors
$ref_id
Definition: sahs_server.php:39
Create new PHPExcel object
obj_idprivate
static renameExecutables($a_dir)
Rename uploaded executables for security reasons.
This class represents a text area property in a property form.
addBackTab(ilTabsGUI $ilTabs)
global $ilDB
$ret
Definition: parser.php:6
setPreviewSession($previewSession)
Class ilObjContentObjectGUI.
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
static getGuiClassNameByQuestionType($questionType)
outQuestionPage($a_temp_var, $a_postponed=false, $active_id="", $html="")
output question page
global $DIC
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
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)
http redirect to other script
save()
save question
static getFeedbackClassNameByQuestionType($questionType)
$_POST["username"]
$html
Definition: example_001.php:87
saveReturn()
save question
getSpecificFeedbackOutput($active_id, $pass)
Returns the answer specific feedback for the question.
setExpand($a_node_id)
set the expand option this value is stored in a SESSION variable to save it different view (lo view...
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)