ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
19 abstract class assQuestionGUI
20 {
21  const FORM_MODE_EDIT = 'edit';
22  const FORM_MODE_ADJUST = 'adjust';
23 
24  const FORM_ENCODING_URLENCODE = 'application/x-www-form-urlencoded';
25  const FORM_ENCODING_MULTIPART = 'multipart/form-data';
26 
27  const SESSION_PREVIEW_DATA_BASE_INDEX = 'ilAssQuestionPreviewAnswers';
28 
36  var $object;
37 
38  var $tpl;
39  var $lng;
40  var $error;
42 
51 
52  private $taxonomyIds = array();
53 
54  private $targetGuiClass = null;
55 
56  private $questionActionCmd = 'handleQuestionAction';
57 
62 
66  function __construct()
67  {
68  global $lng, $tpl, $ilCtrl;
69 
70 
71  $this->lng =& $lng;
72  $this->tpl =& $tpl;
73  $this->ctrl =& $ilCtrl;
74  $this->ctrl->saveParameter($this, "q_id");
75  $this->ctrl->saveParameter($this, "prev_qid");
76  $this->ctrl->saveParameter($this, "calling_test");
77  $this->ctrl->saveParameter($this, "calling_consumer");
78  $this->ctrl->saveParameter($this, "consumer_context");
79  $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'test_express_mode');
80  $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'calling_consumer');
81  $this->ctrl->saveParameterByClass('ilAssQuestionPageGUI', 'consumer_context');
82  $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'test_express_mode');
83  $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'calling_consumer');
84  $this->ctrl->saveParameterByClass('ilobjquestionpoolgui', 'consumer_context');
85 
86  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
87  $this->errormessage = $this->lng->txt("fill_out_all_required_fields");
88 
89  $this->selfassessmenteditingmode = false;
90  $this->new_id_listeners = array();
91  $this->new_id_listener_cnt = 0;
92  }
93 
97  function &executeCommand()
98  {
99  $cmd = $this->ctrl->getCmd("editQuestion");
100  $next_class = $this->ctrl->getNextClass($this);
101 
102  $cmd = $this->getCommand($cmd);
103 
104  switch($next_class)
105  {
106  default:
107  $ret =& $this->$cmd();
108  break;
109  }
110  return $ret;
111  }
112 
113  function getCommand($cmd)
114  {
115  return $cmd;
116  }
117 
121  function getType()
122  {
123  return $this->getQuestionType();
124  }
125 
126  public function setTaxonomyIds($taxonomyIds)
127  {
128  $this->taxonomyIds = $taxonomyIds;
129  }
130 
131  public function getTaxonomyIds()
132  {
133  return $this->taxonomyIds;
134  }
135 
136  public function setTargetGui($linkTargetGui)
137  {
138  $this->setTargetGuiClass( get_class($linkTargetGui) );
139  }
140 
142  {
143  $this->targetGuiClass = $targetGuiClass;
144  }
145 
146  public function getTargetGuiClass()
147  {
148  return $this->targetGuiClass;
149  }
150 
155  {
156  $this->questionHeaderBlockBuilder = $questionHeaderBlockBuilder;
157  }
158 
160  {
161  $this->questionActionCmd = $questionActionCmd;
162 
163  if( is_object($this->object) )
164  {
165  $this->object->questionActionCmd = $questionActionCmd;
166  }
167  }
168 
169  public function getQuestionActionCmd()
170  {
172  }
173 
180  protected function writePostData()
181  {
182  }
183 
187  public function assessment()
188  {
192  global $tpl;
193 
194  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionCumulatedStatisticsTableGUI.php';
195  $stats_table = new ilQuestionCumulatedStatisticsTableGUI($this, 'assessment', '', $this->object);
196 
197  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionUsagesTableGUI.php';
198  $usage_table = new ilQuestionUsagesTableGUI($this, 'assessment', '', $this->object);
199 
200  $tpl->setContent(implode('<br />', array(
201  $stats_table->getHTML(),
202  $usage_table->getHTML()
203  )));
204  }
205 
215  public function &_getQuestionGUI($question_type, $question_id = -1)
216  {
217  global $ilCtrl, $ilDB, $lng;
218 
219  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
220 
221  if ((!$question_type) and ($question_id > 0))
222  {
223  $question_type = assQuestion::getQuestionTypeFromDb($question_id);
224  }
225 
226  if (strlen($question_type) == 0) return NULL;
227 
228  assQuestion::_includeClass($question_type, 1);
229 
230  $question_type_gui = assQuestion::getGuiClassNameByQuestionType($question_type);
231  $question =& new $question_type_gui();
232 
233  $feedbackObjectClassname = assQuestion::getFeedbackClassNameByQuestionType($question_type);
234  $question->object->feedbackOBJ = new $feedbackObjectClassname($question->object, $ilCtrl, $ilDB, $lng);
235 
236  if ($question_id > 0)
237  {
238  $question->object->loadFromDb($question_id);
239  }
240 
241  return $question;
242  }
243 
247  function _getGUIClassNameForId($a_q_id)
248  {
249  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
250  include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
251  $q_type = assQuestion::getQuestionTypeFromDb($a_q_id);
252  $class_name = assQuestionGUI::_getClassNameForQType($q_type);
253  return $class_name;
254  }
255 
259  function _getClassNameForQType($q_type)
260  {
261  return $q_type . "GUI";
262  }
263 
276  function &createQuestionGUI($question_type, $question_id = -1)
277  {
278  include_once "./Modules/TestQuestionPool/classes/class.assQuestionGUI.php";
279  $this->question =& assQuestionGUI::_getQuestionGUI($question_type, $question_id);
280  }
281 
286  {
287  $this->tpl->addBlockFile("CONTENT", "content", "tpl.il_as_qpl_content.html", "Modules/TestQuestionPool");
288  $this->tpl->addBlockFile("STATUSLINE", "statusline", "tpl.statusline.html");
289  $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_as_question.html", "Modules/TestQuestionPool");
290  }
291 
298  function getILIASPage($html = "")
299  {
300  include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
301  $page_gui = new ilAssQuestionPageGUI($this->object->getId());
302  $page_gui->setQuestionHTML(array($this->object->getId() => $html));
303  $page_gui->setOutputMode("presentation");
304  $presentation = $page_gui->presentation();
305  $presentation = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $presentation);
306  return $presentation;
307  }
308 
312  function outQuestionPage($a_temp_var, $a_postponed = false, $active_id = "", $html = "")
313  {
314  $postponed = "";
315  if ($a_postponed)
316  {
317  $postponed = " (" . $this->lng->txt("postponed") . ")";
318  }
319 
320  include_once("./Modules/TestQuestionPool/classes/class.ilAssQuestionPageGUI.php");
321  $this->lng->loadLanguageModule("content");
322  $page_gui = new ilAssQuestionPageGUI($this->object->getId());
323  $page_gui->setTemplateTargetVar($a_temp_var);
324  if (strlen($html))
325  {
326  $page_gui->setQuestionHTML(array($this->object->getId() => $html));
327  }
328  $page_gui->setOutputMode("presentation");
329 
330  include_once "./Modules/Test/classes/class.ilObjTest.php";
331  $title_output = ilObjTest::_getTitleOutput($active_id);
332 
333  if( $this->object->areObligationsToBeConsidered() && ilObjTest::isQuestionObligatory($this->object->getId()) )
334  {
335  $obligatoryString = '([-_-])';
336  }
337  else
338  {
339  $obligatoryString = '';
340  }
341 
342  switch ($title_output)
343  {
344  case 1:
345  $page_gui->setPresentationTitle(sprintf($this->lng->txt("tst_position"), $this->getSequenceNumber(), $this->getQuestionCount())." - ".$this->object->getTitle().$postponed . $obligatoryString);
346  break;
347  case 2:
348  $page_gui->setPresentationTitle(sprintf($this->lng->txt("tst_position"), $this->getSequenceNumber(), $this->getQuestionCount()).$postponed . $obligatoryString);
349  break;
350  case 0:
351  default:
352  if( !is_null($this->questionHeaderBlockBuilder) )
353  {
354  $questionBlockHeader = $this->questionHeaderBlockBuilder->getHTML();
355  }
356  else
357  {
358  $maxpoints = $this->object->getMaximumPoints();
359  if ($maxpoints == 1)
360  {
361  $maxpoints = " (".$maxpoints." ".$this->lng->txt("point").")";
362  }
363  else
364  {
365  $maxpoints = " (".$maxpoints." ".$this->lng->txt("points").")";
366  }
367  $questionBlockHeader = sprintf($this->lng->txt("tst_position"), $this->getSequenceNumber(), $this->getQuestionCount())." - ".$this->object->getTitle().$postponed.$maxpoints . $obligatoryString;
368  }
369 
370  $page_gui->setPresentationTitle($questionBlockHeader);
371  break;
372  }
373  $presentation = $page_gui->presentation();
374  if (strlen($maxpoints)) $presentation = str_replace($maxpoints, "<em>$maxpoints</em>", $presentation);
375  if (strlen($obligatoryString))
376  {
377  $replacement ='<br><span class="obligatory" style="font-size:small">'.
378  $this->lng->txt("tst_you_have_to_answer_this_question").'</span>';
379  $presentation = str_replace($obligatoryString, $replacement, $presentation);
380  }
381  $presentation = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $presentation);
382  return $presentation;
383  }
384 
388  function cancel()
389  {
390  if ($_GET["calling_test"])
391  {
392  $_GET["ref_id"] = $_GET["calling_test"];
393  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
394  }
395  elseif ($_GET["test_ref_id"])
396  {
397  $_GET["ref_id"] = $_GET["test_ref_id"];
398  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["test_ref_id"]);
399  }
400  else
401  {
402  if ($_GET["q_id"] > 0)
403  {
404  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
405  $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
406  }
407  else
408  {
409  $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
410  }
411  }
412  }
413 
418  function originalSyncForm($return_to = "", $return_to_feedback = '')
419  {
420  if (strlen($return_to))
421  {
422  $this->ctrl->setParameter($this, "return_to", $return_to);
423  }
424  else if ($_REQUEST['return_to']) {
425  $this->ctrl->setParameter($this, "return_to", $_REQUEST['return_to']);
426  }
427  if(strlen($return_to_feedback))
428  {
429  $this->ctrl->setParameter($this, 'return_to_fb', 'true');
430  }
431 
432  $template = new ilTemplate("tpl.il_as_qpl_sync_original.html",TRUE, TRUE, "Modules/TestQuestionPool");
433  $template->setVariable("BUTTON_YES", $this->lng->txt("yes"));
434  $template->setVariable("BUTTON_NO", $this->lng->txt("no"));
435  $template->setVariable("FORM_ACTION", $this->ctrl->getFormAction($this));
436  $template->setVariable("TEXT_SYNC", $this->lng->txt("confirm_sync_questions"));
437  $this->tpl->setVariable("ADM_CONTENT", $template->get());
438  }
439 
440  function sync()
441  {
442  $original_id = $this->object->original_id;
443  if ($original_id)
444  {
445  $this->object->syncWithOriginal();
446  }
447  if (strlen($_GET["return_to"]))
448  {
449  $this->ctrl->redirect($this, $_GET["return_to"]);
450  }
451  if (strlen($_REQUEST["return_to_fb"]))
452  {
453  $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
454  }
455  else
456  {
457  if(isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])
458  {
459  $ref_id = (int)$_GET['calling_consumer'];
461  if($consumer instanceof ilQuestionEditingFormConsumer)
462  {
463  ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
464  }
465  require_once 'Services/Link/classes/class.ilLink.php';
467  }
468  $_GET["ref_id"] = $_GET["calling_test"];
469  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
470  }
471  }
472 
473  function cancelSync()
474  {
475  if (strlen($_GET["return_to"]))
476  {
477  $this->ctrl->redirect($this, $_GET["return_to"]);
478  }
479  if(strlen($_REQUEST['return_to_fb']))
480  {
481  $this->ctrl->redirectByClass('ilAssQuestionFeedbackEditingGUI', 'showFeedbackForm');
482  }
483  else
484  {
485  if(isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])
486  {
487  $ref_id = (int)$_GET['calling_consumer'];
489  if($consumer instanceof ilQuestionEditingFormConsumer)
490  {
491  ilUtil::redirect($consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
492  }
493  require_once 'Services/Link/classes/class.ilLink.php';
495  }
496  $_GET["ref_id"] = $_GET["calling_test"];
497  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
498  }
499  }
500 
504  function saveEdit()
505  {
506  global $ilUser;
507 
508  $result = $this->writePostData();
509  if ($result == 0)
510  {
511  $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
512  $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
513  $this->object->saveToDb();
514  $originalexists = $this->object->_questionExists($this->object->original_id);
515  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
516  if ($_GET["calling_test"] && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
517  {
518  $this->ctrl->redirect($this, "originalSyncForm");
519  }
520  elseif ($_GET["calling_test"])
521  {
522  $_GET["ref_id"] = $_GET["calling_test"];
523  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["calling_test"]);
524  return;
525  }
526  elseif ($_GET["test_ref_id"])
527  {
528  global $tree, $ilDB, $ilPluginAdmin;
529 
530  include_once ("./Modules/Test/classes/class.ilObjTest.php");
531  $_GET["ref_id"] = $_GET["test_ref_id"];
532  $test =& new ilObjTest($_GET["test_ref_id"], true);
533 
534  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
535  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
536 
537  $test->insertQuestion( $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId() );
538 
539  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=".$_GET["test_ref_id"]);
540  }
541  else
542  {
543  $this->ctrl->setParameter($this, "q_id", $this->object->getId());
544  $this->editQuestion();
545  if (strcmp($_SESSION["info"], "") != 0)
546  {
547  ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), false);
548  }
549  else
550  {
551  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), false);
552  }
553  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $this->object->getId());
554  $this->ctrl->redirectByClass("ilAssQuestionPageGUI", "edit");
555  }
556  }
557  }
558 
562  function save()
563  {
564  global $ilUser;
565  $old_id = $_GET["q_id"];
566  $result = $this->writePostData();
567 
568  if($result == 0)
569  {
570  $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
571  $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
572  $this->object->saveToDb();
573  $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
574 
575 
576  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
577  if(($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
578  {
579  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
580  $this->ctrl->setParameter($this, 'return_to', 'editQuestion');
581  $this->ctrl->redirect($this, "originalSyncForm");
582  return;
583  }
584  elseif($_GET["calling_test"])
585  {
586  require_once 'Modules/Test/classes/class.ilObjTest.php';
587  $test = new ilObjTest($_GET["calling_test"]);
588  if(!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()))
589  {
590  global $tree, $ilDB, $ilPluginAdmin;
591 
592  include_once("./Modules/Test/classes/class.ilObjTest.php");
593  $_GET["ref_id"] = $_GET["calling_test"];
594  $test = new ilObjTest($_GET["calling_test"], true);
595 
596  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
597  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
598 
599  $new_id = $test->insertQuestion(
600  $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId()
601  );
602 
603  if(isset($_REQUEST['prev_qid']))
604  {
605  $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
606  }
607 
608  $this->ctrl->setParameter($this, 'q_id', $new_id);
609  $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
610  #$this->ctrl->setParameter($this, 'test_ref_id', false);
611  }
612  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
613  $this->ctrl->redirect($this, 'editQuestion');
614 
615  }
616  else
617  {
618  $this->callNewIdListeners($this->object->getId());
619 
620  if($this->object->getId() != $old_id)
621  {
622  // first save
623  $this->ctrl->setParameterByClass($_GET["cmdClass"], "q_id", $this->object->getId());
624  $this->ctrl->setParameterByClass($_GET["cmdClass"], "sel_question_types", $_GET["sel_question_types"]);
625  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
626 
627  //global $___test_express_mode;
631  if($_REQUEST['prev_qid'])
632  {
633  // @todo: bheyser/mbecker wtf? ..... thx@jposselt ....
634  // mbecker: Possible fix: Just instantiate the obj?
635  include_once("./Modules/Test/classes/class.ilObjTest.php");
636  $test =& new ilObjTest($_GET["ref_id"], true);
637  $test->moveQuestionAfter($_REQUEST['prev_qid'], $this->object->getId());
638  }
639  if( /*$___test_express_mode || */ $_REQUEST['express_mode'] )
640  {
641  global $tree, $ilDB, $ilPluginAdmin;
642 
643  include_once("./Modules/Test/classes/class.ilObjTest.php");
644  $test = new ilObjTest($_GET["ref_id"], true);
645 
646  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
647  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
648 
649  $test->insertQuestion(
650  $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId()
651  );
652 
653  require_once 'Modules/Test/classes/class.ilTestExpressPage.php';
654  $_REQUEST['q_id'] = $this->object->getId();
656  }
657 
658  $this->ctrl->redirectByClass($_GET["cmdClass"], "editQuestion");
659  }
660  if(strcmp($_SESSION["info"], "") != 0)
661  {
662  ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
663  }
664  else
665  {
666  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
667  }
668  $this->ctrl->redirect($this, 'editQuestion');
669  }
670  }
671  }
672 
676  function saveReturn()
677  {
678  global $ilUser;
679  $old_id = $_GET["q_id"];
680  $result = $this->writePostData();
681  if($result == 0)
682  {
683  $ilUser->setPref("tst_lastquestiontype", $this->object->getQuestionType());
684  $ilUser->writePref("tst_lastquestiontype", $this->object->getQuestionType());
685  $this->object->saveToDb();
686  $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
687  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
688  if(($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
689  {
690  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
691  $this->ctrl->redirect($this, "originalSyncForm");
692  return;
693  }
694  elseif($_GET["calling_test"])
695  {
696  require_once 'Modules/Test/classes/class.ilObjTest.php';
697  $test = new ilObjTest($_GET["calling_test"]);
698  #var_dump(assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()));
699  $q_id = $this->object->getId();
700  if(!assQuestion::_questionExistsInTest($this->object->getId(), $test->getTestId()))
701  {
702  global $tree, $ilDB, $ilPluginAdmin;
703 
704  include_once("./Modules/Test/classes/class.ilObjTest.php");
705  $_GET["ref_id"] = $_GET["calling_test"];
706  $test = new ilObjTest($_GET["calling_test"], true);
707 
708  require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
709  $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $ilPluginAdmin, $test);
710 
711  $new_id = $test->insertQuestion(
712  $testQuestionSetConfigFactory->getQuestionSetConfig(), $this->object->getId()
713  );
714 
715  $q_id = $new_id;
716  if(isset($_REQUEST['prev_qid']))
717  {
718  $test->moveQuestionAfter($this->object->getId() + 1, $_REQUEST['prev_qid']);
719  }
720 
721  $this->ctrl->setParameter($this, 'q_id', $new_id);
722  $this->ctrl->setParameter($this, 'calling_test', $_GET['calling_test']);
723  #$this->ctrl->setParameter($this, 'test_ref_id', false);
724 
725  }
726  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
727  if( /*$___test_express_mode || */
728  $_REQUEST['test_express_mode']
729  )
730  {
732  }
733  else
734  {
735  ilUtil::redirect("ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=" . $_GET["calling_test"]);
736  }
737  }
738  else
739  {
740  if($this->object->getId() != $old_id)
741  {
742  $this->callNewIdListeners($this->object->getId());
743  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
744  $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
745  }
746  if(strcmp($_SESSION["info"], "") != 0)
747  {
748  ilUtil::sendSuccess($_SESSION["info"] . "<br />" . $this->lng->txt("msg_obj_modified"), true);
749  }
750  else
751  {
752  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
753  }
754  $this->ctrl->redirectByClass("ilobjquestionpoolgui", "questions");
755  }
756  }
757  }
758 
762  function apply()
763  {
764  $this->writePostData();
765  $this->object->saveToDb();
766  $this->ctrl->setParameter($this, "q_id", $this->object->getId());
767  $this->editQuestion();
768  }
769 
776  function getContextPath($cont_obj, $a_endnode_id, $a_startnode_id = 1)
777  {
778  $path = "";
779 
780  $tmpPath = $cont_obj->getLMTree()->getPathFull($a_endnode_id, $a_startnode_id);
781 
782  // count -1, to exclude the learning module itself
783  for ($i = 1; $i < (count($tmpPath) - 1); $i++)
784  {
785  if ($path != "")
786  {
787  $path .= " > ";
788  }
789 
790  $path .= $tmpPath[$i]["title"];
791  }
792 
793  return $path;
794  }
795 
796  function setSequenceNumber($nr)
797  {
798  $this->sequence_no = $nr;
799  }
800 
801  function getSequenceNumber()
802  {
803  return $this->sequence_no;
804  }
805 
806  function setQuestionCount($a_question_count)
807  {
808  $this->question_count = $a_question_count;
809  }
810 
811  function getQuestionCount()
812  {
813  return $this->question_count;
814  }
815 
816  function getErrorMessage()
817  {
818  return $this->errormessage;
819  }
820 
822  {
823  $this->errormessage = $errormessage;
824  }
825 
827  {
828  $this->errormessage .= ((strlen($this->errormessage)) ? "<br />" : "") . $errormessage;
829  }
830 
832  {
833  }
834 
843  function getQuestionType()
844  {
845  return $this->object->getQuestionType();
846  }
847 
855  public function getAsValueAttribute($a_value)
856  {
857  $result = "";
858  if (strlen($a_value))
859  {
860  $result = " value=\"$a_value\" ";
861  }
862  return $result;
863  }
864 
865  // scorm2004-start
870  function addNewIdListener(&$a_object, $a_method, $a_parameters = "")
871  {
872  $cnt = $this->new_id_listener_cnt;
873  $this->new_id_listeners[$cnt]["object"] =& $a_object;
874  $this->new_id_listeners[$cnt]["method"] = $a_method;
875  $this->new_id_listeners[$cnt]["parameters"] = $a_parameters;
876  $this->new_id_listener_cnt++;
877  }
878 
882  function callNewIdListeners($a_new_id)
883  {
884 
885  for ($i=0; $i<$this->new_id_listener_cnt; $i++)
886  {
887  $this->new_id_listeners[$i]["parameters"]["new_id"] = $a_new_id;
888  $object =& $this->new_id_listeners[$i]["object"];
889  $method = $this->new_id_listeners[$i]["method"];
890  $parameters = $this->new_id_listeners[$i]["parameters"];
891 //var_dump($object);
892 //var_dump($method);
893 //var_dump($parameters);
894 
895  $object->$method($parameters);
896  }
897  }
898 
903  {
904  //if (!$this->object->getSelfAssessmentEditingMode() && !$_GET["calling_test"]) $form->addCommandButton("saveEdit", $this->lng->txt("save_edit"));
905  if(!$this->object->getSelfAssessmentEditingMode())
906  {
907  $form->addCommandButton("saveReturn", $this->lng->txt("save_return"));
908  }
909  $form->addCommandButton("save", $this->lng->txt("save"));
910  }
911 
919  {
920  // title
921  $title = new ilTextInputGUI($this->lng->txt("title"), "title");
922  $title->setMaxLength(100);
923  $title->setValue($this->object->getTitle());
924  $title->setRequired(TRUE);
925  $form->addItem($title);
926 
927  if (!$this->object->getSelfAssessmentEditingMode())
928  {
929  // author
930  $author = new ilTextInputGUI($this->lng->txt("author"), "author");
931  $author->setValue($this->object->getAuthor());
932  $author->setRequired(TRUE);
933  $form->addItem($author);
934 
935  // description
936  $description = new ilTextInputGUI($this->lng->txt("description"), "comment");
937  $description->setValue($this->object->getComment());
938  $description->setRequired(FALSE);
939  $form->addItem($description);
940  }
941  else
942  {
943  // author as hidden field
944  $hi = new ilHiddenInputGUI("author");
945  $author = ilUtil::prepareFormOutput($this->object->getAuthor());
946  if (trim($author) == "")
947  {
948  $author = "-";
949  }
950  $hi->setValue($author);
951  $form->addItem($hi);
952 
953  }
954 
955  // questiontext
956  $question = new ilTextAreaInputGUI($this->lng->txt("question"), "question");
957  $question->setValue($this->object->prepareTextareaOutput($this->object->getQuestion()));
958  $question->setRequired(TRUE);
959  $question->setRows(10);
960  $question->setCols(80);
961  if (!$this->object->getSelfAssessmentEditingMode())
962  {
963  if( $this->object->getAdditionalContentEditingMode() != assQuestion::ADDITIONAL_CONTENT_EDITING_MODE_PAGE_OBJECT )
964  {
965  $question->setUseRte(TRUE);
966  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
967  $question->setRteTags(ilObjAdvancedEditing::_getUsedHTMLTags("assessment"));
968  $question->addPlugin("latex");
969  $question->addButton("latex");
970  $question->addButton("pastelatex");
971  $question->setRTESupport($this->object->getId(), "qpl", "assessment");
972  }
973  }
974  else
975  {
976  $question->setRteTags(self::getSelfAssessmentTags());
977  $question->setUseTagsForRteOnly(false);
978  }
979  $form->addItem($question);
980 
981  if (!$this->object->getSelfAssessmentEditingMode())
982  {
983  // duration
984  $duration = new ilDurationInputGUI($this->lng->txt("working_time"), "Estimated");
985  $duration->setShowHours(TRUE);
986  $duration->setShowMinutes(TRUE);
987  $duration->setShowSeconds(TRUE);
988  $ewt = $this->object->getEstimatedWorkingTime();
989  $duration->setHours($ewt["h"]);
990  $duration->setMinutes($ewt["m"]);
991  $duration->setSeconds($ewt["s"]);
992  $duration->setRequired(FALSE);
993  $form->addItem($duration);
994  }
995  else
996  {
997  // number of tries
998  if (strlen($this->object->getNrOfTries()))
999  {
1000  $nr_tries = $this->object->getNrOfTries();
1001  }
1002  else
1003  {
1004  $nr_tries = $this->object->getDefaultNrOfTries();
1005  }
1006  if ($nr_tries < 1)
1007  {
1008  $nr_tries = "";
1009  }
1010 
1011  $ni = new ilNumberInputGUI($this->lng->txt("qst_nr_of_tries"), "nr_of_tries");
1012  $ni->setValue($nr_tries);
1013  $ni->setMinValue(0);
1014  $ni->setSize(5);
1015  $ni->setMaxLength(5);
1016  $form->addItem($ni);
1017  }
1018  }
1019 
1020  protected function saveTaxonomyAssignments()
1021  {
1022  if( count($this->getTaxonomyIds()) )
1023  {
1024  require_once 'Services/Taxonomy/classes/class.ilTaxAssignInputGUI.php';
1025 
1026  foreach($this->getTaxonomyIds() as $taxonomyId)
1027  {
1028  $postvar = "tax_node_assign_$taxonomyId";
1029 
1030  $tax_node_assign = new ilTaxAssignInputGUI($taxonomyId, true, '', $postvar);
1031  // TODO: determine tst/qpl when tax assigns become maintainable within tests
1032  $tax_node_assign->saveInput("qpl", $this->object->getObjId(), "quest", $this->object->getId());
1033  }
1034  }
1035  }
1036 
1038  {
1039  if( count($this->getTaxonomyIds()) )
1040  {
1041  $sectHeader = new ilFormSectionHeaderGUI();
1042  $sectHeader->setTitle($this->lng->txt('qpl_qst_edit_form_taxonomy_section'));
1043  $form->addItem($sectHeader);
1044 
1045  require_once 'Services/Taxonomy/classes/class.ilTaxAssignInputGUI.php';
1046 
1047  foreach($this->getTaxonomyIds() as $taxonomyId)
1048  {
1049  $taxonomy = new ilObjTaxonomy($taxonomyId);
1050  $label = sprintf($this->lng->txt('qpl_qst_edit_form_taxonomy'), $taxonomy->getTitle());
1051  $postvar = "tax_node_assign_$taxonomyId";
1052 
1053  $taxNodeAssign = new ilTaxAssignInputGUI($taxonomy->getId(), true, $label, $postvar);
1054  // TODO: determine tst/qpl when tax assigns become maintainable within tests
1055  $taxNodeAssign->setCurrentValues('qpl', $this->object->getObjId(), 'quest', $this->object->getId());
1056  $form->addItem($taxNodeAssign);
1057  }
1058  }
1059  }
1060 
1066  {
1067  // set tags we allow in self assessment mode
1068  $st = ilUtil::getSecureTags();
1069 
1070  // we allow these tags, since they are typically used in the Tiny Assessment editor
1071  // and should not be deleted, if questions are copied from pools to learning modules
1072  $not_supported = array("img", "p");
1073  $tags = array();
1074  foreach ($st as $s)
1075  {
1076  if (!in_array($s, $not_supported))
1077  {
1078  $tags[] = $s;
1079  }
1080  }
1081 
1082  return $tags;
1083  }
1084 
1085 
1095  function getAnswerFeedbackOutput($active_id, $pass)
1096  {
1097  return $this->getGenericFeedbackOutput($active_id, $pass);
1098  }
1099 
1109  function getGenericFeedbackOutput($active_id, $pass)
1110  {
1111  $output = "";
1112  include_once "./Modules/Test/classes/class.ilObjTest.php";
1113  $manual_feedback = ilObjTest::getManualFeedback($active_id, $this->object->getId(), $pass);
1114  if (strlen($manual_feedback))
1115  {
1116  return $manual_feedback;
1117  }
1118  $correct_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true);
1119  $incorrect_feedback = $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false);
1120  if (strlen($correct_feedback.$incorrect_feedback))
1121  {
1122  $reached_points = $this->object->calculateReachedPoints($active_id, $pass);
1123  $max_points = $this->object->getMaximumPoints();
1124  if ($reached_points == $max_points)
1125  {
1126  $output = $correct_feedback;
1127  }
1128  else
1129  {
1130  $output = $incorrect_feedback;
1131  }
1132  }
1133  return $this->object->prepareTextareaOutput($output, TRUE);
1134  }
1135 
1137  {
1138  return $this->object->prepareTextareaOutput(
1139  $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), true), true
1140  );
1141  }
1142 
1144  {
1145  return $this->object->prepareTextareaOutput(
1146  $this->object->feedbackOBJ->getGenericFeedbackTestPresentation($this->object->getId(), false), true
1147  );
1148  }
1149 
1161  abstract function getSpecificFeedbackOutput($active_id, $pass);
1162 
1163  public function outQuestionType()
1164  {
1165  $count = $this->object->isInUse();
1166 
1167  if (assQuestion::_questionExistsInPool($this->object->getId()) && $count)
1168  {
1169  global $rbacsystem;
1170  if ($rbacsystem->checkAccess("write", $_GET["ref_id"]))
1171  {
1172  ilUtil::sendInfo(sprintf($this->lng->txt("qpl_question_is_in_use"), $count));
1173  }
1174  }
1175 
1176  return assQuestion::_getQuestionTypeName($this->object->getQuestionType());
1177  }
1178 
1179  public function showSuggestedSolution()
1180  {
1181  $this->suggestedsolution();
1182  }
1183 
1189  public function suggestedsolution()
1190  {
1191  global $ilUser;
1192  global $ilAccess;
1193 
1194  $save = (is_array($_POST["cmd"]) && array_key_exists("suggestedsolution", $_POST["cmd"])) ? TRUE : FALSE;
1195 
1196  if ($save && $_POST["deleteSuggestedSolution"] == 1)
1197  {
1198  $this->object->deleteSuggestedSolutions();
1199  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1200  $this->ctrl->redirect($this, "suggestedsolution");
1201  }
1202 
1203  $output = "";
1204  $solution_array = $this->object->getSuggestedSolution(0);
1205  $options = array(
1206  "lm" => $this->lng->txt("obj_lm"),
1207  "st" => $this->lng->txt("obj_st"),
1208  "pg" => $this->lng->txt("obj_pg"),
1209  "git" => $this->lng->txt("glossary_term"),
1210  "file" => $this->lng->txt("fileDownload"),
1211  "text" => $this->lng->txt("solutionText")
1212  );
1213 
1214  if ((strcmp($_POST["solutiontype"], "file") == 0) && (strcmp($solution_array["type"], "file") != 0))
1215  {
1216  $solution_array = array(
1217  "type" => "file"
1218  );
1219  }
1220  elseif ((strcmp($_POST["solutiontype"], "text") == 0) && (strcmp($solution_array["type"], "text") != 0))
1221  {
1222  $solution_array = array(
1223  "type" => "text",
1224  "value" => $this->getSolutionOutput(0, NULL, FALSE, FALSE, TRUE, FALSE, TRUE)
1225  );
1226  }
1227  if ($save && strlen($_POST["filename"]))
1228  {
1229  $solution_array["value"]["filename"] = $_POST["filename"];
1230  }
1231  if ($save && strlen($_POST["solutiontext"]))
1232  {
1233  $solution_array["value"] = $_POST["solutiontext"];
1234  }
1235  include_once("./Services/Form/classes/class.ilPropertyFormGUI.php");
1236  if (count($solution_array))
1237  {
1238  $form = new ilPropertyFormGUI();
1239  $form->setFormAction($this->ctrl->getFormAction($this));
1240  $form->setTitle($this->lng->txt("solution_hint"));
1241  $form->setMultipart(TRUE);
1242  $form->setTableWidth("100%");
1243  $form->setId("suggestedsolutiondisplay");
1244 
1245  // suggested solution output
1246  include_once "./Modules/TestQuestionPool/classes/class.ilSolutionTitleInputGUI.php";
1247  $title = new ilSolutionTitleInputGUI($this->lng->txt("showSuggestedSolution"), "solutiontype");
1248  $template = new ilTemplate("tpl.il_as_qpl_suggested_solution_input_presentation.html", TRUE, TRUE, "Modules/TestQuestionPool");
1249  if (strlen($solution_array["internal_link"]))
1250  {
1251  $href = assQuestion::_getInternalLinkHref($solution_array["internal_link"]);
1252  $template->setCurrentBlock("preview");
1253  $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1254  $template->setVariable("VALUE_SOLUTION", " <a href=\"$href\" target=\"content\">" . $this->lng->txt("view"). "</a> ");
1255  $template->parseCurrentBlock();
1256  }
1257  elseif ((strcmp($solution_array["type"], "file") == 0) && (is_array($solution_array["value"])))
1258  {
1259  $href = $this->object->getSuggestedSolutionPathWeb() . $solution_array["value"]["name"];
1260  $template->setCurrentBlock("preview");
1261  $template->setVariable("TEXT_SOLUTION", $this->lng->txt("suggested_solution"));
1262  $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> ");
1263  $template->parseCurrentBlock();
1264  }
1265  $template->setVariable("TEXT_TYPE", $this->lng->txt("type"));
1266  $template->setVariable("VALUE_TYPE", $options[$solution_array["type"]]);
1267  $title->setHtml($template->get());
1268  $deletesolution = new ilCheckboxInputGUI("", "deleteSuggestedSolution");
1269  $deletesolution->setOptionTitle($this->lng->txt("deleteSuggestedSolution"));
1270  $title->addSubItem($deletesolution);
1271  $form->addItem($title);
1272 
1273  if (strcmp($solution_array["type"], "file") == 0)
1274  {
1275  // file
1276  $file = new ilFileInputGUI($this->lng->txt("fileDownload"), "file");
1277  $file->setRequired(TRUE);
1278  $file->enableFileNameSelection("filename");
1279  //$file->setSuffixes(array("doc","xls","png","jpg","gif","pdf"));
1280  if( $_FILES["file"]["tmp_name"] && $file->checkInput() )
1281  {
1282  if (!file_exists($this->object->getSuggestedSolutionPath())) ilUtil::makeDirParents($this->object->getSuggestedSolutionPath());
1283 
1284  $res = ilUtil::moveUploadedFile($_FILES["file"]["tmp_name"], $_FILES["file"]["name"], $this->object->getSuggestedSolutionPath() . $_FILES["file"]["name"]);
1285  if ($res)
1286  {
1287  ilUtil::renameExecutables($this->object->getSuggestedSolutionPath());
1288 
1289  // remove an old file download
1290  if (is_array($solution_array["value"])) @unlink($this->object->getSuggestedSolutionPath() . $solution_array["value"]["name"]);
1291  $file->setValue($_FILES["file"]["name"]);
1292  $this->object->saveSuggestedSolution("file", "", 0, array("name" => $_FILES["file"]["name"], "type" => $_FILES["file"]["type"], "size" => $_FILES["file"]["size"], "filename" => $_POST["filename"]));
1293  $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
1294  if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
1295  {
1296  return $this->originalSyncForm("suggestedsolution");
1297  }
1298  else
1299  {
1300  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1301  $this->ctrl->redirect($this, "suggestedsolution");
1302  }
1303  }
1304  else
1305  {
1306  // BH: $res as info string? wtf? it holds a bool or something else!!?
1307  ilUtil::sendInfo($res);
1308  }
1309  }
1310  else
1311  {
1312  if (is_array($solution_array["value"]))
1313  {
1314  $file->setValue($solution_array["value"]["name"]);
1315  $file->setFilename((strlen($solution_array["value"]["filename"])) ? $solution_array["value"]["filename"] : $solution_array["value"]["name"]);
1316  }
1317  }
1318  $form->addItem($file);
1319  $hidden = new ilHiddenInputGUI("solutiontype");
1320  $hidden->setValue("file");
1321  $form->addItem($hidden);
1322  }
1323  else if (strcmp($solution_array["type"], "text") == 0)
1324  {
1325  $question = new ilTextAreaInputGUI($this->lng->txt("solutionText"), "solutiontext");
1326  $question->setValue($this->object->prepareTextareaOutput($solution_array["value"]));
1327  $question->setRequired(TRUE);
1328  $question->setRows(10);
1329  $question->setCols(80);
1330  $question->setUseRte(TRUE);
1331  $question->addPlugin("latex");
1332  $question->addButton("latex");
1333  $question->setRTESupport($this->object->getId(), "qpl", "assessment");
1334  $hidden = new ilHiddenInputGUI("solutiontype");
1335  $hidden->setValue("text");
1336  $form->addItem($hidden);
1337  $form->addItem($question);
1338  }
1339  if ($ilAccess->checkAccess("write", "", $_GET['ref_id']))
1340  {
1341  $form->addCommandButton('showSuggestedSolution', $this->lng->txt('cancel'));
1342  $form->addCommandButton('suggestedsolution', $this->lng->txt('save'));
1343  }
1344 
1345  if ($save)
1346  {
1347  if ($form->checkInput())
1348  {
1349  switch ($solution_array["type"])
1350  {
1351  case "file":
1352  $this->object->saveSuggestedSolution("file", "", 0, array(
1353  "name" => $solution_array["value"]["name"],
1354  "type" => $solution_array["value"]["type"],
1355  "size" => $solution_array["value"]["size"],
1356  "filename" => $_POST["filename"]
1357  ));
1358  break;
1359  case "text":
1360  $this->object->saveSuggestedSolution("text", "", 0, $solution_array["value"]);
1361  break;
1362  }
1363  $originalexists = $this->object->_questionExistsInPool($this->object->original_id);
1364  if (($_GET["calling_test"] || (isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])) && $originalexists && assQuestion::_isWriteable($this->object->original_id, $ilUser->getId()))
1365  {
1366  return $this->originalSyncForm("suggestedsolution");
1367  }
1368  else
1369  {
1370  ilUtil::sendSuccess($this->lng->txt("msg_obj_modified"), true);
1371  $this->ctrl->redirect($this, "suggestedsolution");
1372  }
1373  }
1374  }
1375 
1376  $output = $form->getHTML();
1377  }
1378 
1379  $savechange = (strcmp($this->ctrl->getCmd(), "saveSuggestedSolution") == 0) ? TRUE : FALSE;
1380 
1381  $changeoutput = "";
1382  if ($ilAccess->checkAccess("write", "", $_GET['ref_id']))
1383  {
1384  $formchange = new ilPropertyFormGUI();
1385  $formchange->setFormAction($this->ctrl->getFormAction($this));
1386  $formchange->setTitle((count($solution_array)) ? $this->lng->txt("changeSuggestedSolution") : $this->lng->txt("addSuggestedSolution"));
1387  $formchange->setMultipart(FALSE);
1388  $formchange->setTableWidth("100%");
1389  $formchange->setId("suggestedsolution");
1390 
1391  $solutiontype = new ilRadioGroupInputGUI($this->lng->txt("suggestedSolutionType"), "solutiontype");
1392  foreach($options as $opt_value => $opt_caption)
1393  {
1394  $solutiontype->addOption(new ilRadioOption($opt_caption, $opt_value));
1395  }
1396  if (count($solution_array))
1397  {
1398  $solutiontype->setValue($solution_array["type"]);
1399  }
1400  $solutiontype->setRequired(TRUE);
1401  $formchange->addItem($solutiontype);
1402 
1403  $formchange->addCommandButton("saveSuggestedSolution", $this->lng->txt("select"));
1404 
1405  if ($savechange)
1406  {
1407  $formchange->checkInput();
1408  }
1409  $changeoutput = $formchange->getHTML();
1410  }
1411 
1412  $this->tpl->setVariable("ADM_CONTENT", $changeoutput . $output);
1413  }
1414 
1415  public function outSolutionExplorer()
1416  {
1417  global $tree;
1418 
1419  include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1420  $type = $_GET["link_new_type"];
1421  $search = $_GET["search_link_type"];
1422  $this->ctrl->setParameter($this, "link_new_type", $type);
1423  $this->ctrl->setParameter($this, "search_link_type", $search);
1424  $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1425 
1426  ilUtil::sendInfo($this->lng->txt("select_object_to_link"));
1427 
1428  $parent_ref_id = $tree->getParentId($_GET["ref_id"]);
1429  $exp = new ilSolutionExplorer($this->ctrl->getLinkTarget($this, 'suggestedsolution'), get_class($this));
1430  $exp->setExpand($_GET['expand_sol'] ? $_GET['expand_sol'] : $parent_ref_id);
1431  $exp->setExpandTarget($this->ctrl->getLinkTarget($this, 'outSolutionExplorer'));
1432  $exp->setTargetGet("ref_id");
1433  $exp->setRefId($_GET["ref_id"]);
1434  $exp->addFilter($type);
1435  $exp->setSelectableType($type);
1436  if(isset($_GET['expandCurrentPath']) && $_GET['expandCurrentPath'])
1437  {
1438  $exp->expandPathByRefId($parent_ref_id);
1439  }
1440 
1441  // build html-output
1442  $exp->setOutput(0);
1443 
1444  $template = new ilTemplate("tpl.il_as_qpl_explorer.html", TRUE, TRUE, "Modules/TestQuestionPool");
1445  $template->setVariable("EXPLORER_TREE",$exp->getOutput());
1446  $template->setVariable("BUTTON_CANCEL",$this->lng->txt("cancel"));
1447  $template->setVariable("FORMACTION",$this->ctrl->getFormAction($this, "suggestedsolution"));
1448  $this->tpl->setVariable("ADM_CONTENT", $template->get());
1449  }
1450 
1451  public function saveSuggestedSolution()
1452  {
1453  global $tree;
1454 
1455  include_once("./Modules/TestQuestionPool/classes/class.ilSolutionExplorer.php");
1456  switch ($_POST["solutiontype"])
1457  {
1458  case "lm":
1459  $type = "lm";
1460  $search = "lm";
1461  break;
1462  case "git":
1463  $type = "glo";
1464  $search = "glo";
1465  break;
1466  case "st":
1467  $type = "lm";
1468  $search = "st";
1469  break;
1470  case "pg":
1471  $type = "lm";
1472  $search = "pg";
1473  break;
1474  case "file":
1475  case "text":
1476  return $this->suggestedsolution();
1477  break;
1478  default:
1479  return $this->suggestedsolution();
1480  break;
1481  }
1482  if(isset($_POST['solutiontype']))
1483  {
1484  $this->ctrl->setParameter($this, 'expandCurrentPath', 1);
1485  }
1486  $this->ctrl->setParameter($this, "link_new_type", $type);
1487  $this->ctrl->setParameter($this, "search_link_type", $search);
1488  $this->ctrl->redirect($this, "outSolutionExplorer");
1489  }
1490 
1491  function cancelExplorer()
1492  {
1493  $this->ctrl->redirect($this, "suggestedsolution");
1494  }
1495 
1496  function outPageSelector()
1497  {
1498  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1499  require_once 'Modules/LearningModule/classes/class.ilLMPageObject.php';
1500  require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1501 
1502  $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1503 
1504  $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1505  $cont_obj = $cont_obj_gui->object;
1506  $pages = ilLMPageObject::getPageList($cont_obj->getId());
1507  $shownpages = array();
1508  $tree = $cont_obj->getLMTree();
1509  $chapters = $tree->getSubtree($tree->getNodeData($tree->getRootId()));
1510 
1511  $rows = array();
1512 
1513  foreach($chapters as $chapter)
1514  {
1515  $chapterpages = $tree->getChildsByType($chapter['obj_id'], 'pg');
1516  foreach($chapterpages as $page)
1517  {
1518  if($page['type'] == $_GET['search_link_type'])
1519  {
1520  array_push($shownpages, $page['obj_id']);
1521 
1522  if($tree->isInTree($page['obj_id']))
1523  {
1524  $path_str = $this->getContextPath($cont_obj, $page['obj_id']);
1525  }
1526  else
1527  {
1528  $path_str = '---';
1529  }
1530 
1531  $this->ctrl->setParameter($this, $page['type'], $page['obj_id']);
1532  $rows[] = array(
1533  'title' => $page['title'],
1534  'description' => ilUtil::prepareFormOutput($path_str),
1535  'text_add' => $this->lng->txt('add'),
1536  'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($page['type']))
1537  );
1538  }
1539  }
1540  }
1541  foreach($pages as $page)
1542  {
1543  if(!in_array($page['obj_id'], $shownpages))
1544  {
1545  $this->ctrl->setParameter($this, $page['type'], $page['obj_id']);
1546  $rows[] = array(
1547  'title' => $page['title'],
1548  'description' => '---',
1549  'text_add' => $this->lng->txt('add'),
1550  'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($page['type']))
1551  );
1552  }
1553  }
1554 
1555  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1556  $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1557  $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1558  $table->setData($rows);
1559 
1560  $this->tpl->setContent($table->getHTML());
1561  }
1562 
1563  public function outChapterSelector()
1564  {
1565  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1566  require_once 'Modules/LearningModule/classes/class.ilObjContentObjectGUI.php';
1567 
1568  $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1569 
1570  $cont_obj_gui = new ilObjContentObjectGUI('', $_GET['source_id'], true);
1571  $cont_obj = $cont_obj_gui->object;
1572  $ctree = $cont_obj->getLMTree();
1573  $nodes = $ctree->getSubtree($ctree->getNodeData($ctree->getRootId()));
1574 
1575  $rows = array();
1576 
1577  foreach($nodes as $node)
1578  {
1579  if($node['type'] == $_GET['search_link_type'])
1580  {
1581  $this->ctrl->setParameter($this, $node['type'], $node['obj_id']);
1582  $rows[] = array(
1583  'title' => $node['title'],
1584  'description' => '',
1585  'text_add' => $this->lng->txt('add'),
1586  'href_add' => $this->ctrl->getLinkTarget($this, 'add' . strtoupper($node['type']))
1587  );
1588  }
1589  }
1590 
1591  $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1592  $table->setTitle($this->lng->txt('obj_' . ilUtil::stripSlashes($_GET['search_link_type'])));
1593  $table->setData($rows);
1594 
1595  $this->tpl->setContent($table->getHTML());
1596  }
1597 
1598  public function outGlossarySelector()
1599  {
1600  require_once 'Modules/TestQuestionPool/classes/tables/class.ilQuestionInternalLinkSelectionTableGUI.php';
1601  require_once 'Modules/Glossary/classes/class.ilObjGlossary.php';
1602 
1603  $this->ctrl->setParameter($this, 'q_id', $this->object->getId());
1604 
1605  $glossary = new ilObjGlossary($_GET['source_id'], true);
1606  $terms = $glossary->getTermList();
1607 
1608  $rows = array();
1609 
1610  foreach($terms as $term)
1611  {
1612  $this->ctrl->setParameter($this, 'git', $term['id']);
1613  $rows[] = array(
1614  'title' => $term['term'],
1615  'description' => '',
1616  'text_add' => $this->lng->txt('add'),
1617  'href_add' => $this->ctrl->getLinkTarget($this, 'addGIT')
1618  );
1619  }
1620 
1621  $table = new ilQuestionInternalLinkSelectionTableGUI($this, 'cancelExplorer', __METHOD__);
1622  $table->setTitle($this->lng->txt('glossary_term'));
1623  $table->setData($rows);
1624 
1625  $this->tpl->setContent($table->getHTML());
1626  }
1627 
1628  function linkChilds()
1629  {
1630  $this->ctrl->saveParameter($this, array("subquestion_index", "link_new_type", "search_link_type"));
1631  switch ($_GET["search_link_type"])
1632  {
1633  case "pg":
1634  return $this->outPageSelector();
1635  break;
1636  case "st":
1637  return $this->outChapterSelector();
1638  break;
1639  case "glo":
1640  return $this->outGlossarySelector();
1641  break;
1642  case "lm":
1643  $subquestion_index = ($_GET["subquestion_index"] > 0) ? $_GET["subquestion_index"] : 0;
1644  $this->object->saveSuggestedSolution("lm", "il__lm_" . $_GET["source_id"], $subquestion_index);
1645  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1646  $this->ctrl->redirect($this, "suggestedsolution");
1647  break;
1648  }
1649  }
1650 
1651  function addPG()
1652  {
1653  $subquestion_index = 0;
1654  if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0)
1655  {
1656  $subquestion_index = $_GET["subquestion_index"];
1657  }
1658  $this->object->saveSuggestedSolution("pg", "il__pg_" . $_GET["pg"], $subquestion_index);
1659  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1660  $this->ctrl->redirect($this, "suggestedsolution");
1661  }
1662 
1663  function addST()
1664  {
1665  $subquestion_index = 0;
1666  if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0)
1667  {
1668  $subquestion_index = $_GET["subquestion_index"];
1669  }
1670  $this->object->saveSuggestedSolution("st", "il__st_" . $_GET["st"], $subquestion_index);
1671  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1672  $this->ctrl->redirect($this, "suggestedsolution");
1673  }
1674 
1675  function addGIT()
1676  {
1677  $subquestion_index = 0;
1678  if (strlen($_GET["subquestion_index"]) && $_GET["subquestion_index"] >= 0)
1679  {
1680  $subquestion_index = $_GET["subquestion_index"];
1681  }
1682  $this->object->saveSuggestedSolution("git", "il__git_" . $_GET["git"], $subquestion_index);
1683  ilUtil::sendSuccess($this->lng->txt("suggested_solution_added_successfully"), TRUE);
1684  $this->ctrl->redirect($this, "suggestedsolution");
1685  }
1686 
1687  function isSaveCommand()
1688  {
1689  return in_array($this->ctrl->getCmd(), array('save', 'saveEdit', 'saveReturn'));
1690  }
1691 
1700  public static function getCommandsFromClassConstants($guiClassName, $cmdConstantNameBegin = 'CMD_')
1701  {
1702  $reflectionClass = new ReflectionClass($guiClassName);
1703 
1704  $commands = null;
1705 
1706  if( $reflectionClass instanceof ReflectionClass )
1707  {
1708  $commands = array();
1709 
1710  foreach($reflectionClass->getConstants() as $constName => $constValue)
1711  {
1712  if( substr($constName, 0, strlen($cmdConstantNameBegin)) == $cmdConstantNameBegin )
1713  {
1714  $commands[] = $constValue;
1715  }
1716  }
1717  }
1718 
1719  return $commands;
1720  }
1721 
1722  public function setQuestionTabs()
1723  {
1724  global $rbacsystem, $ilTabs;
1725 
1726  $ilTabs->clearTargets();
1727 
1728  $this->ctrl->setParameterByClass("ilAssQuestionPageGUI", "q_id", $_GET["q_id"]);
1729  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1730  $q_type = $this->object->getQuestionType();
1731 
1732  if (strlen($q_type))
1733  {
1734  $classname = $q_type . "GUI";
1735  $this->ctrl->setParameterByClass(strtolower($classname), "sel_question_types", $q_type);
1736  $this->ctrl->setParameterByClass(strtolower($classname), "q_id", $_GET["q_id"]);
1737  }
1738 
1739  if ($_GET["q_id"])
1740  {
1741  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1742  {
1743  // edit page
1744  $ilTabs->addTarget("edit_page",
1745  $this->ctrl->getLinkTargetByClass("ilAssQuestionPageGUI", "edit"),
1746  array("edit", "insert", "exec_pg"),
1747  "", "", $force_active);
1748  }
1749 
1750  $this->addTab_QuestionPreview($ilTabs);
1751  }
1752  $force_active = false;
1753  if ($rbacsystem->checkAccess('write', $_GET["ref_id"]))
1754  {
1755  $url = "";
1756  if ($classname) $url = $this->ctrl->getLinkTargetByClass($classname, "editQuestion");
1757  $force_active = false;
1758  // edit question properties
1759  $ilTabs->addTarget("edit_question",
1760  $url,
1761  $this->getEditQuestionTabCommands(),
1762  $classname, "", $force_active);
1763  }
1764 
1765  // add tab for question feedback within common class assQuestionGUI
1766  $this->addTab_QuestionFeedback($ilTabs);
1767 
1768  // add tab for question hint within common class assQuestionGUI
1769  $this->addTab_QuestionHints($ilTabs);
1770 
1771  // add tab for question's suggested solution within common class assQuestionGUI
1772  $this->addTab_SuggestedSolution($ilTabs, $classname);
1773 
1774  // Assessment of questions sub menu entry
1775  if ($_GET["q_id"])
1776  {
1777  $ilTabs->addTarget("statistics",
1778  $this->ctrl->getLinkTargetByClass($classname, "assessment"),
1779  array("assessment"),
1780  $classname, "");
1781  }
1782 
1783  $this->addBackTab($ilTabs);
1784  }
1785 
1786  public function addTab_SuggestedSolution(ilTabsGUI $tabs, $classname)
1787  {
1788  if ($_GET["q_id"])
1789  {
1790  $tabs->addTarget("suggested_solution",
1791  $this->ctrl->getLinkTargetByClass($classname, "suggestedsolution"),
1792  array("suggestedsolution", "saveSuggestedSolution", "outSolutionExplorer", "cancel",
1793  "addSuggestedSolution","cancelExplorer", "linkChilds", "removeSuggestedSolution"
1794  ),
1795  $classname,
1796  ""
1797  );
1798  }
1799  }
1800 
1801  final public function getEditQuestionTabCommands()
1802  {
1803  return array_merge($this->getBasicEditQuestionTabCommands(), $this->getAdditionalEditQuestionCommands());
1804  }
1805 
1806  protected function getBasicEditQuestionTabCommands()
1807  {
1808  return array('editQuestion', 'save', 'saveEdit', 'originalSyncForm');
1809  }
1810 
1812  {
1813  return array();
1814  }
1815 
1822  protected function addTab_QuestionFeedback(ilTabsGUI $tabs)
1823  {
1824  global $ilCtrl;
1825 
1826  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionFeedbackEditingGUI.php';
1827  $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionFeedbackEditingGUI');
1828 
1829  $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionFeedbackEditingGUI', ilAssQuestionFeedbackEditingGUI::CMD_SHOW);
1830 
1831  $tabs->addTarget('tst_feedback', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
1832  }
1833 
1837  protected function addTab_Units(ilTabsGUI $tabs)
1838  {
1842  global $ilCtrl;
1843 
1844  $tabs->addTarget('units', $ilCtrl->getLinkTargetByClass('ilLocalUnitConfigurationGUI', ''), '', 'illocalunitconfigurationgui');
1845  }
1846 
1853  protected function addTab_QuestionHints(ilTabsGUI $tabs)
1854  {
1855  global $ilCtrl;
1856 
1857  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintsGUI.php';
1858 
1859  switch( $ilCtrl->getCmdClass() )
1860  {
1861  case 'ilassquestionhintsgui':
1862 
1863  $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintsGUI');
1864  break;
1865 
1866  case 'ilassquestionhintgui':
1867 
1868  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionHintGUI.php';
1869  $tabCommands = self::getCommandsFromClassConstants('ilAssQuestionHintGUI');
1870  break;
1871 
1872  default:
1873 
1874  $tabCommands = array();
1875  }
1876 
1877  $tabLink = $ilCtrl->getLinkTargetByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
1878 
1879  $tabs->addTarget('tst_question_hints_tab', $tabLink, $tabCommands, $ilCtrl->getCmdClass(), '');
1880  }
1881 
1882  protected function addTab_QuestionPreview(ilTabsGUI $tabsGUI)
1883  {
1884  require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionPreviewGUI.php';
1885 
1886  $tabsGUI->addTarget(
1888  $this->ctrl->getLinkTargetByClass('ilAssQuestionPreviewGUI', ilAssQuestionPreviewGUI::CMD_SHOW),
1889  array(),
1890  array('ilAssQuestionPreviewGUI')
1891  );
1892  }
1893 
1894  abstract public function getSolutionOutput(
1895  $active_id,
1896  $pass = NULL,
1897  $graphicalOutput = FALSE,
1898  $result_output = FALSE,
1899  $show_question_only = TRUE,
1900  $show_feedback = FALSE,
1901  $show_correct_solution = FALSE,
1902  $show_manual_scoring = FALSE,
1903  $show_question_text = TRUE
1904  );
1905 
1906  public function isAutosaveable()
1907  {
1908  return $this->object->isAutosaveable();
1909  }
1910 
1911  protected function writeQuestionGenericPostData()
1912  {
1913  $this->object->setTitle( $_POST["title"] );
1914  $this->object->setAuthor( $_POST["author"] );
1915  $this->object->setComment( $_POST["comment"] );
1916  if ($this->object->getSelfAssessmentEditingMode())
1917  {
1918  $this->object->setNrOfTries( $_POST['nr_of_tries'] );
1919  }
1920  $this->object->setQuestion( ilUtil::stripOnlySlashes($_POST['question']) ); // ?
1921  $this->object->setEstimatedWorkingTime(
1922  $_POST["Estimated"]["hh"],
1923  $_POST["Estimated"]["mm"],
1924  $_POST["Estimated"]["ss"]
1925  );
1926  }
1927 
1928  abstract public function getPreview($show_question_only = FALSE, $showInlineFeedback = false);
1929 
1938  public function outQuestionForTest(
1939  $formaction,
1940  $active_id,
1941  $pass = NULL,
1942  $is_question_postponed = FALSE,
1943  $user_post_solutions = FALSE,
1944  $show_specific_inline_feedback = FALSE
1945  )
1946  {
1947  $test_output = $this->getTestOutput(
1948  $active_id,
1949  $pass,
1950  $is_question_postponed,
1951  $user_post_solutions,
1952  $show_specific_inline_feedback
1953  );
1954 
1955  $this->tpl->setVariable("QUESTION_OUTPUT", $test_output);
1956  $this->tpl->setVariable("FORMACTION", $formaction);
1957  $this->tpl->setVariable("ENCTYPE", 'enctype="'.$this->getFormEncodingType().'"');
1958  }
1959 
1960  protected function getFormEncodingType()
1961  {
1963  }
1964 
1968  protected function addBackTab(ilTabsGUI $ilTabs)
1969  {
1970  if(($_GET["calling_test"] > 0) || ($_GET["test_ref_id"] > 0))
1971  {
1972  $ref_id = $_GET["calling_test"];
1973  if(strlen($ref_id) == 0) $ref_id = $_GET["test_ref_id"];
1974 
1975  if(!$_GET['test_express_mode'] && !$GLOBALS['___test_express_mode'])
1976  {
1977  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), "ilias.php?baseClass=ilObjTestGUI&cmd=questions&ref_id=$ref_id");
1978  }
1979  else
1980  {
1982  $ilTabs->setBackTarget($this->lng->txt("backtocallingtest"), $link);
1983  }
1984  }
1985  else if(isset($_GET['calling_consumer']) && (int)$_GET['calling_consumer'])
1986  {
1987  $ref_id = (int)$_GET['calling_consumer'];
1989  if($consumer instanceof ilQuestionEditingFormConsumer)
1990  {
1991  $ilTabs->setBackTarget($consumer->getQuestionEditingFormBackTargetLabel(), $consumer->getQuestionEditingFormBackTarget($_GET['consumer_context']));
1992  }
1993  else
1994  {
1995  require_once 'Services/Link/classes/class.ilLink.php';
1996  $ilTabs->setBackTarget($this->lng->txt("qpl"), ilLink::_getLink($ref_id));
1997  }
1998  }
1999  else
2000  {
2001  $ilTabs->setBackTarget($this->lng->txt("qpl"), $this->ctrl->getLinkTargetByClass("ilobjquestionpoolgui", "questions"));
2002  }
2003  }
2004 
2009 
2014  {
2015  $this->previewSession = $previewSession;
2016  }
2017 
2021  public function getPreviewSession()
2022  {
2023  return $this->previewSession;
2024  }
2025 
2029  protected function buildBasicEditFormObject()
2030  {
2031  require_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
2032  $form = new ilPropertyFormGUI();
2033 
2034  $form->setFormAction($this->ctrl->getFormAction($this));
2035 
2036  $form->setId($this->getType());
2037  $form->setTitle($this->outQuestionType());
2038 
2039  $form->setTableWidth('100%');
2040 
2041  $form->setMultipart(true);
2042 
2043  return $form;
2044  }
2045 
2046  public function showHints()
2047  {
2048  global $ilCtrl;
2049  $ilCtrl->redirectByClass('ilAssQuestionHintsGUI', ilAssQuestionHintsGUI::CMD_SHOW_LIST);
2050  }
2051 }