ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilObjTestGUI.php
Go to the documentation of this file.
1 <?php
2 
20 
21 require_once './Modules/Test/classes/inc.AssessmentConstants.php';
22 
63 {
64  private static $infoScreenChildClasses = array(
65  'ilpublicuserprofilegui', 'ilobjportfoliogui'
66  );
67 
70 
71 
73  private $testSessionFactory = null;
74 
78  protected $tabsManager;
79 
84 
88  protected $testAccess;
89 
90  protected \ILIAS\Test\InternalRequestService $testrequest;
91 
92  protected array $ui;
93 
94  protected const INSERT_MODE_BEFORE = 0;
95  protected const INSERT_MODE_AFTER = 1;
96 
102  public function __construct($refId = null)
103  {
104  global $DIC;
105  $lng = $DIC['lng'];
106  $ilCtrl = $DIC['ilCtrl'];
107  $ilDB = $DIC['ilDB'];
108  $component_repository = $DIC['component.repository'];
109  $tree = $DIC['tree'];
110  $lng->loadLanguageModule("assessment");
111 
112  $this->ui = [
113  $DIC['ui.factory'],
114  $DIC['ui.renderer'],
115  $DIC['refinery'],
116  $DIC['http']->request()
117  ];
118 
119  $this->type = "tst";
120  $this->error = $DIC['ilErr'];
121  $this->ctrl = $ilCtrl;
122  $this->ctrl->saveParameter($this, array("ref_id", "test_ref_id", "calling_test", "test_express_mode", "q_id"));
123  $this->testrequest = $DIC->test()->internal()->request();
124  if ($this->testrequest->hasRefId() && is_numeric($this->testrequest->getRefId())) {
125  $refId = $this->testrequest->getRefId();
126  }
127  parent::__construct("", (int) $refId, true, false);
128 
129  if ($this->object instanceof ilObjTest) {
130  $this->testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory($tree, $ilDB, $component_repository, $this->object);
131  $this->testSessionFactory = new ilTestSessionFactory($this->object);
132  $this->setTestAccess(new ilTestAccess($this->ref_id, $this->object->getTestId()));
133  } else {
134  $this->setCreationMode(true); // I think?
135  }
136  $this->objectiveOrientedContainer = new ilTestObjectiveOrientedContainer();
137 
138  if ($this->object instanceof ilObjTest) {
139  $tabsManager = new ilTestTabsManager($this->testAccess, $this->objectiveOrientedContainer);
140  $tabsManager->setTestOBJ($this->object);
141  $tabsManager->setTestSession($this->testSessionFactory->getSession());
142  $tabsManager->setTestQuestionSetConfig($this->testQuestionSetConfigFactory->getQuestionSetConfig());
143  $tabsManager->initSettingsTemplate();
144  if ($this->object->isDynamicTest()) {
145  $hidden_tabs = $tabsManager->getHiddenTabs();
146  $tabsManager->setHiddenTabs(array_merge($hidden_tabs, ['manscoring', 'scoringadjust']));
147  }
149  }
150  }
151 
155  public function executeCommand(): void
156  {
157  global $DIC; /* @var ILIAS\DI\Container $DIC */
158  $ilAccess = $DIC['ilAccess'];
159  $ilNavigationHistory = $DIC['ilNavigationHistory'];
160  $ilCtrl = $DIC['ilCtrl'];
161  $tpl = $DIC['tpl'];
162  $lng = $DIC['lng'];
163  $ilTabs = $DIC['ilTabs'];
164  $component_repository = $DIC['component.repository'];
165  $ilDB = $DIC['ilDB'];
166  $tree = $DIC['tree'];
167  $ilias = $DIC['ilias'];
168  $ilUser = $DIC['ilUser'];
169  $randomGroup = $DIC->refinery()->random();
170 
171  $cmd = $this->ctrl->getCmd("infoScreen");
172 
173  $cmdsDisabledDueToOfflineStatus = array(
174  'resumePlayer', 'resumePlayer', 'outUserResultsOverview', 'outUserListOfAnswerPasses'
175  );
176 
177  if (!$this->getCreationMode() && $this->object->getOfflineStatus() && in_array($cmd, $cmdsDisabledDueToOfflineStatus)) {
178  $cmd = 'infoScreen';
179  }
180 
181  $next_class = $this->ctrl->getNextClass($this);
182 
183  // add entry to navigation history
184  if (!$this->getCreationMode() &&
185  $ilAccess->checkAccess("read", "", $this->testrequest->getRefId())
186  ) {
187  $ilNavigationHistory->addItem(
188  $this->testrequest->getRefId(),
189  "ilias.php?baseClass=ilObjTestGUI&cmd=infoScreen&ref_id=" . $this->testrequest->getRefId(),
190  "tst"
191  );
192  }
193 
194  // elba hack for storing question id for inserting new question after
195  if ($this->testrequest->raw('prev_qid')) {
196  global $___prev_question_id;
197  $___prev_question_id = $this->testrequest->raw('prev_qid');
198  $this->ctrl->setParameter($this, 'prev_qid', $this->testrequest->raw('prev_qid'));
199  }
200 
201  if (!$this->getCreationMode() && isset($this->testQuestionSetConfigFactory) && $this->testQuestionSetConfigFactory->getQuestionSetConfig()->areDepenciesBroken()) {
202  if (!$this->testQuestionSetConfigFactory->getQuestionSetConfig()->isValidRequestOnBrokenQuestionSetDepencies($next_class, $cmd)) {
203  $this->ctrl->redirectByClass('ilObjTestGUI', 'infoScreen');
204  }
205  }
206 
208 
209  switch ($next_class) {
210  case 'illtiproviderobjectsettinggui':
211  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
212  $this->redirectAfterMissingRead();
213  }
214  $this->prepareOutput();
215  $this->addHeaderAction();
216  $this->tabsManager->getSettingsSubTabs();
217  $GLOBALS['DIC']->tabs()->activateTab('settings');
218  $GLOBALS['DIC']->tabs()->activateSubTab('lti_provider');
219  $lti_gui = new ilLTIProviderObjectSettingGUI($this->object->getRefId());
220  $lti_gui->setCustomRolesForSelection($GLOBALS['DIC']->rbac()->review()->getLocalRoles($this->object->getRefId()));
221  $lti_gui->offerLTIRolesForSelection(false);
222  $this->ctrl->forwardCommand($lti_gui);
223  break;
224 
225 
226  case 'iltestexportgui':
227  if (!$ilAccess->checkAccess('write', '', $this->ref_id)) {
228  $this->redirectAfterMissingWrite();
229  }
230 
231  $this->prepareOutput();
232  $this->addHeaderAction();
233  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_EXPORT);
234  $ilCtrl->forwardCommand(new ilTestExportGUI($this));
235  break;
236 
237  case "ilinfoscreengui":
238  if (!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()) && !$ilAccess->checkAccess("visible", "", $this->testrequest->getRefId())) {
239  $this->redirectAfterMissingRead();
240  }
241  $this->prepareOutput();
242  $this->addHeaderAction();
243  $this->infoScreen(); // forwards command
244  break;
245  case 'ilobjectmetadatagui':
246  if (!$ilAccess->checkAccess('write', '', $this->object->getRefId())) {
247  $this->redirectAfterMissingWrite();
248  }
249 
250  $this->prepareOutput();
251  $this->addHeaderAction();
252  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_META_DATA);
253  $md_gui = new ilObjectMetaDataGUI($this->object);
254  $this->ctrl->forwardCommand($md_gui);
255  break;
256 
257  case 'iltestdashboardgui':
258  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
259  $this->redirectAfterMissingRead();
260  }
261  $this->prepareOutput();
262  $this->addHeaderAction();
263 
264  $gui = new ilTestDashboardGUI(
265  $this->getTestObject(),
266  $this->testQuestionSetConfigFactory->getQuestionSetConfig()
267  );
268 
269  $gui->setTestAccess($this->getTestAccess());
270  $gui->setTestTabs($this->getTabsManager());
271  $gui->setObjectiveParent($this->getObjectiveOrientedContainer());
272 
273  $this->ctrl->forwardCommand($gui);
274  break;
275 
276  case 'iltestresultsgui':
277  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
278  $this->redirectAfterMissingRead();
279  }
280  $this->prepareOutput();
281  $this->addHeaderAction();
282 
283  $gui = new ilTestResultsGUI(
284  $this->getTestObject(),
285  $this->testQuestionSetConfigFactory->getQuestionSetConfig()
286  );
287 
288  $gui->setTestAccess($this->getTestAccess());
289  $gui->setTestSession($this->testSessionFactory->getSession());
290  $gui->setTestTabs($this->getTabsManager());
291  $gui->setObjectiveParent($this->getObjectiveOrientedContainer());
292 
293  $this->ctrl->forwardCommand($gui);
294  break;
295 
296  case "iltestplayerfixedquestionsetgui":
297  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
298  $this->redirectAfterMissingRead();
299  }
300  $this->trackTestObjectReadEvent();
301  if (!$this->object->getKioskMode()) {
302  $this->prepareOutput();
303  }
304  $gui = new ilTestPlayerFixedQuestionSetGUI($this->getTestObject());
305  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
306  $this->ctrl->forwardCommand($gui);
307  break;
308 
309  case "iltestplayerrandomquestionsetgui":
310  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
311  $this->redirectAfterMissingRead();
312  }
313  $this->trackTestObjectReadEvent();
314  if (!$this->object->getKioskMode()) {
315  $this->prepareOutput();
316  }
317  $gui = new ilTestPlayerRandomQuestionSetGUI($this->getTestObject());
318  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
319  $this->ctrl->forwardCommand($gui);
320  break;
321 
322  case "iltestevaluationgui":
323  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
324  $this->redirectAfterMissingRead();
325  }
326  $this->forwardToEvaluationGUI();
327  break;
328 
329  case "iltestevalobjectiveorientedgui":
330  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
331  $this->redirectAfterMissingRead();
332  }
333  // @PHP8-CR I believe this is an indicator for an incomplete feature. I wish to leave it in place
334  // "as is"for further analysis.
335  $this->forwardToEvalObjectiveOrientedGUI();
336  break;
337 
338  case "iltestservicegui":
339  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
340  $this->redirectAfterMissingRead();
341  }
342  $this->prepareOutput();
343  $this->addHeaderAction();
344  $serviceGUI = new ilTestServiceGUI($this->object);
345  $this->ctrl->forwardCommand($serviceGUI);
346  break;
347 
348  case 'ilpermissiongui':
349  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
350  $this->redirectAfterMissingRead();
351  }
352  $this->prepareOutput();
353  $this->addHeaderAction();
354  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_PERMISSIONS);
355  $perm_gui = new ilPermissionGUI($this);
356  $ret = $this->ctrl->forwardCommand($perm_gui);
357  break;
358 
359  case "illearningprogressgui":
360  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
361  $this->redirectAfterMissingRead();
362  }
363  $this->prepareOutput();
364  $this->addHeaderAction();
365  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_LEARNING_PROGRESS);
367  $this->ctrl->forwardCommand($new_gui);
368 
369  break;
370 
371  case "ilcertificategui":
372  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
373  $this->redirectAfterMissingRead();
374  }
375  $this->prepareOutput();
376  $this->addHeaderAction();
377 
378  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_SETTINGS);
379 
380  $guiFactory = new ilCertificateGUIFactory();
381  $output_gui = $guiFactory->create($this->object);
382 
383  $this->ctrl->forwardCommand($output_gui);
384  break;
385 
386  case "iltestscoringgui":
387  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
388  $this->redirectAfterMissingRead();
389  }
390  $this->prepareOutput();
391  $this->addHeaderAction();
392  $output_gui = new ilTestScoringGUI($this->object);
393  $output_gui->setTestAccess($this->getTestAccess());
394  $this->ctrl->forwardCommand($output_gui);
395  break;
396 
397  case 'ilmarkschemagui':
398  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
399  $this->redirectAfterMissingRead();
400  }
401  if (!$ilAccess->checkAccess('write', '', $this->object->getRefId())) {
402  $this->tpl->setOnScreenMessage('info', $this->lng->txt('cannot_edit_test'), true);
403  $this->ctrl->redirect($this, 'infoScreen');
404  }
405  $this->prepareOutput();
406  $this->addHeaderAction();
407  $mark_schema_gui = new ilMarkSchemaGUI($this->getTestObject());
408  $this->ctrl->forwardCommand($mark_schema_gui);
409  break;
410 
411  case 'iltestscoringbyquestionsgui':
412  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
413  $this->redirectAfterMissingRead();
414  }
415  $this->prepareOutput();
416  $this->addHeaderAction();
417  $output_gui = new ilTestScoringByQuestionsGUI($this->getTestObject());
418  $output_gui->setTestAccess($this->getTestAccess());
419  $this->ctrl->forwardCommand($output_gui);
420  break;
421 
422  case 'ilobjtestsettingsgeneralgui':
423  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
424  $this->redirectAfterMissingRead();
425  }
426  $this->prepareOutput();
427  $this->addHeaderAction();
428  $gui = new ilObjTestSettingsGeneralGUI(
429  $this->ctrl,
430  $ilAccess,
431  $this->lng,
432  $this->tree,
433  $ilDB,
434  $component_repository,
435  $ilUser,
436  $this
437  );
438  $this->ctrl->forwardCommand($gui);
439  break;
440 
441  case 'ilobjtestsettingsscoringresultsgui':
442  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
443  $this->redirectAfterMissingRead();
444  }
445  $this->prepareOutput();
446  $this->addHeaderAction();
448  $this->ctrl,
449  $ilAccess,
450  $this->lng,
451  $this->tree,
452  $ilDB,
453  $component_repository,
454  $this,
455  $DIC->ui()->mainTemplate(),
456  $ilTabs,
457  $this->getTestObject()->getScoreSettingsRepository(),
458  $this->getTestObject()->getTestId(),
459  $this->ui[0],
460  $this->ui[1],
461  $this->ui[2],
462  $this->ui[3],
464  );
465 
466  $this->ctrl->forwardCommand($gui);
467  break;
468 
469  case 'ilobjtestfixedquestionsetconfiggui':
470  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
471  $this->redirectAfterMissingRead();
472  }
473  $this->prepareOutput();
474  $this->addHeaderAction();
475  $gui = new ilObjTestDynamicQuestionSetConfigGUI($this->ctrl, $ilAccess, $ilTabs, $this->lng, $this->tpl, $ilDB, $tree, $component_repository, $this->getTestObject());
476  $this->ctrl->forwardCommand($gui);
477  break;
478 
479  case 'iltestrandomquestionsetconfiggui':
480  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
481  $this->redirectAfterMissingRead();
482  }
483  $this->prepareOutput();
484  $this->addHeaderAction();
486  $this->ctrl,
487  $ilAccess,
488  $ilTabs,
489  $this->lng,
490  $this->tpl,
491  $ilDB,
492  $tree,
493  $component_repository,
494  $this->getTestObject(),
496  new ilSetting('assessment'),
497  $ilDB
498  ))->withContextId($this->object->getId())
499  );
500  $this->ctrl->forwardCommand($gui);
501  break;
502 
503  case 'ilobjtestdynamicquestionsetconfiggui':
504  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
505  $this->redirectAfterMissingRead();
506  }
507  $this->prepareOutput();
508  $this->addHeaderAction();
509  $gui = new ilObjTestDynamicQuestionSetConfigGUI($this->ctrl, $ilAccess, $ilTabs, $this->lng, $this->tpl, $ilDB, $tree, $component_repository, $this->getTestObject());
510  $this->ctrl->forwardCommand($gui);
511  break;
512 
513  case 'iltestquestionbrowsertablegui':
514  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
515  $this->redirectAfterMissingRead();
516  }
517  $this->prepareOutput();
518  $this->addHeaderAction();
520  $this->ctrl,
521  $this->tpl,
522  $ilTabs,
523  $this->lng,
524  $tree,
525  $ilDB,
526  $component_repository,
527  $this->getTestObject(),
528  $ilAccess,
529  $DIC->http(),
530  $DIC->refinery(),
531  $DIC['ui.factory'],
532  $DIC['ui.renderer']
533  );
534  $gui->setWriteAccess($ilAccess->checkAccess("write", "", $this->ref_id));
535  $gui->init();
536  $this->ctrl->forwardCommand($gui);
537  break;
538 
539  case 'iltestskilladministrationgui':
540  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
541  $this->redirectAfterMissingRead();
542  }
543  $this->prepareOutput();
544  $this->addHeaderAction();
545  $gui = new ilTestSkillAdministrationGUI($ilias, $this->ctrl, $ilAccess, $ilTabs, $this->tpl, $this->lng, $this->refinery, $ilDB, $tree, $component_repository, $this->getTestObject(), $this->ref_id);
546  $this->ctrl->forwardCommand($gui);
547  break;
548 
549  case 'ilobjectcopygui':
550  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
551  $this->redirectAfterMissingRead();
552  }
553  $this->prepareOutput();
554  $this->addHeaderAction();
555  $cp = new ilObjectCopyGUI($this);
556  $cp->setType('tst');
557  $this->ctrl->forwardCommand($cp);
558  break;
559 
560  case 'ilpageeditorgui':
561  case 'iltestexpresspageobjectgui':
562  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
563  $this->redirectAfterMissingRead();
564  }
565  $this->getTabsManager()->getQuestionsSubTabs();
567  $incompleteQuestionPurger = new ilAssIncompleteQuestionPurger($ilDB);
568  $incompleteQuestionPurger->setOwnerId($ilUser->getId());
569  $incompleteQuestionPurger->purge();
570 
571  try {
572  $qid = $this->fetchAuthoringQuestionIdParameter();
573  } catch (ilTestException $e) {
574  $qid = 0;
575  }
576 
577  $this->prepareOutput();
578  if (!in_array($cmd, array('addQuestion', 'browseForQuestions'))) {
579  $this->buildPageViewToolbar($qid);
580  }
581 
582  if (!$qid || in_array($cmd, array('insertQuestions', 'browseForQuestions'))) {
583  $pageObject = new ilTestExpressPageObjectGUI(0);
584  $pageObject->test_object = $this->object;
585  $ret = $this->ctrl->forwardCommand($pageObject);
586  $this->tpl->setContent($ret);
587  break;
588  }
589  $this->tpl->setCurrentBlock("ContentStyle");
590  $this->tpl->setVariable(
591  "LOCATION_CONTENT_STYLESHEET",
593  );
594  $this->tpl->parseCurrentBlock();
595 
596  // syntax style
597  $this->tpl->setCurrentBlock("SyntaxStyle");
598  $this->tpl->setVariable(
599  "LOCATION_SYNTAX_STYLESHEET",
601  );
602  $this->tpl->parseCurrentBlock();
603 
604  $q_gui = assQuestionGUI::_getQuestionGUI("", $qid);
605  if (!($q_gui instanceof assQuestionGUI)) {
606  $this->ctrl->setParameterByClass('iltestexpresspageobjectgui', 'q_id', '');
607  $this->ctrl->redirectByClass('iltestexpresspageobjectgui', $this->ctrl->getCmd());
608  }
609 
610  $q_gui->setRenderPurpose(assQuestionGUI::RENDER_PURPOSE_PREVIEW);
611 
612  $q_gui->outAdditionalOutput();
613  $q_gui->object->setObjId($this->object->getId());
614 
615  $q_gui->setTargetGuiClass(null);
616  $q_gui->setQuestionActionCmd(null);
617 
618  $question = $q_gui->object;
619  $this->ctrl->saveParameter($this, "q_id");
620 
621  #$this->lng->loadLanguageModule("content");
622  $this->ctrl->setReturnByClass("ilTestExpressPageObjectGUI", "view");
623  $this->ctrl->setReturn($this, "questions");
624 
625  $page_gui = new ilTestExpressPageObjectGUI($qid);
626  $page_gui->test_object = $this->object;
627  $page_gui->setEditPreview(true);
628  $page_gui->setEnabledTabs(false);
629  if (strlen($this->ctrl->getCmd()) == 0) {
630  $this->ctrl->setCmdClass(get_class($page_gui));
631  $this->ctrl->setCmd("preview");
632  }
633 
634  $page_gui->setQuestionHTML(array($q_gui->object->getId() => $q_gui->getPreview(true)));
635  $page_gui->setTemplateTargetVar("ADM_CONTENT");
636 
637  $page_gui->setOutputMode($this->object->evalTotalPersons() == 0 ? "edit" : 'preview');
638 
639  $page_gui->setHeader($question->getTitleForHTMLOutput());
640  $page_gui->setFileDownloadLink($this->ctrl->getLinkTarget($this, "downloadFile"));
641  $page_gui->setFullscreenLink($this->ctrl->getLinkTarget($this, "fullscreen"));
642  $page_gui->setSourcecodeDownloadScript($this->ctrl->getLinkTarget($this));
643  $page_gui->setPresentationTitle($question->getTitleForHTMLOutput() . ' [' . $this->lng->txt('question_id_short') . ': ' . $question->getId() . ']');
644  $ret = $this->ctrl->forwardCommand($page_gui);
645  if ($ret != "") {
646  $tpl->setContent($ret);
647  }
648 
649  global $DIC;
650  $ilTabs = $DIC['ilTabs'];
651  $ilTabs->activateTab('assQuestions');
652 
653  break;
654 
655  case 'ilassquestionpreviewgui':
656  if (!$ilAccess->checkAccess('write', '', $this->object->getRefId())) {
657  $this->redirectAfterMissingWrite();
658  }
659  $this->prepareOutput();
660 
661  $this->ctrl->saveParameter($this, "q_id");
662 
663  $gui = new ilAssQuestionPreviewGUI(
664  $this->ctrl,
665  $this->rbac_system,
666  $this->tabs_gui,
667  $this->tpl,
668  $this->lng,
669  $ilDB,
670  $ilUser,
671  $randomGroup,
672  $this->ref_id,
673  $DIC->rbac()
674  );
675 
676  $gui->initQuestion($this->fetchAuthoringQuestionIdParameter(), $this->object->getId());
677  $gui->initPreviewSettings($this->object->getRefId());
678  $gui->initPreviewSession($ilUser->getId(), $this->testrequest->getQuestionId());
679  $gui->initHintTracking();
680  $gui->initStyleSheets();
681 
682  $this->ctrl->forwardCommand($gui);
683 
684  break;
685 
686  case 'ilassquestionpagegui':
687  if ($cmd == 'finishEditing') {
688  $this->ctrl->redirectByClass('ilassquestionpreviewgui', 'show');
689  break;
690  }
691  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
692  $this->redirectAfterMissingRead();
693  }
694  if ($cmd === 'edit' && !$ilAccess->checkAccess('write', '', $this->testrequest->getRefId())) {
695  $this->redirectAfterMissingWrite();
696  }
697  $this->prepareOutput();
698  $forwarder = new ilAssQuestionPageCommandForwarder();
699  $forwarder->setTestObj($this->getTestObject());
700  $forwarder->forward();
701  break;
702 
703  case 'ilassspecfeedbackpagegui':
704  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
705  $this->redirectAfterMissingRead();
706  }
707  $pg_gui = new ilAssSpecFeedbackPageGUI((int) $this->testrequest->raw("feedback_id"));
708  $this->ctrl->forwardCommand($pg_gui);
709  break;
710 
711  case 'ilassgenfeedbackpagegui':
712  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
713  $this->redirectAfterMissingRead();
714  }
715  $pg_gui = new ilAssGenFeedbackPageGUI($this->testrequest->int("feedback_id"));
716  $this->ctrl->forwardCommand($pg_gui);
717  break;
718 
719  case 'illocalunitconfigurationgui':
720  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
721  $this->redirectAfterMissingRead();
722  }
723  $this->prepareSubGuiOutput();
724 
725  // set return target
726  $this->ctrl->setReturn($this, "questions");
728  $questionGUI->object->setObjId($this->object->getId());
729  $questionGUI->setQuestionTabs();
730  $gui = new ilLocalUnitConfigurationGUI(
731  new ilUnitConfigurationRepository($this->testrequest->getQuestionId())
732  );
733  $this->ctrl->forwardCommand($gui);
734  break;
735 
736  case "ilcommonactiondispatchergui":
737  if (!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()) && !$ilAccess->checkAccess("visible", "", $this->testrequest->getRefId())) {
738  $this->redirectAfterMissingRead();
739  }
740  $this->prepareOutput();
742  $this->ctrl->forwardCommand($gui);
743  break;
744 
745  case 'ilassquestionhintsgui':
746  if (!$ilAccess->checkAccess('write', '', $this->object->getRefId())) {
747  $this->redirectAfterMissingWrite();
748  }
749  $this->prepareSubGuiOutput();
750 
751  // set return target
752  $this->ctrl->setReturn($this, "questions");
754  $questionGUI->object->setObjId($this->object->getId());
755  $questionGUI->setQuestionTabs();
756 
757  if ($questionGUI->object->isInActiveTest()) {
758  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("question_is_part_of_running_test"), true);
759  $this->ctrl->redirectByClass('ilAssQuestionPreviewGUI', ilAssQuestionPreviewGUI::CMD_SHOW);
760  }
761  $gui = new ilAssQuestionHintsGUI($questionGUI);
762 
763  $gui->setEditingEnabled(
764  $DIC->access()->checkAccess('write', '', $this->object->getRefId())
765  );
766 
767  $ilCtrl->forwardCommand($gui);
768 
769  break;
770 
771  case 'ilassquestionfeedbackeditinggui':
772  if (!$ilAccess->checkAccess('write', '', $this->object->getRefId())) {
773  $this->redirectAfterMissingWrite();
774  }
775  $this->prepareSubGuiOutput();
776 
777  // set return target
778  $this->ctrl->setReturn($this, "questions");
780  $questionGUI->object->setObjId($this->object->getId());
781  $questionGUI->setQuestionTabs();
782 
783  if ($questionGUI->object->isInActiveTest()) {
784  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("question_is_part_of_running_test"), true);
785  $this->ctrl->redirectByClass('ilAssQuestionPreviewGUI', ilAssQuestionPreviewGUI::CMD_SHOW);
786  }
787  $gui = new ilAssQuestionFeedbackEditingGUI($questionGUI, $ilCtrl, $ilAccess, $tpl, $ilTabs, $lng);
788  $ilCtrl->forwardCommand($gui);
789 
790  break;
791 
792  case 'iltestcorrectionsgui':
793  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
794  $this->redirectAfterMissingRead();
795  }
796  $this->prepareOutput();
797  $gui = new ilTestCorrectionsGUI($DIC, $this->getTestObject());
798  $this->ctrl->forwardCommand($gui);
799  break;
800 
801  case '':
802  case 'ilobjtestgui':
803  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()) && !$ilAccess->checkAccess("visible", "", $this->testrequest->getRefId()))) {
804  $this->redirectAfterMissingRead();
805  }
806  $this->prepareOutput();
807  $this->addHeaderAction();
808  if ((strcmp($cmd, "properties") == 0) && ($this->testrequest->raw("browse"))) {
809  $this->questionsObject();
810  return;
811  }
812  if ((strcmp($cmd, "properties") == 0) && ($this->testrequest->raw("up") || $this->testrequest->raw("down"))) {
813  $this->questionsObject();
814  return;
815  }
816  $cmd .= "Object";
817  $ret = $this->$cmd();
818  break;
819  default:
820  if ((!$ilAccess->checkAccess("read", "", $this->testrequest->getRefId()))) {
821  $this->redirectAfterMissingRead();
822  }
823  if (in_array($cmd, ['editQuestion', 'save', 'suggestedsolution']) && !$ilAccess->checkAccess('write', '', $this->object->getRefId())) {
824  $this->redirectAfterMissingWrite();
825  }
826  // elba hack for storing question id for inserting new question after
827  if ($this->testrequest->raw('prev_qid')) {
828  global $___prev_question_id;
829  $___prev_question_id = $this->testrequest->raw('prev_qid');
830  $this->ctrl->setParameterByClass('ilassquestionpagegui', 'prev_qid', $this->testrequest->raw('prev_qid'));
831  $this->ctrl->setParameterByClass($this->testrequest->raw('sel_question_types') . 'gui', 'prev_qid', $this->testrequest->raw('prev_qid'));
832  }
833  $this->create_question_mode = true;
834  $this->prepareOutput();
835 
836  $this->ctrl->setReturn($this, "questions");
837 
838  try {
839  $qid = $this->fetchAuthoringQuestionIdParameter();
840 
841  $questionGui = assQuestionGUI::_getQuestionGUI(
842  ilUtil::stripSlashes($this->testrequest->raw('sel_question_types') ?? ''),
843  $qid
844  );
845 
846  $questionGui->setEditContext(assQuestionGUI::EDIT_CONTEXT_AUTHORING);
847  $questionGui->object->setObjId($this->object->getId());
848 
849  if (in_array($cmd, ['editQuestion', 'save', 'suggestedsolution']) && $questionGui->object->isInActiveTest()) {
850  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("question_is_part_of_running_test"), true);
851  $this->ctrl->redirectByClass('ilAssQuestionPreviewGUI', ilAssQuestionPreviewGUI::CMD_SHOW);
852  }
853 
854  $questionGuiClass = get_class($questionGui);
855  $this->ctrl->setParameterByClass($questionGuiClass, 'prev_qid', $this->testrequest->raw('prev_qid'));
856  $this->ctrl->setParameterByClass($questionGuiClass, 'test_ref_id', $this->testrequest->getRefId());
857  $this->ctrl->setParameterByClass($questionGuiClass, 'q_id', $qid);
858 
859  if ($this->testrequest->isset('test_express_mode')) {
860  $this->ctrl->setParameterByClass($questionGuiClass, 'test_express_mode', 1);
861  }
862 
863  $questionGui->setQuestionTabs();
864 
865  $this->ctrl->forwardCommand($questionGui);
866  } catch (ilTestException $e) {
867  if ($this->testrequest->isset('test_express_mode')) {
868  $this->ctrl->redirect($this, 'showPage');
869  } else {
870  $this->ctrl->redirect($this, 'questions');
871  }
872  }
873  break;
874  }
875  if (!in_array(strtolower($this->testrequest->raw("baseClass")), array('iladministrationgui', 'ilrepositorygui')) &&
876  $this->getCreationMode() != true) {
877  $this->tpl->printToStdout();
878  }
879  }
880 
881  protected function redirectAfterMissingWrite()
882  {
883  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("no_permission"), true);
884  $target_class = get_class($this->object) . "GUI";
885  $this->ctrl->setParameterByClass($target_class, 'ref_id', $this->ref_id);
886  $this->ctrl->redirectByClass($target_class);
887  }
888 
889  protected function redirectAfterMissingRead(): void
890  {
891  $this->tpl->setOnScreenMessage('failure', sprintf(
892  $this->lng->txt("msg_no_perm_read_item"),
893  $this->object->getTitle()
894  ), true);
895  $this->ctrl->setParameterByClass('ilrepositorygui', 'ref_id', ROOT_FOLDER_ID);
896  $this->ctrl->redirectByClass('ilrepositorygui');
897  }
898 
899  protected function trackTestObjectReadEvent()
900  {
901  /* @var ILIAS\DI\Container $DIC */ global $DIC;
902 
904  $this->object->getType(),
905  $this->object->getRefId(),
906  $this->object->getId(),
907  $DIC->user()->getId()
908  );
909  }
910 
915  protected function exportObject()
916  {
917  global $DIC; /* @var ILIAS\DI\Container $DIC */
918  $DIC->ctrl()->redirectByClass('ilTestExportGUI');
919  }
920 
926  {
927  $qid = $this->testrequest->raw('q_id');
928 
929  if (!$qid || $qid == 'Array') {
930  $questions = $this->object->getQuestionTitlesAndIndexes();
931 
932  $keys = array_keys($questions);
933  $qid = (int) ($keys[0] ?? 0);
934 
935  $_REQUEST['q_id'] = $qid;
936  $_GET['q_id'] = $qid;
937  $_POST['q_id'] = $qid;
938  }
939 
940  if ($this->object->checkQuestionParent($qid)) {
941  return $qid;
942  }
943 
944  throw new ilTestException('question id does not relate to parent object!');
945  }
946 
947  private function questionsTabGatewayObject()
948  {
949  if ($this->object->isRandomTest()) {
950  $this->ctrl->redirectByClass('ilTestRandomQuestionSetConfigGUI');
951  }
952 
953  $this->ctrl->redirectByClass('ilObjTestGUI', 'questions');
954  }
955 
956  private function userResultsGatewayObject()
957  {
958  $this->ctrl->setCmdClass('ilTestEvaluationGUI');
959  $this->ctrl->setCmd('outUserResultsOverview');
960  $this->tabs_gui->clearTargets();
961 
962  $this->forwardToEvaluationGUI();
963  }
964 
965  private function testResultsGatewayObject(): void
966  {
967  $this->ctrl->redirectByClass(
968  [
969  ilRepositoryGUI::class,
970  __CLASS__,
971  ilTestResultsGUI::class,
972  ilParticipantsTestResultsGUI::class
973  ],
974  'showParticipants'
975  );
976  }
977 
981  public function getTestAccess(): ilTestAccess
982  {
983  return $this->testAccess;
984  }
985 
989  public function setTestAccess($testAccess)
990  {
991  $this->testAccess = $testAccess;
992  }
993 
998  {
999  return $this->tabsManager;
1000  }
1001 
1005  public function setTabsManager($tabsManager)
1006  {
1007  $this->tabsManager = $tabsManager;
1008  }
1009 
1010  private function forwardToEvaluationGUI()
1011  {
1012  $this->prepareOutput();
1013  $this->addHeaderAction();
1014  $gui = new ilTestEvaluationGUI($this->getTestObject());
1015  $gui->setObjectiveOrientedContainer($this->getObjectiveOrientedContainer());
1016  $gui->setTestAccess($this->getTestAccess());
1017 
1018  $this->ctrl->forwardCommand($gui);
1019  }
1020 
1022  {
1023  $this->ctrl->redirectByClass('ilObjTestSettingsGeneralGUI', ilObjTestSettingsGeneralGUI::CMD_SHOW_FORM);
1024  }
1025 
1026  private function prepareSubGuiOutput()
1027  {
1028  global $DIC;
1029  $ilUser = $DIC['ilUser'];
1030 
1031  $this->tpl->loadStandardTemplate();
1032 
1033  // set locator
1034  $this->setLocator();
1035 
1036  // set title and description and title icon
1037  $this->setTitleAndDescription();
1038  }
1039 
1040  public function runObject()
1041  {
1042  $this->ctrl->redirect($this, "infoScreen");
1043  }
1044 
1045  public function outEvaluationObject()
1046  {
1047  $this->ctrl->redirectByClass("iltestevaluationgui", "outEvaluation");
1048  }
1049 
1053  protected function importFileObject(int $parent_id = null): void
1054  {
1055  if (!$this->checkPermissionBool("create", "", $_REQUEST["new_type"])) {
1056  $this->redirectAfterMissingWrite();
1057  }
1058 
1059  $form = $this->initImportForm($this->testrequest->raw("new_type"));
1060  if ($form->checkInput()) {
1061  $this->ctrl->setParameter($this, "new_type", $this->type);
1062  $this->uploadTst();
1063  return;
1064  }
1065 
1066  // display form to correct errors
1067  $form->setValuesByPost();
1068  $this->tpl->setContent($form->getHTML());
1069  }
1070 
1071  public function addDidacticTemplateOptions(array &$options): void
1072  {
1073  $tst = new ilObjTest();
1074  $defaults = $tst->getAvailableDefaults();
1075  if (count($defaults)) {
1076  foreach ($defaults as $row) {
1077  $options["tstdef_" . $row["test_defaults_id"]] = array($row["name"],
1078  $this->lng->txt("tst_default_settings"));
1079  }
1080  }
1081  $templates = ilSettingsTemplate::getAllSettingsTemplates("tst");
1082  if ($templates) {
1083  foreach ($templates as $item) {
1084  $options["tsttpl_" . $item["id"]] = array($item["title"],
1085  nl2br(trim($item["description"])));
1086  }
1087  }
1088  }
1089 
1094  public function afterSave(ilObject $new_object): void
1095  {
1096  $new_object->saveToDb();
1097 
1098  $tstdef = $this->getDidacticTemplateVar("tstdef");
1099  if ($tstdef) {
1100  $testDefaultsId = $tstdef;
1101  $testDefaults = ilObjTest::_getTestDefaults($testDefaultsId);
1102  $new_object->applyDefaults($testDefaults);
1103  }
1104 
1105  $template_id = $this->getDidacticTemplateVar("tsttpl");
1106  if ($template_id) {
1108 
1109  $template_settings = $template->getSettings();
1110  if ($template_settings) {
1112  $obj = $new_object;
1113  $this->applyTemplate($template_settings, $obj);
1114  }
1115 
1116  $new_object->setTemplate($template_id);
1117  }
1118 
1119  $new_object->saveToDb();
1120 
1121  // always send a message
1122  $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_added"), true);
1123  $this->ctrl->setParameter($this, 'ref_id', $new_object->getRefId());
1124  $this->ctrl->redirectByClass('ilObjTestSettingsGeneralGUI');
1125  }
1126 
1127  public function backToRepositoryObject()
1128  {
1129  $path = $this->tree->getPathFull($this->object->getRefID());
1130  ilUtil::redirect($this->getReturnLocation("cancel", "./ilias.php?baseClass=ilRepositoryGUI&cmd=frameset&ref_id=" . $path[count($path) - 2]["child"]));
1131  }
1132 
1136  public function uploadTst()
1137  {
1138  if ($_FILES["xmldoc"]["error"] > UPLOAD_ERR_OK) {
1139  $this->lng->loadLanguageModule('file');
1140  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('general_upload_error_occured'));
1141  $this->ctrl->redirect($this, 'create');
1142  return false;
1143  }
1144 
1145  $file = pathinfo($_FILES["xmldoc"]["name"]);
1146  $subdir = basename($file["basename"], "." . $file["extension"]);
1147 
1148  if (strpos($subdir, 'tst') === false) {
1149  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('import_file_not_valid'), true);
1150  $this->ctrl->redirect($this, 'create');
1151  return false;
1152  }
1153 
1154  $basedir = ilObjTest::_createImportDirectory();
1155 
1156  $full_path = $basedir . "/" . $_FILES["xmldoc"]["name"];
1157  try {
1158  ilFileUtils::moveUploadedFile($_FILES["xmldoc"]["tmp_name"], $_FILES["xmldoc"]["name"], $full_path);
1159  } catch (Error $e) {
1160  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('import_file_not_valid'), true);
1161  $this->ctrl->redirect($this, 'create');
1162  return false;
1163  }
1164 
1165  ilFileUtils::unzip($full_path);
1166 
1168  $xml_file = ilObjTest::_getImportDirectory() . '/' . $subdir . '/' . $subdir . ".xml";
1169  $qti_file = ilObjTest::_getImportDirectory() . '/' . $subdir . '/' . preg_replace("/test|tst/", "qti", $subdir) . ".xml";
1170  $results_file = ilObjTest::_getImportDirectory() . '/' . $subdir . '/' . preg_replace("/test|tst/", "results", $subdir) . ".xml";
1171 
1172  if (!is_file($qti_file)) {
1173  ilFileUtils::delDir($basedir);
1174  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("tst_import_non_ilias_zip"), true);
1175  $this->ctrl->redirect($this, 'create');
1176  return false;
1177  }
1178  $qtiParser = new ilQTIParser($qti_file, ilQTIParser::IL_MO_VERIFY_QTI, 0, "");
1179  $qtiParser->startParsing();
1180  $founditems = $qtiParser->getFoundItems();
1181 
1182  $complete = 0;
1183  $incomplete = 0;
1184  foreach ($founditems as $item) {
1185  if (strlen($item["type"])) {
1186  $complete++;
1187  } else {
1188  $incomplete++;
1189  }
1190  }
1191 
1192  if (count($founditems) && $complete == 0) {
1193  ilFileUtils::delDir($basedir);
1194 
1195  $this->tpl->setOnScreenMessage('info', $this->lng->txt("qpl_import_non_ilias_files"));
1196  $this->createObject();
1197  return;
1198  }
1199 
1200  ilSession::set("tst_import_results_file", $results_file);
1201  ilSession::set("tst_import_xml_file", $xml_file);
1202  ilSession::set("tst_import_qti_file", $qti_file);
1203  ilSession::set("tst_import_subdir", $subdir);
1204 
1205  if ($qtiParser->getQuestionSetType() != ilObjTest::QUESTION_SET_TYPE_FIXED
1206  || file_exists($results_file)) {
1207  $this->importVerifiedFileObject();
1208  return;
1209  }
1210 
1211  $importVerificationTpl = new ilTemplate('tpl.tst_import_verification.html', true, true, 'Modules/Test');
1212 
1213  // on import creation screen the pool was chosen (-1 for no pool)
1214  // BUT when no pool is available the input on creation screen is missing, so the field value -1 for no pool is not submitted.
1215  $QplOrTstID = isset($_POST["qpl"]) && (int) $_POST["qpl"] != 0 ? $_POST["qpl"] : -1;
1216 
1217  $importVerificationTpl->setVariable("TEXT_TYPE", $this->lng->txt("question_type"));
1218  $importVerificationTpl->setVariable("TEXT_TITLE", $this->lng->txt("question_title"));
1219  $importVerificationTpl->setVariable("FOUND_QUESTIONS_INTRODUCTION", $this->lng->txt("tst_import_verify_found_questions"));
1220  $importVerificationTpl->setVariable("VERIFICATION_HEADING", $this->lng->txt("import_tst"));
1221  $importVerificationTpl->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
1222  $importVerificationTpl->setVariable("ARROW", ilUtil::getImagePath("arrow_downright.svg"));
1223  $importVerificationTpl->setVariable("QUESTIONPOOL_ID", $QplOrTstID);
1224  $importVerificationTpl->setVariable("VALUE_IMPORT", $this->lng->txt("import"));
1225  $importVerificationTpl->setVariable("VALUE_CANCEL", $this->lng->txt("cancel"));
1226 
1227  $row_class = ["tblrow1", "tblrow2"];
1228  $counter = 0;
1229  foreach ($founditems as $item) {
1230  $importVerificationTpl->setCurrentBlock("verification_row");
1231  $importVerificationTpl->setVariable("ROW_CLASS", $row_class[$counter++ % 2]);
1232  $importVerificationTpl->setVariable("QUESTION_TITLE", $item["title"]);
1233  $importVerificationTpl->setVariable("QUESTION_IDENT", $item["ident"]);
1234 
1235  switch ($item["type"]) {
1238  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assMultipleChoice"));
1239  break;
1242  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assSingleChoice"));
1243  break;
1246  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assKprimChoice"));
1247  break;
1250  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assLongMenu"));
1251  break;
1253  case ilQTIItem::QT_NUMERIC:
1254  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assNumeric"));
1255  break;
1257  case ilQTIItem::QT_FORMULA:
1258  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assFormulaQuestion"));
1259  break;
1262  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assTextSubset"));
1263  break;
1264  case CLOZE_TEST_IDENTIFIER:
1265  case ilQTIItem::QT_CLOZE:
1266  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assClozeTest"));
1267  break;
1268  case ERROR_TEXT_IDENTIFIER:
1270  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assErrorText"));
1271  break;
1274  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assImagemapQuestion"));
1275  break;
1278  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assMatchingQuestion"));
1279  break;
1282  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assOrderingQuestion"));
1283  break;
1286  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assOrderingHorizontal"));
1287  break;
1289  case ilQTIItem::QT_TEXT:
1290  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assTextQuestion"));
1291  break;
1294  $importVerificationTpl->setVariable("QUESTION_TYPE", $this->lng->txt("assFileUpload"));
1295  break;
1296  }
1297  $importVerificationTpl->parseCurrentBlock();
1298  }
1299 
1300  $this->tpl->setContent($importVerificationTpl->get());
1301  }
1302 
1303  public function getTestObject(): ?ilObjTest
1304  {
1306  $test = $this->object;
1307  return $test;
1308  }
1309 
1313  public function importVerifiedFileObject()
1314  {
1315  if (!$this->checkPermissionBool('create', '', $this->testrequest->strVal('new_type'))) {
1316  $this->redirectAfterMissingWrite();
1317  }
1318 
1319  // create new questionpool object
1320  $newObj = new ilObjTest(0, true);
1321  // set type of questionpool object
1322  $newObj->setType($this->testrequest->raw("new_type"));
1323  // set title of questionpool object to "dummy"
1324  $newObj->setTitle("dummy");
1325  // set description of questionpool object
1326  $newObj->setDescription("test import");
1327  // create the questionpool class in the ILIAS database (object_data table)
1328  $newObj->create(true);
1329  // create a reference for the questionpool object in the ILIAS database (object_reference table)
1330  $newObj->createReference();
1331  // put the questionpool object in the administration tree
1332  $newObj->putInTree($this->testrequest->getRefId());
1333  // get default permissions and set the permissions for the questionpool object
1334  $newObj->setPermissions($this->testrequest->getRefId());
1335  // empty mark schema
1336  $newObj->mark_schema->flush();
1337 
1338  // Handle selection of "no questionpool" as qpl_id = -1 -> use test object id instead.
1339  // possible hint: chek if empty strings in $_POST["qpl_id"] relates to a bug or not
1340  if (!isset($_POST["qpl"]) || "-1" === (string) $_POST["qpl"]) {
1341  $questionParentObjId = $newObj->getId();
1342  } else {
1343  $questionParentObjId = $_POST["qpl"];
1344  }
1345 
1346  $imp = new ilImport($this->testrequest->getRefId());
1347  $map = $imp->getMapping();
1348  $map->addMapping('Modules/Test', 'tst', 'new_id', $newObj->getId());
1349 
1350  $fileName = ilSession::get('tst_import_subdir') . '.zip';
1351  $fullPath = ilSession::get('tst_import_dir') . '/' . $fileName;
1352 
1353  if (is_file(ilSession::get("tst_import_dir") . '/' . ilSession::get("tst_import_subdir") . "/manifest.xml")) {
1354  $newObj->saveToDb();
1355 
1356  ilSession::set('tst_import_idents', $_POST['ident'] ?? '');
1357  ilSession::set('tst_import_qst_parent', $questionParentObjId);
1358 
1359  $imp->importObject($newObj, $fullPath, $fileName, 'tst', 'Modules/Test', true);
1360  } else {
1361  $test_importer = new ilTestImporter();
1362  $test_importer->setImport($imp);
1363  $test_importer->setInstallId(IL_INST_ID);
1364  $test_importer->setImportDirectory(ilSession::get("tst_import_dir") . '/' . ilSession::get("tst_import_subdir"));
1365  $test_importer->init();
1366 
1367  $test_importer->importXmlRepresentation(
1368  '',
1369  0,
1370  '',
1371  $map,
1372  );
1373  }
1374 
1375 
1376  // delete import directory
1378  //Note, has been in ilTestImporter, however resetting this there, lead to problem in delDir.
1379  // See: https://github.com/ILIAS-eLearning/ILIAS/pull/5097
1381 
1382  $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_imported"), true);
1383  ilUtil::redirect("ilias.php?ref_id=" . $newObj->getRefId() . "&baseClass=ilObjTestGUI");
1384  }
1385 
1392  public function uploadObject($redirect = true)
1393  {
1394  if (!$this->checkPermissionBool('create', '', $this->testrequest->strVal('new_type'))) {
1395  $this->redirectAfterMissingWrite();
1396  }
1397  $this->uploadTst();
1398  }
1399 
1403  public function downloadFileObject()
1404  {
1405  $file = explode("_", $this->testrequest->raw("file_id"));
1406  $fileObj = new ilObjFile($file[count($file) - 1], false);
1407  $fileObj->sendFile();
1408  exit;
1409  }
1410 
1414  public function fullscreenObject()
1415  {
1416  $page_gui = new ilAssQuestionPageGUI($this->testrequest->raw("pg_id"));
1417  $page_gui->showMediaFullscreen();
1418  }
1419 
1423  public function download_paragraphObject()
1424  {
1425  $pg_obj = new ilAssQuestionPage($this->testrequest->raw("pg_id"));
1426  $pg_obj->send_paragraph($this->testrequest->raw("par_id"), $this->testrequest->raw("downloadtitle"));
1427  exit;
1428  }
1429 
1430  /*
1431  * Removing to get rid of a warning, leaving commented out for further analysis.
1432  public function filterObject()
1433  {
1434  $this->questionBrowser();
1435  }
1436  */
1437 
1438  /*
1439  * Removing to get rid of a warning, leaving commented out for further analysis.
1440  *
1441  public function resetFilterObject()
1442  {
1443  $this->questionBrowser();
1444  }
1445  */
1453  public function backObject()
1454  {
1455  $this->ctrl->redirect($this, "questions");
1456  }
1457 
1466  public function createQuestionPool($name = "dummy", $description = ""): int
1467  {
1468  global $DIC;
1469  $tree = $DIC['tree'];
1470  $parent_ref = $tree->getParentId($this->object->getRefId());
1471  $qpl = new ilObjQuestionPool();
1472  $qpl->setType("qpl");
1473  $qpl->setTitle($name);
1474  $qpl->setDescription($description);
1475  $qpl->create();
1476  $qpl->createReference();
1477  $qpl->putInTree($parent_ref);
1478  $qpl->setPermissions($parent_ref);
1479  $qpl->setOnline(1); // must be online to be available
1480  $qpl->saveToDb();
1481  return $qpl->getRefId();
1482  }
1483 
1484  public function randomselectObject()
1485  {
1486  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1487  $this->redirectAfterMissingWrite();
1488  }
1489  $this->getTabsManager()->getQuestionsSubTabs();
1491 
1492  $form = new ilPropertyFormGUI();
1493  $form->setTitle($this->lng->txt('random_selection'));
1494  $form->setFormAction($this->ctrl->getFormAction($this, 'cancelRandomSelect'));
1495 
1496  $form->addCommandButton('createRandomSelection', $this->lng->txt('submit'));
1497  $form->addCommandButton('cancelRandomSelect', $this->lng->txt('cancel'));
1498 
1499  $amount = new ilNumberInputGUI($this->lng->txt('tst_random_nr_of_questions'), 'nr_of_questions');
1500  $amount->allowDecimals(false);
1501  $amount->setSize(5);
1502  $amount->setMinValue(1);
1503  $amount->setValue(5);
1504  $form->addItem($amount);
1505 
1506  $poolSelection = new ilSelectInputGUI($this->lng->txt('tst_source_question_pool'), 'sel_qpl');
1507  $poolSelection->setInfo($this->lng->txt('tst_random_select_questionpool'));
1508  $poolSelection->setRequired(true);
1509  $poolOptions = [];
1510  $questionpools = $this->object->getAvailableQuestionpools(false, false, false, true);
1511  foreach ($questionpools as $key => $value) {
1512  $poolOptions[$key] = $value['title'];
1513  }
1514  $poolSelection->setOptions(
1515  ['0' => $this->lng->txt('all_available_question_pools')] + $poolOptions
1516  );
1517  $form->addItem($poolSelection);
1518 
1519  $questionType = new ilHiddenInputGUI('sel_question_types');
1520  $questionType->setValue(ilUtil::stripSlashes($_POST['sel_question_types']));
1521  $form->addItem($questionType);
1522 
1523  $this->tpl->setContent($form->getHTML());
1524  }
1525 
1526  public function cancelRandomSelectObject()
1527  {
1528  $this->ctrl->redirect($this, "questions");
1529  }
1530 
1532  {
1533  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1534  $this->redirectAfterMissingWrite();
1535  }
1536  $this->getTabsManager()->getQuestionsSubTabs();
1538 
1539  $randomQuestionSelectionTable = new ilTestRandomQuestionSelectionTableGUI($this, 'createRandomSelection', $this->getTestObject());
1540 
1541  $this->tpl->setContent(
1542  $randomQuestionSelectionTable
1543  ->build((int) $_POST['nr_of_questions'], (int) $_POST['sel_qpl'])
1544  ->getHtml()
1545  );
1546  }
1547 
1556  {
1557  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1558  $this->redirectAfterMissingWrite();
1559  }
1560  $selected_array = explode(",", $_POST["chosen_questions"]);
1561  if (!count($selected_array)) {
1562  $this->tpl->setOnScreenMessage('info', $this->lng->txt("tst_insert_missing_question"));
1563  } else {
1564  $total = $this->object->evalTotalPersons();
1565  if ($total) {
1566  // the test was executed previously
1567  $this->tpl->setOnScreenMessage('info', sprintf($this->lng->txt("tst_insert_questions_and_results"), $total));
1568  } else {
1569  $this->tpl->setOnScreenMessage('info', $this->lng->txt("tst_insert_questions"));
1570  }
1571  foreach ($selected_array as $key => $value) {
1572  $this->object->insertQuestion($this->testQuestionSetConfigFactory->getQuestionSetConfig(), $value);
1573  }
1574  $this->object->saveCompleteStatus($this->testQuestionSetConfigFactory->getQuestionSetConfig());
1575  $this->tpl->setOnScreenMessage('success', $this->lng->txt("tst_questions_inserted"), true);
1576  $this->ctrl->redirect($this, "questions");
1577  return;
1578  }
1579  }
1580 
1581  /*
1582  * Removing to get rid of a warning, leaving commented out for further analysis.
1583  public function browseForQuestionsObject()
1584  {
1585  $this->questionBrowser();
1586  }
1587  */
1588 
1592  public function executeCreateQuestionObject(): void
1593  {
1594  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1595  $this->redirectAfterMissingWrite();
1596  }
1597  $qpl_ref_id = $this->testrequest->raw("sel_qpl");
1598 
1599  try {
1600  $qpl_mode = $this->testrequest->int('usage');
1601  } catch (ConstraintViolationException $e) {
1602  $qpl_mode = 1;
1603  }
1604 
1605  if ($this->testrequest->isset('qtype')) {
1606  $sel_question_types = ilObjQuestionPool::getQuestionTypeByTypeId($this->testrequest->raw("qtype"));
1607  } elseif ($this->testrequest->isset('sel_question_types')) {
1608  $sel_question_types = $this->testrequest->raw("sel_question_types");
1609  }
1610 
1611  if (($qpl_mode == 2 && strcmp($this->testrequest->raw("txt_qpl"), "") == 0) || ($qpl_mode == 3 && strcmp($qpl_ref_id, "") == 0)) {
1612  $this->tpl->setOnScreenMessage('info', $this->lng->txt("questionpool_not_entered"));
1613  $this->createQuestionObject();
1614  return;
1615  } else {
1616  ilSession::set("test_id", $this->object->getRefId());
1617  if ($qpl_mode == 2 && strcmp($this->testrequest->raw("txt_qpl"), "") != 0) {
1618  // create a new question pool and return the reference id
1619  $qpl_ref_id = $this->createQuestionPool($this->testrequest->raw("txt_qpl"));
1620  } elseif ($qpl_mode == 1) {
1621  $qpl_ref_id = $this->testrequest->getRefId();
1622  }
1623  $baselink = "ilias.php?baseClass=ilObjQuestionPoolGUI&ref_id=" . $qpl_ref_id . "&cmd=createQuestionForTest&test_ref_id=" . $this->testrequest->getRefId() . "&calling_test=" . $this->testrequest->getRefId() . "&sel_question_types=" . $sel_question_types;
1624 
1625  if ($this->testrequest->isset('prev_qid')) {
1626  $baselink .= '&prev_qid=' . $this->testrequest->raw('prev_qid');
1627  } elseif ($this->testrequest->isset('position')) {
1628  $baselink .= '&prev_qid=' . $this->testrequest->raw('position');
1629  }
1630 
1631  if ($this->testrequest->raw('test_express_mode')) {
1632  $baselink .= '&test_express_mode=1';
1633  }
1634 
1635  if ($this->testrequest->isset('add_quest_cont_edit_mode')) {
1637  $baselink,
1638  "add_quest_cont_edit_mode={$this->testrequest->raw('add_quest_cont_edit_mode')}",
1639  false
1640  );
1641  }
1642 
1643  ilUtil::redirect($baselink);
1644 
1645  exit();
1646  }
1647  }
1648 
1656  public function cancelCreateQuestionObject()
1657  {
1658  $this->ctrl->redirect($this, "questions");
1659  }
1660 
1668  public function createQuestionObject()
1669  {
1670  global $DIC;
1671  $lng = $DIC['lng'];
1672 
1673  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1674  $this->redirectAfterMissingWrite();
1675  }
1676 
1677  $this->getTabsManager()->getQuestionsSubTabs();
1679  //$this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_as_tst_qpl_select.html", "Modules/Test");
1680  $questionpools = $this->object->getAvailableQuestionpools(false, false, false, true, false, "write");
1681 
1682  $form = new ilPropertyFormGUI();
1683  $form->setFormAction($this->ctrl->getFormAction($this, "executeCreateQuestion"));
1684  $form->setTitle($lng->txt("ass_create_question"));
1685 
1686  if ($this->testrequest->isset('qtype')) {
1687  $sel_question_types = ilObjQuestionPool::getQuestionTypeByTypeId($this->testrequest->raw("qtype"));
1688  } elseif ($this->testrequest->isset('sel_question_types')) {
1689  $sel_question_types = $this->testrequest->raw("sel_question_types");
1690  }
1691 
1692 
1693  $hidden = new ilHiddenInputGUI('sel_question_types');
1694  $hidden->setValue($sel_question_types);
1695  $form->addItem($hidden);
1696 
1697  // content editing mode
1699  $ri = new ilRadioGroupInputGUI($lng->txt("tst_add_quest_cont_edit_mode"), "add_quest_cont_edit_mode");
1700 
1701  $option_ipe = new ilRadioOption(
1702  $lng->txt('tst_add_quest_cont_edit_mode_IPE'),
1704  );
1705  $option_ipe->setInfo($lng->txt('tst_add_quest_cont_edit_mode_IPE_info'));
1706  $ri->addOption($option_ipe);
1707 
1708  $option_rte = new ilRadioOption(
1709  $lng->txt('tst_add_quest_cont_edit_mode_RTE'),
1711  );
1712  $option_rte->setInfo($lng->txt('tst_add_quest_cont_edit_mode_RTE_info'));
1713  $ri->addOption($option_rte);
1714 
1716 
1717  $form->addItem($ri, true);
1718  } else {
1719  $hi = new ilHiddenInputGUI("question_content_editing_type");
1721  $form->addItem($hi, true);
1722  }
1723 
1724  // use pool
1725  $usage = new ilRadioGroupInputGUI($this->lng->txt("assessment_pool_selection"), "usage");
1726  $usage->setRequired(true);
1727  $no_pool = new ilRadioOption($this->lng->txt("assessment_no_pool"), 1);
1728  $usage->addOption($no_pool);
1729  $existing_pool = new ilRadioOption($this->lng->txt("assessment_existing_pool"), 3);
1730  $usage->addOption($existing_pool);
1731  $new_pool = new ilRadioOption($this->lng->txt("assessment_new_pool"), 2);
1732  $usage->addOption($new_pool);
1733  $form->addItem($usage);
1734 
1735  $usage->setValue(1);
1736 
1737  $questionpools = ilObjQuestionPool::_getAvailableQuestionpools(false, false, true, false, false, "write");
1738  $pools_data = array();
1739  foreach ($questionpools as $key => $p) {
1740  $pools_data[$key] = $p['title'];
1741  }
1742  $pools = new ilSelectInputGUI($this->lng->txt("select_questionpool"), "sel_qpl");
1743  $pools->setOptions($pools_data);
1744  $existing_pool->addSubItem($pools);
1745 
1746 
1747  $this->lng->loadLanguageModule('rbac');
1748  $name = new ilTextInputGUI($this->lng->txt("rbac_create_qpl"), "txt_qpl");
1749  $name->setSize(50);
1750  $name->setMaxLength(50);
1751  $new_pool->addSubItem($name);
1752 
1753  $form->addCommandButton("executeCreateQuestion", $lng->txt("submit"));
1754  $form->addCommandButton("cancelCreateQuestion", $lng->txt("cancel"));
1755 
1756  $this->tpl->setVariable('ADM_CONTENT', $form->getHTML());
1757  }
1758 
1763  {
1764  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1765  $this->redirectAfterMissingWrite();
1766  }
1767 
1768  $removeQuestionIds = (array) $_POST["q_id"];
1769 
1770  $questions = $this->object->getQuestionTitlesAndIndexes();
1771 
1772  $this->object->removeQuestions($removeQuestionIds);
1773 
1774  $this->object->saveCompleteStatus($this->testQuestionSetConfigFactory->getQuestionSetConfig());
1775 
1776  $this->tpl->setOnScreenMessage('success', $this->lng->txt("tst_questions_removed"));
1777 
1778  if ($this->testrequest->raw('test_express_mode')) {
1779  $prev = null;
1780  $return_to = null;
1781  $deleted_tmp = $removeQuestionIds;
1782  $first = array_shift($deleted_tmp);
1783  foreach ($questions as $key => $value) {
1784  if (!in_array($key, $removeQuestionIds)) {
1785  $prev = $key;
1786  if (!$first) {
1787  $return_to = $prev;
1788  break;
1789  } else {
1790  continue;
1791  }
1792  } elseif ($key == $first) {
1793  if ($prev) {
1794  $return_to = $prev;
1795  break;
1796  }
1797  $first = array_shift($deleted_tmp);
1798  }
1799  }
1800 
1801  if (
1802  count($questions) == count($removeQuestionIds) ||
1803  !$return_to
1804  ) {
1805  $this->ctrl->setParameter($this, 'q_id', '');
1806  $this->ctrl->redirect($this, 'showPage');
1807  }
1808 
1809  $this->ctrl->setParameter($this, 'q_id', $return_to);
1810  $this->ctrl->redirect($this, "showPage");
1811  } else {
1812  $this->ctrl->setParameter($this, 'q_id', '');
1813  $this->ctrl->redirect($this, 'questions');
1814  }
1815  }
1816 
1825  {
1826  if ($this->testrequest->raw('test_express_mode')) {
1827  $this->ctrl->setParameter($this, 'q_id', $this->testrequest->raw('q_id'));
1828  $this->ctrl->redirect($this, "showPage");
1829  } else {
1830  $this->ctrl->redirect($this, "questions");
1831  }
1832  }
1833 
1841  public function removeQuestionsForm($checked_questions)
1842  {
1843  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1844  $this->redirectAfterMissingWrite();
1845  }
1846 
1847  $total = $this->object->evalTotalPersons();
1848  if ($total) {
1849  // the test was executed previously
1850  $question = sprintf($this->lng->txt("tst_remove_questions_and_results"), $total);
1851  } else {
1852  if (count($checked_questions) == 1) {
1853  $question = $this->lng->txt("tst_remove_question");
1854  } else {
1855  $question = $this->lng->txt("tst_remove_questions");
1856  }
1857  }
1858 
1859  $cgui = new ilConfirmationGUI();
1860  $cgui->setHeaderText($question);
1861 
1862  $this->ctrl->saveParameter($this, 'test_express_mode');
1863  $this->ctrl->saveParameter($this, 'q_id');
1864 
1865  $cgui->setFormAction($this->ctrl->getFormAction($this));
1866  $cgui->setCancel($this->lng->txt("cancel"), "cancelRemoveQuestions");
1867  $cgui->setConfirm($this->lng->txt("confirm"), "confirmRemoveQuestions");
1868  $removablequestions = $this->object->getTestQuestions();
1869  if (count($removablequestions)) {
1870  foreach ($removablequestions as $data) {
1871  if (in_array($data["question_id"], $checked_questions)) {
1872  $txt = $data["title"] . " (" . assQuestion::_getQuestionTypeName($data["type_tag"]) . ")";
1873  $txt .= ' [' . $this->lng->txt('question_id_short') . ': ' . $data['question_id'] . ']';
1874 
1875  if ($data["description"]) {
1876  $txt .= "<div class=\"small\">" . $data["description"] . "</div>";
1877  }
1878 
1879  $cgui->addItem("q_id[]", $data["question_id"], $txt);
1880  }
1881  }
1882  }
1883 
1884  $this->tpl->setContent($cgui->getHTML());
1885  }
1886 
1890  public function removeQuestionsObject()
1891  {
1892  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1893  $this->redirectAfterMissingWrite();
1894  }
1895 
1896  $this->getTabsManager()->getQuestionsSubTabs();
1898 
1899  $checked_questions = $this->testrequest->raw('q_id');
1900 
1901  if (!is_array($checked_questions) && $checked_questions) {
1902  $checked_questions = array($checked_questions);
1903  }
1904 
1905  if (!is_array($checked_questions)) {
1906  $checked_questions = [];
1907  }
1908 
1909  if (count($checked_questions) > 0) {
1910  $this->removeQuestionsForm($checked_questions);
1911  } elseif (0 === count($checked_questions)) {
1912  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("tst_no_question_selected_for_removal"), true);
1913  $this->ctrl->redirect($this, "questions");
1914  }
1915  }
1916 
1920  public function moveQuestionsObject()
1921  {
1922  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1923  $this->redirectAfterMissingWrite();
1924  }
1925 
1926  $selected_questions = $this->testrequest->getQuestionIds()
1927  ? $this->testrequest->getQuestionIds()
1928  : [$this->testrequest->getQuestionId()];
1929  if (count($selected_questions) > 0) {
1930  ilSession::set('tst_qst_move_' . $this->object->getTestId(), $selected_questions);
1931  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_selected_for_move'), true);
1932  } else {
1933  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('no_selection_for_move'), true);
1934  }
1935  $this->ctrl->redirect($this, 'questions');
1936  }
1937 
1942  {
1943  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1944  $this->redirectAfterMissingWrite();
1945  }
1946 
1947  $this->insertQuestionsBeforeOrAfter(self::INSERT_MODE_BEFORE);
1948  }
1949 
1953  public function insertQuestionsAfterObject()
1954  {
1955  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1956  $this->redirectAfterMissingWrite();
1957  }
1958 
1959  $this->insertQuestionsBeforeOrAfter(self::INSERT_MODE_AFTER);
1960  }
1961 
1965  protected function insertQuestionsBeforeOrAfter(int $insert_mode)
1966  {
1967  $target_questions = $this->testrequest->getQuestionIds()
1968  ? $this->testrequest->getQuestionIds()
1969  : [$this->testrequest->getQuestionId()];
1970 
1971  if (count($target_questions) === 0) {
1972  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('no_target_selected_for_move'), true);
1973  $this->ctrl->redirect($this, 'questions');
1974  } elseif (count($target_questions) > 1) {
1975  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('too_many_targets_selected_for_move'), true);
1976  $this->ctrl->redirect($this, 'questions');
1977  }
1978 
1979  $this->object->moveQuestions(ilSession::get('tst_qst_move_' . $this->object->getTestId()), $target_questions[0], $insert_mode);
1980  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_questions_moved'), true);
1981  ilSession::clear('tst_qst_move_' . $this->object->getTestId());
1982  $this->ctrl->redirect($this, 'questions');
1983  }
1984 
1990  public function insertQuestionsObject()
1991  {
1992  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
1993  $this->redirectAfterMissingWrite();
1994  }
1995 
1996  $selected_questions = $this->testrequest->getQuestionIds()
1997  ? $this->testrequest->getQuestionIds()
1998  : [$this->testrequest->getQuestionId()];
1999 
2000  if (count($selected_questions) === 0) {
2001  $this->tpl->setOnScreenMessage('info', $this->lng->txt('tst_insert_missing_question'), true);
2002  $this->ctrl->redirect($this, 'browseForQuestions');
2003  }
2004 
2005  $man_scoring = false;
2006  foreach ($selected_questions as $key => $value) {
2007  $this->object->insertQuestion($this->testQuestionSetConfigFactory->getQuestionSetConfig(), $value);
2008  $man_scoring = $man_scoring || assQuestion::_needsManualScoring($value);
2009  }
2010 
2011  $this->object->saveCompleteStatus($this->testQuestionSetConfigFactory->getQuestionSetConfig());
2012  if ($man_scoring) {
2013  $this->tpl->setOnScreenMessage('info', $this->lng->txt('manscoring_hint'), true);
2014  } else {
2015  $this->tpl->setOnScreenMessage('success', $this->lng->txt('tst_questions_inserted'), true);
2016  }
2017  $this->ctrl->redirect($this, 'questions');
2018  }
2019 
2020  public function addQuestionObject()
2021  {
2022  global $DIC;
2023  $lng = $DIC['lng'];
2024  $ilCtrl = $DIC['ilCtrl'];
2025  $tpl = $DIC['tpl'];
2026  global $DIC; /* @var \ILIAS\DI\Container $DIC */
2027  $ilHelp = $DIC['ilHelp']; /* @var ilHelpGUI $ilHelp */
2028 
2029  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
2030  $this->redirectAfterMissingWrite();
2031  }
2032 
2033  $this->getTabsManager()->getQuestionsSubTabs();
2035 
2036  $subScreenId = array('createQuestion');
2037 
2038  $ilCtrl->setParameter($this, 'qtype', $this->testrequest->raw('qtype'));
2039 
2040  $form = new ilPropertyFormGUI();
2041 
2042  $form->setFormAction($ilCtrl->getFormAction($this, "executeCreateQuestion"));
2043  $form->setTitle($lng->txt("ass_create_question"));
2044 
2045  $pool = new ilObjQuestionPool();
2046  $questionTypes = $pool->getQuestionTypes(false, true, false);
2047  $options = array();
2048 
2049  // question type
2050  foreach ($questionTypes as $label => $data) {
2051  $options[$data['question_type_id']] = $label;
2052  }
2053  $si = new ilSelectInputGUI($lng->txt("question_type"), "qtype");
2054  $si->setOptions($options);
2055  $form->addItem($si, true);
2056 
2057  // position
2058  $questions = $this->object->getQuestionTitlesAndIndexes();
2059  if ($questions) {
2060  $si = new ilSelectInputGUI($lng->txt("position"), "position");
2061  $options = array('0' => $lng->txt('first'));
2062  foreach ($questions as $key => $title) {
2063  $options[$key] = $lng->txt('behind') . ' ' . $title . ' [' . $this->lng->txt('question_id_short') . ': ' . $key . ']';
2064  }
2065  $si->setOptions($options);
2066  $si->setValue($this->testrequest->raw('q_id'));
2067  $form->addItem($si, true);
2068  }
2069 
2070  // content editing mode
2072  $subScreenId[] = 'editMode';
2073 
2074  $ri = new ilRadioGroupInputGUI($lng->txt("tst_add_quest_cont_edit_mode"), "add_quest_cont_edit_mode");
2075 
2076  $option_ipe = new ilRadioOption(
2077  $lng->txt('tst_add_quest_cont_edit_mode_IPE'),
2079  );
2080  $option_ipe->setInfo($lng->txt('tst_add_quest_cont_edit_mode_IPE_info'));
2081  $ri->addOption($option_ipe);
2082 
2083  $option_rte = new ilRadioOption(
2084  $lng->txt('tst_add_quest_cont_edit_mode_RTE'),
2086  );
2087  $option_rte->setInfo($lng->txt('tst_add_quest_cont_edit_mode_RTE_info'));
2088  $ri->addOption($option_rte);
2089 
2091 
2092  $form->addItem($ri, true);
2093  } else {
2094  $hi = new ilHiddenInputGUI("question_content_editing_type");
2096  $form->addItem($hi, true);
2097  }
2098 
2099  $subScreenId[] = 'poolSelect';
2100 
2101  // use pool
2102  $usage = new ilRadioGroupInputGUI($this->lng->txt("assessment_pool_selection"), "usage");
2103  $usage->setRequired(true);
2104  $no_pool = new ilRadioOption($this->lng->txt("assessment_no_pool"), 1);
2105  $usage->addOption($no_pool);
2106  $existing_pool = new ilRadioOption($this->lng->txt("assessment_existing_pool"), 3);
2107  $usage->addOption($existing_pool);
2108  $new_pool = new ilRadioOption($this->lng->txt("assessment_new_pool"), 2);
2109  $usage->addOption($new_pool);
2110  $form->addItem($usage);
2111 
2112  $usage->setValue(1);
2113 
2114  $questionpools = ilObjQuestionPool::_getAvailableQuestionpools(false, false, true, false, false, "write");
2115  $pools_data = array();
2116  foreach ($questionpools as $key => $p) {
2117  $pools_data[$key] = $p['title'];
2118  }
2119  $pools = new ilSelectInputGUI($this->lng->txt("select_questionpool"), "sel_qpl");
2120  $pools->setOptions($pools_data);
2121  $existing_pool->addSubItem($pools);
2122 
2123  $name = new ilTextInputGUI($this->lng->txt("name"), "txt_qpl");
2124  $name->setSize(50);
2125  $name->setMaxLength(50);
2126  $new_pool->addSubItem($name);
2127 
2128  $form->addCommandButton("executeCreateQuestion", $lng->txt("create"));
2129  $form->addCommandButton("questions", $lng->txt("cancel"));
2130 
2131  $DIC->tabs()->activateTab('assQuestions');
2132  $ilHelp->setScreenId('assQuestions');
2133  $ilHelp->setSubScreenId(implode('_', $subScreenId));
2134 
2135  return $tpl->setContent($form->getHTML());
2136  }
2137 
2138  public function questionsObject()
2139  {
2140  global $DIC; /* @var ILIAS\DI\Container $DIC */
2141  $ilAccess = $DIC['ilAccess'];
2142  $ilTabs = $DIC['ilTabs'];
2143 
2144  // #12590
2145  $this->ctrl->setParameter($this, 'test_express_mode', '');
2146 
2147  if (!$ilAccess->checkAccess("write", "", $this->ref_id)) {
2148  // allow only write access
2149  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cannot_edit_test"), true);
2150  $this->ctrl->redirect($this, "infoScreen");
2151  }
2152 
2153  /*
2154  * Removing to get rid of a warning, leaving commented out for further analysis.
2155  if ($_GET['browse']) {
2156  $this->questionbrowser();
2157  return;
2158  }
2159  */
2160 
2161  $this->getTabsManager()->getQuestionsSubTabs();
2163 
2164  // #11631, #12994
2165  $this->ctrl->setParameter($this, 'q_id', '');
2166 
2167  if ($this->testrequest->raw("eqid") && $this->testrequest->raw("eqpl")) {
2168  ilUtil::redirect("ilias.php?baseClass=ilObjQuestionPoolGUI&ref_id=" . $this->testrequest->raw("eqpl") . "&cmd=editQuestionForTest&calling_test=" . $this->testrequest->getRefId() . "&q_id=" . $this->testrequest->raw("eqid"));
2169  }
2170 
2171  if ($this->testrequest->raw("up") > 0) {
2172  $this->object->questionMoveUp($this->testrequest->raw("up"));
2173  }
2174  if ($this->testrequest->raw("down") > 0) {
2175  $this->object->questionMoveDown($this->testrequest->raw("down"));
2176  }
2177 
2178  if ($this->testrequest->raw("add")) {
2179  $selected_array = array();
2180  array_push($selected_array, $this->testrequest->raw("add"));
2181  $total = $this->object->evalTotalPersons();
2182  if ($total) {
2183  // the test was executed previously
2184  $this->tpl->setOnScreenMessage('info', sprintf($this->lng->txt("tst_insert_questions_and_results"), $total));
2185  } else {
2186  $this->tpl->setOnScreenMessage('info', $this->lng->txt("tst_insert_questions"));
2187  }
2188  // @PHP8-CR This call seems to be critically important for the method, but I cannot see how to fix it yet.
2189  // I leave the warning "intact" for further analysis, possibly by T&A TechSquad.
2190  $this->insertQuestions($selected_array);
2191  return;
2192  }
2193 
2194  $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.il_as_tst_questions.html", "Modules/Test");
2195 
2196  $total = $this->object->evalTotalPersons();
2197  if ($ilAccess->checkAccess("write", "", $this->ref_id)) {
2198  if ($total != 0) {
2199  $link = $DIC->ui()->factory()->link()->standard(
2200  $DIC->language()->txt("test_has_datasets_warning_page_view_link"),
2201  $DIC->ctrl()->getLinkTargetByClass(array('ilTestResultsGUI', 'ilParticipantsTestResultsGUI'))
2202  );
2203 
2204  $message = $DIC->language()->txt("test_has_datasets_warning_page_view");
2205 
2206  $msgBox = $DIC->ui()->factory()->messageBox()->info($message)->withLinks(array($link));
2207 
2208  $DIC->ui()->mainTemplate()->setCurrentBlock('mess');
2209  $DIC->ui()->mainTemplate()->setVariable(
2210  'MESSAGE',
2211  $DIC->ui()->renderer()->render($msgBox)
2212  );
2213  $DIC->ui()->mainTemplate()->parseCurrentBlock();
2214  } else {
2215  $ilToolbar = $DIC['ilToolbar'];
2216 
2217  $ilToolbar->addButton($this->lng->txt("ass_create_question"), $this->ctrl->getLinkTarget($this, "addQuestion"));
2218 
2219  $ilToolbar->addSeparator();
2221  }
2222  }
2223 
2224  $table_gui = new ilTestQuestionsTableGUI(
2225  $this,
2226  'questions',
2227  $this->object->getRefId()
2228  );
2229 
2230  $isset = ilSession::get('tst_qst_move_' . $this->object->getTestId()) !== null;
2231  $table_gui->setPositionInsertCommandsEnabled(
2232  $isset
2233  && is_array(ilSession::get('tst_qst_move_' . $this->object->getTestId()))
2234  && count(ilSession::get('tst_qst_move_' . $this->object->getTestId()))
2235  );
2236 
2237  $table_gui->setQuestionPositioningEnabled(!$total);
2238  $table_gui->setQuestionManagingEnabled(!$total);
2239  $table_gui->setObligatoryQuestionsHandlingEnabled($this->object->areObligationsEnabled());
2240 
2241  $table_gui->setTotalPoints($this->object->getFixedQuestionSetTotalPoints());
2242 
2243  $table_gui->init();
2244 
2245  $table_gui->setData($this->object->getTestQuestions());
2246 
2247  $this->tpl->setPermanentLink($this->object->getType(), $this->object->getRefId(), '_qst');
2248 
2249  $this->tpl->setCurrentBlock("adm_content");
2250  $this->tpl->setVariable("ACTION_QUESTION_FORM", $this->ctrl->getFormAction($this));
2251  $this->tpl->setVariable('QUESTIONBROWSER', $table_gui->getHTML());
2252  $this->tpl->parseCurrentBlock();
2253  }
2254 
2256  {
2257  $this->ctrl->setParameterByClass(
2258  ilTestQuestionBrowserTableGUI::class,
2260  $context
2261  );
2262  $this->ctrl->setParameterByClass(
2263  ilTestQuestionBrowserTableGUI::class,
2266  );
2267 
2268  $toolbar->addButton(
2269  $this->lng->txt("tst_browse_for_qpl_questions"),
2270  $this->ctrl->getLinkTargetByClass(
2271  ilTestQuestionBrowserTableGUI::class,
2273  )
2274  );
2275 
2276  $this->ctrl->setParameterByClass(
2277  ilTestQuestionBrowserTableGUI::class,
2280  );
2281 
2282  $toolbar->addButton(
2283  $this->lng->txt("tst_browse_for_tst_questions"),
2284  $this->ctrl->getLinkTargetByClass(
2285  ilTestQuestionBrowserTableGUI::class,
2287  )
2288  );
2289  }
2290 
2291  public function takenObject()
2292  {
2293  }
2294 
2302  public function historyObject()
2303  {
2304  global $DIC; /* @var ILIAS\DI\Container $DIC */
2305 
2306  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
2307  $this->redirectAfterMissingWrite();
2308  }
2309 
2310  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_HISTORY);
2311  $table_gui = new ilTestHistoryTableGUI($this, 'history');
2312  $table_gui->setTestObject($this->object);
2313  $log = ilObjAssessmentFolder::_getLog(0, time(), $this->object->getId(), true);
2314  $table_gui->setData($log);
2315  $this->tpl->setVariable('ADM_CONTENT', $table_gui->getHTML());
2316  }
2317 
2318  public function initImportForm(string $new_type): ilPropertyFormGUI
2319  {
2320  $form = new ilPropertyFormGUI();
2321  $form->setTarget("_top");
2322  $n_type = $this->testrequest->raw("new_type");
2323  $this->ctrl->setParameter($this, "new_type", $n_type);
2324  $form->setFormAction($this->ctrl->getFormAction($this));
2325  $form->setTitle($this->lng->txt("import_tst"));
2326  $fi = new ilFileInputGUI($this->lng->txt("import_file"), "xmldoc");
2327  $fi->setSuffixes(array("zip"));
2328  $fi->setRequired(true);
2329  $form->addItem($fi);
2330  $tst = new ilObjTest();
2331  $questionpools = $tst->getAvailableQuestionpools(true, false, true, true);
2332  if (count($questionpools)) {
2333  $options = array("-1" => $this->lng->txt("dont_use_questionpool"));
2334  foreach ($questionpools as $key => $value) {
2335  $options[$key] = $value["title"];
2336  }
2337 
2338  $pool = new ilSelectInputGUI($this->lng->txt("select_questionpool"), "qpl");
2339  $pool->setInfo($this->lng->txt('select_question_pool_info'));
2340  $pool->setOptions($options);
2341  $form->addItem($pool);
2342  }
2343 
2344  $form->addCommandButton("importFile", $this->lng->txt("import"));
2345  $form->addCommandButton("cancel", $this->lng->txt("cancel"));
2346 
2347  return $form;
2348  }
2349 
2355  public function participantsActionObject()
2356  {
2357  $command = $_POST["command"];
2358  if (strlen($command)) {
2359  $method = $command . "Object";
2360  if (method_exists($this, $method)) {
2361  $this->$method();
2362  return;
2363  }
2364  }
2365  $this->ctrl->redirect($this, "participants");
2366  }
2367 
2375  public function printobject()
2376  {
2377  global $DIC;
2378  $ilAccess = $DIC['ilAccess'];
2379  if (!$ilAccess->checkAccess("write", "", $this->ref_id)) {
2380  // allow only write access
2381  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cannot_edit_test"), true);
2382  $this->ctrl->redirect($this, "infoScreen");
2383  }
2384 
2385  $isPdfDeliveryRequest = $DIC->test()->internal()->request()->isset('pdf') &&
2386  $DIC->test()->internal()->request()->raw('pdf');
2387 
2388  $this->getTabsManager()->getQuestionsSubTabs();
2389  $template = new ilTemplate("tpl.il_as_tst_print_test_confirm.html", true, true, "Modules/Test");
2390 
2391  if (!$isPdfDeliveryRequest) { // #15243
2392  $this->ctrl->setParameter($this, "pdf", "1");
2393  $template->setCurrentBlock("pdf_export");
2394  $template->setVariable("PDF_URL", $this->ctrl->getLinkTarget($this, "print"));
2395  $this->ctrl->setParameter($this, "pdf", "");
2396  $template->setVariable("PDF_TEXT", $this->lng->txt("pdf_export"));
2397  $template->parseCurrentBlock();
2398 
2399  $template->setCurrentBlock("navigation_buttons");
2400  $template->setVariable("BUTTON_PRINT", $this->lng->txt("print"));
2401  $template->parseCurrentBlock();
2402  }
2403  // prepare generation before contents are processed (for mathjax)
2404  else {
2406  }
2407 
2408  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
2409 
2410  global $DIC;
2411  $ilUser = $DIC['ilUser'];
2412  $print_date = mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y"));
2413  $max_points = 0;
2414  $counter = 1;
2415  $questionHeaderBlockBuilder = new ilTestQuestionHeaderBlockBuilder($this->lng);
2416  $questionHeaderBlockBuilder->setHeaderMode($this->object->getTitleOutput());
2417 
2418  if ($isPdfDeliveryRequest) {
2420  }
2421 
2422  foreach ($this->object->questions as $question) {
2423  $template->setCurrentBlock("question");
2424  $question_gui = $this->object->createQuestionGUI("", $question);
2425  $question_gui->setPresentationContext(assQuestionGUI::PRESENTATION_CONTEXT_TEST);
2426 
2427  if ($isPdfDeliveryRequest) {
2428  $question_gui->setRenderPurpose(assQuestionGUI::RENDER_PURPOSE_PRINT_PDF);
2429  }
2430 
2431  $questionHeaderBlockBuilder->setQuestionTitle($question_gui->object->getTitleForHTMLOutput());
2432  $questionHeaderBlockBuilder->setQuestionPoints($question_gui->object->getMaximumPoints());
2433  $questionHeaderBlockBuilder->setQuestionPosition($counter);
2434  $template->setVariable("QUESTION_HEADER", $questionHeaderBlockBuilder->getHTML());
2435 
2436  $template->setVariable("TXT_QUESTION_ID", $this->lng->txt('question_id_short'));
2437  $template->setVariable("QUESTION_ID", $question_gui->object->getId());
2438  $result_output = $question_gui->getSolutionOutput(0, null, false, true, false, false);
2439  $template->setVariable("SOLUTION_OUTPUT", $result_output);
2440  $template->parseCurrentBlock("question");
2441  $counter++;
2442  $max_points += $question_gui->object->getMaximumPoints();
2443  }
2444 
2445  $template->setVariable("TITLE", strip_tags($this->object->getTitleForHTMLOutput(), ilObjectGUI::ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION));
2446  $template->setVariable("PRINT_TEST", ilLegacyFormElementsUtil::prepareFormOutput($this->lng->txt("tst_print")));
2447  $template->setVariable("TXT_PRINT_DATE", ilLegacyFormElementsUtil::prepareFormOutput($this->lng->txt("date")));
2448  $used_relative_dates = ilDatePresentation::useRelativeDates();
2449  $template->setVariable(
2450  "VALUE_PRINT_DATE",
2452  );
2453  $use = ilDatePresentation::setUseRelativeDates($used_relative_dates);
2454  $template->setVariable(
2455  "TXT_MAXIMUM_POINTS",
2456  ilLegacyFormElementsUtil::prepareFormOutput($this->lng->txt("tst_maximum_points"))
2457  );
2458  $template->setVariable("VALUE_MAXIMUM_POINTS", ilLegacyFormElementsUtil::prepareFormOutput($max_points));
2459 
2460  if ($isPdfDeliveryRequest) {
2461  ilTestPDFGenerator::generatePDF($template->get(), ilTestPDFGenerator::PDF_OUTPUT_DOWNLOAD, $this->object->getTitleFilenameCompliant(), PDF_PRINT_VIEW_QUESTIONS);
2462  } else {
2463  $this->tpl->setVariable("PRINT_CONTENT", $template->get());
2464  }
2465  }
2466 
2474  public function reviewobject()
2475  {
2476  global $DIC;
2477  $ilAccess = $DIC['ilAccess'];
2478 
2479  if (!$ilAccess->checkAccess("write", "", $this->ref_id)) {
2480  // allow only write access
2481  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cannot_edit_test"), true);
2482  $this->ctrl->redirect($this, "infoScreen");
2483  }
2484  $this->getTabsManager()->getQuestionsSubTabs();
2485  $template = new ilTemplate("tpl.il_as_tst_print_test_confirm.html", true, true, "Modules/Test");
2486 
2487  $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
2488 
2489  $isPdfDeliveryRequest = $DIC->test()->internal()->request()->isset('pdf') &&
2490  $DIC->test()->internal()->request()->raw('pdf');
2491 
2492  $max_points = 0;
2493  $counter = 1;
2494  $questionHeaderBlockBuilder = new ilTestQuestionHeaderBlockBuilder($this->lng);
2495  $questionHeaderBlockBuilder->setHeaderMode($this->object->getTitleOutput());
2496 
2497  if ($isPdfDeliveryRequest) {
2499 
2500  // prepare generation before contents are processed (for mathjax)
2502  }
2503 
2504  foreach ($this->object->questions as $question) {
2505  $template->setCurrentBlock("question");
2506  $question_gui = $this->object->createQuestionGUI("", $question);
2507  $question_gui->setRenderPurpose(assQuestionGUI::RENDER_PURPOSE_PREVIEW);
2508 
2509  $questionHeaderBlockBuilder->setQuestionTitle($question_gui->object->getTitleForHTMLOutput());
2510  $questionHeaderBlockBuilder->setQuestionPoints($question_gui->object->getMaximumPoints());
2511  $questionHeaderBlockBuilder->setQuestionPosition($counter);
2512  $template->setVariable("QUESTION_HEADER", $questionHeaderBlockBuilder->getHTML());
2513 
2514  $template->setVariable("SOLUTION_OUTPUT", $question_gui->getPreview(false));
2515  $template->parseCurrentBlock("question");
2516  $counter++;
2517  $max_points += $question_gui->object->getMaximumPoints();
2518  }
2519 
2520  $template->setVariable("TITLE", strip_tags($this->object->getTitle(), ilObjectGUI::ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION));
2521  $template->setVariable(
2522  "PRINT_TEST",
2523  ilLegacyFormElementsUtil::prepareFormOutput($this->lng->txt("review_view"))
2524  );
2525  $template->setVariable("TXT_PRINT_DATE", ilLegacyFormElementsUtil::prepareFormOutput($this->lng->txt("date")));
2526  $usedRelativeDates = ilDatePresentation::useRelativeDates();
2528  $template->setVariable(
2529  "VALUE_PRINT_DATE",
2531  );
2532  ilDatePresentation::setUseRelativeDates($usedRelativeDates);
2533  $template->setVariable(
2534  "TXT_MAXIMUM_POINTS",
2535  ilLegacyFormElementsUtil::prepareFormOutput($this->lng->txt("tst_maximum_points"))
2536  );
2537  $template->setVariable("VALUE_MAXIMUM_POINTS", ilLegacyFormElementsUtil::prepareFormOutput($max_points));
2538 
2539  if ($isPdfDeliveryRequest) {
2540  ilTestPDFGenerator::generatePDF($template->get(), ilTestPDFGenerator::PDF_OUTPUT_DOWNLOAD, $this->object->getTitleFilenameCompliant(), PDF_PRINT_VIEW_QUESTIONS);
2541  } else {
2542  $this->ctrl->setParameter($this, "pdf", "1");
2543  $template->setCurrentBlock("pdf_export");
2544  $template->setVariable("PDF_URL", $this->ctrl->getLinkTarget($this, "review"));
2545  $this->ctrl->setParameter($this, "pdf", "");
2546  $template->setVariable("PDF_TEXT", $this->lng->txt("pdf_export"));
2547  $template->parseCurrentBlock();
2548 
2549  $template->setCurrentBlock("navigation_buttons");
2550  $template->setVariable("BUTTON_PRINT", $this->lng->txt("print"));
2551  $template->parseCurrentBlock();
2552 
2553 
2554  $this->tpl->setVariable("PRINT_CONTENT", $template->get());
2555  }
2556  }
2557 
2561  public function defaultsObject()
2562  {
2568  global $DIC;
2569  $ilAccess = $DIC['ilAccess'];
2570  $ilToolbar = $DIC['ilToolbar'];
2571  $tpl = $DIC['tpl'];
2572 
2573  if (!$ilAccess->checkAccess("write", "", $this->ref_id)) {
2574  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cannot_edit_test"), true);
2575  $this->ctrl->redirect($this, "infoScreen");
2576  }
2577 
2578  global $DIC; /* @var ILIAS\DI\Container $DIC */
2579 
2580  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_SETTINGS);
2581 
2582  $ilToolbar->setFormAction($this->ctrl->getFormAction($this, 'addDefaults'));
2583  $ilToolbar->addFormButton($this->lng->txt('add'), 'addDefaults');
2584  $ilToolbar->addInputItem(new ilTextInputGUI($this->lng->txt('tst_defaults_defaults_of_test'), 'name'), true);
2585  $table = new ilTestPersonalDefaultSettingsTableGUI($this, 'defaults');
2586  $defaults = $this->object->getAvailableDefaults();
2587  $table->setData($defaults);
2588  $tpl->setContent($table->getHTML());
2589  }
2590 
2594  public function deleteDefaultsObject()
2595  {
2596  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
2597  $this->redirectAfterMissingWrite();
2598  }
2599 
2600  if (isset($_POST['chb_defaults']) && is_array($_POST['chb_defaults']) && count($_POST['chb_defaults'])) {
2601  foreach ($_POST['chb_defaults'] as $test_default_id) {
2602  $this->object->deleteDefaults($test_default_id);
2603  }
2604  } else {
2605  $this->tpl->setOnScreenMessage('info', $this->lng->txt('select_one'));
2606  }
2607  $this->defaultsObject();
2608  }
2609 
2614  {
2615  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
2616  $this->redirectAfterMissingWrite();
2617  }
2618 
2619  $this->applyDefaultsObject(true);
2620  return;
2621  }
2622 
2626  public function applyDefaultsObject($confirmed = false)
2627  {
2628  if (!isset($_POST['chb_defaults']) || !is_array($_POST["chb_defaults"]) || 1 !== count($_POST["chb_defaults"])) {
2629  $this->tpl->setOnScreenMessage('info', $this->lng->txt("tst_defaults_apply_select_one"));
2630 
2631  $this->defaultsObject();
2632  return;
2633  }
2634 
2635  // do not apply if user datasets exist
2636  if ($this->object->evalTotalPersons() > 0) {
2637  $this->tpl->setOnScreenMessage('info', $this->lng->txt("tst_defaults_apply_not_possible"));
2638 
2639  $this->defaultsObject();
2640  return;
2641  }
2642 
2643  $defaults = $this->object->getTestDefaults($_POST["chb_defaults"][0]);
2644  $defaultSettings = unserialize($defaults["defaults"]);
2645 
2646  if (isset($defaultSettings['isRandomTest'])) {
2647  if ($defaultSettings['isRandomTest']) {
2648  $newQuestionSetType = ilObjTest::QUESTION_SET_TYPE_RANDOM;
2649  $this->object->setQuestionSetType(ilObjTest::QUESTION_SET_TYPE_RANDOM);
2650  } else {
2651  $newQuestionSetType = ilObjTest::QUESTION_SET_TYPE_FIXED;
2652  $this->object->setQuestionSetType(ilObjTest::QUESTION_SET_TYPE_FIXED);
2653  }
2654  } elseif (isset($defaultSettings['questionSetType'])) {
2655  $newQuestionSetType = $defaultSettings['questionSetType'];
2656  }
2657  $oldQuestionSetType = $this->object->getQuestionSetType();
2658  $questionSetTypeSettingSwitched = ($oldQuestionSetType != $newQuestionSetType);
2659 
2660  $oldQuestionSetConfig = $this->testQuestionSetConfigFactory->getQuestionSetConfigByType();
2661 
2662  switch (true) {
2663  case !$questionSetTypeSettingSwitched:
2664  case !$oldQuestionSetConfig->doesQuestionSetRelatedDataExist():
2665  case $confirmed:
2666 
2667  break;
2668 
2669  default:
2670 
2671  $confirmation = new ilTestSettingsChangeConfirmationGUI($this->getTestObject());
2672 
2673  $confirmation->setFormAction($this->ctrl->getFormAction($this));
2674  $confirmation->setCancel($this->lng->txt('cancel'), 'defaults');
2675  $confirmation->setConfirm($this->lng->txt('confirm'), 'confirmedApplyDefaults');
2676 
2677  $confirmation->setOldQuestionSetType($this->object->getQuestionSetType());
2678  $confirmation->setNewQuestionSetType($newQuestionSetType);
2679  $confirmation->setQuestionLossInfoEnabled(false);
2680  $confirmation->build();
2681 
2682  $confirmation->populateParametersFromPost();
2683 
2684  $this->tpl->setContent($this->ctrl->getHTML($confirmation));
2685 
2686  return;
2687  }
2688 
2689  if ($questionSetTypeSettingSwitched && !$this->object->getOfflineStatus()) {
2690  $this->object->setOfflineStatus(true);
2691 
2692  $info = $this->lng->txt("tst_set_offline_due_to_switched_question_set_type_setting");
2693 
2694  $this->tpl->setOnScreenMessage('info', $info, true);
2695  }
2696 
2697  $this->object->applyDefaults($defaults);
2698 
2699  $this->tpl->setOnScreenMessage('success', $this->lng->txt("tst_defaults_applied"), true);
2700 
2701  if ($questionSetTypeSettingSwitched && $oldQuestionSetConfig->doesQuestionSetRelatedDataExist()) {
2702  $oldQuestionSetConfig->removeQuestionSetRelatedData();
2703  }
2704 
2705  $this->ctrl->redirect($this, 'defaults');
2706  }
2707 
2711  public function addDefaultsObject()
2712  {
2713  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
2714  $this->redirectAfterMissingWrite();
2715  }
2716 
2717  if (strlen($_POST["name"]) > 0) {
2718  $this->object->addDefaults($_POST['name']);
2719  } else {
2720  $this->tpl->setOnScreenMessage('info', $this->lng->txt("tst_defaults_enter_name"));
2721  }
2722  $this->defaultsObject();
2723  }
2724 
2725  private function isCommandClassAnyInfoScreenChild(): bool
2726  {
2727  if (in_array($this->ctrl->getCmdClass(), self::$infoScreenChildClasses)) {
2728  return true;
2729  }
2730 
2731  return false;
2732  }
2733 
2739  public function infoScreenObject()
2740  {
2741  $this->ctrl->setCmd("showSummary");
2742  $this->ctrl->setCmdClass("ilinfoscreengui");
2743  $this->infoScreen();
2744  }
2745 
2746  public function redirectToInfoScreenObject()
2747  {
2748  $this->ctrl->setCmd("showSummary");
2749  $this->ctrl->setCmdClass("ilinfoscreengui");
2750  $this->infoScreen($this->testrequest->raw('lock'));
2751  }
2752 
2756  public function infoScreen($session_lock = "")
2757  {
2758  /* @var ILIAS\DI\Container $DIC */
2759  global $DIC;
2760  $ilAccess = $DIC['ilAccess'];
2761  $ilUser = $DIC['ilUser'];
2762  $ilToolbar = $DIC['ilToolbar'];
2763 
2764  if (!$ilAccess->checkAccess("visible", "", $this->ref_id) && !$ilAccess->checkAccess("read", "", $_GET["ref_id"])) {
2765  $this->redirectAfterMissingRead();
2766  return '';
2767  }
2768 
2769  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_INFOSCREEN);
2770 
2771  if ($ilAccess->checkAccess("read", "", $this->testrequest->getRefId())) {
2772  $this->trackTestObjectReadEvent();
2773  }
2774  $info = new ilInfoScreenGUI($this);
2775 
2776  if ($this->isCommandClassAnyInfoScreenChild()) {
2777  return $this->ctrl->forwardCommand($info);
2778  }
2779  $toolbarFactory = new ilTestInfoScreenToolbarFactory();
2780  $toolbarFactory->setTestOBJ($this->getTestObject());
2781  $toolbar = $toolbarFactory->getToolbarInstance();
2782 
2783  $toolbar->setGlobalToolbar($GLOBALS['DIC']['ilToolbar']);
2784  $toolbar->setCloseFormTag(false);
2785 
2786  $toolbar->setSessionLockString($session_lock);
2787  $toolbar->build();
2788  $toolbar->sendMessages();
2789 
2790  if ($this->object->getShowInfo()) {
2791  $info->enablePrivateNotes();
2792  }
2793 
2794  if ($this->object->getIntroduction() !== '') {
2795  $info->addSection($this->lng->txt("tst_introduction"));
2796  $info->addProperty("", $this->object->prepareTextareaOutput($this->object->getIntroduction(), true) .
2797  "<br />" . $info->getHiddenToggleButton());
2798  } else {
2799  $info->addSection($this->lng->txt("show_details"));
2800  $info->addProperty("", $info->getHiddenToggleButton());
2801  }
2802 
2803  $info->addSection($this->lng->txt("tst_general_properties"));
2804  if ($this->object->getShowInfo()) {
2805  $info->addProperty(
2806  $this->lng->txt("author"),
2807  strip_tags(
2808  $this->object->getAuthor(),
2810  )
2811  );
2812  $info->addProperty(
2813  $this->lng->txt("title"),
2814  strip_tags(
2815  $this->object->getTitle(),
2817  )
2818  );
2819  }
2820  if (!$this->object->getOfflineStatus() &&
2821  $this->object->isComplete($this->testQuestionSetConfigFactory->getQuestionSetConfig()) &&
2822  $ilAccess->checkAccess("read", "", $this->ref_id) &&
2823  !$this->object->isRandomTest() &&
2824  !$this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired() &&
2825  $this->object->getNrOfTries() != 1) {
2826  if ($this->object->getUsePreviousAnswers() == 0) {
2827  if ($this->object->getShowInfo()) {
2828  $info->addProperty($this->lng->txt("tst_use_previous_answers"), $this->lng->txt("tst_dont_use_previous_answers"));
2829  }
2830  } else {
2831  $checked_previous_answers = false;
2832  if ($ilUser->getPref("tst_use_previous_answers")) {
2833  $checked_previous_answers = true;
2834  }
2835  $info->addPropertyCheckbox($this->lng->txt("tst_use_previous_answers"), "chb_use_previous_answers", 1, $this->lng->txt("tst_use_previous_answers_user"), $checked_previous_answers);
2836  }
2837  }
2838 
2839  $info->hideFurtherSections(false);
2840 
2841  if ($this->object->getShowInfo()) {
2842  $info->addSection($this->lng->txt("tst_sequence_properties"));
2843  $info->addProperty($this->lng->txt("tst_sequence"), $this->lng->txt(($this->object->getSequenceSettings() == TEST_FIXED_SEQUENCE) ? "tst_sequence_fixed" : "tst_sequence_postpone"));
2844 
2845  $info->addSection($this->lng->txt("tst_heading_scoring"));
2846  $info->addProperty($this->lng->txt("tst_text_count_system"), $this->lng->txt(($this->object->getCountSystem() == COUNT_PARTIAL_SOLUTIONS) ? "tst_count_partial_solutions" : "tst_count_correct_solutions"));
2847  if ($this->object->isRandomTest()) {
2848  $info->addProperty($this->lng->txt("tst_pass_scoring"), $this->lng->txt(($this->object->getPassScoring() == SCORE_BEST_PASS) ? "tst_pass_best_pass" : "tst_pass_last_pass"));
2849  }
2850 
2851  $info->addSection($this->lng->txt("tst_score_reporting"));
2852  $score_reporting_text = "";
2853  switch ($this->object->getScoreReporting()) {
2855  $score_reporting_text = $this->lng->txt("tst_report_after_test");
2856  break;
2858  $score_reporting_text = $this->lng->txt("tst_report_after_first_question");
2859  break;
2861  $score_reporting_text = $this->lng->txt("tst_report_after_date");
2862  break;
2864  $score_reporting_text = $this->lng->txt("tst_report_after_passed");
2865  break;
2866  default:
2867  $score_reporting_text = $this->lng->txt("tst_report_never");
2868  break;
2869  }
2870  $info->addProperty($this->lng->txt("tst_score_reporting"), $score_reporting_text);
2871  $reporting_date = $this->getTestObject()
2872  ->getScoreSettings()
2873  ->getResultSummarySettings()
2874  ->getReportingDate();
2875  if ($reporting_date !== null) {
2876  $info->addProperty(
2877  $this->lng->txt('tst_score_reporting_date'),
2879  $reporting_date->format('YmdHis'),
2881  $reporting_date->getTimezone()->getName()
2882  ))
2883  );
2884  }
2885 
2886  $info->addSection($this->lng->txt("tst_session_settings"));
2887  $info->addProperty($this->lng->txt("tst_nr_of_tries"), ($this->object->getNrOfTries() == 0) ? $this->lng->txt("unlimited") : $this->object->getNrOfTries());
2888  if ($this->object->getNrOfTries() != 1) {
2889  $info->addProperty($this->lng->txt("tst_nr_of_tries_of_user"), ($toolbar->getTestSession()->getPass() == false) ? $this->lng->txt("tst_no_tries") : $toolbar->getTestSequence()->getPass());
2890  }
2891 
2892  if ($this->object->getEnableProcessingTime()) {
2893  $info->addProperty($this->lng->txt("tst_processing_time"), $this->object->getProcessingTime());
2894  }
2895  if (strlen($this->object->getAllowedUsers()) && ($this->object->getAllowedUsersTimeGap())) {
2896  $info->addProperty($this->lng->txt("tst_allowed_users"), $this->object->getAllowedUsers());
2897  }
2898 
2899  $starting_time = $this->object->getStartingTime();
2900  if ($this->object->isStartingTimeEnabled() && $starting_time != 0) {
2901  $info->addProperty($this->lng->txt("tst_starting_time"), ilDatePresentation::formatDate(new ilDateTime($starting_time, IL_CAL_UNIX)));
2902  }
2903  $ending_time = $this->object->getEndingTime();
2904  if ($this->object->isEndingTimeEnabled() && $ending_time != 0) {
2905  $info->addProperty($this->lng->txt("tst_ending_time"), ilDatePresentation::formatDate(new ilDateTime($ending_time, IL_CAL_UNIX)));
2906  }
2907  $info->addMetaDataSections($this->object->getId(), 0, $this->object->getType());
2908  // forward the command
2909  }
2910 
2911  $this->ctrl->forwardCommand($info);
2912  return null;
2913  }
2914 
2915  protected function removeImportFailsObject()
2916  {
2917  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
2918  $this->redirectAfterMissingWrite();
2919  }
2920 
2921  $qsaImportFails = new ilAssQuestionSkillAssignmentImportFails($this->object->getId());
2922  $qsaImportFails->deleteRegisteredImportFails();
2923  $sltImportFails = new ilTestSkillLevelThresholdImportFails($this->object->getId());
2924  $sltImportFails->deleteRegisteredImportFails();
2925 
2926  $this->ctrl->redirect($this, 'infoScreen');
2927  }
2928 
2929  public function addLocatorItems(): void
2930  {
2931  global $DIC;
2932  $ilLocator = $DIC['ilLocator'];
2933  switch ($this->ctrl->getCmd()) {
2934  case "run":
2935  case "infoScreen":
2936  case "redirectToInfoScreen":
2937  case "start":
2938  case "resume":
2939  case "previous":
2940  case "next":
2941  case "summary":
2942  case "finishTest":
2943  case "outCorrectSolution":
2944  case "passDetails":
2945  case "showAnswersOfUser":
2946  case "outUserResultsOverview":
2947  case "backFromSummary":
2948  case "show_answers":
2949  case "setsolved":
2950  case "resetsolved":
2951  case "outTestSummary":
2952  case "outQuestionSummary":
2953  case "gotoQuestion":
2954  case "selectImagemapRegion":
2955  case "confirmSubmitAnswers":
2956  case "finalSubmission":
2957  case "postpone":
2958  case "outUserPassDetails":
2959  case "checkPassword":
2960  $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, "infoScreen"), "", $this->testrequest->getRefId());
2961  break;
2962  case "eval_stat":
2963  case "evalAllUsers":
2964  case "evalUserDetail":
2965  $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, "eval_stat"), "", $this->testrequest->getRefId());
2966  break;
2967  case "create":
2968  case "save":
2969  case "cancel":
2970  case "importFile":
2971  case "cloneAll":
2972  case "importVerifiedFile":
2973  case "cancelImport":
2974  break;
2975  default:
2976  $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, ""), "", $this->testrequest->getRefId());
2977  break;
2978  }
2979  }
2980 
2981  public function statisticsObject()
2982  {
2983  }
2984 
2988  public function certificateObject()
2989  {
2990  global $DIC; /* @var ILIAS\DI\Container $DIC */
2991 
2992  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
2993  $this->redirectAfterMissingWrite();
2994  }
2995 
2996  $DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_SETTINGS);
2997 
2998  $guiFactory = new ilCertificateGUIFactory();
2999  $output_gui = $guiFactory->create($this->object);
3000 
3001  $output_gui->certificateEditor();
3002  }
3003 
3009  public function getTabs(): void
3010  {
3011  global $DIC;
3012  $help = $DIC['ilHelp'];
3013  $help->setScreenIdComponent("tst");
3014 
3015  if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) {
3016  $courseLink = ilLink::_getLink($this->getObjectiveOrientedContainer()->getRefId());
3017  $this->getTabsManager()->setParentBackLabel($this->lng->txt('back_to_objective_container'));
3018  $this->getTabsManager()->setParentBackHref($courseLink);
3019  }
3020 
3021  $this->getTabsManager()->perform();
3022  }
3023 
3024  public static function accessViolationRedirect()
3025  {
3026  global $DIC;
3027  $main_tpl = $DIC->ui()->mainTemplate(); /* @var ILIAS\DI\Container $DIC */
3028 
3029  $main_tpl->setOnScreenMessage('info', $DIC->language()->txt("no_permission"), true);
3030  $DIC->ctrl()->redirectByClass('ilObjTestGUI', "infoScreen");
3031  }
3032 
3041  public static function _goto($a_target, array $target_parts)
3042  {
3043  global $DIC;
3044  $main_tpl = $DIC->ui()->mainTemplate();
3045  $ilAccess = $DIC['ilAccess'];
3046  $ilErr = $DIC['ilErr'];
3047  $lng = $DIC['lng'];
3048 
3049  if (isset($target_parts[2]) && $target_parts[2] === 'qst' &&
3050  $ilAccess->checkAccess('write', '', (int) $a_target)) {
3052  $tst = ilObjectFactory::getInstanceByRefId((int) $a_target);
3053  if ($tst->isFixedTest()) {
3054  $DIC->ctrl()->setParameterByClass(__CLASS__, 'ref_id', $a_target);
3055  $DIC->ctrl()->redirectByClass(
3056  __CLASS__,
3057  'questions'
3058  );
3059  $DIC->ctrl()->redirectByClass('ilObjTestGUI', 'questions');
3060  } elseif ($tst->isRandomTest()) {
3061  $DIC->ctrl()->setParameterByClass(ilTestRandomQuestionSetConfigGUI::class, 'ref_id', $a_target);
3062  $DIC->ctrl()->redirectByClass([
3063  __CLASS__,
3064  ilTestRandomQuestionSetConfigGUI::class
3065  ]);
3066  } elseif ($tst->isDynamicTest()) {
3067  $target = $DIC->ctrl()->getLinkTargetByClass('ilObjTestDynamicQuestionSetConfigGUI');
3068  $DIC->ctrl()->setParameterByClass(ilObjTestDynamicQuestionSetConfigGUI::class, 'ref_id', $a_target);
3069  $DIC->ctrl()->redirectByClass([
3070  __CLASS__,
3071  ilObjTestDynamicQuestionSetConfigGUI::class
3072  ]);
3073  }
3074  }
3075 
3076  if ($ilAccess->checkAccess("read", "", $a_target) || $ilAccess->checkAccess("visible", "", $a_target)) {
3077  $DIC->ctrl()->setParameterByClass('ilObjTestGUI', 'ref_id', $a_target);
3078  $DIC->ctrl()->redirectByClass('ilObjTestGUI', 'infoScreen');
3079  } elseif ($ilAccess->checkAccess("read", "", ROOT_FOLDER_ID)) {
3080  $main_tpl->setOnScreenMessage('info', sprintf(
3081  $lng->txt("msg_no_perm_read_item"),
3083  ), true);
3085  }
3086 
3087  $ilErr->raiseError($lng->txt("msg_no_perm_read_lm"), $ilErr->FATAL);
3088  }
3089 
3090  public function buildPageViewToolbar($qid = 0)
3091  {
3092  if ($this->create_question_mode) {
3093  return;
3094  }
3095 
3096  global $DIC;
3097  $ilToolbar = $DIC['ilToolbar'];
3098  $ilCtrl = $DIC['ilCtrl'];
3099  $lng = $DIC['lng'];
3100 
3101  $ilCtrl->saveParameter($this, 'q_mode');
3102 
3103  $ilCtrl->setParameterByClass('iltestexpresspageobjectgui', 'test_express_mode', 1);
3104  $ilCtrl->setParameter($this, 'test_express_mode', 1);
3105  $ilCtrl->setParameterByClass('iltestexpresspageobjectgui', 'q_id', $this->testrequest->raw('q_id'));
3106  $ilCtrl->setParameter($this, 'q_id', $this->testrequest->raw('q_id'));
3107  $ilToolbar->setFormAction($ilCtrl->getFormActionByClass('iltestexpresspageobjectgui', 'edit'));
3108 
3109  if ($this->object->evalTotalPersons() == 0) {
3110  $ilToolbar->addFormButton($lng->txt("ass_create_question"), "addQuestion");
3111 
3112  $ilToolbar->addSeparator();
3113 
3115 
3116  $show_separator = true;
3117  }
3118 
3119  $questions = $this->object->getQuestionTitlesAndIndexes();
3120 
3121  // desc
3122  $options = array();
3123  foreach ($questions as $id => $label) {
3124  $options[$id] = $label . ' [' . $this->lng->txt('question_id_short') . ': ' . $id . ']';
3125  }
3126 
3127  $optionKeys = array_keys($options);
3128 
3129  if (!$options) {
3130  $options[] = $lng->txt('none');
3131  }
3132 
3133  if (count($questions)) {
3134  if (isset($show_separator) && $show_separator) {
3135  $ilToolbar->addSeparator();
3136  }
3137 
3138  $btn = ilLinkButton::getInstance();
3139  $btn->setCaption("test_prev_question");
3140  $btn->setUrl($ilCtrl->getLinkTargetByClass('iltestexpresspageobjectgui', 'prevQuestion'));
3141  $ilToolbar->addButtonInstance($btn);
3142 
3143  if (count($options) <= 1 || $optionKeys[0] == $qid) {
3144  $btn->setDisabled(true);
3145  }
3146 
3147  $btn = ilLinkButton::getInstance();
3148  $btn->setCaption("test_next_question");
3149  $btn->setUrl($ilCtrl->getLinkTargetByClass('iltestexpresspageobjectgui', 'nextQuestion'));
3150  $ilToolbar->addButtonInstance($btn);
3151 
3152  if (count($options) <= 1 || $optionKeys[count($optionKeys) - 1] == $qid) {
3153  $btn->setDisabled(true);
3154  }
3155  }
3156 
3157  if (count($questions) > 1) {
3158  $ilToolbar->addSeparator();
3159  $si = new ilSelectInputGUI($lng->txt("test_jump_to"), "q_id");
3160  $si->addCustomAttribute("onChange=\"forms['ilToolbar'].submit();\"");
3161  $si->setOptions($options);
3162 
3163  if ($qid) {
3164  $si->setValue($qid);
3165  }
3166 
3167  $ilToolbar->addInputItem($si, true);
3168  }
3169 
3170  $total = $this->object->evalTotalPersons();
3171 
3172  if (count($questions) && !$total) {
3173  $ilCtrl->setParameter($this, 'q_id', $this->testrequest->raw('q_id'));
3174  $ilToolbar->addSeparator();
3175  $ilToolbar->addButton($lng->txt("test_delete_page"), $ilCtrl->getLinkTarget($this, "removeQuestions"));
3176  }
3177 
3178  if (count($questions) > 1 && !$total) {
3179  $ilToolbar->addSeparator();
3180  $ilToolbar->addButton($lng->txt("test_move_page"), $ilCtrl->getLinkTarget($this, "movePageForm"));
3181  }
3182 
3183  global $DIC;
3184  $ilAccess = $DIC['ilAccess'];
3185  $ilUser = $DIC['ilUser'];
3186 
3187  $online_access = false;
3188  if ($this->object->getFixedParticipants()) {
3189  $online_access_result = ilObjTestAccess::_lookupOnlineTestAccess($this->object->getId(), $ilUser->getId());
3190  if ($online_access_result === true) {
3191  $online_access = true;
3192  }
3193  }
3194 
3195  if (!$this->object->getOfflineStatus() && $this->object->isComplete($this->testQuestionSetConfigFactory->getQuestionSetConfig())) {
3196  if ((!$this->object->getFixedParticipants() || $online_access) && $ilAccess->checkAccess("read", "", $this->ref_id)) {
3197  $testSession = $this->testSessionFactory->getSession();
3198 
3199  $executable = $this->object->isExecutable($testSession, $ilUser->getId(), $allowPassIncrease = true);
3200 
3201  if ($executable["executable"]) {
3202  $player_factory = new ilTestPlayerFactory($this->getTestObject());
3203  $player_instance = $player_factory->getPlayerGUI();
3204 
3205  $ilToolbar->addSeparator();
3206  if ($testSession->getActiveId() > 0) {
3207  $ilToolbar->addButton($lng->txt('tst_resume_test'), $ilCtrl->getLinkTarget($player_instance, 'resumePlayer'));
3208  } else {
3209  $ilToolbar->addButton($lng->txt('tst_start_test'), $ilCtrl->getLinkTarget($player_instance, 'startTest'));
3210  }
3211  }
3212  }
3213  }
3214  }
3215 
3216  public function copyQuestionsToPoolObject()
3217  {
3218  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
3219  $this->redirectAfterMissingWrite();
3220  }
3221 
3222  $this->copyQuestionsToPool($this->testrequest->raw('q_id'), $this->testrequest->raw('sel_qpl'));
3223  $this->ctrl->redirect($this, 'questions');
3224  }
3225 
3226  public function copyQuestionsToPool($questionIds, $qplId): stdClass
3227  {
3228  $newIds = array();
3229  foreach ($questionIds as $q_id) {
3230  $newId = $this->copyQuestionToPool($q_id, $qplId);
3231  $newIds[$q_id] = $newId;
3232  }
3233 
3234  $result = new stdClass();
3235  $result->ids = $newIds;
3236  $result->qpoolid = $qplId;
3237 
3238  return $result;
3239  }
3240 
3241  public function copyQuestionToPool($sourceQuestionId, $targetParentId)
3242  {
3243  $question_gui = assQuestion::instantiateQuestionGUI($sourceQuestionId);
3244 
3245  $newtitle = $question_gui->object->getTitle();
3246  if ($question_gui->object->questionTitleExists($targetParentId, $question_gui->object->getTitle())) {
3247  $counter = 2;
3248  while ($question_gui->object->questionTitleExists($targetParentId, $question_gui->object->getTitle() . " ($counter)")) {
3249  $counter++;
3250  }
3251  $newtitle = $question_gui->object->getTitle() . " ($counter)";
3252  }
3253 
3254  return $question_gui->object->createNewOriginalFromThisDuplicate($targetParentId, $newtitle);
3255  }
3256 
3261  {
3262  global $DIC;
3263  $ilObjDataCache = $DIC['ilObjDataCache'];
3264 
3265  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
3266  $this->redirectAfterMissingWrite();
3267  }
3268 
3269  if (!(int) $this->testrequest->raw('sel_qpl')) {
3270  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("questionpool_not_selected"));
3272  return;
3273  }
3274 
3275  $qplId = $ilObjDataCache->lookupObjId((int) $this->testrequest->raw('sel_qpl'));
3276  $result = $this->copyQuestionsToPool($this->testrequest->raw('q_id'), $qplId);
3277 
3278  foreach ($result->ids as $oldId => $newId) {
3279  $questionInstance = assQuestion::instantiateQuestion($oldId);
3280 
3281  $original_question_id = $questionInstance->getOriginalId();
3282  if ($original_question_id !== null
3283  && assQuestion::originalQuestionExists($original_question_id)) {
3284  $oldOriginal = assQuestion::instantiateQuestion($original_question_id);
3285  $oldOriginal->delete($oldOriginal->getId());
3286  }
3287 
3288  $questionInstance->setNewOriginalId($newId);
3289  }
3290 
3291  $this->tpl->setOnScreenMessage('success', $this->lng->txt('tst_qst_added_to_pool_' . (count($result->ids) > 1 ? 'p' : 's')), true);
3292  $this->ctrl->redirect($this, 'questions');
3293  }
3294 
3296  {
3297  global $DIC;
3298  $lng = $DIC['lng'];
3299  $form = new ilPropertyFormGUI();
3300 
3301  $title = new ilTextInputGUI($lng->txt('title'), 'title');
3302  $title->setRequired(true);
3303  $form->addItem($title);
3304 
3305  $description = new ilTextAreaInputGUI($lng->txt('description'), 'description');
3306  $form->addItem($description);
3307 
3308  $form->addCommandButton('createQuestionPoolAndCopy', $lng->txt('create'));
3309 
3310  if ($this->testrequest->isset('q_id') && is_array($this->testrequest->raw('q_id'))) {
3311  foreach ($this->testrequest->raw('q_id') as $id) {
3312  $hidden = new ilHiddenInputGUI('q_id[]');
3313  $hidden->setValue($id);
3314  $form->addItem($hidden);
3315  }
3316  }
3317 
3318  return $form;
3319  }
3320 
3321  public function copyToQuestionpoolObject()
3322  {
3323  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
3324  $this->redirectAfterMissingWrite();
3325  }
3326 
3327  $this->createQuestionpoolTargetObject('copyQuestionsToPool');
3328  }
3329 
3331  {
3332  global $DIC;
3333  $lng = $DIC['lng'];
3334 
3335  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
3336  $this->redirectAfterMissingWrite();
3337  }
3338 
3339  // #13761; All methods use for this request should be revised, thx japo ;-)
3340  if (
3341  'copyAndLinkToQuestionpool' == $this->ctrl->getCmd() &&
3342  (!$this->testrequest->isset('q_id') || !is_array($this->testrequest->raw('q_id')))
3343  ) {
3344  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('tst_no_question_selected_for_moving_to_qpl'), true);
3345  $this->ctrl->redirect($this, 'questions');
3346  }
3347 
3348  if ($this->testrequest->isset('q_id') && is_array($this->testrequest->raw('q_id'))) {
3349  foreach ($this->testrequest->raw('q_id') as $q_id) {
3351  continue;
3352  }
3353 
3355 
3356  if ($type !== 'tst') {
3357  $this->tpl->setOnScreenMessage('failure', $lng->txt('tst_link_only_unassigned'), true);
3358  $this->ctrl->redirect($this, 'questions');
3359  return;
3360  }
3361  }
3362  }
3363 
3364  $this->createQuestionpoolTargetObject('copyAndLinkQuestionsToPool');
3365  }
3366 
3368  {
3369  if (!$this->access->checkAccess('write', '', $this->object->getRefId())
3370  || !$this->checkPermissionBool('create', '', 'qpl')) {
3371  $this->redirectAfterMissingWrite();
3372  }
3373 
3374  if ($this->testrequest->raw('title')) {
3375  $title = $this->testrequest->raw('title');
3376  } else {
3377  $title = $this->testrequest->raw('txt_qpl');
3378  }
3379 
3380  if (!$title) {
3381  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("questionpool_not_entered"));
3383  return;
3384  }
3385 
3386  $ref_id = $this->createQuestionPool($title, $this->testrequest->raw('description'));
3387  $_REQUEST['sel_qpl'] = $ref_id;
3388 
3389  //if ($_REQUEST['link'])
3390  //{
3392  //}
3393  //else
3394  //{
3395  // $this->copyQuestionsToPoolObject();
3396  //}
3397  }
3398 
3405  public function createQuestionpoolTargetObject($cmd)
3406  {
3407  global $DIC; /* @var \ILIAS\DI\Container $DIC */
3408 
3409  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
3410  $this->redirectAfterMissingWrite();
3411  }
3412 
3413  $this->getTabsManager()->getQuestionsSubTabs();
3415 
3416  $questionpools = $this->object->getAvailableQuestionpools(
3417  false,
3418  false,
3419  false,
3420  true,
3421  false,
3422  "write"
3423  );
3424 
3425  if (count($questionpools) == 0) {
3426  $form = $this->getTargetQuestionpoolForm($questionpools, 'createQuestionPoolAndCopy');
3427  } else {
3428  $form = $this->getTargetQuestionpoolForm($questionpools, $cmd);
3429 
3430  switch ($cmd) {
3431  case 'copyQuestionsToPool':
3432  break;
3433 
3434  case 'copyAndLinkQuestionsToPool':
3435  $hidden = new ilHiddenInputGUI('link');
3436  $hidden->setValue(1);
3437  $form->addItem($hidden);
3438  break;
3439  }
3440  }
3441 
3442  $DIC->ui()->mainTemplate()->setContent($form->getHTML());
3443  }
3444 
3445  protected function getTargetQuestionpoolForm($questionpools, $cmd): ilPropertyFormGUI
3446  {
3447  global $DIC; /* @var \ILIAS\DI\Container $DIC */
3448 
3449  $form = new ilPropertyFormGUI();
3450  $form->setFormAction($DIC->ctrl()->getFormAction($this));
3451  $form->addCommandButton($cmd, $DIC->language()->txt('submit'));
3452  $form->addCommandButton('cancelCreateQuestion', $DIC->language()->txt('cancel'));
3453 
3454  if (count($questionpools) == 0) {
3455  $form->setTitle($this->lng->txt("tst_enter_questionpool"));
3456 
3457  $title = new ilTextInputGUI($DIC->language()->txt('title'), 'title');
3458  $title->setRequired(true);
3459  $form->addItem($title);
3460 
3461  $description = new ilTextAreaInputGUI($DIC->language()->txt('description'), 'description');
3462  $form->addItem($description);
3463  } else {
3464  $form->setTitle($this->lng->txt("tst_select_questionpool"));
3465 
3466  $selectOptions = [
3467  '' => $DIC->language()->txt('please_select')
3468  ];
3469 
3470  foreach ($questionpools as $key => $value) {
3471  $selectOptions[$key] = $value["title"];
3472  }
3473 
3474  $select = new ilSelectInputGUI($DIC->language()->txt('tst_source_question_pool'), 'sel_qpl');
3475  $select->setRequired(true);
3476  $select->setOptions($selectOptions);
3477 
3478  $form->addItem($select);
3479  }
3480 
3481  if ($this->testrequest->isset('q_id') && is_array($this->testrequest->raw('q_id'))) {
3482  foreach ($this->testrequest->raw('q_id') as $id) {
3483  $hidden = new ilHiddenInputGUI('q_id[]');
3484  $hidden->setValue($id);
3485  $form->addItem($hidden);
3486  }
3487  }
3488 
3489  return $form;
3490  }
3491 
3492  public function applyTemplate($templateData, ilObjTest $object)
3493  {
3494  // map formFieldName => setterName
3495  $simpleSetters = array(
3496 
3497  // general properties
3498  'use_pool' => 'setPoolUsage',
3499  'question_set_type' => 'setQuestionSetType',
3500 
3501  // test intro properties
3502  'intro_enabled' => 'setIntroductionEnabled',
3503  'showinfo' => 'setShowInfo',
3504 
3505  // test access properties
3506  'chb_starting_time' => 'setStartingTimeEnabled',
3507  'chb_ending_time' => 'setEndingTimeEnabled',
3508  'password_enabled' => 'setPasswordEnabled',
3509  'fixedparticipants' => 'setFixedParticipants',
3510  'limitUsers' => 'setLimitUsersEnabled',
3511 
3512  // test run properties
3513  'nr_of_tries' => 'setNrOfTries',
3514  'chb_processing_time' => 'setEnableProcessingTime',
3515  'kiosk' => 'setKiosk',
3516  'examid_in_test_pass' => 'setShowExamIdInTestPassEnabled',
3517 
3518  // question behavior properties
3519  'title_output' => 'setTitleOutput',
3520  'autosave' => null, // handled specially in loop below
3521  'chb_shuffle_questions' => 'setShuffleQuestions',
3522  'offer_hints' => 'setOfferingQuestionHintsEnabled',
3523  'instant_feedback_contents' => 'setInstantFeedbackOptionsByArray',
3524  'instant_feedback_trigger' => 'setForceInstantFeedbackEnabled',
3525  'answer_fixation_handling' => null, // handled specially in loop below
3526  'obligations_enabled' => 'setObligationsEnabled',
3527 
3528  // test sequence properties
3529  'chb_use_previous_answers' => 'setUsePreviousAnswers',
3530  'chb_show_cancel' => 'setShowCancel',
3531  'chb_postpone' => 'setPostponingEnabled',
3532  'list_of_questions' => 'setListOfQuestionsSettings',
3533  'chb_show_marker' => 'setShowMarker',
3534 
3535  // test finish properties
3536  'enable_examview' => 'setEnableExamview',
3537  'showfinalstatement' => 'setShowFinalStatement',
3538  'redirection_enabled' => null, // handled specially in loop below
3539  'sign_submission' => 'setSignSubmission',
3540  'mailnotification' => 'setMailNotification',
3541 
3542  // scoring options properties
3543  'count_system' => 'withCountSystem',
3544  'score_cutting' => 'withScoreCutting',
3545  'pass_scoring' => 'withPassScoring',
3546 
3547  // result summary properties
3548  'grading_status' => 'withShowGradingStatusEnabled',
3549  'grading_mark' => 'withShowGradingMarkEnabled',
3550  'pass_deletion_allowed' => 'withPassDeletionAllowed',
3551  'results_access_enabled' => 'withScoreReporting',
3552 
3553  // result details properties
3554  'solution_details' => 'withShowSolutionDetails',
3555  'solution_feedback' => 'withShowSolutionFeedback',
3556  'solution_suggested' => 'withShowSolutionSuggested',
3557  'solution_printview' => 'setShowSolutionPrintview',
3558  'solution_signature' => 'withShowSolutionSignature',
3559  'examid_in_test_res' => 'withShowExamIdInTestResults',
3560  'exp_sc_short' => 'withExportSettingsSingleChoiceShort',
3561 
3562 
3563  // result gamification properties
3564  'highscore_enabled' => 'withHighscoreEnabled',
3565 
3566  // misc scoring & result properties
3567  'anonymity' => 'setAnonymity',
3568  'enable_archiving' => 'setEnableArchiving'
3569  );
3570 
3571  if (isset($templateData['results_presentation']['value'])) {
3572  $templateData['results_presentation']['value'] = array();
3573  }
3574 
3575 
3576 
3577  $score_settings = $object->getScoreSettings();
3578  foreach ($simpleSetters as $field => $setter) {
3579  if (!array_key_exists($field, $templateData)) {
3580  continue;
3581  }
3582 
3583  switch ($field) {
3584 
3585  case 'count_system':
3586  case 'count_system':
3587  case 'pass_scoring':
3588  case 'score_cutting':
3589  $score_settings = $score_settings->withScoringSettings(
3590  $score_settings->getScoringSettings()->$setter(
3591  (int) $templateData[$field]['value']
3592  )
3593  );
3594  break;
3595 
3596  case 'pass_deletion_allowed':
3597  case 'grading_status':
3598  case 'grading_mark':
3599  $score_settings = $score_settings->withResultSummarySettings(
3600  $score_settings->getResultSummarySettings()->$setter(
3601  (bool) $templateData[$field]['value']
3602  )
3603  );
3604  break;
3605  case 'results_access_enabled':
3606  $score_settings = $score_settings->withResultSummarySettings(
3607  $score_settings->getResultSummarySettings()->$setter(
3608  (int) $templateData[$field]['value']
3609  )
3610  );
3611  break;
3612 
3613  case 'solution_details':
3614  case 'solution_feedback':
3615  case 'solution_suggested':
3616  case 'solution_printview':
3617  case 'solution_signature':
3618  case 'examid_in_test_res':
3619  case 'exp_sc_short':
3620  $score_settings = $score_settings->withResultDetailsSettings(
3621  $score_settings->getResultDetailsSettings()->$setter(
3622  (bool) $templateData[$field]['value']
3623  )
3624  );
3625  break;
3626 
3627  case 'highscore_enabled':
3628  $score_settings = $score_settings->withGamificationSettings(
3629  $score_settings->getGamificationSettings()->$setter(
3630  (bool) $templateData[$field]['value']
3631  )
3632  );
3633  break;
3634 
3635  case 'autosave':
3636  if ($templateData[$field]['value'] > 0) {
3637  $object->setAutosave(true);
3638  $object->setAutosaveIval($templateData[$field]['value'] * 1000);
3639  } else {
3640  $object->setAutosave(false);
3641  }
3642  break;
3643 
3644  case 'redirection_enabled':
3645  /* if( $templateData[$field]['value'] > REDIRECT_NONE )
3646  {
3647  $object->setRedirectionMode($templateData[$field]['value']);
3648  }
3649  else
3650  {
3651  $object->setRedirectionMode(REDIRECT_NONE);
3652  } */
3653  if (strlen($templateData[$field]['value'])) {
3655  $object->setRedirectionUrl($templateData[$field]['value']);
3656  } else {
3658  $object->setRedirectionUrl('');
3659  }
3660  break;
3661 
3662  case 'answer_fixation_handling':
3663  switch ($templateData[$field]['value']) {
3667  break;
3668 
3672  break;
3673 
3677  break;
3678 
3682  break;
3683  }
3684  break;
3685 
3686  default:
3687  if (strlen($setter)) {
3688  $object->$setter($templateData[$field]['value']);
3689  }
3690  }
3691  }
3692  $object->getScoreSettingsRepository()->store($score_settings);
3693  }
3694 
3696  {
3697  global $DIC;
3698  $ilAccess = $DIC['ilAccess'];
3699  if (!$ilAccess->checkAccess("write", "", $this->ref_id)) {
3700  // allow only write access
3701  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cannot_edit_test"), true);
3702  $this->ctrl->redirect($this, "infoScreen");
3703  }
3704 
3705  global $DIC;
3706  $ilCtrl = $DIC['ilCtrl'];
3707 
3708  $orders = $obligations = array();
3709 
3710  foreach ((array) $this->testrequest->raw('order') as $qId => $order) {
3711  $id = (int) str_replace('q_', '', $qId);
3712 
3713  $orders[$id] = $order;
3714  }
3715 
3716  if ($this->object->areObligationsEnabled() && $this->testrequest->isset('obligatory') && is_array($this->testrequest->raw('obligatory'))) {
3717  foreach ($this->testrequest->raw('obligatory') as $qId => $obligation) {
3718  $id = (int) str_replace('q_', '', $qId);
3719 
3721  $obligations[$id] = $obligation;
3722  }
3723  }
3724  }
3725 
3726  $this->object->setQuestionOrderAndObligations(
3727  $orders,
3728  $obligations
3729  );
3730 
3731  $this->tpl->setOnScreenMessage('success', $this->lng->txt('saved_successfully'), true);
3732  $ilCtrl->redirect($this, 'questions');
3733  }
3734 
3738  protected function movePageFormObject()
3739  {
3740  global $DIC;
3741  $lng = $DIC['lng'];
3742  $ilCtrl = $DIC['ilCtrl'];
3743  $tpl = $DIC['tpl'];
3744 
3745  if (!$this->access->checkAccess('write', '', $this->object->getRefId())) {
3746  $this->redirectAfterMissingWrite();
3747  }
3748 
3749  $form = new ilPropertyFormGUI();
3750  $form->setFormAction($ilCtrl->getFormAction($this, "movePage"));
3751  $form->setTitle($lng->txt("test_move_page"));
3752 
3753  $old_pos = new ilHiddenInputGUI("q_id");
3754  $old_pos->setValue($this->testrequest->raw('q_id'));
3755  $form->addItem($old_pos);
3756 
3757  $questions = $this->object->getQuestionTitlesAndIndexes();
3758  if (!is_array($questions)) {
3759  $questions = array();
3760  }
3761 
3762  foreach ($questions as $k => $q) {
3763  if ($k == $this->testrequest->raw('q_id')) {
3764  unset($questions[$k]);
3765  continue;
3766  }
3767  $questions[$k] = $lng->txt('behind') . ' ' . $q;
3768  }
3769  #$questions['0'] = $lng->txt('first');
3770 
3771  $options = array(
3772  0 => $lng->txt('first')
3773  );
3774  foreach ($questions as $k => $q) {
3775  $options[$k] = $q . ' [' . $this->lng->txt('question_id_short') . ': ' . $k . ']';
3776  }
3777 
3778  $pos = new ilSelectInputGUI($lng->txt("position"), "position_after");
3779  $pos->setOptions($options);
3780  $form->addItem($pos);
3781 
3782  $form->addCommandButton("movePage", $lng->txt("submit"));
3783  $form->addCommandButton("showPage", $lng->txt("cancel"));
3784 
3785  return $tpl->setContent($form->getHTML());
3786  }
3787 
3788  public function movePageObject()
3789  {
3790  global $DIC;
3791  $ilAccess = $DIC['ilAccess'];
3792  if (!$ilAccess->checkAccess("write", "", $this->ref_id)) {
3793  // allow only write access
3794  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cannot_edit_test"), true);
3795  $this->ctrl->redirect($this, "infoScreen");
3796  }
3797 
3798  $this->object->moveQuestionAfter($this->testrequest->raw('q_id'), $this->testrequest->raw('position_after'));
3799  $this->showPageObject();
3800  }
3801 
3802  public function showPageObject()
3803  {
3804  global $DIC;
3805  $ilCtrl = $DIC['ilCtrl'];
3806 
3807  $ilCtrl->setParameterByClass('iltestexpresspageobjectgui', 'q_id', $this->testrequest->raw('q_id'));
3808  $ilCtrl->redirectByClass('iltestexpresspageobjectgui', 'showPage');
3809  }
3810 
3811  public function copyQuestionObject()
3812  {
3813  global $DIC;
3814  $ilAccess = $DIC['ilAccess'];
3815  if (!$ilAccess->checkAccess("write", "", $this->ref_id)) {
3816  // allow only write access
3817  $this->tpl->setOnScreenMessage('info', $this->lng->txt("cannot_edit_test"), true);
3818  $this->ctrl->redirect($this, "infoScreen");
3819  }
3820 
3821  if ($this->testrequest->hasQuestionId() && !is_array($this->testrequest->raw('q_id'))) {
3822  $ids = [$this->testrequest->getQuestionId()];
3823  } elseif ($this->testrequest->getQuestionIds()) {
3824  $ids = $this->testrequest->getQuestionIds();
3825  } else {
3826  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('copy_no_questions_selected'), true);
3827  $this->ctrl->redirect($this, 'questions');
3828  }
3829 
3830  $copy_count = 0;
3831 
3832  $questionTitles = $this->object->getQuestionTitles();
3833 
3834  foreach ($ids as $id) {
3835  $question = assQuestion::instantiateQuestionGUI($id);
3836  if ($question) {
3837  $title = $question->object->getTitle();
3838  $i = 2;
3839  while (in_array($title . ' (' . $i . ')', $questionTitles)) {
3840  $i++;
3841  }
3842 
3843  $title .= ' (' . $i . ')';
3844 
3845  $questionTitles[] = $title;
3846 
3847  $new_id = $question->object->duplicate(false, $title);
3848 
3849  $clone = assQuestion::instantiateQuestionGUI($new_id);
3850  $clone->object->setObjId($this->object->getId());
3851  $clone->object->saveToDb();
3852 
3853  $this->object->insertQuestion($this->testQuestionSetConfigFactory->getQuestionSetConfig(), $new_id, true);
3854 
3855  $copy_count++;
3856  }
3857  }
3858 
3859  $this->tpl->setOnScreenMessage('success', $this->lng->txt('copy_questions_success'), true);
3860 
3861  $this->ctrl->redirect($this, 'questions');
3862  }
3863 
3865  {
3866  if (!ilLOSettings::isObjectiveTest($this->ref_id)) {
3867  return;
3868  }
3869 
3870  $path = $this->tree->getPathFull($this->ref_id);
3871 
3872  while ($parent = array_pop($path)) {
3873  if ($parent['type'] === 'crs') {
3874  $container_ref_id = $parent['ref_id'];
3875  break;
3876  }
3877  }
3878 
3879  $container_obj_id = ilObject2::_lookupObjId($container_ref_id);
3880 
3881  $this->objectiveOrientedContainer->setObjId($container_obj_id);
3882  $this->objectiveOrientedContainer->setRefId($container_ref_id);
3883  }
3884 
3886  {
3888  }
3889 }
const MATCHING_QUESTION_IDENTIFIER
initImportForm(string $new_type)
const MULTIPLE_CHOICE_QUESTION_IDENTIFIER
const ADDITIONAL_CONTENT_EDITING_MODE_IPE
const QT_NUMERIC
static get(string $a_var)
const PDF_PRINT_VIEW_QUESTIONS
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getAvailableQuestionpools($use_object_id=false, $equal_points=false, $could_be_offline=false, $showPath=false, $with_questioncount=false, $permission="read", $usr_id="")
Returns the available question pools for the active user.
populateQuestionBrowserToolbarButtons(ilToolbarGUI $toolbar, string $context)
setAutosave($autosave)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static appendUrlParameterString(string $a_url, string $a_par, bool $xml_style=false)
exit
Definition: login.php:28
Class ilInfoScreenGUI.
const ERROR_TEXT_IDENTIFIER
$context
Definition: webdav.php:29
createQuestionObject()
Called when a new question should be created from a test.
const IL_INST_ID
Definition: constants.php:40
setCloseFormTag(bool $a_val)
setRedirectionMode($redirection_mode=0)
getTabs()
adds tabs to tab gui object
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilObjTestGUI.
static _getLog(int $ts_from, int $ts_to, int $test_id, bool $test_only=false)
Retrieve assessment log datasets from the database.
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
reviewobject()
Review tab to create a print of all questions without points and solutions.
fullscreenObject()
show fullscreen view
GUI class for the workflow of copying objects.
const QUESTION_SET_TYPE_RANDOM
copyQuestionToPool($sourceQuestionId, $targetParentId)
uploadObject($redirect=true)
display status information or report errors messages in case of error
const ROOT_FOLDER_ID
Definition: constants.php:32
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setOnScreenMessage(string $type, string $a_txt, bool $a_keep=false)
Set a message to be displayed to the user.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
prepareOutput(bool $show_sub_objects=true)
cancelCreateQuestionObject()
Called when the creation of a new question is cancelled.
This class represents a file property in a property form.
buildPageViewToolbar($qid=0)
setInfo(string $a_info)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static getQuestionTypeByTypeId($type_id)
const SCORE_REPORTING_AFTER_PASSED
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
setTestAccess($testAccess)
insertQuestionsBeforeObject()
Insert checked questions before the actual selection.
const KPRIM_CHOICE_QUESTION_IDENTIFIER
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
getDidacticTemplateVar(string $type)
Get didactic template setting from creation screen.
static _getQuestionTypeName($type_tag)
const LONG_MENU_QUESTION_IDENTIFIER
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const TEXTSUBSET_QUESTION_IDENTIFIER
static lookupParentObjId(int $questionId)
const QT_ORDERING
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getOriginalId(int $question_id)
$refId
Definition: xapitoken.php:58
const REDIRECT_NONE
Redirect after finishing test constants.
historyObject()
Creates the change history for a test.
downloadFileObject()
download file
setSuffixes(array $a_suffixes)
loadLanguageModule(string $a_module)
Load language module.
createQuestionpoolTargetObject($cmd)
Called when a new question should be created from a test Important: $cmd may be overwritten if no que...
createObject()
create new object form
insertRandomSelectionObject()
Inserts a random selection into the test.
redirectTo_ilObjTestSettingsGeneralGUI_showForm_Object()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
confirmRemoveQuestionsObject()
Remove questions from the test after confirmation.
static prepareFormOutput($a_str, bool $a_strip=false)
const IL_CAL_UNIX
static setTokenMaxLifetimeInSeconds(int $token_max_lifetime_in_seconds)
static getStyleSheetLocation(string $mode="output", string $a_css_name="", string $a_css_location="")
get full style sheet file name (path inclusive) of current user
static accessViolationRedirect()
infoScreen($session_lock="")
show information screen
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static $infoScreenChildClasses
setRedirectionUrl($redirection_url=null)
static _getQuestionGUI(string $question_type='', int $question_id=-1)
Creates a question gui representation and returns the alias to the question gui.
addDefaultsObject()
Adds the defaults of this test to the defaults.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$ilErr
Definition: raiseError.php:17
$path
Definition: ltiservices.php:32
participantsActionObject()
Evaluates the actions on the participants page.
const FILE_UPLOAD_IDENTIFIER
static unzip(string $path_to_zip_file, bool $overwrite_existing=false, bool $unpack_flat=false)
uploadTst()
imports test and question(s)
static _lookupObjId(int $ref_id)
static instantiateQuestionGUI(int $a_question_id)
setCreationMode(bool $mode=true)
if true, a creation screen is displayed the current [ref_id] don&#39;t belong to the current class! The m...
cancelRemoveQuestionsObject()
Cancels the removal of questions from the test.
Interface ilCtrlBaseClassInterface describes ilCtrl base classes.
global $DIC
Definition: feed.php:28
const REDIRECT_ALWAYS
allowDecimals(bool $a_value)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if($format !==null) $name
Definition: metadata.php:247
ilLanguage $lng
const QT_FILEUPLOAD
copyAndLinkQuestionsToPoolObject()
ilObjectDataCache $ilObjDataCache
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const SCORE_REPORTING_IMMIDIATLY
static _lookupOnlineTestAccess($a_test_id, $a_user_id)
Checks if a user is allowd to run an online exam.
static instantiateQuestion(int $question_id)
const ALLOWED_TAGS_IN_TITLE_AND_DESCRIPTION
const QT_KPRIM_CHOICE
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _needsManualScoring(int $question_id)
This class represents a property in a property form.
addButton(string $a_txt, string $a_cmd, string $a_target="", ?int $a_acc_key=null, string $a_additional_attrs='', string $a_id="", string $a_class='submit')
setAutosaveIval($autosave_ival)
ilGlobalTemplateInterface $tpl
static _lookupTitle(int $obj_id)
const NUMERIC_QUESTION_IDENTIFIER
setContent(string $a_html)
Sets content for standard template.
$keys
Definition: metadata.php:204
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$_GET['client_id']
Definition: saml1-acs.php:21
$log
Definition: result.php:33
removeQuestionsObject()
Called when a selection of questions should be removed from the test.
const ORDERING_HORIZONTAL_IDENTIFIER
This class represents a number property in a property form.
const QT_FORMULA
const COUNT_PARTIAL_SOLUTIONS
applyDefaultsObject($confirmed=false)
Applies the selected test defaults.
download_paragraphObject()
download source code paragraph
const QT_MULTIPLE_CHOICE_SR
Class ilObjectGUI Basic methods of all Output classes.
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
setValue(string $a_value)
const ORDERING_QUESTION_IDENTIFIER
insertQuestionsAfterObject()
Insert checked questions after the actual selection.
static _recordReadEvent(string $a_type, int $a_ref_id, int $obj_id, int $usr_id, bool $isCatchupWriteEvents=true, $a_ext_rc=null, $a_ext_time=null)
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
createQuestionPool($name="dummy", $description="")
Creates a new questionpool and returns the reference id.
Class ilObjFile.
const QT_ERRORTEXT
__construct($refId=null)
Constructor public.
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
static originalQuestionExists(int $questionId)
string $key
Consumer key/client ID value.
Definition: System.php:193
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilToolbarGUI $toolbar
afterSave(ilObject $new_object)
Post (successful) object creation hook.
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
getParentId(int $a_node_id)
get parent id of given node
infoScreenObject()
this one is called from the info button in the repository not very nice to set cmdClass/Cmd manually...
insertQuestionsBeforeOrAfter(int $insert_mode)
const TEXT_QUESTION_IDENTIFIER
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addDidacticTemplateOptions(array &$options)
const QT_LONG_MENU
$txt
Definition: error.php:13
setRequired(bool $a_required)
static isQuestionObligationPossible($questionId)
checks wether the obligation for question with given id is possible or not
static getContentStylePath(int $a_style_id, bool $add_random=true, bool $add_token=true)
get content style path static (to avoid full reading)
setCustomRolesForSelection(array $a_roles)
Set custom roles for mapping to LTI roles.
getTargetQuestionpoolForm($questionpools, $cmd)
setTabsManager($tabsManager)
const QT_MULTIPLE_CHOICE_MR
static getAllSettingsTemplates(string $a_type, bool $a_include_auto_generated=false)
Get all settings templates of type.
checkPermissionBool(string $perm, string $cmd="", string $type="", ?int $ref_id=null)
const SCORE_REPORTING_FINISHED
static isObjectiveTest(int $a_trst_ref_id)
Check if test ref_id is used in an objective course.
importFileObject(int $parent_id=null)
form for new test object import
static redirect(string $a_script)
static _createImportDirectory()
creates data directory for import files (data_dir/tst_data/tst_<id>/import, depending on data directo...
const TEST_FIXED_SEQUENCE
Test constants.
executeCommand()
execute command
exportObject()
Gateway for exports initiated from workspace, as there is a generic forward to {objTypeMainGUI}::expo...
const SCORE_REPORTING_DATE
const QT_MATCHING
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
importVerifiedFileObject()
imports question(s) into the questionpool (after verification)
certificateObject()
Shows the certificate editor.
__construct(Container $dic, ilPlugin $plugin)
applyTemplate($templateData, ilObjTest $object)
getReturnLocation(string $cmd, string $default_location="")
Get return location for command (command is method name without "Object", e.g.
This class represents a text area property in a property form.
const QT_TEXTSUBSET
const ADDITIONAL_CONTENT_EDITING_MODE_RTE
executeCreateQuestionObject()
Called when a new question should be created from a test after confirmation.
$ilUser
Definition: imgupload.php:34
initQuestion($questionId, $parentObjId)
static isAdditionalQuestionContentEditingModePageObjectEnabled()
Returns the fact wether content editing with ilias page editor is enabled for questions or not...
const QUESTION_SET_TYPE_FIXED
setFollowupQuestionAnswerFixationEnabled($followupQuestionAnswerFixationEnabled)
movePageFormObject()
Move current page.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
moveQuestionsObject()
Marks selected questions for moving.
$message
Definition: xapiexit.php:32
New PermissionGUI (extends from old ilPermission2GUI) RBAC related output.
Service GUI class for tests.
insertQuestionsObject()
Insert questions from the questionbrowser into the test.
printobject()
Print tab to create a print of all questions with points and solutions.
static generatePDF($pdf_output, $output_mode, $filename=null, $purpose=null)
const IL_CAL_TIMESTAMP
const QT_IMAGEMAP
static prepareGenerationRequest(string $service, string $purpose)
Prepare the content processing for a PDF generation request This function should be called as in a re...
deleteDefaultsObject()
Deletes selected test defaults.
static _lookupType(int $id, bool $reference=false)
setInstantFeedbackAnswerFixationEnabled($instantFeedbackAnswerFixationEnabled)
static setUseRelativeDates(bool $a_status)
set use relative dates
backObject()
Called when the back button in the question browser was pressed.
const SINGLE_CHOICE_QUESTION_IDENTIFIER
addHeaderAction()
Add header action menu.
static clear(string $a_var)
copyQuestionsToPool($questionIds, $qplId)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ILIAS Test InternalRequestService $testrequest
static set(string $a_var, $a_val)
Set a value.
showMediaFullscreen(int $a_style_id=0)
show fullscreen view of media object
Settings template application class.
const CLOZE_TEST_IDENTIFIER
Question identifier constants.
const SCORE_BEST_PASS
static _setImportDirectory($a_import_dir=null)
send_paragraph(string $par_id, string $filename)
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
static _getTestDefaults($test_defaults_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _gotoRepositoryRoot(bool $raise_error=false)
Goto repository root.
static _getImportDirectory()
Get the import directory location of the test.
$i
Definition: metadata.php:41
const QT_ORDERING_HORIZONTAL
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const IMAGEMAP_QUESTION_IDENTIFIER
const FORMULA_QUESTION_IDENTIFIER
removeQuestionsForm($checked_questions)
Displays a form to confirm the removal of questions from the test.